




















@@ -58,6 +58,26 @@ function createApiRequestMock(impl?: TwilioApiRequest) {
5858return vi.fn<TwilioApiRequest>(impl ?? (async () => ({})));
5959}
606061+function requireApiRequestCall(
62+apiRequest: ReturnType<typeof createApiRequestMock>,
63+index = 0,
64+): Parameters<TwilioApiRequest> {
65+const call = apiRequest.mock.calls[index];
66+if (!call) {
67+throw new Error(`expected Twilio API request call ${index}`);
68+}
69+return call;
70+}
71+72+function expectApiRequestEndpoint(
73+apiRequest: ReturnType<typeof createApiRequestMock>,
74+index: number,
75+endpoint: string,
76+): void {
77+const [actualEndpoint] = requireApiRequestCall(apiRequest, index);
78+expect(actualEndpoint).toBe(endpoint);
79+}
80+6181function createTwilioCallStateRaceError(): TwilioApiError {
6282return new TwilioApiError(
6383400,
@@ -107,15 +127,15 @@ describe("TwilioProvider", () => {
107127108128expect(result).toEqual({ providerCallId: "CA123", status: "queued" });
109129expect(apiRequest).toHaveBeenCalledTimes(1);
110-const [endpoint, params] = apiRequest.mock.calls[0] ?? [];
130+const [endpoint, params] = requireApiRequestCall(apiRequest);
111131expect(endpoint).toBe("/Calls.json");
112-expect(params?.To).toBe("+14155550123");
113-expect(params?.From).toBe("+14155550100");
114-expect(params?.Twiml).toBe("<Response><Say>Hello</Say></Response>");
115-expect(params?.StatusCallback).toBe(
132+expect(params.To).toBe("+14155550123");
133+expect(params.From).toBe("+14155550100");
134+expect(params.Twiml).toBe("<Response><Say>Hello</Say></Response>");
135+expect(params.StatusCallback).toBe(
116136"https://example.ngrok.app/voice/webhook?callId=call-1&type=status",
117137);
118-expect(params?.StatusCallbackEvent).toEqual(["initiated", "ringing", "answered", "completed"]);
138+expect(params.StatusCallbackEvent).toEqual(["initiated", "ringing", "answered", "completed"]);
119139expect(params).not.toHaveProperty("Url");
120140});
121141@@ -136,10 +156,10 @@ describe("TwilioProvider", () => {
136156});
137157138158expect(apiRequest).toHaveBeenCalledTimes(1);
139-const [endpoint, params] = apiRequest.mock.calls[0] ?? [];
159+const [endpoint, params] = requireApiRequestCall(apiRequest);
140160expect(endpoint).toBe("/Calls.json");
141-expect(params?.Url).toBe("https://example.ngrok.app/voice/webhook?callId=call-1");
142-expect(params?.StatusCallback).toBe(
161+expect(params.Url).toBe("https://example.ngrok.app/voice/webhook?callId=call-1");
162+expect(params.StatusCallback).toBe(
143163"https://example.ngrok.app/voice/webhook?callId=call-1&type=status",
144164);
145165expect(params).not.toHaveProperty("Twiml");
@@ -376,9 +396,7 @@ describe("TwilioProvider", () => {
376396}),
377397).resolves.toBeUndefined();
378398expect(apiRequest).toHaveBeenCalledTimes(1);
379-const call = apiRequest.mock.calls[0];
380-const endpoint = call[0];
381-const params = call[1] as { Twiml?: string };
399+const [endpoint, params] = requireApiRequestCall(apiRequest) as [string, { Twiml?: string }];
382400expect(endpoint).toBe("/Calls/CA-nostream.json");
383401expect(params.Twiml).toContain("<Say");
384402});
@@ -404,8 +422,8 @@ describe("TwilioProvider", () => {
404422await expect(playback).resolves.toBeUndefined();
405423406424expect(apiRequest).toHaveBeenCalledTimes(2);
407-expect(apiRequest.mock.calls[0]?.[0]).toBe("/Calls/CA-race-play.json");
408-expect(apiRequest.mock.calls[1]?.[0]).toBe("/Calls/CA-race-play.json");
425+expectApiRequestEndpoint(apiRequest, 0, "/Calls/CA-race-play.json");
426+expectApiRequestEndpoint(apiRequest, 1, "/Calls/CA-race-play.json");
409427expect(warn).toHaveBeenCalledWith(
410428"[voice-call] Twilio playTts update hit call state race (21220); retrying in 250ms",
411429);
@@ -429,9 +447,7 @@ describe("TwilioProvider", () => {
429447).resolves.toBeUndefined();
430448431449expect(apiRequest).toHaveBeenCalledTimes(1);
432-const call = apiRequest.mock.calls[0];
433-const endpoint = call[0];
434-const params = call[1] as { Twiml?: string };
450+const [endpoint, params] = requireApiRequestCall(apiRequest) as [string, { Twiml?: string }];
435451expect(endpoint).toBe("/Calls/CA-dtmf.json");
436452expect(params.Twiml).toContain('<Play digits="ww123#"');
437453expect(params.Twiml).toContain("<Redirect");
@@ -458,8 +474,8 @@ describe("TwilioProvider", () => {
458474await expect(listening).resolves.toBeUndefined();
459475460476expect(apiRequest).toHaveBeenCalledTimes(2);
461-expect(apiRequest.mock.calls[0]?.[0]).toBe("/Calls/CA-race-listen.json");
462-expect(apiRequest.mock.calls[1]?.[0]).toBe("/Calls/CA-race-listen.json");
477+expectApiRequestEndpoint(apiRequest, 0, "/Calls/CA-race-listen.json");
478+expectApiRequestEndpoint(apiRequest, 1, "/Calls/CA-race-listen.json");
463479expect(warn).toHaveBeenCalledWith(
464480"[voice-call] Twilio startListening update hit call state race (21220); retrying in 250ms",
465481);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。