import { describe, expect, it } from "vitest"; import { decodeSyncMessage, encodeSyncMessage, isSyncMessage } from "./sync-wire"; import type { SyncMessage } from "./sync-types"; describe("sync wire codec", () => { it("round-trips SYNC_VAULT_SEND through base64url JSON", () => { const message: SyncMessage = { type: "SYNC_VAULT_SEND", vault_a: "ciphertext-a", vault_b: "ciphertext-b", sent_at: 1_778_000_000_000, }; const encoded = encodeSyncMessage(message); expect(encoded).toMatch(/^[A-Za-z0-9_-]+$/); expect(encoded).not.toMatch(/[+/=]/); expect(decodeSyncMessage(encoded)).toEqual(message); }); it("round-trips ACK / ERROR / pairing messages", () => { const messages: SyncMessage[] = [ { type: "SYNC_VAULT_ACK", received_at: 42 }, { type: "SYNC_ERROR", reason: "vault_locked" }, { type: "PAIR_REQUEST", public_key_hex: "ab".repeat(32), device_name: "June's Laptop", }, { type: "PAIR_ACCEPT", public_key_hex: "cd".repeat(32), device_name: "June's Phone", }, { type: "PAIR_REJECT", reason: "user_declined" }, ]; for (const message of messages) { expect(decodeSyncMessage(encodeSyncMessage(message))).toEqual(message); } }); it("validates message-specific required fields", () => { expect( isSyncMessage({ type: "SYNC_VAULT_SEND", vault_a: "a", vault_b: "b", sent_at: 1, }), ).toBe(true); expect( isSyncMessage({ type: "PAIR_ACCEPT", public_key_hex: "deadbeef", device_name: "Phone", }), ).toBe(true); // Missing sent_at expect( isSyncMessage({ type: "SYNC_VAULT_SEND", vault_a: "a", vault_b: "b" }), ).toBe(false); // Wrong type for received_at expect(isSyncMessage({ type: "SYNC_VAULT_ACK", received_at: "now" })).toBe(false); // Missing reason expect(isSyncMessage({ type: "SYNC_ERROR" })).toBe(false); // Missing device_name expect(isSyncMessage({ type: "PAIR_REQUEST", public_key_hex: "abc" })).toBe(false); // Unknown variant expect(isSyncMessage({ type: "UNKNOWN" })).toBe(false); }); it("rejects malformed wire payloads with a stable error", () => { const malformedJson = btoa("{").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, ""); const unknownType = btoa(JSON.stringify({ type: "BOGUS" })) .replace(/\+/g, "-") .replace(/\//g, "_") .replace(/=+$/g, ""); expect(() => decodeSyncMessage("@@@")).toThrow("invalid sync message"); expect(() => decodeSyncMessage("A")).toThrow("invalid sync message"); expect(() => decodeSyncMessage(malformedJson)).toThrow("invalid sync message"); expect(() => decodeSyncMessage(unknownType)).toThrow("invalid sync message"); }); });