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:
167
__tests__/versions.test.ts
Normal file
167
__tests__/versions.test.ts
Normal 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)
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user