6402f802e9
- Generate Drizzle migrations (databases/migrations/) - Add databases/schema.kit.ts for drizzle-kit (Node-compatible imports) - Update drizzle.config.ts to use schema.kit.ts - Add deno tasks: test:unit, test:integration, migrate - Add tests/helpers/db_integration.ts: testDb, truncateAll, seed helpers - Add .gitea/workflows/test.yml: CI with postgres service container - Update lint.yml: run test:unit only (no DB needed) - Update deploy.yml: add check-code job, gate deploy on it
107 lines
3.1 KiB
TypeScript
107 lines
3.1 KiB
TypeScript
// Helper pour les tests d'intégration avec PostgreSQL
|
|
// Nécessite les variables d'environnement POSTGRES_* (ou TEST_DATABASE_URL)
|
|
|
|
import { drizzle } from "npm:drizzle-orm@0.45.2/node-postgres";
|
|
import pg from "npm:pg@8.20.0";
|
|
import * as schema from "$root/databases/schema.ts";
|
|
|
|
const { Pool } = pg;
|
|
|
|
function createTestPool(): pg.Pool {
|
|
const url = Deno.env.get("TEST_DATABASE_URL");
|
|
if (url) {
|
|
return new Pool({ connectionString: url });
|
|
}
|
|
return new Pool({
|
|
host: Deno.env.get("POSTGRES_HOST") ?? "localhost",
|
|
port: Number(Deno.env.get("POSTGRES_PORT") ?? 5432),
|
|
user: Deno.env.get("POSTGRES_USER") ?? "test",
|
|
password: Deno.env.get("POSTGRES_PASS") ?? "test",
|
|
database: Deno.env.get("POSTGRES_DB") ?? "polympr_test",
|
|
});
|
|
}
|
|
|
|
export const testPool = createTestPool();
|
|
export const testDb = drizzle(testPool, { schema });
|
|
|
|
// Ordre de truncate respectant les FK (enfants avant parents)
|
|
const TRUNCATE_ORDER = [
|
|
"mobility",
|
|
"ajustements",
|
|
"notes",
|
|
"ue_modules",
|
|
"enseignements",
|
|
"role_permissions",
|
|
"students",
|
|
"ue_modules",
|
|
"users",
|
|
"modules",
|
|
"ues",
|
|
"promotions",
|
|
"permissions",
|
|
"roles",
|
|
] as const;
|
|
|
|
/**
|
|
* Vide toutes les tables dans le bon ordre.
|
|
* À appeler dans beforeEach de chaque test d'intégration.
|
|
*/
|
|
export async function truncateAll(): Promise<void> {
|
|
const client = await testPool.connect();
|
|
try {
|
|
// Désactiver les FK temporairement pour simplifier
|
|
await client.query("SET session_replication_role = replica");
|
|
for (const table of TRUNCATE_ORDER) {
|
|
await client.query(`TRUNCATE TABLE "${table}" RESTART IDENTITY CASCADE`);
|
|
}
|
|
await client.query("SET session_replication_role = DEFAULT");
|
|
} finally {
|
|
client.release();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Ferme le pool à la fin de la suite de tests.
|
|
*/
|
|
export async function closeTestPool(): Promise<void> {
|
|
await testPool.end();
|
|
}
|
|
|
|
// --- Helpers d'insertion de fixtures ---
|
|
|
|
export async function seedRoles(
|
|
rows: { nom: string }[],
|
|
): Promise<typeof schema.roles.$inferSelect[]> {
|
|
return await testDb.insert(schema.roles).values(rows).returning();
|
|
}
|
|
|
|
export async function seedPromotions(
|
|
rows: { id: string; annee?: string }[],
|
|
): Promise<typeof schema.promotions.$inferSelect[]> {
|
|
return await testDb.insert(schema.promotions).values(rows).returning();
|
|
}
|
|
|
|
export async function seedStudents(
|
|
rows: { nom: string; prenom: string; idPromo?: string }[],
|
|
): Promise<typeof schema.students.$inferSelect[]> {
|
|
return await testDb.insert(schema.students).values(rows).returning();
|
|
}
|
|
|
|
export async function seedModules(
|
|
rows: { id: string; nom: string }[],
|
|
): Promise<typeof schema.modules.$inferSelect[]> {
|
|
return await testDb.insert(schema.modules).values(rows).returning();
|
|
}
|
|
|
|
export async function seedUes(
|
|
rows: { nom: string }[],
|
|
): Promise<typeof schema.ues.$inferSelect[]> {
|
|
return await testDb.insert(schema.ues).values(rows).returning();
|
|
}
|
|
|
|
export async function seedUsers(
|
|
rows: { id: string; nom: string; prenom: string; idRole?: number }[],
|
|
): Promise<typeof schema.users.$inferSelect[]> {
|
|
return await testDb.insert(schema.users).values(rows).returning();
|
|
}
|