mirror of
https://github.com/R0m1k3/PleinR.git
synced 2026-10-11 17:27:54 +02:00
Accueil, pied de page et catégories : compteur réel, boutons alignés, référentiel complété
- Accueil : le bandeau « Faites partie de l'aventure » affiche le nombre d'adhérents validés (statut active) au lieu de « plus de 120 » codé en dur. - Pied de page : les boutons Facebook / LinkedIn ont la même largeur (grille à une colonne dimensionnée sur le plus long) et une icône à largeur fixe. - Catégories : référentiel unique dans src/db/categories.ts (104 métiers, dont assurance, bazar/discount, grande distribution, librairie-presse, tabac, vétérinaire, auto-école, etc.), inséré par la migration 0012 avec ON CONFLICT (slug) : les catégories manquantes apparaissent au prochain démarrage, sans écraser un libellé renommé depuis le backend. Le seed et l'action « Ajouter une catégorie » réutilisent ce référentiel et sa palette. - tests/categories.test.ts vérifie unicité des slugs, contraintes de la table et cohérence entre le référentiel et la migration. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HDbKbJrPWweXXYSxA8MXW7
This commit is contained in:
12 files changed
+1718
-108
No files matched your search
@@ -0,0 +1,46 @@
|
||||
import { strict as assert } from "node:assert";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { describe, it } from "node:test";
|
||||
|
||||
import { CATEGORY_PALETTE, CATEGORY_REFERENTIAL, categoryRows } from "../src/db/categories";
|
||||
|
||||
describe("Référentiel des catégories", () => {
|
||||
it("garde des slugs uniques et stables", () => {
|
||||
const slugs = CATEGORY_REFERENTIAL.map((c) => c.slug);
|
||||
assert.equal(new Set(slugs).size, slugs.length, "slug en double");
|
||||
for (const slug of slugs) {
|
||||
assert.match(slug, /^[a-z0-9]+(?:-[a-z0-9]+)*$/, `slug invalide : ${slug}`);
|
||||
}
|
||||
// Slugs historiques : des fiches adhérents y sont rattachées.
|
||||
for (const legacy of ["alimentation", "boulangerie", "restauration", "mode-beaute", "artisanat", "services", "sante"]) {
|
||||
assert.ok(slugs.includes(legacy), `${legacy} doit rester présent`);
|
||||
}
|
||||
});
|
||||
|
||||
it("couvre les métiers demandés (assurance, bazar/discount, grande distribution…)", () => {
|
||||
const slugs = new Set(CATEGORY_REFERENTIAL.map((c) => c.slug));
|
||||
for (const expected of ["assurance", "bazar-discount", "supermarche", "librairie-papeterie", "tabac-presse", "veterinaire", "auto-ecole"]) {
|
||||
assert.ok(slugs.has(expected), `${expected} manquant`);
|
||||
}
|
||||
});
|
||||
|
||||
it("respecte les contraintes de la table", () => {
|
||||
for (const row of categoryRows()) {
|
||||
assert.ok(row.label.length <= 120, `libellé trop long : ${row.label}`);
|
||||
assert.ok(row.slug.length <= 80);
|
||||
assert.ok(CATEGORY_PALETTE.some((p) => p.accent === row.accent && p.tint === row.tint));
|
||||
assert.ok(row.sort >= 1);
|
||||
}
|
||||
});
|
||||
|
||||
it("est intégralement repris par la migration 0012", () => {
|
||||
const sql = readFileSync(new URL("../drizzle/0012_referentiel_categories.sql", import.meta.url), "utf8");
|
||||
for (const row of categoryRows()) {
|
||||
assert.ok(sql.includes(`('${row.slug}', '${row.label.replace(/'/g, "''")}', '${row.accent}', '${row.tint}', ${row.sort})`),
|
||||
`${row.slug} absent ou différent dans la migration`);
|
||||
}
|
||||
// Ne jamais écraser un libellé renommé depuis le backend.
|
||||
assert.ok(sql.includes('ON CONFLICT ("slug") DO UPDATE SET "sort" = EXCLUDED."sort";'));
|
||||
assert.ok(!/DO UPDATE SET[^;]*"label"/.test(sql));
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user