feat: introduce a shared config with an optional local override
The mairie form needs an organiser, an email and the café defaults. Ship the defaults in the repo and let each volunteer override the personal bits in config.local.json (gitignored, optional: a fresh clone still works). config.js carries neither import nor export on purpose, so that it loads both as a classic script (content script, background) and as an ESM module. That is what lets presentation.js drop its duplicated café address. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
342fda9a0b
commit
b103ab78ec
@@ -0,0 +1,63 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
// config.js n'exporte RIEN (chargeable en script classique ET en module) :
|
||||
// on l'importe pour son effet de bord et on lit le namespace global.
|
||||
import "./extension/config.js";
|
||||
|
||||
const { DEFAUTS, fusionner, CLE_CONFIG_LOCALE } = (globalThis as any).EchoConfig;
|
||||
|
||||
describe("DEFAUTS", () => {
|
||||
test("themeDefaut est une valeur exacte du dropdown mairie (RECHERCHE §3)", () => {
|
||||
expect(DEFAUTS.themeDefaut).toBe("Culture");
|
||||
});
|
||||
|
||||
test("organisateur et email sont vides : jamais inventés, signalés à l'utilisateur", () => {
|
||||
expect(DEFAUTS.organisateur).toBe("");
|
||||
expect(DEFAUTS.email).toBe("");
|
||||
});
|
||||
|
||||
test("le café porte l'adresse et les coordonnées de RECHERCHE §2", () => {
|
||||
expect(DEFAUTS.cafe.adresse).toBe("8 Rue du Pré Vicinal 31270 Cugnaux");
|
||||
expect(DEFAUTS.cafe.coords).toBe("43.53753132806989|1.342981890597508");
|
||||
});
|
||||
|
||||
test("tarifs par défaut : Gratuit", () => {
|
||||
expect(DEFAUTS.tarifs).toBe("Gratuit");
|
||||
});
|
||||
});
|
||||
|
||||
describe("CLE_CONFIG_LOCALE", () => {
|
||||
test("est la clé de storage partagée background → content script", () => {
|
||||
expect(CLE_CONFIG_LOCALE).toBe("config-locale");
|
||||
});
|
||||
});
|
||||
|
||||
describe("fusionner", () => {
|
||||
// Un clone frais n'a pas de config.local.json : le repli doit être total,
|
||||
// jamais une exception.
|
||||
test.each([
|
||||
["absente", undefined],
|
||||
["null", null],
|
||||
["une chaîne", "n'importe quoi"],
|
||||
["un tableau vide", []],
|
||||
])("locale %s → défauts nus", (_libelle, locale) => {
|
||||
expect(fusionner(DEFAUTS, locale)).toEqual(DEFAUTS);
|
||||
});
|
||||
|
||||
test("organisateur et email surchargent, le reste survit", () => {
|
||||
const fusion = fusionner(DEFAUTS, {
|
||||
organisateur: "L'Atelier du Huit",
|
||||
email: "contact@atelier-huit.fr",
|
||||
});
|
||||
|
||||
expect(fusion.organisateur).toBe("L'Atelier du Huit");
|
||||
expect(fusion.email).toBe("contact@atelier-huit.fr");
|
||||
expect(fusion.themeDefaut).toBe("Culture");
|
||||
expect(fusion.cafe).toEqual(DEFAUTS.cafe);
|
||||
});
|
||||
|
||||
test("ne mute pas DEFAUTS (le module est partagé par tout le monde)", () => {
|
||||
fusionner(DEFAUTS, { organisateur: "Autre" });
|
||||
|
||||
expect(DEFAUTS.organisateur).toBe("");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user