/** * Boundary schema tests for WebRTCPluginConfigSchema and friends. */ import { describe, expect, it } from "@suaveplan/testing/runner"; import { IceServerSchema, P2PConfigSchema, SignalingConfigSchema, SubChunkConfigSchema, WebRTCPluginConfigSchema, } from "../src/index.js"; describe("IceServerSchema", () => { it("accepts a single-URL form", { timeout: 5000 }, () => { expect( IceServerSchema.safeParse({ urls: "stun:stun.l.google.com:19302", }).success ).toBe(true); }); it("accepts a non-empty URL array with credentials", { timeout: 5000, }, () => { expect( IceServerSchema.safeParse({ urls: ["turn:turn.example.com:3478"], username: "u", credential: "p", credentialType: "password", }).success ).toBe(true); }); it("rejects an empty URL array", { timeout: 5000 }, () => { expect(IceServerSchema.safeParse({ urls: [] }).success).toBe(false); }); it("rejects unknown credentialType", { timeout: 5000 }, () => { expect( IceServerSchema.safeParse({ urls: "stun:x", credentialType: "oauth", }).success ).toBe(false); }); }); describe("SignalingConfigSchema", () => { it("accepts minimal valid config", { timeout: 5000 }, () => { expect( SignalingConfigSchema.safeParse({ url: "wss://signal.example.com", }).success ).toBe(true); }); it("rejects empty url", { timeout: 5000 }, () => { expect(SignalingConfigSchema.safeParse({ url: "" }).success).toBe( false ); }); it("rejects non-positive reconnectDelay", { timeout: 5000 }, () => { expect( SignalingConfigSchema.safeParse({ url: "wss://x", reconnectDelay: 0, }).success ).toBe(false); }); }); describe("P2PConfigSchema", () => { it("accepts empty config", { timeout: 5000 }, () => { expect(P2PConfigSchema.safeParse({}).success).toBe(true); }); it("accepts a populated config", { timeout: 5000 }, () => { expect( P2PConfigSchema.safeParse({ priority: 10, timeout: 30_000, iceServers: [{ urls: "stun:stun.l.google.com:19302" }], maxConcurrentDownloads: 5, }).success ).toBe(true); }); it("rejects negative priority", { timeout: 5000 }, () => { expect(P2PConfigSchema.safeParse({ priority: -1 }).success).toBe(false); }); it("rejects zero maxConcurrentDownloads", { timeout: 5000 }, () => { expect( P2PConfigSchema.safeParse({ maxConcurrentDownloads: 0 }).success ).toBe(false); }); it("rejects float timeout", { timeout: 5000 }, () => { expect(P2PConfigSchema.safeParse({ timeout: 1.5 }).success).toBe(false); }); }); describe("SubChunkConfigSchema", () => { it("accepts empty config", { timeout: 5000 }, () => { expect(SubChunkConfigSchema.safeParse({}).success).toBe(true); }); it("accepts a populated rateLimit", { timeout: 5000 }, () => { expect( SubChunkConfigSchema.safeParse({ size: 16_000, backpressure: 262_144, rateLimit: { delayMs: 5, everyNParts: 10 }, }).success ).toBe(true); }); it("rejects zero everyNParts", { timeout: 5000 }, () => { expect( SubChunkConfigSchema.safeParse({ rateLimit: { delayMs: 0, everyNParts: 0 }, }).success ).toBe(false); }); it("rejects negative delayMs", { timeout: 5000 }, () => { expect( SubChunkConfigSchema.safeParse({ rateLimit: { delayMs: -1, everyNParts: 1 }, }).success ).toBe(false); }); }); describe("WebRTCPluginConfigSchema", () => { it("accepts minimal valid config", { timeout: 5000 }, () => { expect( WebRTCPluginConfigSchema.safeParse({ signaling: { url: "wss://signal.example.com" }, }).success ).toBe(true); }); it("rejects missing signaling", { timeout: 5000 }, () => { expect(WebRTCPluginConfigSchema.safeParse({}).success).toBe(false); }); it("rejects invalid nested p2p config", { timeout: 5000 }, () => { expect( WebRTCPluginConfigSchema.safeParse({ signaling: { url: "wss://x" }, p2p: { timeout: -5 }, }).success ).toBe(false); }); it("accepts a fully populated config", { timeout: 5000 }, () => { expect( WebRTCPluginConfigSchema.safeParse({ signaling: { url: "wss://signal.example.com", peerId: "peer-a", peerName: "Alice", authToken: "tok", reconnect: true, reconnectDelay: 1000, }, p2p: { priority: 5, timeout: 30_000, iceServers: [{ urls: "stun:stun.l.google.com:19302" }], maxConcurrentDownloads: 5, }, subChunks: { size: 16_000, backpressure: 262_144, rateLimit: { delayMs: 5, everyNParts: 10 }, }, }).success ).toBe(true); }); });