43 lines
1.5 KiB
TypeScript
43 lines
1.5 KiB
TypeScript
import { test } from 'node:test';
|
|||
|
|
import assert from 'node:assert/strict';
|
||
|
|
import { isExpired, RETENTION_PRESETS, RETENTION_MIN_MS } 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',
|
||
|
|
);
|
||
|
|
});
|