import { describe, it, expect, vi, beforeEach } from 'vitest'; import { isHttpError } from '@sveltejs/kit'; vi.mock('$lib/db', () => ({ prisma: { proclamation: { findMany: vi.fn() }, licenseKey: { findUnique: vi.fn() }, user: { findUnique: vi.fn() }, userProclamations: { findMany: vi.fn() }, colorPalette: { findMany: vi.fn() } } })); import { prisma } from '$lib/db'; import { GET } from './+server'; type GETEvent = Parameters[0]; const mockProclamationFindMany = prisma.proclamation.findMany as ReturnType; const mockLicenseKey = prisma.licenseKey.findUnique as ReturnType; const mockUser = prisma.user.findUnique as ReturnType; const mockUserProclamations = prisma.userProclamations.findMany as ReturnType; const mockColorPalette = prisma.colorPalette.findMany as ReturnType; const palettes = [ { solfeggioFrequencyId: 5, colors: ['#32CD32', '#3CB371', '#90EE90', '#98FB98', '#ADFFA9', '#C8FFD2', '#F0FFF0'] }, { solfeggioFrequencyId: 7, colors: ['#00BFFF', '#1E90FF', '#4169E1', '#6495ED', '#87CEEB', '#ADD8E6', '#F0F8FF'] } ]; const peaceProclamation = { id: 'b40fdcb9-703c-420e-af32-a081964c6f08', name: 'Peace & Relaxation', content: '

The text content

', categoryId: 5, groupId: 1, solfeggioFrequencyId: 5, solfeggioFrequency: { id: 5, name: 'Solar Plexus', value: 528 } }; const crown936 = { id: '936-hz-proclamation', name: 'Crown 936', content: '

no canonical id

', categoryId: 4, solfeggioFrequencyId: 1, solfeggioFrequency: { id: 1, name: 'Crown', value: 936 } }; function getRequest(headers: Record = {}): Request { return new Request('http://localhost/api/v2/proclamations', { headers }); } async function expectHttpError(promise: unknown, status: number, message: string) { try { await promise; } catch (e) { expect(isHttpError(e)).toBe(true); const err = e as { status: number; body: { message: string } }; expect(err.status).toBe(status); expect(err.body.message).toBe(message); return; } throw new Error('expected handler to throw an HttpError'); } describe('GET /api/v2/proclamations', () => { beforeEach(() => { vi.clearAllMocks(); }); it('returns full proclamation records with canonical ids and embedded palettes', async () => { mockProclamationFindMany.mockResolvedValue([peaceProclamation]); mockColorPalette.mockResolvedValue(palettes); const res = await GET({ request: getRequest() } as GETEvent); expect(res.status).toBe(200); expect(await res.json()).toEqual([ { id: peaceProclamation.id, name: peaceProclamation.name, content: peaceProclamation.content, categoryId: 5, groupId: 1, solfeggioFrequencyId: 5, colorPalette: palettes[0].colors } ]); }); it('drops proclamations whose frequency has no canonical id (936 Hz)', async () => { mockProclamationFindMany.mockResolvedValue([peaceProclamation, crown936]); mockColorPalette.mockResolvedValue(palettes); const res = await GET({ request: getRequest() } as GETEvent); const body = (await res.json()) as { id: string }[]; expect(body).toHaveLength(1); expect(body[0].id).toBe(peaceProclamation.id); }); it('returns the entitled proclamations as full records when headers are supplied', async () => { mockLicenseKey.mockResolvedValue({ id: 'key-1', key: 'ABCD-EFGH-IJKL-MNOP' }); mockUser.mockResolvedValue({ id: 'user-1', email: 'user@example.com', licenseKeys: [{ id: 'key-1', key: 'ABCD-EFGH-IJKL-MNOP' }] }); mockUserProclamations.mockResolvedValue([ { userId: 'user-1', proclamationId: peaceProclamation.id, proclamation: peaceProclamation } ]); mockColorPalette.mockResolvedValue(palettes); const res = await GET({ request: getRequest({ 'x-license-key': 'ABCD-EFGH-IJKL-MNOP', 'x-email': 'user@example.com' }) } as GETEvent); expect(res.status).toBe(200); const body = (await res.json()) as { id: string }[]; expect(body).toHaveLength(1); expect(body[0].id).toBe(peaceProclamation.id); expect(mockUserProclamations).toHaveBeenCalledWith( expect.objectContaining({ where: { userId: 'user-1' } }) ); }); it('rejects when only one entitlement header is supplied', async () => { await expectHttpError( GET({ request: getRequest({ 'x-license-key': 'ABCD-EFGH-IJKL-MNOP' }) } as GETEvent), 400, 'not-authorized' ); }); it('rejects an unknown license key', async () => { mockLicenseKey.mockResolvedValue(null); await expectHttpError( GET({ request: getRequest({ 'x-license-key': 'UNKNOWN-KEY', 'x-email': 'user@example.com' }) } as GETEvent), 400, 'not-authorized' ); }); it('rejects a key that does not belong to the user', async () => { mockLicenseKey.mockResolvedValue({ id: 'key-2', key: 'OTHER-KEY' }); mockUser.mockResolvedValue({ id: 'user-1', email: 'user@example.com', licenseKeys: [{ id: 'key-1', key: 'ABCD-EFGH-IJKL-MNOP' }] }); await expectHttpError( GET({ request: getRequest({ 'x-license-key': 'OTHER-KEY', 'x-email': 'user@example.com' }) } as GETEvent), 400, "this key doesn't appear to belong to you" ); }); });