import { beforeEach, describe, expect, it } from 'vitest'; import { newClient } from '../helpers/api'; import { resetDatabase } from '../helpers/database'; import { createAnswer, createFile, createHunt, createQuest, createTeam, createUser, TEST_PASSWORD } from '../helpers/factories'; import { prisma } from './setup'; beforeEach(resetDatabase); /** * Hunt with one quest and three finalized answers: * - a public picture (shown) * - a private picture (hidden) * - no picture at all (hidden) */ async function seedDiashow(reveal: boolean) { const creator = await createUser(); const hunt = await createHunt(creator.id, { revealAnswers: reveal, revealQuests: reveal }); const quest = await createQuest(hunt.id); const owner = await createUser(); const team = await createTeam(hunt.id, owner.id); const answerPublic = await createAnswer({ teamId: team.id, questId: quest.id, memberId: owner.id }); const publicFile = await createFile(owner.id, { answerId: answerPublic.id }); await prisma.questAnswer.update({ where: { id: answerPublic.id }, data: { pictureId: publicFile.id, final: true } }); const answerPrivate = await createAnswer({ teamId: team.id, questId: quest.id, memberId: owner.id }); const privateFile = await createFile(owner.id, { answerId: answerPrivate.id, private: true }); await prisma.questAnswer.update({ where: { id: answerPrivate.id }, data: { pictureId: privateFile.id, final: true } }); await createAnswer( { teamId: team.id, questId: quest.id, memberId: owner.id }, { final: true, text: 'no picture' } ); return { hunt, quest, team, publicFile }; } describe('diashow (GET /api/hunt/[huntId]/diashow)', () => { it('returns 404 for unknown hunts', async () => { const res = await newClient().get('/api/hunt/999999/diashow'); expect(res.status).toBe(404); }); it('blocks anonymous users before answers are revealed', async () => { const { hunt } = await seedDiashow(false); const res = await newClient().get(`/api/hunt/${hunt.id}/diashow`); expect(res.status).toBe(403); }); it('lets the hunt creator peek before reveal', async () => { const { hunt } = await seedDiashow(false); const creator = await prisma.user.findFirstOrThrow({ where: { huntsCreated: { some: { id: hunt.id } } } }); const client = newClient(); await client.login(creator.email, TEST_PASSWORD); const res = await client.get(`/api/hunt/${hunt.id}/diashow`); expect(res.status).toBe(200); }); it('only shows finalized answers with public pictures', async () => { const { hunt, quest, team, publicFile } = await seedDiashow(true); const res = await newClient().get(`/api/hunt/${hunt.id}/diashow`); expect(res.status).toBe(200); const body = await res.json(); expect(body.id).toBe(hunt.id); expect(body.quests).toHaveLength(1); expect(body.quests[0].id).toBe(quest.id); expect(body.quests[0].answers).toHaveLength(1); expect(body.quests[0].answers[0].picture.url).toBe(publicFile.url); expect(body.quests[0].answers[0].team).toMatchObject({ id: team.id, name: team.name }); }); it('omits quests whose final answers are all private', async () => { const creator = await createUser(); const hunt = await createHunt(creator.id, { revealAnswers: true, revealQuests: true }); const quest = await createQuest(hunt.id); const owner = await createUser(); const team = await createTeam(hunt.id, owner.id); const answer = await createAnswer({ teamId: team.id, questId: quest.id, memberId: owner.id }); const privateFile = await createFile(owner.id, { answerId: answer.id, private: true }); await prisma.questAnswer.update({ where: { id: answer.id }, data: { pictureId: privateFile.id, final: true } }); const res = await newClient().get(`/api/hunt/${hunt.id}/diashow`); expect(res.status).toBe(200); const body = await res.json(); expect(body.quests).toEqual([]); }); });