test: MVP-4 Sprint 4 - Version history tests

- Add 11 tests for versions.ts (create, get, restore, edge cases)
- Add noteVersion mock to api.integration.test.ts
This commit is contained in:
2026-03-22 17:45:53 -03:00
parent 9ed7d8acec
commit a67442e9ed
2 changed files with 172 additions and 0 deletions

View File

@@ -38,6 +38,11 @@ const mockPrisma = {
create: jest.fn(), create: jest.fn(),
createMany: jest.fn(), createMany: jest.fn(),
}, },
noteVersion: {
create: jest.fn(),
findMany: jest.fn(),
findUnique: jest.fn(),
},
$transaction: jest.fn((callback) => callback(mockPrisma)), $transaction: jest.fn((callback) => callback(mockPrisma)),
} }

167
__tests__/versions.test.ts Normal file
View File

@@ -0,0 +1,167 @@
import { createVersion, getVersions, getVersion, restoreVersion } from '@/lib/versions'
jest.mock('@/lib/prisma', () => ({
prisma: {
note: { findUnique: jest.fn(), update: jest.fn() },
noteVersion: { create: jest.fn(), findMany: jest.fn(), findUnique: jest.fn() },
},
}))
import { prisma } from '@/lib/prisma'
import { NotFoundError } from '@/lib/errors'
describe('versions.ts', () => {
beforeEach(() => {
jest.clearAllMocks()
})
describe('createVersion', () => {
it('creates a version with correct noteId, title, content', async () => {
const mockNote = { id: 'note-1', title: 'Test Title', content: 'Test Content' }
const mockVersion = { id: 'version-1', noteId: 'note-1', title: 'Test Title', content: 'Test Content', createdAt: new Date() }
;(prisma.note.findUnique as jest.Mock).mockResolvedValue(mockNote)
;(prisma.noteVersion.create as jest.Mock).mockResolvedValue(mockVersion)
const result = await createVersion('note-1')
expect(result).toEqual(mockVersion)
expect(prisma.note.findUnique).toHaveBeenCalledWith({
where: { id: 'note-1' },
select: { id: true, title: true, content: true },
})
expect(prisma.noteVersion.create).toHaveBeenCalledWith({
data: {
noteId: 'note-1',
title: 'Test Title',
content: 'Test Content',
},
})
})
it('throws NotFoundError if note does not exist', async () => {
;(prisma.note.findUnique as jest.Mock).mockResolvedValue(null)
await expect(createVersion('note-1')).rejects.toThrow(NotFoundError)
})
})
describe('getVersions', () => {
it('returns all versions for a note ordered by createdAt desc', async () => {
const mockNote = { id: 'note-1' }
const mockVersions = [
{ id: 'version-2', noteId: 'note-1', title: 'Title 2', content: 'Content 2', createdAt: new Date('2024-01-02') },
{ id: 'version-1', noteId: 'note-1', title: 'Title 1', content: 'Content 1', createdAt: new Date('2024-01-01') },
]
;(prisma.note.findUnique as jest.Mock).mockResolvedValue(mockNote)
;(prisma.noteVersion.findMany as jest.Mock).mockResolvedValue(mockVersions)
const result = await getVersions('note-1')
expect(result).toEqual(mockVersions)
expect(prisma.note.findUnique).toHaveBeenCalledWith({ where: { id: 'note-1' } })
expect(prisma.noteVersion.findMany).toHaveBeenCalledWith({
where: { noteId: 'note-1' },
orderBy: { createdAt: 'desc' },
select: {
id: true,
noteId: true,
title: true,
content: true,
createdAt: true,
},
})
})
it('throws NotFoundError if note does not exist', async () => {
;(prisma.note.findUnique as jest.Mock).mockResolvedValue(null)
await expect(getVersions('note-1')).rejects.toThrow(NotFoundError)
})
})
describe('getVersion', () => {
it('returns version by ID', async () => {
const mockVersion = { id: 'version-1', noteId: 'note-1', title: 'Title', content: 'Content', createdAt: new Date() }
;(prisma.noteVersion.findUnique as jest.Mock).mockResolvedValue(mockVersion)
const result = await getVersion('version-1')
expect(result).toEqual(mockVersion)
expect(prisma.noteVersion.findUnique).toHaveBeenCalledWith({ where: { id: 'version-1' } })
})
it('throws NotFoundError if version does not exist', async () => {
;(prisma.noteVersion.findUnique as jest.Mock).mockResolvedValue(null)
await expect(getVersion('version-1')).rejects.toThrow(NotFoundError)
})
})
describe('restoreVersion', () => {
it('updates note title and content from version', async () => {
const mockNote = { id: 'note-1', title: 'Old Title', content: 'Old Content' }
const mockVersion = { id: 'version-1', noteId: 'note-1', title: 'Old Title', content: 'Old Content', createdAt: new Date() }
const updatedNote = { id: 'note-1', title: 'Old Title', content: 'Old Content', updatedAt: new Date() }
;(prisma.note.findUnique as jest.Mock).mockResolvedValue(mockNote)
;(prisma.noteVersion.findUnique as jest.Mock).mockResolvedValue(mockVersion)
;(prisma.note.update as jest.Mock).mockResolvedValue(updatedNote)
const result = await restoreVersion('note-1', 'version-1')
expect(result).toEqual(updatedNote)
expect(prisma.note.update).toHaveBeenCalledWith({
where: { id: 'note-1' },
data: {
title: 'Old Title',
content: 'Old Content',
updatedAt: expect.any(Date),
},
select: {
id: true,
title: true,
content: true,
updatedAt: true,
},
})
})
it('updates note updatedAt timestamp', async () => {
const mockNote = { id: 'note-1', title: 'Title', content: 'Content' }
const mockVersion = { id: 'version-1', noteId: 'note-1', title: 'Title', content: 'Content', createdAt: new Date() }
const beforeUpdate = new Date('2024-01-01')
const afterUpdate = new Date('2024-01-02')
;(prisma.note.findUnique as jest.Mock).mockResolvedValue(mockNote)
;(prisma.noteVersion.findUnique as jest.Mock).mockResolvedValue(mockVersion)
;(prisma.note.update as jest.Mock).mockResolvedValue({ id: 'note-1', title: 'Title', content: 'Content', updatedAt: afterUpdate })
const result = await restoreVersion('note-1', 'version-1')
expect(result.updatedAt).toEqual(afterUpdate)
})
it('throws NotFoundError if note does not exist', async () => {
;(prisma.note.findUnique as jest.Mock).mockResolvedValue(null)
await expect(restoreVersion('note-1', 'version-1')).rejects.toThrow(NotFoundError)
})
it('throws NotFoundError if version does not exist', async () => {
;(prisma.note.findUnique as jest.Mock).mockResolvedValue({ id: 'note-1' })
;(prisma.noteVersion.findUnique as jest.Mock).mockResolvedValue(null)
await expect(restoreVersion('note-1', 'version-1')).rejects.toThrow(NotFoundError)
})
it('throws NotFoundError if version does not belong to note', async () => {
;(prisma.note.findUnique as jest.Mock).mockResolvedValue({ id: 'note-1' })
;(prisma.noteVersion.findUnique as jest.Mock).mockResolvedValue({ id: 'version-1', noteId: 'note-2' })
await expect(restoreVersion('note-1', 'version-1')).rejects.toThrow(NotFoundError)
})
})
})