Wire the seam end to end: the background mirrors config.local.json into storage (a content script would need web_accessible_resources, which would expose the email to the mairie page), and the content script lays the computed values into the form. The layer is deliberately thin and untested: all the logic lives in formulaire-valeurs.js. It never writes an empty value, never touches the image, the honeypots or the CSRF tokens, and never submits: a human reads and sends. A banner states what is left to do, and warns when a field could not be filled, so that a silent failure stays diagnosable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
92 lines
3.0 KiB
TypeScript
92 lines
3.0 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import { existsSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
|
|
const extensionDir = join(import.meta.dir, "extension");
|
|
const manifest = await Bun.file(join(extensionDir, "manifest.json")).json();
|
|
|
|
describe("manifest.json", () => {
|
|
test("est en Manifest V3", () => {
|
|
expect(manifest.manifest_version).toBe(3);
|
|
});
|
|
|
|
test("déclare background.js comme script d'arrière-plan", () => {
|
|
expect(manifest.background.scripts).toContain("background.js");
|
|
});
|
|
|
|
// Scripts classiques : pas d'import, l'ordre du tableau EST la dépendance.
|
|
// config.js pose globalThis.EchoConfig, que background.js lit.
|
|
test("charge config.js avant background.js", () => {
|
|
expect(manifest.background.scripts).toEqual(["config.js", "background.js"]);
|
|
});
|
|
|
|
test("demande les host_permissions des deux sources", () => {
|
|
expect(manifest.host_permissions).toEqual([
|
|
"https://atelier-huit.frama.space/*",
|
|
"https://www.ville-cugnaux.fr/*",
|
|
]);
|
|
});
|
|
|
|
test("demande la permission storage (couture liste → formulaire)", () => {
|
|
expect(manifest.permissions).toContain("storage");
|
|
});
|
|
|
|
test("ne définit PAS default_popup (sinon onClicked devient muet)", () => {
|
|
expect(manifest.action.default_popup).toBeUndefined();
|
|
});
|
|
|
|
test("porte un identifiant gecko", () => {
|
|
expect(manifest.browser_specific_settings.gecko.id).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe("content_scripts (pré-remplissage du formulaire mairie)", () => {
|
|
const contentScript = manifest.content_scripts?.[0];
|
|
|
|
// URL exacte du formulaire, pas tout ville-cugnaux.fr : on n'injecte pas de
|
|
// code sur les pages d'un tiers sans raison.
|
|
test("ne s'injecte que sur le formulaire de la mairie", () => {
|
|
expect(contentScript.matches).toEqual([
|
|
"https://www.ville-cugnaux.fr/mes-loisirs/associations/proposer-un-evenement-dans-lagenda/*",
|
|
]);
|
|
});
|
|
|
|
test("charge config, valeurs puis poseur (l'ordre EST la dépendance)", () => {
|
|
expect(contentScript.js).toEqual([
|
|
"config.js",
|
|
"formulaire-valeurs.js",
|
|
"formulaire-mairie.js",
|
|
]);
|
|
});
|
|
|
|
test("porte le style du bandeau", () => {
|
|
expect(contentScript.css).toEqual(["formulaire-mairie.css"]);
|
|
});
|
|
|
|
test("chaque fichier déclaré existe sur le disque", () => {
|
|
for (const fichier of [...contentScript.js, ...contentScript.css]) {
|
|
expect(existsSync(join(extensionDir, fichier))).toBe(true);
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("ressources référencées", () => {
|
|
test("background.js existe", () => {
|
|
expect(existsSync(join(extensionDir, "background.js"))).toBe(true);
|
|
});
|
|
|
|
test("chaque script d'arrière-plan existe", () => {
|
|
for (const fichier of manifest.background.scripts) {
|
|
expect(existsSync(join(extensionDir, fichier))).toBe(true);
|
|
}
|
|
});
|
|
|
|
test("liste.html existe", () => {
|
|
expect(existsSync(join(extensionDir, "liste.html"))).toBe(true);
|
|
});
|
|
|
|
test("l'icône référencée existe", () => {
|
|
expect(existsSync(join(extensionDir, manifest.action.default_icon))).toBe(true);
|
|
});
|
|
});
|