diff --git a/tests/helpers/api_mock.ts b/tests/helpers/api_mock.ts new file mode 100644 index 0000000..686f32d --- /dev/null +++ b/tests/helpers/api_mock.ts @@ -0,0 +1,56 @@ +// Mock de fetch() pour les tests + +// deno-lint-ignore no-explicit-any +let _originalFetch: ((input: any, init?: any) => Promise) | null = + null; + +/** + * Remplace globalThis.fetch par un mock qui retourne des réponses + * pré-configurées selon l'URL. + * + * @param routes - Map URL pattern → données de réponse (sera sérialisé en JSON) + */ +export function mockFetch( + routes: Record, +): void { + _originalFetch = globalThis.fetch; + + globalThis.fetch = ( + input: string | URL | Request, + _init?: RequestInit, + ): Promise => { + const url = typeof input === "string" + ? input + : input instanceof URL + ? input.toString() + : input.url; + + for (const [pattern, data] of Object.entries(routes)) { + if (url.includes(pattern)) { + return Promise.resolve( + new Response(JSON.stringify(data), { + status: 200, + headers: { "Content-Type": "application/json" }, + }), + ); + } + } + + return Promise.resolve( + new Response(JSON.stringify({ error: "Not Found" }), { + status: 404, + headers: { "Content-Type": "application/json" }, + }), + ); + }; +} + +/** + * Restaure le fetch original. + */ +export function restoreFetch(): void { + if (_originalFetch) { + globalThis.fetch = _originalFetch; + _originalFetch = null; + } +} diff --git a/tests/helpers/fixtures.ts b/tests/helpers/fixtures.ts new file mode 100644 index 0000000..e63920e --- /dev/null +++ b/tests/helpers/fixtures.ts @@ -0,0 +1,107 @@ +// Types et données de test pour l'API PolyMPR + +export interface Student { + numEtud: number; + nom: string; + prenom: string; + idPromo: number; +} + +export interface Promotion { + idPromo: number; + annee: string; +} + +export interface Prof { + id: number; + nom: string; + prenom: string; +} + +export interface Module { + id: number; + nom: string; +} + +export interface Note { + note: number; + numEtud: number; + idModule: number; +} + +export interface UE { + id: number; + nom: string; +} + +export interface UeModule { + idModule: number; + idUE: number; + idPromo: number; + coeff: number; +} + +export interface Enseignement { + idProf: number; + idModule: number; + idPromo: number; +} + +export interface Ajustement { + numEtud: number; + idUE: number; + valeur: number; +} + +// --- Fixtures --- + +export const students: Student[] = [ + { numEtud: 1, nom: "Dupont", prenom: "Alice", idPromo: 1 }, + { numEtud: 2, nom: "Martin", prenom: "Bob", idPromo: 1 }, + { numEtud: 3, nom: "Durand", prenom: "Claire", idPromo: 2 }, +]; + +export const promotions: Promotion[] = [ + { idPromo: 1, annee: "2025-2026" }, + { idPromo: 2, annee: "2024-2025" }, +]; + +export const profs: Prof[] = [ + { id: 1, nom: "Leclerc", prenom: "Jean" }, + { id: 2, nom: "Moreau", prenom: "Sophie" }, +]; + +export const modules: Module[] = [ + { id: 1, nom: "Mathématiques" }, + { id: 2, nom: "Informatique" }, + { id: 3, nom: "Physique" }, +]; + +export const notes: Note[] = [ + { note: 15, numEtud: 1, idModule: 1 }, + { note: 12, numEtud: 1, idModule: 2 }, + { note: 18, numEtud: 2, idModule: 1 }, + { note: 9, numEtud: 3, idModule: 3 }, +]; + +export const ues: UE[] = [ + { id: 1, nom: "Sciences fondamentales" }, + { id: 2, nom: "Sciences appliquées" }, +]; + +export const ueModules: UeModule[] = [ + { idModule: 1, idUE: 1, idPromo: 1, coeff: 3 }, + { idModule: 2, idUE: 2, idPromo: 1, coeff: 4 }, + { idModule: 3, idUE: 1, idPromo: 2, coeff: 2 }, +]; + +export const enseignements: Enseignement[] = [ + { idProf: 1, idModule: 1, idPromo: 1 }, + { idProf: 2, idModule: 2, idPromo: 1 }, + { idProf: 1, idModule: 3, idPromo: 2 }, +]; + +export const ajustements: Ajustement[] = [ + { numEtud: 1, idUE: 1, valeur: 0.5 }, + { numEtud: 3, idUE: 1, valeur: -1 }, +]; diff --git a/tests/helpers/render.ts b/tests/helpers/render.ts new file mode 100644 index 0000000..f87b1d9 --- /dev/null +++ b/tests/helpers/render.ts @@ -0,0 +1,55 @@ +// Setup happy-dom + wrapper render pour les tests de composants Preact + +import { Window } from "happy-dom"; + +let _window: Window | null = null; + +/** + * Initialise un environnement DOM virtuel via happy-dom. + * À appeler avant de rendre des composants Preact dans les tests. + */ +export function setupDOM(): void { + _window = new Window({ url: "http://localhost" }); + + // Expose les globals DOM nécessaires à Preact + const globals = _window as unknown as Record; + const target = globalThis as unknown as Record; + + for ( + const key of [ + "document", + "navigator", + "location", + "HTMLElement", + "HTMLInputElement", + "HTMLTextAreaElement", + "HTMLSelectElement", + "Event", + "CustomEvent", + "KeyboardEvent", + "MouseEvent", + "InputEvent", + "MutationObserver", + "requestAnimationFrame", + "cancelAnimationFrame", + ] + ) { + target[key] = globals[key]; + } + + target["window"] = _window; +} + +/** + * Nettoie l'environnement DOM. + * À appeler dans un afterEach ou à la fin d'un test. + */ +export function cleanupDOM(): void { + if (_window) { + const doc = _window.document; + doc.body.innerHTML = ""; + doc.head.innerHTML = ""; + _window.close(); + _window = null; + } +}