Skip to content

Commit 35ceba0

Browse files
committed
test: clear telegram fetch broad matchers
1 parent 651c60f commit 35ceba0

1 file changed

Lines changed: 84 additions & 166 deletions

File tree

extensions/telegram/src/fetch.test.ts

Lines changed: 84 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ let resolveTelegramTransport: typeof import("./fetch.js").resolveTelegramTranspo
107107
type TelegramDispatcherPolicy = NonNullable<
108108
ReturnType<typeof resolveTelegramTransport>["dispatcherAttempts"]
109109
>[number]["dispatcherPolicy"];
110+
type DirectTelegramDispatcherPolicy = Extract<TelegramDispatcherPolicy, { mode: "direct" }>;
111+
type ExplicitProxyTelegramDispatcherPolicy = Extract<
112+
TelegramDispatcherPolicy,
113+
{ mode: "explicit-proxy" }
114+
>;
110115

111116
beforeAll(async () => {
112117
({ resolveTelegramApiBase, resolveTelegramFetch, resolveTelegramTransport } =
@@ -221,12 +226,9 @@ function expectStickyAutoSelectDispatcher(
221226
| undefined,
222227
field: "connect" | "proxyTls" | "requestTls" = "connect",
223228
): void {
224-
expect(dispatcher?.options?.[field]).toEqual(
225-
expect.objectContaining({
226-
autoSelectFamily: true,
227-
autoSelectFamilyAttemptTimeout: 300,
228-
}),
229-
);
229+
const options = dispatcher?.options?.[field];
230+
expect(options?.autoSelectFamily).toBe(true);
231+
expect(options?.autoSelectFamilyAttemptTimeout).toBe(300);
230232
}
231233

232234
function expectHttp1OnlyDispatcher(
@@ -238,11 +240,7 @@ function expectHttp1OnlyDispatcher(
238240
}
239241
| undefined,
240242
): void {
241-
expect(dispatcher?.options).toEqual(
242-
expect.objectContaining({
243-
allowH2: false,
244-
}),
245-
);
243+
expect(dispatcher?.options?.allowH2).toBe(false);
246244
}
247245

248246
function expectPinnedIpv4ConnectDispatcher(args: {
@@ -251,12 +249,8 @@ function expectPinnedIpv4ConnectDispatcher(args: {
251249
followupCall?: number;
252250
}): void {
253251
const pinnedDispatcher = getDispatcherFromUndiciCall(args.pinnedCall);
254-
expect(pinnedDispatcher?.options?.connect).toEqual(
255-
expect.objectContaining({
256-
family: 4,
257-
autoSelectFamily: false,
258-
}),
259-
);
252+
expect(pinnedDispatcher?.options?.connect?.family).toBe(4);
253+
expect(pinnedDispatcher?.options?.connect?.autoSelectFamily).toBe(false);
260254
if (args.firstCall) {
261255
expect(getDispatcherFromUndiciCall(args.firstCall)).not.toBe(pinnedDispatcher);
262256
}
@@ -267,13 +261,9 @@ function expectPinnedIpv4ConnectDispatcher(args: {
267261

268262
function expectPinnedFallbackIpDispatcher(callIndex: number) {
269263
const dispatcher = getDispatcherFromUndiciCall(callIndex);
270-
expect(dispatcher?.options?.connect).toEqual(
271-
expect.objectContaining({
272-
family: 4,
273-
autoSelectFamily: false,
274-
lookup: expect.any(Function),
275-
}),
276-
);
264+
expect(dispatcher?.options?.connect?.family).toBe(4);
265+
expect(dispatcher?.options?.connect?.autoSelectFamily).toBe(false);
266+
expect(typeof dispatcher?.options?.connect?.lookup).toBe("function");
277267
const callback = vi.fn();
278268
(
279269
dispatcher?.options?.connect?.lookup as
@@ -368,13 +358,9 @@ describe("resolveTelegramFetch", () => {
368358

369359
const dispatcher = getDispatcherFromUndiciCall(1);
370360
expectHttp1OnlyDispatcher(dispatcher);
371-
expect(dispatcher?.options?.connect).toEqual(
372-
expect.objectContaining({
373-
autoSelectFamily: true,
374-
autoSelectFamilyAttemptTimeout: 300,
375-
lookup: expect.any(Function),
376-
}),
377-
);
361+
expect(dispatcher?.options?.connect?.autoSelectFamily).toBe(true);
362+
expect(dispatcher?.options?.connect?.autoSelectFamilyAttemptTimeout).toBe(300);
363+
expect(typeof dispatcher?.options?.connect?.lookup).toBe("function");
378364
});
379365

380366
it("emits default transport decisions at debug level", () => {
@@ -400,27 +386,15 @@ describe("resolveTelegramFetch", () => {
400386
await resolved("https://api.telegram.org/botx/getMe");
401387

402388
expect(EnvHttpProxyAgentCtor).toHaveBeenCalledTimes(1);
403-
expect(EnvHttpProxyAgentCtor).toHaveBeenCalledWith(
404-
expect.objectContaining({
405-
httpsProxy: "http://127.0.0.1:7890",
406-
}),
407-
);
389+
expect(EnvHttpProxyAgentCtor.mock.calls[0]?.[0]?.httpsProxy).toBe("http://127.0.0.1:7890");
408390
expect(AgentCtor).not.toHaveBeenCalled();
409391

410392
const dispatcher = getDispatcherFromUndiciCall(1);
411393
expectHttp1OnlyDispatcher(dispatcher);
412-
expect(dispatcher?.options?.connect).toEqual(
413-
expect.objectContaining({
414-
autoSelectFamily: false,
415-
autoSelectFamilyAttemptTimeout: 300,
416-
}),
417-
);
418-
expect(dispatcher?.options?.proxyTls).toEqual(
419-
expect.objectContaining({
420-
autoSelectFamily: false,
421-
autoSelectFamilyAttemptTimeout: 300,
422-
}),
423-
);
394+
expect(dispatcher?.options?.connect?.autoSelectFamily).toBe(false);
395+
expect(dispatcher?.options?.connect?.autoSelectFamilyAttemptTimeout).toBe(300);
396+
expect(dispatcher?.options?.proxyTls?.autoSelectFamily).toBe(false);
397+
expect(dispatcher?.options?.proxyTls?.autoSelectFamilyAttemptTimeout).toBe(300);
424398
});
425399

426400
it("uses the OpenClaw debug proxy URL when no explicit proxy fetch is provided", async () => {
@@ -432,12 +406,11 @@ describe("resolveTelegramFetch", () => {
432406
await resolved("https://api.telegram.org/botTOKEN/getMe");
433407

434408
expect(ProxyAgentCtor).toHaveBeenCalledTimes(1);
435-
expect(ProxyAgentCtor).toHaveBeenCalledWith(
436-
expect.objectContaining({
437-
allowH2: false,
438-
uri: "http://127.0.0.1:7777",
439-
}),
440-
);
409+
const proxyOptions = ProxyAgentCtor.mock.calls[0]?.[0] as
410+
| { allowH2?: boolean; uri?: string }
411+
| undefined;
412+
expect(proxyOptions?.allowH2).toBe(false);
413+
expect(proxyOptions?.uri).toBe("http://127.0.0.1:7777");
441414
});
442415

443416
it("uses OPENCLAW_PROXY_URL as a Telegram explicit proxy when proxy env is absent", async () => {
@@ -454,23 +427,19 @@ describe("resolveTelegramFetch", () => {
454427
await transport.fetch("https://api.telegram.org/botTOKEN/getMe");
455428

456429
expect(ProxyAgentCtor).toHaveBeenCalledTimes(1);
457-
expect(ProxyAgentCtor).toHaveBeenCalledWith(
458-
expect.objectContaining({
459-
allowH2: false,
460-
uri: "http://127.0.0.1:7788",
461-
requestTls: expect.objectContaining({
462-
autoSelectFamily: false,
463-
}),
464-
}),
465-
);
430+
const proxyOptions = ProxyAgentCtor.mock.calls[0]?.[0] as
431+
| { allowH2?: boolean; uri?: string; requestTls?: { autoSelectFamily?: boolean } }
432+
| undefined;
433+
expect(proxyOptions?.allowH2).toBe(false);
434+
expect(proxyOptions?.uri).toBe("http://127.0.0.1:7788");
435+
expect(proxyOptions?.requestTls?.autoSelectFamily).toBe(false);
466436
expect(EnvHttpProxyAgentCtor).not.toHaveBeenCalled();
467437
expect(AgentCtor).not.toHaveBeenCalled();
468-
expect(transport.dispatcherAttempts?.[0]?.dispatcherPolicy).toEqual(
469-
expect.objectContaining({
470-
mode: "explicit-proxy",
471-
proxyUrl: "http://127.0.0.1:7788",
472-
}),
473-
);
438+
const dispatcherPolicy = transport.dispatcherAttempts?.[0]?.dispatcherPolicy as
439+
| ExplicitProxyTelegramDispatcherPolicy
440+
| undefined;
441+
expect(dispatcherPolicy?.mode).toBe("explicit-proxy");
442+
expect(dispatcherPolicy?.proxyUrl).toBe("http://127.0.0.1:7788");
474443
});
475444

476445
it("preserves caller-provided custom fetch when OPENCLAW_PROXY_URL is present", async () => {
@@ -529,18 +498,10 @@ describe("resolveTelegramFetch", () => {
529498

530499
const dispatcher = getDispatcherFromUndiciCall(1);
531500
expectHttp1OnlyDispatcher(dispatcher);
532-
expect(dispatcher?.options?.connect).toEqual(
533-
expect.objectContaining({
534-
autoSelectFamily: true,
535-
autoSelectFamilyAttemptTimeout: 300,
536-
}),
537-
);
538-
expect(dispatcher?.options?.proxyTls).toEqual(
539-
expect.objectContaining({
540-
autoSelectFamily: true,
541-
autoSelectFamilyAttemptTimeout: 300,
542-
}),
543-
);
501+
expect(dispatcher?.options?.connect?.autoSelectFamily).toBe(true);
502+
expect(dispatcher?.options?.connect?.autoSelectFamilyAttemptTimeout).toBe(300);
503+
expect(dispatcher?.options?.proxyTls?.autoSelectFamily).toBe(true);
504+
expect(dispatcher?.options?.proxyTls?.autoSelectFamilyAttemptTimeout).toBe(300);
544505
});
545506

546507
it("keeps resolver-scoped transport policy for OpenClaw proxy fetches", async () => {
@@ -563,16 +524,10 @@ describe("resolveTelegramFetch", () => {
563524
expect(AgentCtor).not.toHaveBeenCalled();
564525
const dispatcher = getDispatcherFromUndiciCall(1);
565526
expectHttp1OnlyDispatcher(dispatcher);
566-
expect(dispatcher?.options).toEqual(
567-
expect.objectContaining({
568-
uri: "http://127.0.0.1:7890",
569-
}),
570-
);
571-
expect(dispatcher?.options?.requestTls).toEqual(
572-
expect.objectContaining({
573-
autoSelectFamily: false,
574-
}),
527+
expect((dispatcher?.options as { uri?: string } | undefined)?.uri).toBe(
528+
"http://127.0.0.1:7890",
575529
);
530+
expect(dispatcher?.options?.requestTls?.autoSelectFamily).toBe(false);
576531
});
577532

578533
it("exports fallback dispatcher attempts for Telegram media downloads", async () => {
@@ -595,43 +550,28 @@ describe("resolveTelegramFetch", () => {
595550
expect(transport.dispatcherAttempts).toHaveLength(3);
596551

597552
const [defaultAttempt, ipv4Attempt, pinnedAttempt] = transport.dispatcherAttempts as Array<{
598-
dispatcherPolicy?: TelegramDispatcherPolicy;
553+
dispatcherPolicy?: DirectTelegramDispatcherPolicy;
599554
}>;
600555

601-
expect(defaultAttempt.dispatcherPolicy).toEqual(
602-
expect.objectContaining({
603-
mode: "direct",
604-
connect: expect.objectContaining({
605-
autoSelectFamily: true,
606-
autoSelectFamilyAttemptTimeout: 300,
607-
lookup: expect.any(Function),
608-
}),
609-
}),
610-
);
611-
expect(ipv4Attempt.dispatcherPolicy).toEqual(
612-
expect.objectContaining({
613-
mode: "direct",
614-
connect: expect.objectContaining({
615-
family: 4,
616-
autoSelectFamily: false,
617-
lookup: expect.any(Function),
618-
}),
619-
}),
620-
);
621-
expect(pinnedAttempt.dispatcherPolicy).toEqual(
622-
expect.objectContaining({
623-
mode: "direct",
624-
pinnedHostname: {
625-
hostname: "api.telegram.org",
626-
addresses: ["149.154.167.220"],
627-
},
628-
connect: expect.objectContaining({
629-
family: 4,
630-
autoSelectFamily: false,
631-
lookup: expect.any(Function),
632-
}),
633-
}),
634-
);
556+
const defaultPolicy = defaultAttempt.dispatcherPolicy;
557+
const ipv4Policy = ipv4Attempt.dispatcherPolicy;
558+
const pinnedPolicy = pinnedAttempt.dispatcherPolicy;
559+
expect(defaultPolicy?.mode).toBe("direct");
560+
expect(defaultPolicy?.connect?.autoSelectFamily).toBe(true);
561+
expect(defaultPolicy?.connect?.autoSelectFamilyAttemptTimeout).toBe(300);
562+
expect(typeof defaultPolicy?.connect?.lookup).toBe("function");
563+
expect(ipv4Policy?.mode).toBe("direct");
564+
expect(ipv4Policy?.connect?.family).toBe(4);
565+
expect(ipv4Policy?.connect?.autoSelectFamily).toBe(false);
566+
expect(typeof ipv4Policy?.connect?.lookup).toBe("function");
567+
expect(pinnedPolicy?.mode).toBe("direct");
568+
expect(pinnedPolicy?.pinnedHostname).toEqual({
569+
hostname: "api.telegram.org",
570+
addresses: ["149.154.167.220"],
571+
});
572+
expect(pinnedPolicy?.connect?.family).toBe(4);
573+
expect(pinnedPolicy?.connect?.autoSelectFamily).toBe(false);
574+
expect(typeof pinnedPolicy?.connect?.lookup).toBe("function");
635575
});
636576

637577
it("does not blind-retry when sticky IPv4 fallback is disallowed for explicit proxy paths", async () => {
@@ -688,20 +628,13 @@ describe("resolveTelegramFetch", () => {
688628
await resolved("https://api.telegram.org/botx/sendMessage");
689629

690630
expect(EnvHttpProxyAgentCtor).toHaveBeenCalledTimes(1);
691-
expect(EnvHttpProxyAgentCtor).toHaveBeenCalledWith(
692-
expect.objectContaining({
693-
allowH2: false,
694-
httpProxy: "http://127.0.0.1:7891",
695-
httpsProxy: "http://127.0.0.1:7891",
696-
}),
697-
);
631+
const proxyOptions = EnvHttpProxyAgentCtor.mock.calls[0]?.[0];
632+
expect(proxyOptions?.allowH2).toBe(false);
633+
expect(proxyOptions?.httpProxy).toBe("http://127.0.0.1:7891");
634+
expect(proxyOptions?.httpsProxy).toBe("http://127.0.0.1:7891");
698635
expect(AgentCtor).not.toHaveBeenCalled();
699636

700-
expect(transport.dispatcherAttempts?.[0]?.dispatcherPolicy).toEqual(
701-
expect.objectContaining({
702-
mode: "env-proxy",
703-
}),
704-
);
637+
expect(transport.dispatcherAttempts?.[0]?.dispatcherPolicy?.mode).toBe("env-proxy");
705638
});
706639

707640
it("arms sticky IPv4 fallback when env proxy init falls back to direct Agent", async () => {
@@ -794,11 +727,7 @@ describe("resolveTelegramFetch", () => {
794727
expect(AgentCtor).toHaveBeenCalledTimes(1);
795728

796729
const dispatcher = getDispatcherFromUndiciCall(1);
797-
expect(dispatcher?.options?.connect).toEqual(
798-
expect.objectContaining({
799-
autoSelectFamily: false,
800-
}),
801-
);
730+
expect(dispatcher?.options?.connect?.autoSelectFamily).toBe(false);
802731
});
803732

804733
it("retries once, keeps sticky IPv4, then recovers to primary dispatcher", async () => {
@@ -834,12 +763,8 @@ describe("resolveTelegramFetch", () => {
834763
expect(eighthDispatcher).toBe(firstDispatcher);
835764

836765
expectStickyAutoSelectDispatcher(firstDispatcher);
837-
expect(secondDispatcher?.options?.connect).toEqual(
838-
expect.objectContaining({
839-
family: 4,
840-
autoSelectFamily: false,
841-
}),
842-
);
766+
expect(secondDispatcher?.options?.connect?.family).toBe(4);
767+
expect(secondDispatcher?.options?.connect?.autoSelectFamily).toBe(false);
843768
expect(loggerDebug).toHaveBeenCalledWith(
844769
expect.stringContaining("fetch fallback: enabling sticky IPv4-only dispatcher"),
845770
);
@@ -1101,16 +1026,8 @@ describe("resolveTelegramFetch", () => {
11011026

11021027
expect(dispatcherA).not.toBe(dispatcherB);
11031028

1104-
expect(dispatcherA?.options?.connect).toEqual(
1105-
expect.objectContaining({
1106-
autoSelectFamily: false,
1107-
}),
1108-
);
1109-
expect(dispatcherB?.options?.connect).toEqual(
1110-
expect.objectContaining({
1111-
autoSelectFamily: true,
1112-
}),
1113-
);
1029+
expect(dispatcherA?.options?.connect?.autoSelectFamily).toBe(false);
1030+
expect(dispatcherB?.options?.connect?.autoSelectFamily).toBe(true);
11141031

11151032
// Core guarantee: Telegram transport no longer mutates process-global defaults.
11161033
expect(setGlobalDispatcher).not.toHaveBeenCalled();
@@ -1130,15 +1047,16 @@ describe("resolveTelegramFetch", () => {
11301047
// One direct Agent for the default dispatcher plus two lazy fallbacks not yet touched.
11311048
expect(AgentCtor).toHaveBeenCalledTimes(1);
11321049
const defaultAgent = AgentCtor.mock.instances[0]?.options;
1133-
expect(defaultAgent).toEqual(
1134-
expect.objectContaining({
1135-
allowH2: false,
1136-
keepAliveTimeout: expect.any(Number),
1137-
keepAliveMaxTimeout: expect.any(Number),
1138-
connections: expect.any(Number),
1139-
pipelining: expect.any(Number),
1140-
}),
1050+
expect(typeof defaultAgent).toBe("object");
1051+
expect((defaultAgent as { allowH2?: boolean } | undefined)?.allowH2).toBe(false);
1052+
expect(typeof (defaultAgent as { keepAliveTimeout?: unknown }).keepAliveTimeout).toBe(
1053+
"number",
1054+
);
1055+
expect(typeof (defaultAgent as { keepAliveMaxTimeout?: unknown }).keepAliveMaxTimeout).toBe(
1056+
"number",
11411057
);
1058+
expect(typeof (defaultAgent as { connections?: unknown }).connections).toBe("number");
1059+
expect(typeof (defaultAgent as { pipelining?: unknown }).pipelining).toBe("number");
11421060
const connections = (defaultAgent as { connections?: number }).connections;
11431061
expect(connections).toBeGreaterThan(0);
11441062
expect(connections).toBeLessThan(100);

0 commit comments

Comments
 (0)