test(gateway): dedupe loopback cases and trim setup resets
This commit is contained in:
@@ -79,10 +79,10 @@ const { buildGatewayConnectionDetails, callGateway, callGatewayCli, callGatewayS
|
||||
await import("./call.js");
|
||||
|
||||
function resetGatewayCallMocks() {
|
||||
loadConfig.mockReset();
|
||||
resolveGatewayPort.mockReset();
|
||||
pickPrimaryTailnetIPv4.mockReset();
|
||||
pickPrimaryLanIPv4.mockReset();
|
||||
loadConfig.mockClear();
|
||||
resolveGatewayPort.mockClear();
|
||||
pickPrimaryTailnetIPv4.mockClear();
|
||||
pickPrimaryLanIPv4.mockClear();
|
||||
lastClientOptions = null;
|
||||
startMode = "hello";
|
||||
closeCode = 1006;
|
||||
@@ -133,61 +133,51 @@ describe("callGateway url resolution", () => {
|
||||
expect(lastClientOptions?.url).toBe("ws://127.0.0.1:18800");
|
||||
});
|
||||
|
||||
it("uses loopback with TLS when local bind is tailnet", async () => {
|
||||
loadConfig.mockReturnValue({
|
||||
it.each([
|
||||
{
|
||||
label: "tailnet with TLS",
|
||||
gateway: { mode: "local", bind: "tailnet", tls: { enabled: true } },
|
||||
});
|
||||
resolveGatewayPort.mockReturnValue(18800);
|
||||
pickPrimaryTailnetIPv4.mockReturnValue("100.64.0.1");
|
||||
|
||||
await callGateway({ method: "health" });
|
||||
|
||||
expect(lastClientOptions?.url).toBe("wss://127.0.0.1:18800");
|
||||
});
|
||||
|
||||
it("uses loopback without TLS when local bind is tailnet", async () => {
|
||||
loadConfig.mockReturnValue({ gateway: { mode: "local", bind: "tailnet" } });
|
||||
resolveGatewayPort.mockReturnValue(18800);
|
||||
pickPrimaryTailnetIPv4.mockReturnValue("100.64.0.1");
|
||||
|
||||
await callGateway({ method: "health" });
|
||||
|
||||
expect(lastClientOptions?.url).toBe("ws://127.0.0.1:18800");
|
||||
});
|
||||
|
||||
it("uses loopback with TLS when bind is lan", async () => {
|
||||
loadConfig.mockReturnValue({
|
||||
tailnetIp: "100.64.0.1",
|
||||
lanIp: undefined,
|
||||
expectedUrl: "wss://127.0.0.1:18800",
|
||||
},
|
||||
{
|
||||
label: "tailnet without TLS",
|
||||
gateway: { mode: "local", bind: "tailnet" },
|
||||
tailnetIp: "100.64.0.1",
|
||||
lanIp: undefined,
|
||||
expectedUrl: "ws://127.0.0.1:18800",
|
||||
},
|
||||
{
|
||||
label: "lan with TLS",
|
||||
gateway: { mode: "local", bind: "lan", tls: { enabled: true } },
|
||||
});
|
||||
tailnetIp: undefined,
|
||||
lanIp: "192.168.1.42",
|
||||
expectedUrl: "wss://127.0.0.1:18800",
|
||||
},
|
||||
{
|
||||
label: "lan without TLS",
|
||||
gateway: { mode: "local", bind: "lan" },
|
||||
tailnetIp: undefined,
|
||||
lanIp: "192.168.1.42",
|
||||
expectedUrl: "ws://127.0.0.1:18800",
|
||||
},
|
||||
{
|
||||
label: "lan without discovered LAN IP",
|
||||
gateway: { mode: "local", bind: "lan" },
|
||||
tailnetIp: undefined,
|
||||
lanIp: undefined,
|
||||
expectedUrl: "ws://127.0.0.1:18800",
|
||||
},
|
||||
])("uses loopback for $label", async ({ gateway, tailnetIp, lanIp, expectedUrl }) => {
|
||||
loadConfig.mockReturnValue({ gateway });
|
||||
resolveGatewayPort.mockReturnValue(18800);
|
||||
pickPrimaryTailnetIPv4.mockReturnValue(undefined);
|
||||
pickPrimaryLanIPv4.mockReturnValue("192.168.1.42");
|
||||
pickPrimaryTailnetIPv4.mockReturnValue(tailnetIp);
|
||||
pickPrimaryLanIPv4.mockReturnValue(lanIp);
|
||||
|
||||
await callGateway({ method: "health" });
|
||||
|
||||
expect(lastClientOptions?.url).toBe("wss://127.0.0.1:18800");
|
||||
});
|
||||
|
||||
it("uses loopback without TLS when bind is lan", async () => {
|
||||
loadConfig.mockReturnValue({ gateway: { mode: "local", bind: "lan" } });
|
||||
resolveGatewayPort.mockReturnValue(18800);
|
||||
pickPrimaryTailnetIPv4.mockReturnValue(undefined);
|
||||
pickPrimaryLanIPv4.mockReturnValue("192.168.1.42");
|
||||
|
||||
await callGateway({ method: "health" });
|
||||
|
||||
expect(lastClientOptions?.url).toBe("ws://127.0.0.1:18800");
|
||||
});
|
||||
|
||||
it("falls back to loopback when bind is lan but no LAN IP found", async () => {
|
||||
loadConfig.mockReturnValue({ gateway: { mode: "local", bind: "lan" } });
|
||||
resolveGatewayPort.mockReturnValue(18800);
|
||||
pickPrimaryTailnetIPv4.mockReturnValue(undefined);
|
||||
pickPrimaryLanIPv4.mockReturnValue(undefined);
|
||||
|
||||
await callGateway({ method: "health" });
|
||||
|
||||
expect(lastClientOptions?.url).toBe("ws://127.0.0.1:18800");
|
||||
expect(lastClientOptions?.url).toBe(expectedUrl);
|
||||
});
|
||||
|
||||
it("uses url override in remote mode even when remote url is missing", async () => {
|
||||
@@ -274,35 +264,30 @@ describe("buildGatewayConnectionDetails", () => {
|
||||
expect(details.message).toContain("Gateway target: ws://127.0.0.1:18789");
|
||||
});
|
||||
|
||||
it("uses loopback URL and loopback source when bind is lan", () => {
|
||||
loadConfig.mockReturnValue({
|
||||
it.each([
|
||||
{
|
||||
label: "with TLS",
|
||||
gateway: { mode: "local", bind: "lan", tls: { enabled: true } },
|
||||
});
|
||||
expectedUrl: "wss://127.0.0.1:18800",
|
||||
},
|
||||
{
|
||||
label: "without TLS",
|
||||
gateway: { mode: "local", bind: "lan" },
|
||||
expectedUrl: "ws://127.0.0.1:18800",
|
||||
},
|
||||
])("uses loopback URL for bind=lan $label", ({ gateway, expectedUrl }) => {
|
||||
loadConfig.mockReturnValue({ gateway });
|
||||
resolveGatewayPort.mockReturnValue(18800);
|
||||
pickPrimaryTailnetIPv4.mockReturnValue(undefined);
|
||||
pickPrimaryLanIPv4.mockReturnValue("10.0.0.5");
|
||||
|
||||
const details = buildGatewayConnectionDetails();
|
||||
|
||||
expect(details.url).toBe("wss://127.0.0.1:18800");
|
||||
expect(details.url).toBe(expectedUrl);
|
||||
expect(details.urlSource).toBe("local loopback");
|
||||
expect(details.bindDetail).toBe("Bind: lan");
|
||||
});
|
||||
|
||||
it("uses loopback URL for bind=lan without TLS", () => {
|
||||
loadConfig.mockReturnValue({
|
||||
gateway: { mode: "local", bind: "lan" },
|
||||
});
|
||||
resolveGatewayPort.mockReturnValue(18800);
|
||||
pickPrimaryTailnetIPv4.mockReturnValue(undefined);
|
||||
pickPrimaryLanIPv4.mockReturnValue("10.0.0.5");
|
||||
|
||||
const details = buildGatewayConnectionDetails();
|
||||
|
||||
expect(details.url).toBe("ws://127.0.0.1:18800");
|
||||
expect(details.urlSource).toBe("local loopback");
|
||||
});
|
||||
|
||||
it("prefers remote url when configured", () => {
|
||||
loadConfig.mockReturnValue({
|
||||
gateway: {
|
||||
|
||||
@@ -103,11 +103,11 @@ describe("gateway bonjour advertiser", () => {
|
||||
process.env[key] = value;
|
||||
}
|
||||
|
||||
createService.mockReset();
|
||||
shutdown.mockReset();
|
||||
registerUnhandledRejectionHandler.mockReset();
|
||||
logWarn.mockReset();
|
||||
logDebug.mockReset();
|
||||
createService.mockClear();
|
||||
shutdown.mockClear();
|
||||
registerUnhandledRejectionHandler.mockClear();
|
||||
logWarn.mockClear();
|
||||
logDebug.mockClear();
|
||||
vi.useRealTimers();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
@@ -18,9 +18,9 @@ describe("resolveMessagingTarget (directory fallback)", () => {
|
||||
const cfg = {} as OpenClawConfig;
|
||||
|
||||
beforeEach(() => {
|
||||
mocks.listGroups.mockReset();
|
||||
mocks.listGroupsLive.mockReset();
|
||||
mocks.getChannelPlugin.mockReset();
|
||||
mocks.listGroups.mockClear();
|
||||
mocks.listGroupsLive.mockClear();
|
||||
mocks.getChannelPlugin.mockClear();
|
||||
resetDirectoryCache();
|
||||
mocks.getChannelPlugin.mockReturnValue({
|
||||
directory: {
|
||||
|
||||
Reference in New Issue
Block a user