/** * Tests for src/modules/algorithms/algo.coldThreshold.ts * * Pure function — no mocking needed. */ import { describe, test, expect } from "bun:test"; import { checkColdStatus, COLD_THRESHOLDS, } from "../../src/modules/algorithms/algo.coldThreshold"; describe("COLD_THRESHOLDS", () => { test("defines thresholds for QuoteSent (43) and ConfirmedQuote (57)", () => { expect(COLD_THRESHOLDS[43]).toBeDefined(); expect(COLD_THRESHOLDS[43].days).toBe(14); expect(COLD_THRESHOLDS[57]).toBeDefined(); expect(COLD_THRESHOLDS[57].days).toBe(30); }); test("ms values match day values", () => { expect(COLD_THRESHOLDS[43].ms).toBe(14 * 24 * 60 * 60 * 1000); expect(COLD_THRESHOLDS[57].ms).toBe(30 * 24 * 60 * 60 * 1000); }); }); describe("checkColdStatus", () => { test("returns not cold when statusCwId is null", () => { const result = checkColdStatus({ statusCwId: null, lastActivityDate: new Date(), }); expect(result.cold).toBe(false); expect(result.triggeredBy).toBeNull(); }); test("returns not cold for non-eligible status", () => { const result = checkColdStatus({ statusCwId: 24, // New — not in threshold table lastActivityDate: new Date("2020-01-01"), now: new Date("2026-06-01"), }); expect(result.cold).toBe(false); }); test("returns not cold when lastActivityDate is null", () => { const result = checkColdStatus({ statusCwId: 43, // QuoteSent lastActivityDate: null, }); expect(result.cold).toBe(false); }); test("returns not cold when within threshold (QuoteSent, 13 days)", () => { const now = new Date("2026-03-14T00:00:00Z"); const lastActivity = new Date("2026-03-01T00:00:00Z"); // 13 days ago const result = checkColdStatus({ statusCwId: 43, lastActivityDate: lastActivity, now, }); expect(result.cold).toBe(false); }); test("returns cold when QuoteSent exceeds 14 days", () => { const now = new Date("2026-03-16T00:00:00Z"); const lastActivity = new Date("2026-03-01T00:00:00Z"); // 15 days ago const result = checkColdStatus({ statusCwId: 43, lastActivityDate: lastActivity, now, }); expect(result.cold).toBe(true); expect(result.triggeredBy).not.toBeNull(); expect(result.triggeredBy!.statusCwId).toBe(43); expect(result.triggeredBy!.statusName).toBe("QuoteSent"); expect(result.triggeredBy!.thresholdDays).toBe(14); expect(result.triggeredBy!.staleDays).toBe(15); }); test("returns cold when ConfirmedQuote exceeds 30 days", () => { const now = new Date("2026-04-01T00:00:00Z"); const lastActivity = new Date("2026-02-28T00:00:00Z"); // 32 days const result = checkColdStatus({ statusCwId: 57, lastActivityDate: lastActivity, now, }); expect(result.cold).toBe(true); expect(result.triggeredBy!.statusName).toBe("ConfirmedQuote"); expect(result.triggeredBy!.thresholdDays).toBe(30); expect(result.triggeredBy!.staleDays).toBeGreaterThanOrEqual(30); }); test("returns not cold when ConfirmedQuote within 30 days", () => { const now = new Date("2026-03-20T00:00:00Z"); const lastActivity = new Date("2026-03-01T00:00:00Z"); // 19 days const result = checkColdStatus({ statusCwId: 57, lastActivityDate: lastActivity, now, }); expect(result.cold).toBe(false); }); test("exactly at threshold is cold (>= threshold)", () => { const now = new Date("2026-03-15T00:00:00Z"); const lastActivity = new Date("2026-03-01T00:00:00Z"); // exactly 14 days const result = checkColdStatus({ statusCwId: 43, lastActivityDate: lastActivity, now, }); expect(result.cold).toBe(true); expect(result.triggeredBy!.staleDays).toBe(14); }); test("now override works as expected", () => { const fixed = new Date("2026-06-01T00:00:00Z"); const lastActivity = new Date("2026-05-01T00:00:00Z"); // 31 days const result = checkColdStatus({ statusCwId: 57, lastActivityDate: lastActivity, now: fixed, }); expect(result.cold).toBe(true); expect(result.triggeredBy!.staleDays).toBe(31); }); });