Luigit
repositories / will

will

owned by admin

src/shared/retention.test.ts

Raw
import assert from 'node:assert/strict'
import { test } from 'node:test'
import fc from 'fast-check'
import {
  cutoffIso,
  groupByMonth,
  monthOf,
  type RetentionRow,
  rowsToArchive,
  type SegmentSidecar,
  segmentsOverlapping,
} from './retention.ts'

test('cutoff subtracts hot days', () => {
  assert.equal(cutoffIso(new Date('2026-09-12T00:00:00Z'), 90), '2026-06-14T00:00:00.000Z')
})

test('only rows strictly older than the cutoff archive', () => {
  const rows: RetentionRow[] = [
    { id: 'a', ts: '2026-06-13T23:59:59Z' },
    { id: 'b', ts: '2026-06-14T00:00:00.000Z' },
    { id: 'c', ts: '2026-09-01T00:00:00Z' },
  ]
  assert.deepEqual(
    rowsToArchive(rows, '2026-06-14T00:00:00.000Z').map((r) => r.id),
    ['a'],
  )
})

test('rows group by month', () => {
  const groups = groupByMonth([
    { id: 'a', ts: '2026-01-15T00:00:00Z' },
    { id: 'b', ts: '2026-01-02T00:00:00Z' },
    { id: 'c', ts: '2026-02-01T00:00:00Z' },
  ])
  assert.deepEqual([...groups.keys()], ['2026-01', '2026-02'])
  assert.equal(groups.get('2026-01')?.length, 2)
})

test('sidecar overlap selection skips non-overlapping segments', () => {
  const sc = (month: string, firstTs: string, lastTs: string): SegmentSidecar => ({
    version: 1,
    kind: 'audit',
    month,
    segment: 's',
    count: 1,
    firstId: 'x',
    lastId: 'x',
    firstTs,
    lastTs,
    sha256: '0'.repeat(64),
    bytes: 1,
  })
  const sidecars = [
    sc('2026-01', '2026-01-01T00:00:00Z', '2026-01-31T00:00:00Z'),
    sc('2026-03', '2026-03-01T00:00:00Z', '2026-03-31T00:00:00Z'),
  ]
  assert.equal(segmentsOverlapping(sidecars, { since: '2026-02-01T00:00:00Z' }).length, 1)
  assert.equal(segmentsOverlapping(sidecars, { since: '2026-04-01T00:00:00Z' }).length, 0)
  assert.equal(segmentsOverlapping(sidecars, {}).length, 2)
})

test('property: every row lands in exactly one month group', () => {
  let counter = 0
  const arbRow = fc.record({
    id: fc.integer({ min: 0, max: 1_000_000 }).map((n) => `id-${counter++}-${n}`),
    ts: fc
      .integer({ min: Date.UTC(2000, 0, 1), max: Date.UTC(2030, 0, 1) })
      .map((ms) => new Date(ms).toISOString()),
  })
  fc.assert(
    fc.property(fc.array(arbRow, { maxLength: 60 }), (rows) => {
      const groups = groupByMonth(rows)
      let total = 0
      for (const [month, bucket] of groups) {
        for (const r of bucket) assert.equal(monthOf(r.ts), month)
        total += bucket.length
      }
      assert.equal(total, rows.length)
    }),
  )
})