Pure matching (date locale Cugnaux + titre normalisé) and paginated transport, both fully tested. HTML extraction via DOMParser stays impure and untested (absent from Bun), like formulaire-mairie.js. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
136 lines
4.7 KiB
TypeScript
136 lines
4.7 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
||
import {
|
||
dateLocaleCugnaux,
|
||
indexerCartes,
|
||
normaliserTitre,
|
||
trouverPublication,
|
||
} from "./extension/publication.js";
|
||
|
||
// Fixtures = Event littéraux (comme presentation.test.ts) : le parsing vit
|
||
// ailleurs. Ici on éprouve le matching, vrai risque produit.
|
||
function evenement(surcharges: Record<string, unknown> = {}) {
|
||
return {
|
||
uid: "uid-1",
|
||
titre: "Atelier dessin",
|
||
description: "",
|
||
lieu: "",
|
||
debut: new Date("2026-07-10T16:00:00Z"),
|
||
fin: new Date("2026-07-10T18:00:00Z"),
|
||
categories: [],
|
||
journeeEntiere: false,
|
||
...surcharges,
|
||
};
|
||
}
|
||
|
||
function carte(surcharges: Record<string, unknown> = {}) {
|
||
return {
|
||
date: "2026-07-10",
|
||
titre: "Atelier dessin",
|
||
lien: "https://www.ville-cugnaux.fr/agenda/atelier-dessin-2/",
|
||
...surcharges,
|
||
};
|
||
}
|
||
|
||
describe("normaliserTitre", () => {
|
||
test("accents supprimés (NFD)", () => {
|
||
expect(normaliserTitre("Soirée jazz")).toBe("soiree jazz");
|
||
});
|
||
|
||
test("casse repliée", () => {
|
||
expect(normaliserTitre("ATELIER Dessin")).toBe("atelier dessin");
|
||
});
|
||
|
||
test("apostrophes droites et typographiques retirées", () => {
|
||
expect(normaliserTitre("L'atelier")).toBe(normaliserTitre("L’atelier"));
|
||
expect(normaliserTitre("L'atelier")).toBe("latelier");
|
||
});
|
||
|
||
test("tirets simples et cadratins retirés", () => {
|
||
expect(normaliserTitre("ciné-club")).toBe(normaliserTitre("ciné–club"));
|
||
});
|
||
|
||
test("deux-points et ponctuation retirés sans insérer d'espace", () => {
|
||
// « Atelier B.D. » == « Atelier BD » une fois la ponctuation retirée.
|
||
expect(normaliserTitre("Atelier B.D.")).toBe(normaliserTitre("Atelier BD"));
|
||
});
|
||
|
||
test("emojis retirés", () => {
|
||
expect(normaliserTitre("Fête \u{1F389} du village")).toBe("fete du village");
|
||
});
|
||
|
||
test("espaces multiples compressés et bords élagués", () => {
|
||
expect(normaliserTitre(" Atelier dessin ")).toBe("atelier dessin");
|
||
});
|
||
});
|
||
|
||
describe("dateLocaleCugnaux", () => {
|
||
test("horodaté à 22:00 Paris (été) → même jour", () => {
|
||
// 20:00 UTC = 22:00 Paris l'été.
|
||
const ev = evenement({ debut: new Date("2026-07-10T20:00:00Z") });
|
||
expect(dateLocaleCugnaux(ev)).toBe("2026-07-10");
|
||
});
|
||
|
||
test("horodaté à 00:30 Paris = 22:30 UTC la veille → jour de Cugnaux, pas UTC", () => {
|
||
const ev = evenement({ debut: new Date("2026-07-09T22:30:00Z") });
|
||
expect(dateLocaleCugnaux(ev)).toBe("2026-07-10");
|
||
});
|
||
|
||
test("journée entière → composantes locales, sans glissement de fuseau", () => {
|
||
// Date flottante : composantes locales (cf. presentation.js / DECISIONS.md).
|
||
const ev = evenement({ debut: new Date(2026, 6, 10), journeeEntiere: true });
|
||
expect(dateLocaleCugnaux(ev)).toBe("2026-07-10");
|
||
});
|
||
});
|
||
|
||
describe("trouverPublication", () => {
|
||
test("même date + titre normalisé identique → publié avec le bon lien", () => {
|
||
const index = indexerCartes([carte()]);
|
||
expect(trouverPublication(evenement(), index)).toEqual({
|
||
publie: true,
|
||
lien: "https://www.ville-cugnaux.fr/agenda/atelier-dessin-2/",
|
||
});
|
||
});
|
||
|
||
test("même titre mais date différente → non publié", () => {
|
||
const index = indexerCartes([carte({ date: "2026-07-11" })]);
|
||
expect(trouverPublication(evenement(), index)).toEqual({ publie: false });
|
||
});
|
||
|
||
test("même date mais titre différent → non publié", () => {
|
||
const index = indexerCartes([carte({ titre: "Concert" })]);
|
||
expect(trouverPublication(evenement(), index)).toEqual({ publie: false });
|
||
});
|
||
|
||
test("titre ne différant que par accents/emoji/casse/ponctuation → match", () => {
|
||
const index = indexerCartes([
|
||
carte({ titre: "Atelier Dessin \u{1F3A8}", lien: "https://x/agenda/a/" }),
|
||
]);
|
||
expect(trouverPublication(evenement({ titre: "atelier dessin" }), index)).toEqual({
|
||
publie: true,
|
||
lien: "https://x/agenda/a/",
|
||
});
|
||
});
|
||
|
||
test("titre proche mais non strictement identique le même jour → non publié (biais précision v1)", () => {
|
||
const index = indexerCartes([carte({ titre: "Atelier peinture libre" })]);
|
||
expect(trouverPublication(evenement({ titre: "Atelier peinture" }), index)).toEqual({
|
||
publie: false,
|
||
});
|
||
});
|
||
|
||
test("index vide (agenda injoignable) → non publié", () => {
|
||
expect(trouverPublication(evenement(), new Map())).toEqual({ publie: false });
|
||
});
|
||
|
||
test("deux cartes le même jour, titres distincts → la bonne est choisie", () => {
|
||
const index = indexerCartes([
|
||
carte({ titre: "Concert", lien: "https://x/agenda/concert/" }),
|
||
carte({ titre: "Atelier dessin", lien: "https://x/agenda/atelier-dessin/" }),
|
||
]);
|
||
expect(trouverPublication(evenement(), index)).toEqual({
|
||
publie: true,
|
||
lien: "https://x/agenda/atelier-dessin/",
|
||
});
|
||
});
|
||
});
|