import { describe, it, expect, vi, beforeEach } from "vitest"; import request from "supertest"; vi.mock("@glossa/db", () => ({ getGameTerms: vi.fn(), getDistractors: vi.fn(), })); import { getGameTerms, getDistractors } from "@glossa/db"; import { createApp } from "../app.js"; const app = createApp(); const mockGetGameTerms = vi.mocked(getGameTerms); const mockGetDistractors = vi.mocked(getDistractors); const validBody = { source_language: "en", target_language: "it", pos: "noun", difficulty: "easy", rounds: "3", }; const fakeTerms = [ { termId: "t1", sourceText: "dog", targetText: "cane", sourceGloss: null }, { termId: "t2", sourceText: "cat", targetText: "gatto", sourceGloss: null }, { termId: "t3", sourceText: "house", targetText: "casa", sourceGloss: null }, ]; beforeEach(() => { vi.clearAllMocks(); mockGetGameTerms.mockResolvedValue(fakeTerms); mockGetDistractors.mockResolvedValue(["wrong1", "wrong2", "wrong3"]); }); describe("POST /api/v1/game/start", () => { it("returns 200 with a valid game session", async () => { const res = await request(app).post("/api/v1/game/start").send(validBody); expect(res.status).toBe(200); expect(res.body.success).toBe(true); expect(res.body.data.sessionId).toBeDefined(); expect(res.body.data.questions).toHaveLength(3); }); it("returns 400 when the body is empty", async () => { const res = await request(app).post("/api/v1/game/start").send({}); expect(res.status).toBe(400); expect(res.body.success).toBe(false); expect(res.body.error).toBeDefined(); }); it("returns 400 when required fields are missing", async () => { const res = await request(app) .post("/api/v1/game/start") .send({ source_language: "en" }); expect(res.status).toBe(400); expect(res.body.success).toBe(false); }); it("returns 400 when a field has an invalid value", async () => { const res = await request(app) .post("/api/v1/game/start") .send({ ...validBody, difficulty: "impossible" }); expect(res.status).toBe(400); expect(res.body.success).toBe(false); }); }); describe("POST /api/v1/game/answer", () => { it("returns 200 with an answer result for a valid submission", async () => { // Start a game first const startRes = await request(app) .post("/api/v1/game/start") .send(validBody); const { sessionId, questions } = startRes.body.data; const question = questions[0]; const res = await request(app) .post("/api/v1/game/answer") .send({ sessionId, questionId: question.questionId, selectedOptionId: 0, }); expect(res.status).toBe(200); expect(res.body.success).toBe(true); expect(res.body.data.questionId).toBe(question.questionId); expect(typeof res.body.data.isCorrect).toBe("boolean"); expect(typeof res.body.data.correctOptionId).toBe("number"); expect(res.body.data.selectedOptionId).toBe(0); }); it("returns 400 when the body is empty", async () => { const res = await request(app).post("/api/v1/game/answer").send({}); expect(res.status).toBe(400); expect(res.body.success).toBe(false); }); it("returns 404 when the session does not exist", async () => { const res = await request(app) .post("/api/v1/game/answer") .send({ sessionId: "00000000-0000-0000-0000-000000000000", questionId: "00000000-0000-0000-0000-000000000000", selectedOptionId: 0, }); expect(res.status).toBe(404); expect(res.body.success).toBe(false); expect(res.body.error).toContain("Game session not found"); }); it("returns 404 when the question does not exist in the session", async () => { const startRes = await request(app) .post("/api/v1/game/start") .send(validBody); const { sessionId } = startRes.body.data; const res = await request(app) .post("/api/v1/game/answer") .send({ sessionId, questionId: "00000000-0000-0000-0000-000000000000", selectedOptionId: 0, }); expect(res.status).toBe(404); expect(res.body.success).toBe(false); expect(res.body.error).toContain("Question not found"); }); });