import { describe, test, expect } from "bun:test"; import { computeSubResourceCacheTTL, SUB_TTL_HIGH_ACTIVITY, SUB_TTL_MODERATE_ACTIVITY, SUB_TTL_LOW_ACTIVITY, } from "../../src/modules/algorithms/computeSubResourceCacheTTL"; const NOW = new Date("2026-03-02T12:00:00Z"); const DAY_MS = 24 * 60 * 60 * 1000; describe("computeSubResourceCacheTTL", () => { // -- Rule 1a: closed > 30 days → null ----------------------------------- test("returns null for records closed > 30 days ago", () => { const result = computeSubResourceCacheTTL({ closedFlag: true, closedDate: new Date(NOW.getTime() - 31 * DAY_MS), expectedCloseDate: null, lastUpdated: null, now: NOW, }); expect(result).toBeNull(); }); // -- Rule 1b: closed within 30 days → SUB_TTL_LOW_ACTIVITY --------------- test("returns SUB_TTL_LOW_ACTIVITY for recently-closed records", () => { const result = computeSubResourceCacheTTL({ closedFlag: true, closedDate: new Date(NOW.getTime() - 10 * DAY_MS), expectedCloseDate: null, lastUpdated: null, now: NOW, }); expect(result).toBe(SUB_TTL_LOW_ACTIVITY); }); // -- Rule 2: within 5 days → SUB_TTL_HIGH_ACTIVITY ---------------------- test("returns SUB_TTL_HIGH_ACTIVITY when expectedCloseDate is within 5 days", () => { const result = computeSubResourceCacheTTL({ closedFlag: false, closedDate: null, expectedCloseDate: new Date(NOW.getTime() + 2 * DAY_MS), lastUpdated: null, now: NOW, }); expect(result).toBe(SUB_TTL_HIGH_ACTIVITY); }); test("returns SUB_TTL_HIGH_ACTIVITY when lastUpdated is within 5 days", () => { const result = computeSubResourceCacheTTL({ closedFlag: false, closedDate: null, expectedCloseDate: null, lastUpdated: new Date(NOW.getTime() - 3 * DAY_MS), now: NOW, }); expect(result).toBe(SUB_TTL_HIGH_ACTIVITY); }); // -- Rule 3: within 14 days → SUB_TTL_MODERATE_ACTIVITY ----------------- test("returns SUB_TTL_MODERATE_ACTIVITY when expectedCloseDate is within 14 days", () => { const result = computeSubResourceCacheTTL({ closedFlag: false, closedDate: null, expectedCloseDate: new Date(NOW.getTime() + 10 * DAY_MS), lastUpdated: null, now: NOW, }); expect(result).toBe(SUB_TTL_MODERATE_ACTIVITY); }); test("returns SUB_TTL_MODERATE_ACTIVITY when lastUpdated is within 14 days", () => { const result = computeSubResourceCacheTTL({ closedFlag: false, closedDate: null, expectedCloseDate: null, lastUpdated: new Date(NOW.getTime() - 8 * DAY_MS), now: NOW, }); expect(result).toBe(SUB_TTL_MODERATE_ACTIVITY); }); // -- Rule 4: everything else → SUB_TTL_LOW_ACTIVITY --------------------- test("returns SUB_TTL_LOW_ACTIVITY for stale records", () => { const result = computeSubResourceCacheTTL({ closedFlag: false, closedDate: null, expectedCloseDate: new Date(NOW.getTime() - 30 * DAY_MS), lastUpdated: new Date(NOW.getTime() - 30 * DAY_MS), now: NOW, }); expect(result).toBe(SUB_TTL_LOW_ACTIVITY); }); test("returns SUB_TTL_LOW_ACTIVITY when no dates are set", () => { const result = computeSubResourceCacheTTL({ closedFlag: false, closedDate: null, expectedCloseDate: null, lastUpdated: null, now: NOW, }); expect(result).toBe(SUB_TTL_LOW_ACTIVITY); }); // -- TTL ordering ------------------------------------------------------- test("SUB_TTL values are ordered correctly", () => { expect(SUB_TTL_HIGH_ACTIVITY).toBe(60_000); expect(SUB_TTL_MODERATE_ACTIVITY).toBe(120_000); expect(SUB_TTL_LOW_ACTIVITY).toBe(300_000); expect(SUB_TTL_HIGH_ACTIVITY).toBeLessThan(SUB_TTL_MODERATE_ACTIVITY); expect(SUB_TTL_MODERATE_ACTIVITY).toBeLessThan(SUB_TTL_LOW_ACTIVITY); }); // -- Closed flag takes priority ------------------------------------------ test("closed flag takes priority over recent activity dates", () => { const result = computeSubResourceCacheTTL({ closedFlag: true, closedDate: new Date(NOW.getTime() - 60 * DAY_MS), expectedCloseDate: new Date(NOW.getTime() - 1 * DAY_MS), lastUpdated: new Date(NOW.getTime() - 1 * DAY_MS), now: NOW, }); expect(result).toBeNull(); }); });