import { describe, expect, it } from "vitest"; import { publishingIdempotencyKey } from "@tactical-media-broadcast-hub/core"; import { canonicalPostHash } from "./approval.js"; describe("approval and attempt identity", () => { it("sorts nested keys, excludes execution metadata, and preserves target and array order", () => { const post = { text: "hi", mediaAssetIds: ["a", "b"], providerMetadata: { connectionId: "target", nested: { z: 2, a: 1 } } }; const reordered = { providerMetadata: { nested: { a: 1, z: 2 }, connectionId: "target", draftId: "injected", idempotencyKey: "key" }, mediaAssetIds: ["a", "b"], text: "hi" }; expect(canonicalPostHash(post)).toBe(canonicalPostHash(reordered)); expect(canonicalPostHash(post)).not.toBe(canonicalPostHash({ ...post, mediaAssetIds: ["b", "a"] })); expect(canonicalPostHash(post)).not.toBe(canonicalPostHash({ ...post, providerMetadata: { ...post.providerMetadata, connectionId: "other" } })); }); it("uses decimal bigint attempts without precision loss", () => { expect(publishingIdempotencyKey({ workspaceId: "ws", draftId: "draft", attemptNo: "9007199254740993" })).toBe("wp3:ws:draft:a9007199254740993:publish"); expect(() => publishingIdempotencyKey({ workspaceId: "ws", draftId: "draft", attemptNo: Number.MAX_SAFE_INTEGER + 1 })).toThrow(); for (const attemptNo of ["0", "01", "-1", "1.1"]) expect(() => publishingIdempotencyKey({ workspaceId: "ws", draftId: "draft", attemptNo })).toThrow(); }); });