import { describe, it, expect, vi, beforeEach } from 'vitest'; import { NextRequest } from 'next/server'; vi.mock('@/lib/db/queries', () => ({ getReviewCheckpoints: vi.fn(), getNextReviewAt: vi.fn().mockResolvedValue(null), })); import { GET } from '../route'; import { getReviewCheckpoints } from '@/lib/db/queries'; const mockGet = vi.mocked(getReviewCheckpoints); const REVIEW_ITEMS = [ { conceptId: 'c1', conceptName: 'Closures', score: 0.65, checkpointId: 'cp1', checkpointPrompt: 'Explain what a closure is.', checkpointKind: 'explain' as const, }, ]; function makeRequest(userId?: string) { const url = userId ? `http://localhost:3000/api/review?userId=${userId}` : 'http://localhost:3000/api/review'; return new NextRequest(url); } describe('GET /api/review', () => { beforeEach(() => vi.clearAllMocks()); it('returns 400 when userId is missing', async () => { const res = await GET(makeRequest()); expect(res.status).toBe(400); }); it('returns 200 with empty list when nothing due', async () => { mockGet.mockResolvedValue([]); const res = await GET(makeRequest('user-1')); expect(res.status).toBe(200); const body = await res.json(); expect(body.checkpoints).toHaveLength(0); }); it('returns 200 with due checkpoints', async () => { mockGet.mockResolvedValue(REVIEW_ITEMS); const res = await GET(makeRequest('user-1')); expect(res.status).toBe(200); const body = await res.json(); expect(body.checkpoints).toHaveLength(1); expect(body.checkpoints[0].conceptName).toBe('Closures'); expect(body.checkpoints[0].score).toBe(0.65); }); it('passes userId to getReviewCheckpoints', async () => { mockGet.mockResolvedValue([]); await GET(makeRequest('user-abc')); expect(mockGet).toHaveBeenCalledWith('user-abc'); }); });