ultisuite-client/lib/agenda/agenda-recurrence.test.ts
R3D347HR4Y 3bbf3691b0
Some checks failed
E2E / Playwright e2e (push) Has been cancelled
bordel c'est beau
2026-06-11 10:10:39 +02:00

117 lines
3.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import assert from "node:assert/strict"
import { describe, it } from "node:test"
import { describeRRule, expandOccurrences, parseRRule } from "./agenda-recurrence.ts"
const d = (iso: string) => new Date(iso)
describe("parseRRule", () => {
it("parse une règle hebdomadaire avec BYDAY", () => {
const rule = parseRRule("FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,TH")
assert.deepEqual(rule, {
freq: "WEEKLY",
interval: 2,
count: undefined,
until: undefined,
byday: [1, 4],
})
})
it("rejette une fréquence inconnue", () => {
assert.equal(parseRRule("FREQ=HOURLY"), null)
})
})
describe("expandOccurrences", () => {
it("développe une règle quotidienne dans la fenêtre", () => {
const rule = parseRRule("FREQ=DAILY")!
const out = expandOccurrences(
d("2026-06-01T10:00:00"),
rule,
new Set(),
d("2026-06-10T00:00:00"),
d("2026-06-12T23:59:59"),
)
assert.deepEqual(out.map((x) => x.getDate()), [10, 11, 12])
})
it("respecte COUNT depuis la première occurrence", () => {
const rule = parseRRule("FREQ=DAILY;COUNT=5")!
const out = expandOccurrences(
d("2026-06-01T10:00:00"),
rule,
new Set(),
d("2026-06-04T00:00:00"),
d("2026-06-30T23:59:59"),
)
// Occurrences 15 = 1er au 5 juin ; fenêtre depuis le 4 → 4 et 5 juin.
assert.deepEqual(out.map((x) => x.getDate()), [4, 5])
})
it("respecte UNTIL", () => {
const rule = parseRRule("FREQ=WEEKLY;UNTIL=20260615T000000Z")!
const out = expandOccurrences(
d("2026-06-01T10:00:00"),
rule,
new Set(),
d("2026-06-01T00:00:00"),
d("2026-07-31T23:59:59"),
)
assert.equal(out.length, 2) // 1er et 8 juin (15 juin 10:00 > UNTIL)
})
it("développe BYDAY hebdomadaire en gardant l'heure", () => {
const rule = parseRRule("FREQ=WEEKLY;BYDAY=MO,WE")!
// Lundi 1er juin 2026 à 09:30.
const out = expandOccurrences(
d("2026-06-01T09:30:00"),
rule,
new Set(),
d("2026-06-01T00:00:00"),
d("2026-06-07T23:59:59"),
)
assert.deepEqual(
out.map((x) => [x.getDate(), x.getHours(), x.getMinutes()]),
[
[1, 9, 30],
[3, 9, 30],
],
)
})
it("exclut les EXDATE", () => {
const rule = parseRRule("FREQ=DAILY")!
const out = expandOccurrences(
d("2026-06-01T10:00:00"),
rule,
new Set([d("2026-06-02T10:00:00").getTime()]),
d("2026-06-01T00:00:00"),
d("2026-06-03T23:59:59"),
)
assert.deepEqual(out.map((x) => x.getDate()), [1, 3])
})
it("ne produit aucune occurrence avant le début du master", () => {
const rule = parseRRule("FREQ=WEEKLY;BYDAY=MO,FR")!
// Master mercredi 3 juin 2026 → seul le vendredi 5 reste cette semaine-là.
const out = expandOccurrences(
d("2026-06-03T10:00:00"),
rule,
new Set(),
d("2026-06-01T00:00:00"),
d("2026-06-07T23:59:59"),
)
assert.deepEqual(out.map((x) => x.getDate()), [5])
})
})
describe("describeRRule", () => {
it("décrit les règles courantes", () => {
assert.equal(describeRRule("FREQ=DAILY"), "Tous les jours")
assert.equal(
describeRRule("FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR"),
"Tous les jours ouvrés (lun.ven.)",
)
assert.equal(describeRRule("FREQ=MONTHLY;INTERVAL=3"), "Tous les 3 mois")
})
})