feat: list upcoming events with a create button
The list page now parses the calendar feed and renders each upcoming event (title, date, place) in chronological order, with a button that hands the event over to the town hall form. Sorting, date formatting and the café fallback live in a pure presentation module rather than in liste.js, which touches the DOM and cannot be imported under bun test. The seam to the sibling task's content script lives in transfert.js: a single storage slot, since a content script running on the town hall site has no way to learn a uid. The deposit is awaited before opening the tab, otherwise the content script could read before the write lands. Test timezone is pinned to Europe/Paris: date formatting is the core logic here and would otherwise pass only on machines set to Paris. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
d1a1c194bb
commit
3d86330894
@@ -0,0 +1,86 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import {
|
||||
CLE_EVENEMENT_EN_ATTENTE,
|
||||
deposerEvenement,
|
||||
serialiserPourFormulaire,
|
||||
} from "./extension/transfert.js";
|
||||
|
||||
function evenement(surcharges: Record<string, unknown> = {}) {
|
||||
return {
|
||||
uid: "uid-1",
|
||||
titre: "Atelier",
|
||||
description: "Venez nombreux",
|
||||
lieu: "Salle des fêtes",
|
||||
debut: new Date("2026-07-10T16:00:00Z"),
|
||||
fin: new Date("2026-07-10T18:00:00Z"),
|
||||
categories: ["soumis"],
|
||||
journeeEntiere: false,
|
||||
...surcharges,
|
||||
};
|
||||
}
|
||||
|
||||
// Storage factice (Chicago) : capture ce qui est écrit, pas de mock lourd.
|
||||
function storageFactice() {
|
||||
const ecrit: Record<string, unknown> = {};
|
||||
return {
|
||||
ecrit,
|
||||
set: async (objet: Record<string, unknown>) => Object.assign(ecrit, objet),
|
||||
};
|
||||
}
|
||||
|
||||
describe("serialiserPourFormulaire", () => {
|
||||
test("debut et fin deviennent des chaînes ISO", () => {
|
||||
const payload = serialiserPourFormulaire(evenement());
|
||||
|
||||
expect(payload.debut).toBe("2026-07-10T16:00:00.000Z");
|
||||
expect(payload.fin).toBe("2026-07-10T18:00:00.000Z");
|
||||
});
|
||||
|
||||
test("un lieu vide reste vide (pas de défaut café — D4)", () => {
|
||||
const payload = serialiserPourFormulaire(evenement({ lieu: "" }));
|
||||
|
||||
expect(payload.lieu).toBe("");
|
||||
});
|
||||
|
||||
test("porte tous les champs du contrat Event", () => {
|
||||
const payload = serialiserPourFormulaire(evenement());
|
||||
|
||||
expect(payload).toEqual({
|
||||
uid: "uid-1",
|
||||
titre: "Atelier",
|
||||
description: "Venez nombreux",
|
||||
lieu: "Salle des fêtes",
|
||||
debut: "2026-07-10T16:00:00.000Z",
|
||||
fin: "2026-07-10T18:00:00.000Z",
|
||||
categories: ["soumis"],
|
||||
journeeEntiere: false,
|
||||
});
|
||||
});
|
||||
|
||||
test("aller-retour : le content script peut réhydrater debut", () => {
|
||||
const ev = evenement();
|
||||
const payload = serialiserPourFormulaire(ev);
|
||||
|
||||
expect(new Date(payload.debut).getTime()).toBe(ev.debut.getTime());
|
||||
});
|
||||
});
|
||||
|
||||
describe("deposerEvenement", () => {
|
||||
test("écrit sous la clé evenement-en-attente", async () => {
|
||||
const storage = storageFactice();
|
||||
|
||||
await deposerEvenement(storage, evenement());
|
||||
|
||||
expect(storage.ecrit[CLE_EVENEMENT_EN_ATTENTE]).toMatchObject({ uid: "uid-1" });
|
||||
});
|
||||
|
||||
test("un second dépôt écrase le premier (slot unique — D2)", async () => {
|
||||
const storage = storageFactice();
|
||||
|
||||
await deposerEvenement(storage, evenement({ uid: "premier" }));
|
||||
await deposerEvenement(storage, evenement({ uid: "second" }));
|
||||
|
||||
expect(Object.keys(storage.ecrit)).toEqual([CLE_EVENEMENT_EN_ATTENTE]);
|
||||
expect(storage.ecrit[CLE_EVENEMENT_EN_ATTENTE]).toMatchObject({ uid: "second" });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user