/** * API Integration Tests * * These tests verify the API endpoints work correctly. * They require a test database setup. */ import { NextRequest } from 'next/server' // Mock Prisma for API tests const mockPrisma = { note: { findMany: jest.fn().mockResolvedValue([]), findUnique: jest.fn(), create: jest.fn(), update: jest.fn(), delete: jest.fn(), }, tag: { findMany: jest.fn().mockResolvedValue([]), findUnique: jest.fn(), upsert: jest.fn(), }, noteTag: { create: jest.fn(), deleteMany: jest.fn(), }, } jest.mock('@/lib/prisma', () => ({ prisma: mockPrisma, })) describe('API Endpoints', () => { beforeEach(() => { jest.clearAllMocks() }) describe('GET /api/notes', () => { it('returns all notes without query params', async () => { const mockNotes = [ { id: '1', title: 'Test Note', content: 'Content', type: 'note', tags: [] }, ] mockPrisma.note.findMany.mockResolvedValue(mockNotes) // Import the route handler const { GET } = await import('@/app/api/notes/route') const response = await GET() const data = await response.json() expect(response.status).toBe(200) expect(data).toEqual(mockNotes) }) }) describe('GET /api/tags', () => { it('returns all tags', async () => { const mockTags = [ { id: '1', name: 'javascript' }, { id: '2', name: 'python' }, ] mockPrisma.tag.findMany.mockResolvedValue(mockTags) const { GET } = await import('@/app/api/tags/route') const response = await GET(new NextRequest('http://localhost/api/tags')) const data = await response.json() expect(response.status).toBe(200) expect(data).toEqual(mockTags) }) it('returns tag suggestions when q param is provided', async () => { const mockTags = [ { id: '1', name: 'javascript' }, { id: '2', name: 'java' }, ] mockPrisma.tag.findMany.mockResolvedValue(mockTags) const { GET } = await import('@/app/api/tags/route') const response = await GET(new NextRequest('http://localhost/api/tags?q=java')) const data = await response.json() expect(response.status).toBe(200) expect(Array.isArray(data)).toBe(true) }) }) describe('POST /api/notes', () => { it('creates a note with tags', async () => { const newNote = { id: '1', title: 'New Note', content: 'Content', type: 'note', isFavorite: false, isPinned: false, createdAt: new Date(), updatedAt: new Date(), tags: [], } const createdTag = { id: '1', name: 'javascript' } mockPrisma.note.create.mockResolvedValue(newNote) mockPrisma.tag.upsert.mockResolvedValue(createdTag) const { POST } = await import('@/app/api/notes/route') const request = new NextRequest('http://localhost/api/notes', { method: 'POST', body: JSON.stringify({ title: 'New Note', content: 'Content', tags: ['JavaScript'], }), }) const response = await POST(request) const data = await response.json() expect(response.status).toBe(201) expect(data.title).toBe('New Note') }) it('returns 400 for invalid note data', async () => { const { POST } = await import('@/app/api/notes/route') const request = new NextRequest('http://localhost/api/notes', { method: 'POST', body: JSON.stringify({ title: '', // Invalid: empty title content: '', }), }) const response = await POST(request) expect(response.status).toBe(400) }) }) describe('GET /api/search', () => { it('returns search results', async () => { const mockScoredNotes = [ { id: '1', title: 'Test Note', content: 'Content about JavaScript', type: 'note', isFavorite: false, isPinned: false, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), tags: [], score: 5, matchType: 'exact' as const, }, ] // This would require the actual search module const { GET } = await import('@/app/api/search/route') const response = await GET(new NextRequest('http://localhost/api/search?q=test')) const data = await response.json() expect(response.status).toBe(200) }) }) })