import { describe, it, expect } from "vitest"; import { pipelineFlow, isStageRecord, type StageRecord } from "../pipeline-flow"; const src = (over: Partial = {}): StageRecord => ({ kind: "source.stage", stage: "s", position: "early", message: { name: "orders.place", kind: "command" }, correlationId: "c1", shortCircuited: false, durationMs: 1, appName: "app", ts: "2026-06-16T00:00:00.000Z", ...(over as object), }) as StageRecord; const sink = (over: Partial = {}): StageRecord => ({ kind: "sink.stage", stage: "k", position: "terminal", event: "order.placed", correlationId: "c1", shortCircuited: false, durationMs: 1, appName: "app", ts: "2026-06-16T00:00:00.000Z", ...(over as object), }) as StageRecord; describe("isStageRecord", () => { it("matches only the two stage kinds", () => { expect(isStageRecord({ kind: "source.stage" })).toBe(true); expect(isStageRecord({ kind: "sink.stage" })).toBe(true); expect(isStageRecord({ kind: "action.dispatched" })).toBe(false); expect(isStageRecord({ kind: "hook.step" })).toBe(false); }); }); describe("pipelineFlow", () => { it("returns empty flows when no correlation is selected", () => { expect(pipelineFlow([src()], undefined)).toEqual({ inbound: [], outbound: [] }); }); it("splits inbound (source) from outbound (sink) for the correlation", () => { const flow = pipelineFlow([src(), sink()], "c1"); expect(flow.inbound.map((r) => r.stage)).toEqual(["s"]); expect(flow.outbound.map((r) => r.stage)).toEqual(["k"]); expect(flow.inbound[0]!.label).toBe("orders.place"); expect(flow.outbound[0]!.label).toBe("order.placed"); expect(flow.inbound[0]!.direction).toBe("inbound"); expect(flow.outbound[0]!.direction).toBe("outbound"); }); it("excludes records from other correlations", () => { const flow = pipelineFlow([src(), src({ correlationId: "other" })], "c1"); expect(flow.inbound).toHaveLength(1); }); it("orders inbound by position (early → middle → terminal) then ts", () => { const flow = pipelineFlow( [ src({ stage: "term", position: "terminal", ts: "2026-06-16T00:00:01.000Z" }), src({ stage: "early-b", position: "early", ts: "2026-06-16T00:00:00.500Z" }), src({ stage: "early-a", position: "early", ts: "2026-06-16T00:00:00.100Z" }), src({ stage: "mid", position: "middle", ts: "2026-06-16T00:00:00.800Z" }), ], "c1", ); expect(flow.inbound.map((r) => r.stage)).toEqual(["early-a", "early-b", "mid", "term"]); }); it("carries the short-circuit flag and duration through", () => { const flow = pipelineFlow([sink({ shortCircuited: true, durationMs: 12 })], "c1"); expect(flow.outbound[0]!.shortCircuited).toBe(true); expect(flow.outbound[0]!.durationMs).toBe(12); }); });