import { test } from 'node:test'; import assert from 'node:assert/strict'; import { effectiveRetentionMs, isExpired, RETENTION_DELETE_GRACE_MS, RETENTION_MIN_MS, RETENTION_PRESETS, retentionDeletesAllowed, } from './retention'; // MSC1763 retention: `isExpired` decides whether a message is past the room's // retention window. It must be strict (> window, not >=) and a disabled policy // (0) must never expire anything. const HOUR = 60 * 60 * 1000; test('isExpired: an event older than the window is expired', () => { const now = 10 * HOUR; assert.equal(isExpired(now - 2 * HOUR, HOUR, now), true); }); test('isExpired: an event within the window is NOT expired', () => { const now = 10 * HOUR; assert.equal(isExpired(now - HOUR / 2, HOUR, now), false); }); test('isExpired: exactly at the boundary is NOT expired (strict >)', () => { const now = 10 * HOUR; assert.equal(isExpired(now - HOUR, HOUR, now), false); }); test('isExpired: a disabled policy (0 / negative) never expires', () => { const now = 10 * HOUR; assert.equal(isExpired(now - 100 * HOUR, 0, now), false); assert.equal(isExpired(0, -1, now), false); }); test('presets: Off is 0 and the rest are strictly increasing, all >= the floor', () => { assert.equal(RETENTION_PRESETS[0].ms, 0); const nonZero = RETENTION_PRESETS.slice(1).map((p) => p.ms); for (let i = 1; i < nonZero.length; i += 1) { assert.ok(nonZero[i] > nonZero[i - 1], 'presets increase'); } assert.ok( nonZero.every((ms) => ms >= RETENTION_MIN_MS), 'all presets above the floor', ); }); test('effectiveRetentionMs: tiny or invalid windows count as off (#298)', () => { assert.equal(effectiveRetentionMs(1000), undefined, '1 s is a typo, not a policy'); assert.equal(effectiveRetentionMs(RETENTION_MIN_MS - 1), undefined); assert.equal(effectiveRetentionMs(RETENTION_MIN_MS), RETENTION_MIN_MS); assert.equal(effectiveRetentionMs(86_400_000), 86_400_000); assert.equal(effectiveRetentionMs(0), undefined); assert.equal(effectiveRetentionMs(-5), undefined); assert.equal(effectiveRetentionMs('86400000'), undefined); assert.equal(effectiveRetentionMs(Number.NaN), undefined); }); test('retentionDeletesAllowed: no deletions in the first 24 h of a policy (#298)', () => { const now = 1_000 * HOUR; assert.equal(retentionDeletesAllowed(now - 2 * HOUR, now), false); assert.equal(retentionDeletesAllowed(now - RETENTION_DELETE_GRACE_MS + 1, now), false); assert.equal(retentionDeletesAllowed(now - RETENTION_DELETE_GRACE_MS, now), true); assert.equal(retentionDeletesAllowed(now - 72 * HOUR, now), true); });