/** * Second targeted branch-coverage suite — closes the remaining * istanbul branch gaps (default-arms of `??` chains, "fetch undefined" * arms of per-provider `common()`, parseInbound default-fall-through * shapes, http content-type-absent path, default baseUrl path for * AWS SNS, conditional-spread absent-arms for delivery receipts, and * the non-object `safeJsonObject` fallback). */ import { afterEach, describe, expect, it } from "@suaveplan/testing/runner"; import { AwsSnsProvider } from "../src/aws-sns/aws-sns.js"; import { httpRequest } from "../src/http/http.js"; import { MessageBirdProvider } from "../src/messagebird/messagebird.js"; import { PlivoProvider } from "../src/plivo/plivo.js"; import { TwilioProvider } from "../src/twilio/twilio.js"; import type { FetchLike } from "../src/types/provider.js"; import { VonageProvider } from "../src/vonage/vonage.js"; import { jsonResponder, type RecordingServer, startRecordingServer, } from "./setup/http-server.js"; let server: RecordingServer | undefined; afterEach(async () => { if (server) { await server.close(); server = undefined; } }); /** * Temporarily replace `globalThis.fetch` with a path-rewriting fetch that * routes any URL to the recording server's origin via the captured * platform fetch. Restores the original on exit. Used so providers * constructed without an explicit `fetch` config option exercise the * "this.fetch !== undefined === false" arm of their `common()` helper. */ async function withGlobalFetch( origin: string, body: () => Promise ): Promise { const original = globalThis.fetch; const rewriter = async ( input: RequestInfo | URL, init?: RequestInit ): Promise => { const inputUrl = typeof input === "string" || input instanceof URL ? new URL(input.toString()) : new URL(input.url); const rerouted = `${origin}${inputUrl.pathname}${inputUrl.search}`; return original.call(globalThis, rerouted, init); }; Object.defineProperty(globalThis, "fetch", { configurable: true, writable: true, value: rewriter as unknown as typeof fetch, }); try { return await body(); } finally { Object.defineProperty(globalThis, "fetch", { configurable: true, writable: true, value: original, }); } } describe("http.ts — headers.get('content-type') returns null", () => { it("treats a missing content-type header as empty and falls back to start-byte JSON sniffing", { timeout: 5000, }, async () => { const fetchImpl: FetchLike = async () => ({ ok: true, status: 200, headers: { get: () => null }, text: async () => '{"k":1}', }) as unknown as Response; const { data } = await httpRequest<{ k: number }>({ method: "GET", url: "https://x/", fetch: fetchImpl, }); expect(data).toEqual({ k: 1 }); }); }); describe("Twilio — getStatus without date_created falls back to a fresh Date", () => { it("returns a Date timestamp when date_created is omitted", { timeout: 5000, }, async () => { server = await startRecordingServer( jsonResponder({ sid: "S", status: "sent", to: "+1" }) ); const t = new TwilioProvider({ accountSid: "AC", authToken: "T", baseUrl: server.origin, fetch: server.fetch, }); const r = await t.getStatus("S"); expect(r.timestamp).toBeInstanceOf(Date); }); }); describe("common() — this.fetch === undefined arm (default global fetch)", () => { it("Twilio.send works when no explicit fetch is configured", { timeout: 5000, }, async () => { server = await startRecordingServer( jsonResponder({ sid: "S", status: "queued", to: "+1" }) ); const localServer = server; const t = new TwilioProvider({ accountSid: "AC", authToken: "T", baseUrl: server.origin, }); const r = await withGlobalFetch(localServer.origin, () => t.send({ to: "+1", body: "x" }) ); expect(r.messageId).toBe("S"); }); it("Vonage.send works when no explicit fetch is configured", { timeout: 5000, }, async () => { server = await startRecordingServer( jsonResponder({ "message-count": "1", messages: [{ to: "1", "message-id": "x", status: "0" }], }) ); const localServer = server; const v = new VonageProvider({ apiKey: "k", apiSecret: "s", baseUrl: server.origin, }); const r = await withGlobalFetch(localServer.origin, () => v.send({ to: "+1", body: "hi" }) ); expect(r.messageId).toBe("x"); }); it("MessageBird.send works when no explicit fetch is configured", { timeout: 5000, }, async () => { server = await startRecordingServer( jsonResponder({ id: "mb", originator: "S", body: "x", type: "sms", recipients: { totalCount: 1, items: [{ recipient: 1, status: "sent" }], }, }) ); const localServer = server; const m = new MessageBirdProvider({ accessKey: "K", baseUrl: server.origin, }); const r = await withGlobalFetch(localServer.origin, () => m.send({ to: "+1", body: "x" }) ); expect(r.messageId).toBe("mb"); }); it("Plivo.send works when no explicit fetch is configured", { timeout: 5000, }, async () => { server = await startRecordingServer( jsonResponder( { api_id: "x", message: "ok", message_uuid: ["u1"], }, 202 ) ); const localServer = server; const p = new PlivoProvider({ authId: "A", authToken: "T", baseUrl: server.origin, }); const r = await withGlobalFetch(localServer.origin, () => p.send({ to: "+1", body: "x" }) ); expect(r.messageId).toBe("u1"); }); it("AwsSns.send works when no explicit fetch is configured", { timeout: 5000, }, async () => { const PUBLISH_XML = 'x'; server = await startRecordingServer((_req, res) => { res.writeHead(200, { "content-type": "text/xml" }); res.end(PUBLISH_XML); }); const localServer = server; const a = new AwsSnsProvider({ region: "us-east-1", accessKeyId: "K", secretAccessKey: "S", baseUrl: server.origin, now: () => new Date("2026-04-24T10:00:00Z"), }); const r = await withGlobalFetch(localServer.origin, () => a.send({ to: "+1", body: "hi" }) ); expect(r.messageId).toBe("x"); }); }); describe("AWS SNS — default baseUrl path (config.baseUrl omitted)", () => { it("constructs the default https://sns..amazonaws.com base URL when baseUrl is omitted", { timeout: 5000, }, async () => { // We exercise the `?? \`https://${host}\`` default arm of the // constructor; the resulting fetch URL hits the AWS host, but // the swapped global fetch routes it to our recording server. const PUBLISH_XML = 'm1'; server = await startRecordingServer((_req, res) => { res.writeHead(200, { "content-type": "text/xml" }); res.end(PUBLISH_XML); }); const localServer = server; const a = new AwsSnsProvider({ region: "us-east-1", accessKeyId: "K", secretAccessKey: "S", now: () => new Date("2026-04-24T10:00:00Z"), }); const r = await withGlobalFetch(localServer.origin, () => a.send({ to: "+1", body: "hi" }) ); expect(r.messageId).toBe("m1"); }); }); describe("AWS SNS — parseInbound delivery receipt without errorCode", () => { it("omits errorCode when the SNS Message payload has no string errorCode field", { timeout: 5000, }, async () => { server = await startRecordingServer(jsonResponder({})); const a = new AwsSnsProvider({ region: "us-east-1", accessKeyId: "K", secretAccessKey: "S", baseUrl: server.origin, fetch: server.fetch, now: () => new Date("2026-04-24T10:00:00Z"), }); const evt = a.parseInbound({ Type: "Notification", MessageId: "m1", Subject: "AWS SMS Delivery Receipt", Message: JSON.stringify({ status: "DELIVERED" }), Timestamp: "2026-04-24T10:00:00Z", TopicArn: "arn:aws:sns:us-east-1:000000000000:topic", Signature: "", SigningCertURL: "", SignatureVersion: "1", }); expect(evt.type).toBe("delivery_receipt"); if (evt.type === "delivery_receipt") { expect(evt.errorCode).toBeUndefined(); } }); it("falls back to '' status when the SNS Message payload lacks a status field (delivery receipt path)", { timeout: 5000, }, async () => { server = await startRecordingServer(jsonResponder({})); const a = new AwsSnsProvider({ region: "us-east-1", accessKeyId: "K", secretAccessKey: "S", baseUrl: server.origin, fetch: server.fetch, now: () => new Date("2026-04-24T10:00:00Z"), }); const evt = a.parseInbound({ Type: "Notification", MessageId: "m2", Subject: "AWS SMS Delivery Receipt", Message: JSON.stringify({}), Timestamp: "2026-04-24T10:00:00Z", TopicArn: "arn:aws:sns:us-east-1:000000000000:topic", Signature: "", SigningCertURL: "", SignatureVersion: "1", }); expect(evt.type).toBe("delivery_receipt"); if (evt.type === "delivery_receipt") { // `mapStatus("")` defaults to "failed" per the SNS table. expect(evt.status).toBe("failed"); } }); }); describe("AWS SNS — safeJsonObject non-object fallback", () => { it("parseInbound treats a non-object JSON payload as an empty object (covers the `typeof === 'object' && !== null` else arm)", { timeout: 5000, }, async () => { server = await startRecordingServer(jsonResponder({})); const a = new AwsSnsProvider({ region: "us-east-1", accessKeyId: "K", secretAccessKey: "S", baseUrl: server.origin, fetch: server.fetch, now: () => new Date("2026-04-24T10:00:00Z"), }); // `42` parses to a number — `typeof parsed === "object"` is false, // so safeJsonObject returns `{}`. The non-delivery-receipt branch // then produces a message_received event with empty fields. const evt = a.parseInbound({ Type: "Notification", MessageId: "mX", Message: "42", Timestamp: "2026-04-24T10:00:00Z", TopicArn: "arn:aws:sns:us-east-1:000000000000:topic", Signature: "", SigningCertURL: "", SignatureVersion: "1", }); expect(evt.type).toBe("message_received"); if (evt.type === "message_received") { expect(evt.from).toBe(""); expect(evt.to).toBe(""); expect(evt.body).toBe(""); } }); }); describe("AWS SNS — fetchPem default-fetch arm (no provider fetch configured)", () => { it("verifyNotification fetches the SNS signing cert via globalThis.fetch when no fetch is configured", { timeout: 5000, }, async () => { const PEM = "-----BEGIN CERTIFICATE-----\nMIIB\n-----END CERTIFICATE-----\n"; server = await startRecordingServer((_req, res) => { res.writeHead(200, { "content-type": "application/x-pem-file", }); res.end(PEM); }); const localServer = server; const a = new AwsSnsProvider({ region: "us-east-1", accessKeyId: "K", secretAccessKey: "S", now: () => new Date("2026-04-24T10:00:00Z"), }); const ok = await withGlobalFetch(localServer.origin, () => a.verifyNotification( { Type: "Notification", MessageId: "m", Message: "{}", Timestamp: "2026-04-24T10:00:00Z", TopicArn: "arn:aws:sns:us-east-1:0:t", Signature: "x", SigningCertURL: `${localServer.origin}/cert.pem`, SignatureVersion: "1", }, async () => true ) ); expect(ok).toBe(true); }); }); describe("MessageBird — verifyWebhookSignature without nowMs (default arm)", () => { it("accepts a JWT issued at the real wall-clock when nowMs is omitted", { timeout: 5000, }, async () => { server = await startRecordingServer(jsonResponder({})); const { createHmac } = await import("node:crypto"); const b64url = (input: Buffer | string): string => { const buf = typeof input === "string" ? Buffer.from(input, "utf8") : input; return buf .toString("base64") .replace(/=+$/, "") .replace(/\+/g, "-") .replace(/\//g, "_"); }; const nowSec = Math.floor(Date.now() / 1000); const header = b64url(JSON.stringify({ alg: "HS256", typ: "JWT" })); const payload = b64url( JSON.stringify({ iat: nowSec - 1, exp: nowSec + 60 }) ); const sig = createHmac("sha256", "secret") .update(`${header}.${payload}`) .digest(); const token = `${header}.${payload}.${b64url(sig)}`; const m = new MessageBirdProvider({ accessKey: "K", baseUrl: server.origin, fetch: server.fetch, }); const ok = await m.verifyWebhookSignature(token, "secret", {}); expect(ok).toBe(true); }); }); describe("MessageBird — parseInbound fallthrough defaults", () => { it("returns message_received with from='' when originator is absent", { timeout: 5000, }, async () => { server = await startRecordingServer(jsonResponder({})); const m = new MessageBirdProvider({ accessKey: "K", baseUrl: server.origin, fetch: server.fetch, }); const evt = m.parseInbound({ recipient: "+2", payload: "hello" }); expect(evt.type).toBe("message_received"); if (evt.type === "message_received") { expect(evt.from).toBe(""); expect(evt.body).toBe("hello"); } }); it("returns message_received with body='' when neither payload nor body is present", { timeout: 5000, }, async () => { server = await startRecordingServer(jsonResponder({})); const m = new MessageBirdProvider({ accessKey: "K", baseUrl: server.origin, fetch: server.fetch, }); const evt = m.parseInbound({ originator: "+1", recipient: "+2", }); expect(evt.type).toBe("message_received"); if (evt.type === "message_received") { expect(evt.body).toBe(""); } }); }); describe("Plivo — parseInbound fallthrough defaults", () => { it("returns message_received with from='' when From is absent", { timeout: 5000, }, async () => { server = await startRecordingServer(jsonResponder({})); const p = new PlivoProvider({ authId: "A", authToken: "T", baseUrl: server.origin, fetch: server.fetch, }); const evt = p.parseInbound({ To: "+2", Text: "hello" }); expect(evt.type).toBe("message_received"); if (evt.type === "message_received") { expect(evt.from).toBe(""); } }); it("returns message_received with body='' when neither Text nor text is present", { timeout: 5000, }, async () => { server = await startRecordingServer(jsonResponder({})); const p = new PlivoProvider({ authId: "A", authToken: "T", baseUrl: server.origin, fetch: server.fetch, }); const evt = p.parseInbound({ From: "+1", To: "+2" }); expect(evt.type).toBe("message_received"); if (evt.type === "message_received") { expect(evt.body).toBe(""); } }); }); describe("Vonage — parseInbound fallthrough default", () => { it("returns message_received with body='' when text is absent", { timeout: 5000, }, async () => { server = await startRecordingServer(jsonResponder({})); const v = new VonageProvider({ apiKey: "k", apiSecret: "s", baseUrl: server.origin, fetch: server.fetch, }); const evt = v.parseInbound({ msisdn: "+1", to: "+2" }); expect(evt.type).toBe("message_received"); if (evt.type === "message_received") { expect(evt.body).toBe(""); } }); });