318 lines
9.8 KiB
TypeScript
318 lines
9.8 KiB
TypeScript
/**
|
|
* Targeted branch-coverage suite for the conditional spreads
|
|
* (`...(x ? {y:x} : {})`) and default-config paths that the per-provider
|
|
* feature tests skip for readability.
|
|
*/
|
|
import {
|
|
afterEach,
|
|
beforeEach,
|
|
describe,
|
|
expect,
|
|
it,
|
|
} from "@suaveplan/testing/runner";
|
|
import { AwsSnsProvider } from "../src/aws-sns/aws-sns.js";
|
|
import { MessageBirdProvider } from "../src/messagebird/messagebird.js";
|
|
import { PlivoProvider } from "../src/plivo/plivo.js";
|
|
import { TwilioProvider } from "../src/twilio/twilio.js";
|
|
import { VonageProvider } from "../src/vonage/vonage.js";
|
|
import {
|
|
jsonResponder,
|
|
type RecordingServer,
|
|
startRecordingServer,
|
|
} from "./setup/http-server.js";
|
|
|
|
let server!: RecordingServer;
|
|
|
|
afterEach(async () => {
|
|
await server.close();
|
|
});
|
|
|
|
describe("branch coverage — Twilio", () => {
|
|
it("getStatus returns a report with errorCode + errorMessage when present", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
server = await startRecordingServer(
|
|
jsonResponder({
|
|
sid: "S",
|
|
status: "failed",
|
|
to: "+1",
|
|
date_created: "2026-04-24T10:00:00Z",
|
|
error_code: 30007,
|
|
error_message: "carrier",
|
|
})
|
|
);
|
|
const t = new TwilioProvider({
|
|
accountSid: "AC",
|
|
authToken: "T",
|
|
baseUrl: server.origin,
|
|
fetch: server.fetch,
|
|
});
|
|
const r = await t.getStatus("S");
|
|
expect(r.errorCode).toBe("30007");
|
|
expect(r.errorMessage).toBe("carrier");
|
|
});
|
|
|
|
it("send omits From when message.from is undefined", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
server = await startRecordingServer(
|
|
jsonResponder({ sid: "S", status: "queued", to: "+1" })
|
|
);
|
|
const t = new TwilioProvider({
|
|
accountSid: "AC",
|
|
authToken: "T",
|
|
baseUrl: server.origin,
|
|
fetch: server.fetch,
|
|
});
|
|
await t.send({ to: "+1", body: "x" });
|
|
expect(server.requests[0]!.body).not.toContain("From=");
|
|
});
|
|
});
|
|
|
|
describe("branch coverage — Vonage", () => {
|
|
it("send omits from when message.from is undefined", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
server = await startRecordingServer(
|
|
jsonResponder({
|
|
"message-count": "1",
|
|
messages: [{ to: "1", "message-id": "x", status: "0" }],
|
|
})
|
|
);
|
|
const v = new VonageProvider({
|
|
apiKey: "k",
|
|
apiSecret: "s",
|
|
baseUrl: server.origin,
|
|
fetch: server.fetch,
|
|
});
|
|
await v.send({ to: "+1", body: "hi" });
|
|
expect(server.requests[0]!.body).not.toContain("from=");
|
|
});
|
|
|
|
it("send returns sent without errorCode/errorMessage when status=0 and no error-text", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
server = await startRecordingServer(
|
|
jsonResponder({
|
|
"message-count": "1",
|
|
messages: [{ to: "1", "message-id": "x", status: "0" }],
|
|
})
|
|
);
|
|
const v = new VonageProvider({
|
|
apiKey: "k",
|
|
apiSecret: "s",
|
|
baseUrl: server.origin,
|
|
fetch: server.fetch,
|
|
});
|
|
const r = await v.send({ to: "+1", body: "hi" });
|
|
expect(r.errorCode).toBeUndefined();
|
|
expect(r.errorMessage).toBeUndefined();
|
|
});
|
|
|
|
it("getStatus omits errorCode / errorMessage when absent", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
server = await startRecordingServer(
|
|
jsonResponder({
|
|
"message-id": "x",
|
|
to: "1",
|
|
status: "delivered",
|
|
})
|
|
);
|
|
const v = new VonageProvider({
|
|
apiKey: "k",
|
|
apiSecret: "s",
|
|
baseUrl: server.origin,
|
|
fetch: server.fetch,
|
|
});
|
|
const r = await v.getStatus("x");
|
|
expect(r.errorCode).toBeUndefined();
|
|
expect(r.errorMessage).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("branch coverage — Plivo", () => {
|
|
it("getStatus omits errorCode when absent", { timeout: 5000 }, async () => {
|
|
server = await startRecordingServer(
|
|
jsonResponder({
|
|
api_id: "x",
|
|
message_uuid: "u",
|
|
to_number: "+1",
|
|
message_state: "sent",
|
|
})
|
|
);
|
|
const p = new PlivoProvider({
|
|
authId: "A",
|
|
authToken: "T",
|
|
baseUrl: server.origin,
|
|
fetch: server.fetch,
|
|
});
|
|
const r = await p.getStatus("u");
|
|
expect(r.errorCode).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("branch coverage — AWS SNS", () => {
|
|
it("send falls through to a default `now` factory", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
const PUBLISH_XML =
|
|
'<?xml version="1.0"?><PublishResponse><PublishResult><MessageId>x</MessageId></PublishResult></PublishResponse>';
|
|
server = await startRecordingServer((_req, res) => {
|
|
res.writeHead(200, { "content-type": "text/xml" });
|
|
res.end(PUBLISH_XML);
|
|
});
|
|
const a = new AwsSnsProvider({
|
|
region: "us-east-1",
|
|
accessKeyId: "K",
|
|
secretAccessKey: "S",
|
|
baseUrl: server.origin,
|
|
fetch: server.fetch,
|
|
});
|
|
const r = await a.send({ to: "+1", body: "hi" });
|
|
expect(r.messageId).toBe("x");
|
|
});
|
|
});
|
|
|
|
describe("branch coverage — MessageBird", () => {
|
|
it("send works without options (signal omitted)", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
server = await startRecordingServer(
|
|
jsonResponder({
|
|
id: "mb1",
|
|
originator: "S",
|
|
body: "x",
|
|
type: "sms",
|
|
recipients: {
|
|
totalCount: 1,
|
|
items: [{ recipient: 1, status: "sent" }],
|
|
},
|
|
})
|
|
);
|
|
const m = new MessageBirdProvider({
|
|
accessKey: "K",
|
|
baseUrl: server.origin,
|
|
fetch: server.fetch,
|
|
});
|
|
const r = await m.send({ to: "+1", body: "hi" });
|
|
expect(r.messageId).toBe("mb1");
|
|
});
|
|
});
|
|
|
|
describe("branch coverage — default baseUrl path", () => {
|
|
it("Twilio falls through to the documented default base URL", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
server = await startRecordingServer(
|
|
jsonResponder({ sid: "S", status: "queued", to: "+1" })
|
|
);
|
|
const t = new TwilioProvider({
|
|
accountSid: "AC",
|
|
authToken: "T",
|
|
fetch: server.fetch,
|
|
});
|
|
const r = await t.send({ to: "+1", body: "x" });
|
|
expect(r.messageId).toBe("S");
|
|
});
|
|
|
|
it("Vonage falls through to the documented default base URL", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
server = await startRecordingServer(
|
|
jsonResponder({
|
|
"message-count": "1",
|
|
messages: [{ to: "1", "message-id": "x", status: "0" }],
|
|
})
|
|
);
|
|
const v = new VonageProvider({
|
|
apiKey: "k",
|
|
apiSecret: "s",
|
|
fetch: server.fetch,
|
|
});
|
|
const r = await v.send({ to: "+1", body: "x" });
|
|
expect(r.messageId).toBe("x");
|
|
});
|
|
|
|
it("MessageBird falls through to the documented default base URL", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
server = await startRecordingServer(
|
|
jsonResponder({
|
|
id: "mb",
|
|
originator: "S",
|
|
body: "x",
|
|
type: "sms",
|
|
recipients: {
|
|
totalCount: 1,
|
|
items: [{ recipient: 1, status: "sent" }],
|
|
},
|
|
})
|
|
);
|
|
const m = new MessageBirdProvider({
|
|
accessKey: "K",
|
|
fetch: server.fetch,
|
|
});
|
|
const r = await m.send({ to: "+1", body: "x" });
|
|
expect(r.messageId).toBe("mb");
|
|
});
|
|
|
|
it("Plivo falls through to the documented default base URL", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
server = await startRecordingServer(
|
|
jsonResponder(
|
|
{
|
|
api_id: "x",
|
|
message: "ok",
|
|
message_uuid: ["u1"],
|
|
},
|
|
202
|
|
)
|
|
);
|
|
const p = new PlivoProvider({
|
|
authId: "A",
|
|
authToken: "T",
|
|
fetch: server.fetch,
|
|
});
|
|
const r = await p.send({ to: "+1", body: "x" });
|
|
expect(r.messageId).toBe("u1");
|
|
});
|
|
});
|
|
|
|
describe("branch coverage — extractSnsMessageId fallback for non-object/non-string", () => {
|
|
it("returns undefined for a plain object without MessageId", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
server = await startRecordingServer(jsonResponder({ random: "x" }));
|
|
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"),
|
|
});
|
|
await expect(a.send({ to: "+1", body: "x" })).rejects.toBeTruthy();
|
|
});
|
|
|
|
it("returns undefined for a non-string MessageId on the JSON shape", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
server = await startRecordingServer(jsonResponder({ MessageId: 42 }));
|
|
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"),
|
|
});
|
|
await expect(a.send({ to: "+1", body: "x" })).rejects.toBeTruthy();
|
|
});
|
|
});
|
|
|
|
beforeEach(() => {
|
|
// no-op: each it() block sets up its own server before any work.
|
|
});
|