import { describe, expect, it } from "bun:test"; import { buildFlowActionSucceededV1 } from "../app-event"; import { buildEventFlowActionSucceeded, eventFlowActionSucceededSchema, isEventFlowActionSucceeded, } from "./host-core-flow-action-succeeded"; const event = buildFlowActionSucceededV1({ flowId: "flow_1", flowVersionId: "flow_version_1", flowVersionNumber: 2, flowRunId: "flow_run_1", flowSurface: "widget", actionPlacementId: "placement_1", actionInvocationId: "invocation_1", actionKey: "upgrade", actionVersion: 1, actionKind: "runtime-action", }); describe("host to Core Flow Action Succeeded observation", () => { it("builds the strict provenance-only message", () => { const message = buildEventFlowActionSucceeded({ gen: 3, instanceId: "instance_1", event, timestamp: 1_786_000_000_000, }); expect(message).toEqual({ t: "getuserfeedback:event:flowActionSucceeded", gen: 3, instanceId: "instance_1", event, timestamp: 1_786_000_000_000, }); expect(isEventFlowActionSucceeded(message)).toBe(true); }); it("rejects identity, transport, and invalid timestamp additions", () => { const base = { t: "getuserfeedback:event:flowActionSucceeded", gen: 3, instanceId: "instance_1", event, timestamp: 1_786_000_000_000, }; for (const candidate of [ { ...base, identities: [] }, { ...base, traits: {} }, { ...base, context: {} }, { ...base, apiKey: "secret" }, { ...base, timestamp: -1 }, { ...base, timestamp: Number.NaN }, ]) { expect(eventFlowActionSucceededSchema.safeParse(candidate).success).toBe( false, ); } }); });