// #110 - E2E tests for /promotions endpoints import { assertEquals } from "@std/assert"; import { makeContextWithAffiliation, makeEmployeeContext, makeGetRequest, makeJsonRequest, } from "../helpers/handler.ts"; import { seedPromotions, truncateAll } from "../helpers/db_integration.ts"; import { handler as promotionsHandler } from "$apps/students/api/promotions.ts"; import { handler as promotionHandler } from "$apps/students/api/promotions/[idPromo].ts"; // --- GET /promotions --- Deno.test({ name: "e2e promotions: GET /promotions returns all as employee", async fn() { await truncateAll(); await seedPromotions([ { id: "PEIP1-2024", annee: "2024" }, { id: "PEIP2-2024", annee: "2024" }, ]); const res = await promotionsHandler.GET!( makeGetRequest("/promotions"), makeEmployeeContext(), ); assertEquals(res.status, 200); const body = await res.json(); assertEquals(body.length, 2); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "e2e promotions: GET /promotions returns empty for non-employee", async fn() { await truncateAll(); await seedPromotions([{ id: "PEIP1-2024", annee: "2024" }]); const res = await promotionsHandler.GET!( makeGetRequest("/promotions"), makeContextWithAffiliation("student"), ); assertEquals(res.status, 200); const body = await res.json(); assertEquals(body.length, 0); }, sanitizeResources: false, sanitizeOps: false, }); // --- POST /promotions --- Deno.test({ name: "e2e promotions: POST /promotions creates promotion (201)", async fn() { await truncateAll(); const res = await promotionsHandler.POST!( makeJsonRequest("/promotions", "POST", { idPromo: "INFO3-2025", annee: "2025", }), makeEmployeeContext(), ); assertEquals(res.status, 201); const body = await res.json(); assertEquals(body.id, "INFO3-2025"); assertEquals(body.annee, "2025"); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "e2e promotions: POST /promotions 403 for non-employee", async fn() { await truncateAll(); const res = await promotionsHandler.POST!( makeJsonRequest("/promotions", "POST", { idPromo: "X", annee: "2025" }), makeContextWithAffiliation("student"), ); assertEquals(res.status, 403); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "e2e promotions: POST /promotions 400 on missing fields", async fn() { await truncateAll(); const res = await promotionsHandler.POST!( makeJsonRequest("/promotions", "POST", { idPromo: "X" }), makeEmployeeContext(), ); assertEquals(res.status, 400); }, sanitizeResources: false, sanitizeOps: false, }); // --- GET /promotions/:idPromo --- Deno.test({ name: "e2e promotions: GET /promotions/:id returns promotion", async fn() { await truncateAll(); await seedPromotions([{ id: "INFO3-2024", annee: "2024" }]); const res = await promotionHandler.GET!( makeGetRequest("/promotions/INFO3-2024"), makeEmployeeContext({ idPromo: "INFO3-2024" }), ); assertEquals(res.status, 200); const body = await res.json(); assertEquals(body.id, "INFO3-2024"); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "e2e promotions: GET /promotions/:id 404 when not found", async fn() { await truncateAll(); const res = await promotionHandler.GET!( makeGetRequest("/promotions/GHOST"), makeEmployeeContext({ idPromo: "GHOST" }), ); assertEquals(res.status, 404); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "e2e promotions: GET /promotions/:id 403 for non-employee", async fn() { await truncateAll(); const res = await promotionHandler.GET!( makeGetRequest("/promotions/INFO3-2024"), makeContextWithAffiliation("student", { idPromo: "INFO3-2024" }), ); assertEquals(res.status, 403); }, sanitizeResources: false, sanitizeOps: false, }); // --- PUT /promotions/:idPromo --- Deno.test({ name: "e2e promotions: PUT /promotions/:id updates annee", async fn() { await truncateAll(); await seedPromotions([{ id: "INFO3-2023", annee: "2023" }]); const res = await promotionHandler.PUT!( makeJsonRequest("/promotions/INFO3-2023", "PUT", { annee: "2024" }), makeEmployeeContext({ idPromo: "INFO3-2023" }), ); assertEquals(res.status, 200); const body = await res.json(); assertEquals(body.annee, "2024"); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "e2e promotions: PUT /promotions/:id 404 when not found", async fn() { await truncateAll(); const res = await promotionHandler.PUT!( makeJsonRequest("/promotions/GHOST", "PUT", { annee: "2025" }), makeEmployeeContext({ idPromo: "GHOST" }), ); assertEquals(res.status, 404); }, sanitizeResources: false, sanitizeOps: false, }); // --- DELETE /promotions/:idPromo --- Deno.test({ name: "e2e promotions: DELETE /promotions/:id returns 204", async fn() { await truncateAll(); await seedPromotions([{ id: "INFO3-2022", annee: "2022" }]); const res = await promotionHandler.DELETE!( makeGetRequest("/promotions/INFO3-2022"), makeEmployeeContext({ idPromo: "INFO3-2022" }), ); assertEquals(res.status, 204); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "e2e promotions: DELETE /promotions/:id 404 when not found", async fn() { await truncateAll(); const res = await promotionHandler.DELETE!( makeGetRequest("/promotions/GHOST"), makeEmployeeContext({ idPromo: "GHOST" }), ); assertEquals(res.status, 404); }, sanitizeResources: false, sanitizeOps: false, });