/*
RFC-0188 Phase 3: prove the canonical→generic stage bridge is total and lands only on
valid generic stages, so the Pipedrive sync worker (STAGE_MAP) keeps working while the precise
funnel_stage is preserved. Pure — no I/O.
- No DB — the bridge is a pure mapping.
- RFC-0188 Phase 3: initial stage-bridge test.
*/
import { test, expect } from "vitest";
import {
BUFFER_DEAL_STAGES,
FUNNEL_STAGE_TO_BUFFER_STAGE,
bridgeFunnelStage,
VISITOR_FUNNEL_STAGES,
isValidFunnelStage,
} from "../funnel.ts";
test("the bridge maps every canonical funnel stage onto a valid generic stage", () => {
const generic = new Set(BUFFER_DEAL_STAGES);
for (const stage of VISITOR_FUNNEL_STAGES) {
const mapped = FUNNEL_STAGE_TO_BUFFER_STAGE[stage];
expect(mapped).toBeTruthy();
expect(generic.has(mapped)).toBeTruthy();
}
// Totality: no extra keys beyond the canonical catalog.
expect(Object.keys(FUNNEL_STAGE_TO_BUFFER_STAGE).length).toBe(VISITOR_FUNNEL_STAGES.length);
});
test("terminal funnel stages bridge to their generic equivalents", () => {
expect(bridgeFunnelStage("won")).toBe("won");
expect(bridgeFunnelStage("lost")).toBe("lost");
expect(bridgeFunnelStage("offer_presented")).toBe("proposal");
expect(bridgeFunnelStage("new_session")).toBe("new");
});
test("isValidFunnelStage guards the canonical catalog", () => {
expect(isValidFunnelStage("offer_presented")).toBe(true);
expect(isValidFunnelStage("q_website_tier")).toBe(false); // legacy UChat string
expect(isValidFunnelStage("new")).toBe(false); // generic buffer stage, not a funnel stage
});