import { describe, expect, it } from "bun:test"; import { createGeneration } from "./v3-generation.js"; import { bindViewHostControlEnvelope, bindViewToCoreRelayEnvelope, parseCoreToViewRelayEnvelope, } from "./view-relay-contract.js"; describe("view relay contract", () => { const generation = createGeneration(7); const channelViewId = "view-channel"; it("rejects messages from another generation", () => { const message = { t: "getuserfeedback:event:message", gen: createGeneration(8), payload: { kind: "ping" }, }; expect( bindViewToCoreRelayEnvelope(message, { generation, viewId: channelViewId, }), ).toBeNull(); }); it("stamps a missing viewId on a view relay", () => { const message = { t: "getuserfeedback:event:message", gen: generation, payload: { kind: "ping" }, }; expect( bindViewToCoreRelayEnvelope(message, { generation, viewId: channelViewId, }), ).toEqual({ ...message, viewId: channelViewId }); }); it("rejects a conflicting channel viewId", () => { const message = { t: "getuserfeedback:event:message", gen: generation, viewId: "other-view", payload: { kind: "ping" }, }; expect( bindViewToCoreRelayEnvelope(message, { generation, viewId: channelViewId, }), ).toBeNull(); }); it("compares a padded message viewId after canonical trimming", () => { const message = { t: "getuserfeedback:event:message", gen: generation, viewId: ` ${channelViewId} `, payload: { kind: "ping" }, }; expect( bindViewToCoreRelayEnvelope(message, { generation, viewId: channelViewId, }), ).toEqual({ ...message, viewId: channelViewId }); }); it("rejects a whitespace-only message viewId", () => { const message = { t: "getuserfeedback:event:message", gen: generation, viewId: " ", payload: { kind: "ping" }, }; expect( bindViewToCoreRelayEnvelope(message, { generation, viewId: channelViewId, }), ).toBeNull(); }); it("rejects disallowed view message kinds", () => { const message = { t: "getuserfeedback:action:closeView", gen: generation, viewId: channelViewId, }; expect( bindViewHostControlEnvelope(message, { generation, viewId: channelViewId, }), ).toBeNull(); expect( bindViewToCoreRelayEnvelope(message, { generation, viewId: channelViewId, }), ).toBeNull(); }); it("extracts the explicit Core target and preserves RPC fields", () => { const message = { t: "getuserfeedback:rpc:response", gen: generation, viewId: channelViewId, rpcId: "rpc-1", ok: true, result: { value: 42 }, futureField: { preserved: true }, }; expect(parseCoreToViewRelayEnvelope(message, { generation })).toEqual({ viewId: channelViewId, message, }); }); it("requires an explicit Core target", () => { const message = { t: "getuserfeedback:event:message", gen: generation, payload: { kind: "broadcast" }, }; expect(parseCoreToViewRelayEnvelope(message, { generation })).toBeNull(); }); it("binds host controls to the channel identity", () => { const message = { t: "getuserfeedback:action:requestCloseView", gen: generation, }; expect( bindViewHostControlEnvelope(message, { generation, viewId: channelViewId, }), ).toEqual({ ...message, viewId: channelViewId }); }); it("rejects Core relays from another generation", () => { const message = { t: "getuserfeedback:event:message", gen: createGeneration(8), viewId: channelViewId, payload: { kind: "ping" }, }; expect(parseCoreToViewRelayEnvelope(message, { generation })).toBeNull(); }); });