@@ -680,6 +680,38 @@ describe("resolveTelegramFetch", () => {
|
680 | 680 | expect(typeof pinnedPolicy?.connect?.lookup).toBe("function"); |
681 | 681 | }); |
682 | 682 | |
| 683 | +it("skips sticky IPv4 fallback when user explicitly configures network settings", async () => { |
| 684 | +undiciFetch.mockResolvedValueOnce({ ok: true } as Response); |
| 685 | +const transport = resolveTelegramTransport(undefined, { |
| 686 | +network: { |
| 687 | +autoSelectFamily: true, |
| 688 | +dnsResultOrder: "verbatim", |
| 689 | +}, |
| 690 | +}); |
| 691 | + |
| 692 | +await expect( |
| 693 | +transport.sourceFetch("https://api.telegram.org/botTOKEN/getFile"), |
| 694 | +).resolves.toEqual({ ok: true }); |
| 695 | +// Only the default dispatcher — no IPv4 fallback or pinned IP attempts |
| 696 | +expect(transport.dispatcherAttempts).toHaveLength(1); |
| 697 | +const [defaultAttempt] = transport.dispatcherAttempts as Array<{ |
| 698 | +dispatcherPolicy?: DirectTelegramDispatcherPolicy; |
| 699 | +}>; |
| 700 | +expect(defaultAttempt.dispatcherPolicy?.mode).toBe("direct"); |
| 701 | +expect(defaultAttempt.dispatcherPolicy?.connect?.autoSelectFamily).toBe(true); |
| 702 | +}); |
| 703 | + |
| 704 | +it("skips sticky IPv4 fallback when the DNS result order env override is verbatim", async () => { |
| 705 | +vi.stubEnv("OPENCLAW_TELEGRAM_DNS_RESULT_ORDER", "verbatim"); |
| 706 | +undiciFetch.mockResolvedValueOnce({ ok: true } as Response); |
| 707 | +const transport = resolveTelegramTransport(); |
| 708 | + |
| 709 | +await expect( |
| 710 | +transport.sourceFetch("https://api.telegram.org/botTOKEN/getFile"), |
| 711 | +).resolves.toEqual({ ok: true }); |
| 712 | +expect(transport.dispatcherAttempts).toHaveLength(1); |
| 713 | +}); |
| 714 | + |
683 | 715 | it("does not blind-retry when sticky IPv4 fallback is disallowed for explicit proxy paths", async () => { |
684 | 716 | const { makeProxyFetch } = await import("./proxy.js"); |
685 | 717 | const proxyFetch = makeProxyFetch("http://127.0.0.1:7890"); |
|