Files
recall/__tests__/versions.test.ts
Daniel Arroyo a67442e9ed 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
2026-03-22 17:45:53 -03:00

168 lines
6.3 KiB
TypeScript

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)
})
})
})