log-fanout.test.ts49 lines · main
| 1 | /** |
| 2 | * Audit-log retention boundary tests — pin the 13-month window so a |
| 3 | * tweak to the constant or the math surfaces in CI rather than as a |
| 4 | * silent compliance drift (privacy policy §5). |
| 5 | * |
| 6 | * The DB-touching path (pruneOldAuditLogs) is exercised by the |
| 7 | * post-deploy smoke; this file pins the pure cutoff calculation. |
| 8 | */ |
| 9 | |
| 10 | import { describe, expect, test } from 'bun:test'; |
| 11 | |
| 12 | import { AUDIT_RETENTION_DAYS, auditRetentionCutoff } from './log-fanout.js'; |
| 13 | |
| 14 | describe('AUDIT_RETENTION_DAYS', () => { |
| 15 | test('matches the policy commitment of 13 months (≈ 390 days)', () => { |
| 16 | expect(AUDIT_RETENTION_DAYS).toBe(390); |
| 17 | }); |
| 18 | }); |
| 19 | |
| 20 | describe('auditRetentionCutoff', () => { |
| 21 | // Fixed point so the deltas are easy to reason about. |
| 22 | const NOW = new Date('2026-05-11T00:00:00Z').getTime(); |
| 23 | const ONE_DAY = 86_400_000; |
| 24 | |
| 25 | test('cutoff is exactly 13 months before now', () => { |
| 26 | const cutoff = auditRetentionCutoff(NOW); |
| 27 | const deltaDays = Math.round((NOW - cutoff.getTime()) / ONE_DAY); |
| 28 | expect(deltaDays).toBe(AUDIT_RETENTION_DAYS); |
| 29 | }); |
| 30 | |
| 31 | test('cutoff rolls forward with now (no caching surprise)', () => { |
| 32 | const cutoff1 = auditRetentionCutoff(NOW); |
| 33 | const cutoff2 = auditRetentionCutoff(NOW + 7 * ONE_DAY); |
| 34 | expect(cutoff2.getTime() - cutoff1.getTime()).toBe(7 * ONE_DAY); |
| 35 | }); |
| 36 | |
| 37 | test('a row 13 months + 1 day old is past cutoff', () => { |
| 38 | const cutoff = auditRetentionCutoff(NOW); |
| 39 | const rowAge = AUDIT_RETENTION_DAYS + 1; |
| 40 | const rowCreatedAt = new Date(NOW - rowAge * ONE_DAY); |
| 41 | expect(rowCreatedAt.getTime()).toBeLessThan(cutoff.getTime()); |
| 42 | }); |
| 43 | |
| 44 | test('a row 12 months old is still inside the window', () => { |
| 45 | const cutoff = auditRetentionCutoff(NOW); |
| 46 | const rowCreatedAt = new Date(NOW - 360 * ONE_DAY); |
| 47 | expect(rowCreatedAt.getTime()).toBeGreaterThan(cutoff.getTime()); |
| 48 | }); |
| 49 | }); |