Some checks failed
Docker image / build-and-push-image (push) Has been cancelled
Move the lifecycle predicate into lib/acl/lifecycle.ts (re-exported from the ACL module) so it can be unit-tested without a database. Adds Node built-in test-runner coverage for the boundary conditions that define the fix: past expiry -> dead, expiry == now -> dead (exclusive), revoke beats a future expiry, and liveWhere kept in lockstep with grantIsLive. Runner is node:test via ts-node (no new dependency; pnpm add is blocked by the nix-built node_modules hoist pattern). 'npm test' -> 7 passing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
44 lines
1.8 KiB
TypeScript
44 lines
1.8 KiB
TypeScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { grantIsLive, liveWhere } from '../src/daemon/lib/acl/lifecycle';
|
|
|
|
// Fixed reference clock so the assertions don't depend on wall time.
|
|
const now = new Date('2026-06-19T12:00:00.000Z');
|
|
const past = new Date(now.getTime() - 60_000);
|
|
const future = new Date(now.getTime() + 60_000);
|
|
|
|
test('grantIsLive: no revoke, no expiry -> live', () => {
|
|
assert.equal(grantIsLive({}, now), true);
|
|
assert.equal(grantIsLive({ revokedAt: null, expiresAt: null }, now), true);
|
|
});
|
|
|
|
test('grantIsLive: future expiry -> live', () => {
|
|
assert.equal(grantIsLive({ expiresAt: future }, now), true);
|
|
});
|
|
|
|
test('grantIsLive: past expiry -> dead (the #24 case the old code missed at sign time)', () => {
|
|
assert.equal(grantIsLive({ expiresAt: past }, now), false);
|
|
});
|
|
|
|
test('grantIsLive: expiry exactly now -> dead (boundary is exclusive)', () => {
|
|
assert.equal(grantIsLive({ expiresAt: new Date(now.getTime()) }, now), false);
|
|
});
|
|
|
|
test('grantIsLive: revoked -> dead even with a future expiry (revoke wins)', () => {
|
|
assert.equal(grantIsLive({ revokedAt: past, expiresAt: future }, now), false);
|
|
});
|
|
|
|
test('grantIsLive: defaults now to the current time', () => {
|
|
assert.equal(grantIsLive({ expiresAt: new Date(Date.now() + 3_600_000) }), true);
|
|
assert.equal(grantIsLive({ expiresAt: new Date(Date.now() - 3_600_000) }), false);
|
|
});
|
|
|
|
// liveWhere is the SQL mirror of grantIsLive; pin its shape so the two
|
|
// can't silently drift (a drift would re-open the redeem-vs-sign gap #25
|
|
// exists to close).
|
|
test('liveWhere: mirrors grantIsLive as a prisma where-fragment', () => {
|
|
assert.deepEqual(liveWhere(now), {
|
|
revokedAt: null,
|
|
OR: [{ expiresAt: null }, { expiresAt: { gt: now } }],
|
|
});
|
|
});
|