50afe2ae66
test: add tests for fixtures, mock fetch, mock db, and happy-dom - Add comprehensive fixture shape tests. - Expand mockFetch to support methods, status codes, and body tracking. - Introduce getFetchCalls to inspect intercepted requests. - Add mockDb helper for in-memory DB operations. - Reorganize tests for clarity and coverage. - Ensure happy-dom setup/cleanup works correctly.
123 lines
3.3 KiB
TypeScript
123 lines
3.3 KiB
TypeScript
// Mock de la couche Drizzle pour les tests unitaires/intégration
|
|
// Permet de tester les handlers sans connexion PostgreSQL
|
|
|
|
export interface MockQueryResult<T> {
|
|
rows: T[];
|
|
}
|
|
|
|
export interface MockDbConfig {
|
|
// Table name → array of rows
|
|
// deno-lint-ignore no-explicit-any
|
|
tables: Record<string, Record<string, any>[]>;
|
|
}
|
|
|
|
/**
|
|
* Crée un mock de la DB Drizzle.
|
|
* Simule select/insert/update/delete avec un store en mémoire.
|
|
*
|
|
* Usage :
|
|
* ```ts
|
|
* const db = createMockDb({
|
|
* tables: {
|
|
* students: [{ numEtud: 21212006, nom: "Dupont", ... }],
|
|
* notes: [],
|
|
* }
|
|
* });
|
|
*
|
|
* // Lire toutes les lignes d'une table
|
|
* const rows = db.getTable("students");
|
|
*
|
|
* // Insérer
|
|
* db.insert("students", { numEtud: 21212009, nom: "Test", ... });
|
|
*
|
|
* // Trouver par clé
|
|
* const student = db.findOne("students", (r) => r.numEtud === 21212006);
|
|
*
|
|
* // Supprimer
|
|
* db.deleteWhere("students", (r) => r.numEtud === 21212006);
|
|
* ```
|
|
*/
|
|
export function createMockDb(config: MockDbConfig) {
|
|
// Deep clone pour éviter les mutations entre tests
|
|
// deno-lint-ignore no-explicit-any
|
|
const tables: Record<string, Record<string, any>[]> = {};
|
|
for (const [name, rows] of Object.entries(config.tables)) {
|
|
tables[name] = rows.map((r) => ({ ...r }));
|
|
}
|
|
|
|
return {
|
|
/** Retourne toutes les lignes d'une table */
|
|
getTable<T = Record<string, unknown>>(name: string): T[] {
|
|
return (tables[name] ?? []) as T[];
|
|
},
|
|
|
|
/** Retourne les lignes qui matchent le filtre */
|
|
findMany<T = Record<string, unknown>>(
|
|
name: string,
|
|
predicate: (row: T) => boolean,
|
|
): T[] {
|
|
return (this.getTable<T>(name)).filter(predicate);
|
|
},
|
|
|
|
/** Retourne la première ligne qui matche, ou undefined */
|
|
findOne<T = Record<string, unknown>>(
|
|
name: string,
|
|
predicate: (row: T) => boolean,
|
|
): T | undefined {
|
|
return (this.getTable<T>(name)).find(predicate);
|
|
},
|
|
|
|
/** Insère une ligne dans la table */
|
|
insert<T = Record<string, unknown>>(name: string, row: T): T {
|
|
if (!tables[name]) tables[name] = [];
|
|
const copy = { ...row } as T;
|
|
// deno-lint-ignore no-explicit-any
|
|
tables[name].push(copy as any);
|
|
return copy;
|
|
},
|
|
|
|
/** Met à jour les lignes qui matchent le prédicat */
|
|
updateWhere<T = Record<string, unknown>>(
|
|
name: string,
|
|
predicate: (row: T) => boolean,
|
|
updates: Partial<T>,
|
|
): number {
|
|
const rows = this.getTable<T>(name);
|
|
let count = 0;
|
|
for (const row of rows) {
|
|
if (predicate(row)) {
|
|
Object.assign(row as Record<string, unknown>, updates);
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
},
|
|
|
|
/** Supprime les lignes qui matchent le prédicat */
|
|
deleteWhere<T = Record<string, unknown>>(
|
|
name: string,
|
|
predicate: (row: T) => boolean,
|
|
): number {
|
|
const before = (tables[name] ?? []).length;
|
|
tables[name] = (tables[name] ?? []).filter(
|
|
(r) => !predicate(r as unknown as T),
|
|
);
|
|
return before - tables[name].length;
|
|
},
|
|
|
|
/** Vide une table */
|
|
clear(name: string): void {
|
|
tables[name] = [];
|
|
},
|
|
|
|
/** Vide toutes les tables */
|
|
reset(): void {
|
|
for (const name of Object.keys(tables)) {
|
|
tables[name] = [];
|
|
}
|
|
},
|
|
};
|
|
}
|
|
|
|
export type MockDb = ReturnType<typeof createMockDb>;
|