// #110 - Unit tests for /promotions endpoints import { assertEquals, assertExists } from "@std/assert"; import { mockFetch, restoreFetch } from "../helpers/api_mock.ts"; import { createMockDb } from "../helpers/db_mock.ts"; import { type Promotion, promotions } from "../helpers/fixtures.ts"; // --- Fixtures --- Deno.test("promotions: fixtures have correct shape", () => { assertEquals(promotions.length, 3); assertEquals(typeof promotions[0].idPromo, "string"); assertEquals(typeof promotions[0].annee, "string"); }); // --- Mock API --- Deno.test("mock API: GET /promotions returns list", async () => { mockFetch({ "/promotions": promotions }); try { const res = await fetch("http://localhost/api/promotions"); assertEquals(res.status, 200); const data: Promotion[] = await res.json(); assertEquals(data.length, 3); assertExists(data.find((p) => p.idPromo === "4AFISE25/26")); } finally { restoreFetch(); } }); Deno.test("mock API: GET /promotions/:id returns one", async () => { mockFetch({ "/promotions/4AFISE25%2F26": promotions[0] }); try { const res = await fetch("http://localhost/api/promotions/4AFISE25%2F26"); assertEquals(res.status, 200); const data: Promotion = await res.json(); assertEquals(data.idPromo, "4AFISE25/26"); } finally { restoreFetch(); } }); Deno.test("mock API: GET /promotions/:id 404 when not found", async () => { mockFetch({ "/promotions/UNKNOWN": { status: 404, body: { error: "Ressource introuvable" }, }, }); try { const res = await fetch("http://localhost/api/promotions/UNKNOWN"); assertEquals(res.status, 404); } finally { restoreFetch(); } }); Deno.test("mock API: POST /promotions creates promotion (201)", async () => { const newPromo: Promotion = { idPromo: "NEW2025", annee: "2025" }; mockFetch({ "/promotions": { method: "POST", status: 201, body: newPromo } }); try { const res = await fetch("http://localhost/api/promotions", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ idPromo: "NEW2025", annee: "2025" }), }); assertEquals(res.status, 201); const data: Promotion = await res.json(); assertEquals(data.idPromo, "NEW2025"); } finally { restoreFetch(); } }); Deno.test("mock API: POST /promotions 400 on missing fields", async () => { mockFetch({ "/promotions": { method: "POST", status: 400 } }); try { const res = await fetch("http://localhost/api/promotions", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ idPromo: "NEW2025" }), }); assertEquals(res.status, 400); } finally { restoreFetch(); } }); Deno.test("mock API: PUT /promotions/:id updates promotion", async () => { const updated = { idPromo: "4AFISE25/26", annee: "2026" }; mockFetch({ "/promotions/4AFISE25%2F26": { method: "PUT", status: 200, body: updated }, }); try { const res = await fetch("http://localhost/api/promotions/4AFISE25%2F26", { method: "PUT", headers: { "content-type": "application/json" }, body: JSON.stringify({ annee: "2026" }), }); assertEquals(res.status, 200); const data: Promotion = await res.json(); assertEquals(data.annee, "2026"); } finally { restoreFetch(); } }); Deno.test("mock API: DELETE /promotions/:id returns 204", async () => { mockFetch({ "/promotions/4AFISE25%2F26": { method: "DELETE", status: 204 } }); try { const res = await fetch("http://localhost/api/promotions/4AFISE25%2F26", { method: "DELETE", }); assertEquals(res.status, 204); } finally { restoreFetch(); } }); // --- Mock DB --- Deno.test("mock DB: find promotion by idPromo", () => { const db = createMockDb({ tables: { promotions: [...promotions] } }); const p = db.findOne( "promotions", (r) => r.idPromo === "4AFISE25/26", ); assertExists(p); assertEquals(p.annee, "2025"); }); Deno.test("mock DB: insert promotion", () => { const db = createMockDb({ tables: { promotions: [...promotions] } }); db.insert("promotions", { idPromo: "NEW2025", annee: "2025" }); assertEquals(db.getTable("promotions").length, 4); }); Deno.test("mock DB: update promotion annee", () => { const db = createMockDb({ tables: { promotions: [...promotions] } }); db.updateWhere( "promotions", (p) => p.idPromo === "4AFISE25/26", { annee: "2026" }, ); assertEquals( db.findOne("promotions", (p) => p.idPromo === "4AFISE25/26") ?.annee, "2026", ); }); Deno.test("mock DB: delete promotion", () => { const db = createMockDb({ tables: { promotions: [...promotions] } }); const count = db.deleteWhere( "promotions", (p) => p.idPromo === "4AFISE25/26", ); assertEquals(count, 1); assertEquals(db.getTable("promotions").length, 2); });