import { describe, expect, it } from 'vitest'; import { archiveFileName, backupIdTime, dumpFileName, expiredSets, listSets, newBackupId, } from './backup-set.js'; const DAY = 24 * 60 * 60 * 1000; function setFiles(id: string): string[] { return [dumpFileName(id), archiveFileName(id)]; } describe('backup ids', () => { it('round-trips through the id format', () => { const now = new Date('2026-07-11T03:00:00Z'); const id = newBackupId(now); expect(id).toBe('20260711-030000'); expect(backupIdTime(id)?.toISOString()).toBe(now.toISOString()); }); it('rejects malformed ids', () => { expect(backupIdTime('not-a-backup')).toBeNull(); expect(backupIdTime('20260711')).toBeNull(); }); }); describe('listSets', () => { it('groups files by id and flags completeness', () => { const sets = listSets([ 'status.json', 'db-20260701-030000.dump.partial', ...setFiles('20260710-030000'), 'db-20260711-030000.dump', ]); expect(sets.map((set) => set.id)).toEqual(['20260710-030000', '20260711-030000']); expect(sets[0]?.complete).toBe(true); expect(sets[1]?.complete).toBe(false); }); }); describe('expiredSets', () => { const now = new Date('2026-07-31T04:00:00Z'); it('removes only sets past retention', () => { const fresh = newBackupId(new Date(now.getTime() - 2 * DAY)); const old = newBackupId(new Date(now.getTime() - 10 * DAY)); const newest = newBackupId(new Date(now.getTime() - 1 * DAY)); const sets = listSets([...setFiles(old), ...setFiles(fresh), ...setFiles(newest)]); const expired = expiredSets(sets, now, 7); expect(expired.map((set) => set.id)).toEqual([old]); }); it('never removes the newest complete set, even when expired', () => { const older = newBackupId(new Date(now.getTime() - 40 * DAY)); const newestComplete = newBackupId(new Date(now.getTime() - 20 * DAY)); // A newer but incomplete set (crashed run) must not shield the complete one. const newerIncomplete = newBackupId(new Date(now.getTime() - 9 * DAY)); const sets = listSets([ ...setFiles(older), ...setFiles(newestComplete), dumpFileName(newerIncomplete), ]); const expired = expiredSets(sets, now, 7); expect(expired.map((set) => set.id)).toEqual([older, newerIncomplete]); }); });