import assert from "node:assert/strict"; import test from "node:test"; import { createChannelEnvelope, createChannelEnvelopeDecoder, encodeChannelEnvelope, nextReconnectDelay, normalizeCertificateIdentities, normalizeChannelEnvelope, } from "../src/index.mjs"; const now = "2026-08-11T12:00:00.000Z"; function envelope(overrides = {}) { return createChannelEnvelope({ edgeRegistrationId: "edge:pilot-1", channelGeneration: "generation:pilot-1", trackerSessionId: "channel:control", adapterProfileRef: "channel.control.v1", sequence: 1, eventAt: now, receivedAt: now, messageKind: "channel.hello", correlationId: "correlation:hello-1", payload: { status: "ready" }, ...overrides, }, { direction: "edge-to-core" }); } test("round-trips a bounded versioned Edge envelope", () => { const decoder = createChannelEnvelopeDecoder({ direction: "edge-to-core" }); const encoded = encodeChannelEnvelope(envelope(), { direction: "edge-to-core", }); const split = Math.floor(encoded.length / 2); assert.deepEqual(decoder.push(encoded.subarray(0, split)), []); assert.deepEqual(decoder.push(encoded.subarray(split)), [envelope()]); assert.equal(decoder.bufferedBytes(), 0); decoder.finish(); }); test("fails closed on unknown kinds, payload mismatches and oversized frames", () => { const valid = envelope(); assert.throws(() => normalizeChannelEnvelope({ ...valid, messageKind: "tcp.forward", }, { direction: "edge-to-core" }), /message_kind_invalid/); assert.throws(() => normalizeChannelEnvelope({ ...valid, payloadBytes: valid.payloadBytes + 1, }, { direction: "edge-to-core" }), /payload_length_mismatch/); const decoder = createChannelEnvelopeDecoder({ direction: "edge-to-core", maxEnvelopeBytes: 256, }); assert.throws(() => decoder.push(Buffer.alloc(257, 0x61)), /envelope_too_large/); }); test("uses bounded jittered exponential reconnect delays", () => { assert.equal(nextReconnectDelay(0, { minimumMs: 1000, maximumMs: 30_000, random: () => 1, }), 1000); assert.equal(nextReconnectDelay(5, { minimumMs: 1000, maximumMs: 30_000, random: () => 1, }), 30_000); assert.equal(nextReconnectDelay(5, { minimumMs: 1000, maximumMs: 30_000, random: () => 0, }), 15_000); }); test("allows exactly one active and at most one staged certificate generation", () => { const activeFingerprint = "AA:".repeat(31) + "AA"; const stagedFingerprint = "BB:".repeat(31) + "BB"; const identities = normalizeCertificateIdentities([ { generationRef: "trust-generation:1", fingerprint: activeFingerprint, status: "active", }, { generationRef: "trust-generation:2", fingerprint: stagedFingerprint, status: "staged", }, ]); assert.equal(identities.length, 2); assert.equal(identities[0].status, "active"); assert.equal(identities[1].status, "staged"); assert.throws(() => normalizeCertificateIdentities([ { ...identities[0], status: "staged" }, identities[1], ]), /active_certificate_identity_invalid/); assert.throws(() => normalizeCertificateIdentities([ identities[0], { ...identities[1], status: "active" }, ]), /active_certificate_identity_invalid/); });