import { describe, it, expect } from 'vitest'; import { prismaMock } from '../test/setup'; import { addComment, deleteComment } from './commentService'; import { HttpError } from '../lib/httpError'; describe('commentService.addComment', () => { it('404s when ticket not found', async () => { prismaMock.ticket.findFirst.mockResolvedValue(null); await expect(addComment('V1', 'body', 'u1')).rejects.toMatchObject({ status: 404 }); }); it('accepts either id or displayId and writes audit + comment', async () => { prismaMock.ticket.findFirst.mockResolvedValue({ id: 'tid', displayId: 'V111', title: 't', overview: 'o', severity: 3, status: 'OPEN', categoryId: 'c', typeId: 'ty', itemId: 'i', assigneeId: null, createdById: 'u1', createdAt: new Date(), updatedAt: new Date(), resolvedAt: null, }); prismaMock.comment.create.mockResolvedValue({ id: 'cid', body: 'hi', ticketId: 'tid', authorId: 'u1', createdAt: new Date(), }); await addComment('V111', 'hi', 'u1'); expect(prismaMock.comment.create).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ ticketId: 'tid', body: 'hi' }) }), ); expect(prismaMock.auditLog.create).toHaveBeenCalledWith( expect.objectContaining({ data: expect.objectContaining({ action: 'COMMENT_ADDED', detail: 'hi' }), }), ); }); }); describe('commentService.deleteComment', () => { const baseComment = { id: 'cid', body: 'x', ticketId: 'tid', authorId: 'author1', createdAt: new Date(), }; it('rejects non-author non-admin with 403', async () => { prismaMock.comment.findUnique.mockResolvedValue(baseComment); await expect( deleteComment('cid', { id: 'other', role: 'AGENT' }), ).rejects.toMatchObject({ status: 403 }); }); it('allows the author to delete', async () => { prismaMock.comment.findUnique.mockResolvedValue(baseComment); await expect(deleteComment('cid', { id: 'author1', role: 'AGENT' })).resolves.toBeUndefined(); expect(prismaMock.comment.delete).toHaveBeenCalled(); }); it('allows admin to delete', async () => { prismaMock.comment.findUnique.mockResolvedValue(baseComment); await expect(deleteComment('cid', { id: 'other', role: 'ADMIN' })).resolves.toBeUndefined(); expect(prismaMock.comment.delete).toHaveBeenCalled(); }); it('404s when comment missing', async () => { prismaMock.comment.findUnique.mockResolvedValue(null); await expect( deleteComment('missing', { id: 'u', role: 'ADMIN' }), ).rejects.toThrow(HttpError); }); });