mirror of
https://github.com/R0m1k3/PleinR.git
synced 2026-10-11 17:27:54 +02:00
Une promotion peut désormais porter une date de début et une date de fin, toutes deux facultatives et indépendantes. Sans date, rien n'est affiché. - Schéma : `promotions.starts_on` / `ends_on` (`date`), migration 0015. - `src/lib/promo-validity.ts` (pur, testé) : `formatValidity()` produit « Valable du 1er au 15 mars 2027 », « Valable jusqu'au … », « Valable à partir du … » en repliant mois et année quand ils se répètent ; `formatValidityShort()` pour les lignes de méta ; `isRangeInvalid()` pour la validation. - Espace adhérent : deux champs date, aperçu en direct de la phrase et blocage de l'envoi si la fin précède le début. - `publishPromo` relit et revalide les bornes côté serveur. - Affichage : carte d'accueil, fiche adhérent, liste de l'adhérent, carte de modération — et le message Facebook / LinkedIn, via le même formateur. - L'ancien texte libre `valid_until` reste comme repli d'affichage pour les promotions de démonstration. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QXNXRC4j5VLfKvpyyisrnb
77 lines
2.7 KiB
TypeScript
77 lines
2.7 KiB
TypeScript
import { strict as assert } from "node:assert";
|
|
import { describe, it } from "node:test";
|
|
|
|
import {
|
|
formatValidity,
|
|
formatValidityShort,
|
|
isExpired,
|
|
isRangeInvalid,
|
|
} from "../src/lib/promo-validity";
|
|
|
|
describe("Période de validité d'une promotion", () => {
|
|
it("affiche les deux bornes", () => {
|
|
assert.equal(
|
|
formatValidity({ startsOn: "2027-03-01", endsOn: "2027-03-15" }),
|
|
"Valable du 1er au 15 mars 2027"
|
|
);
|
|
});
|
|
|
|
it("ne répète pas l'année quand elle est identique", () => {
|
|
assert.equal(
|
|
formatValidity({ startsOn: "2027-03-01", endsOn: "2027-04-10" }),
|
|
"Valable du 1er mars au 10 avril 2027"
|
|
);
|
|
});
|
|
|
|
it("écrit les deux années quand elles diffèrent", () => {
|
|
assert.equal(
|
|
formatValidity({ startsOn: "2027-12-20", endsOn: "2028-01-05" }),
|
|
"Valable du 20 décembre 2027 au 5 janvier 2028"
|
|
);
|
|
});
|
|
|
|
it("gère une seule borne", () => {
|
|
assert.equal(formatValidity({ endsOn: "2027-06-30" }), "Valable jusqu'au 30 juin 2027");
|
|
assert.equal(
|
|
formatValidity({ startsOn: "2027-06-01" }),
|
|
"Valable à partir du 1er juin 2027"
|
|
);
|
|
});
|
|
|
|
it("ne renvoie rien sans date ni texte : la carte n'affiche alors aucune mention", () => {
|
|
assert.equal(formatValidity({}), null);
|
|
assert.equal(formatValidity({ startsOn: null, endsOn: null, validUntil: " " }), null);
|
|
});
|
|
|
|
it("retombe sur l'ancien texte libre des promotions existantes", () => {
|
|
assert.equal(formatValidity({ validUntil: "Tout l'été" }), "Tout l'été");
|
|
// Les dates priment sur le texte libre.
|
|
assert.equal(
|
|
formatValidity({ endsOn: "2027-07-31", validUntil: "Tout l'été" }),
|
|
"Valable jusqu'au 31 juillet 2027"
|
|
);
|
|
});
|
|
|
|
it("ignore une date illisible", () => {
|
|
assert.equal(formatValidity({ endsOn: "pas-une-date" }), null);
|
|
assert.equal(formatValidity({ endsOn: "2027-13-45" }), null);
|
|
});
|
|
|
|
it("propose une variante sans le mot « Valable »", () => {
|
|
assert.equal(formatValidityShort({ endsOn: "2027-06-30" }), "jusqu'au 30 juin 2027");
|
|
});
|
|
|
|
it("considère le dernier jour comme encore valable", () => {
|
|
const end = { endsOn: "2027-06-30" };
|
|
assert.equal(isExpired(end, new Date("2027-06-30T23:00:00Z")), false);
|
|
assert.equal(isExpired(end, new Date("2027-07-01T12:00:00Z")), true);
|
|
assert.equal(isExpired({}, new Date("2099-01-01T00:00:00Z")), false);
|
|
});
|
|
|
|
it("détecte une fin antérieure au début", () => {
|
|
assert.equal(isRangeInvalid({ startsOn: "2027-06-10", endsOn: "2027-06-01" }), true);
|
|
assert.equal(isRangeInvalid({ startsOn: "2027-06-01", endsOn: "2027-06-01" }), false);
|
|
assert.equal(isRangeInvalid({ startsOn: "2027-06-01" }), false);
|
|
});
|
|
});
|