import { describe, expect, test } from "bun:test"; import { DEFAULT_STALE_MINUTES, getStaleWarning, isStale } from "./freshness"; // isStale is the shared rule every billable surface (invoices/reports) uses to // decide whether the local activity data is recent enough. Stale when: ingest // predates the report window end (coverage gap), or ingest is older than // maxAgeMinutes. A null/unparseable timestamp is "unknown" (no history) — NOT // stale, so the hub / fresh installs don't emit false warnings. const asOf = new Date("2026-01-01T12:00:00Z"); const minsBefore = (n: number) => new Date(asOf.getTime() - n * 60_000).toISOString(); describe("isStale", () => { test("never ingested → unknown, not stale (no false warning)", () => { expect(isStale({ lastIngestAt: null, asOf })).toBe(false); }); test("unparseable timestamp → unknown, not stale", () => { expect(isStale({ lastIngestAt: "not-a-date", asOf })).toBe(false); }); test("ingest within default threshold → fresh", () => { expect(isStale({ lastIngestAt: minsBefore(30), asOf })).toBe(false); }); test("ingest exactly at the default threshold → fresh (not strictly older)", () => { expect( isStale({ lastIngestAt: minsBefore(DEFAULT_STALE_MINUTES), asOf }), ).toBe(false); }); test("ingest older than default threshold → stale", () => { expect( isStale({ lastIngestAt: minsBefore(DEFAULT_STALE_MINUTES + 1), asOf }), ).toBe(true); }); test("custom maxAgeMinutes is respected", () => { expect( isStale({ lastIngestAt: minsBefore(20), asOf, maxAgeMinutes: 15 }), ).toBe(true); expect( isStale({ lastIngestAt: minsBefore(10), asOf, maxAgeMinutes: 15 }), ).toBe(false); }); test("ingest before window end → stale (coverage gap) even if recent", () => { // Ingested 5 min ago (well within 60), but the invoice window ends after // the last ingest, so the period isn't fully captured. const windowEnd = new Date(asOf.getTime() + 60 * 60_000); expect(isStale({ lastIngestAt: minsBefore(5), asOf, windowEnd })).toBe( true, ); }); test("ingest after window end → fresh (window fully captured)", () => { const windowEnd = new Date(asOf.getTime() - 24 * 60 * 60_000); expect(isStale({ lastIngestAt: minsBefore(5), asOf, windowEnd })).toBe( false, ); }); test("null windowEnd is ignored", () => { expect( isStale({ lastIngestAt: minsBefore(5), asOf, windowEnd: null }), ).toBe(false); }); }); describe("getStaleWarning", () => { test("fresh data → no warning", () => { expect( getStaleWarning({ lastIngestAt: minsBefore(5) }, { asOf }), ).toBeNull(); }); test("never ingested → no warning (unknown, not a false 'stale')", () => { expect(getStaleWarning({ lastIngestAt: null }, { asOf })).toBeNull(); }); test("stale by age → warning reports a humanized age", () => { const msg = getStaleWarning({ lastIngestAt: minsBefore(180) }, { asOf }); expect(msg).toContain("3h ago"); expect(msg).toContain("run sync/ingest"); }); });