mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-07 01:12:54 +00:00
120 lines
4.1 KiB
TypeScript
120 lines
4.1 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
|
const mocks = vi.hoisted(() => ({
|
|
enableTailscaleServe: vi.fn(async (_port: number) => undefined),
|
|
disableTailscaleServe: vi.fn(async () => undefined),
|
|
enableTailscaleFunnel: vi.fn(async (_port: number) => undefined),
|
|
disableTailscaleFunnel: vi.fn(async () => undefined),
|
|
getTailnetHostname: vi.fn(async () => null),
|
|
hasTailscaleFunnelRouteForPort: vi.fn(async (_port: number) => false),
|
|
}));
|
|
|
|
vi.mock("../infra/tailscale.js", () => ({
|
|
enableTailscaleServe: mocks.enableTailscaleServe,
|
|
disableTailscaleServe: mocks.disableTailscaleServe,
|
|
enableTailscaleFunnel: mocks.enableTailscaleFunnel,
|
|
disableTailscaleFunnel: mocks.disableTailscaleFunnel,
|
|
getTailnetHostname: mocks.getTailnetHostname,
|
|
hasTailscaleFunnelRouteForPort: mocks.hasTailscaleFunnelRouteForPort,
|
|
}));
|
|
|
|
import { startGatewayTailscaleExposure } from "./server-tailscale.js";
|
|
|
|
function createLogger() {
|
|
return { info: vi.fn(), warn: vi.fn() };
|
|
}
|
|
|
|
afterEach(() => {
|
|
for (const fn of Object.values(mocks)) {
|
|
fn.mockReset();
|
|
}
|
|
mocks.enableTailscaleServe.mockResolvedValue(undefined);
|
|
mocks.disableTailscaleServe.mockResolvedValue(undefined);
|
|
mocks.enableTailscaleFunnel.mockResolvedValue(undefined);
|
|
mocks.disableTailscaleFunnel.mockResolvedValue(undefined);
|
|
mocks.getTailnetHostname.mockResolvedValue(null);
|
|
mocks.hasTailscaleFunnelRouteForPort.mockResolvedValue(false);
|
|
});
|
|
|
|
describe("startGatewayTailscaleExposure preserveFunnel", () => {
|
|
it("calls enableTailscaleServe in serve mode when preserveFunnel is unset", async () => {
|
|
const logTailscale = createLogger();
|
|
|
|
await startGatewayTailscaleExposure({
|
|
tailscaleMode: "serve",
|
|
port: 18789,
|
|
logTailscale,
|
|
});
|
|
|
|
expect(mocks.enableTailscaleServe).toHaveBeenCalledWith(18789);
|
|
expect(mocks.hasTailscaleFunnelRouteForPort).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("skips enableTailscaleServe when preserveFunnel is true and a Funnel route covers the port", async () => {
|
|
const logTailscale = createLogger();
|
|
mocks.hasTailscaleFunnelRouteForPort.mockResolvedValue(true);
|
|
|
|
await startGatewayTailscaleExposure({
|
|
tailscaleMode: "serve",
|
|
port: 18789,
|
|
preserveFunnel: true,
|
|
logTailscale,
|
|
});
|
|
|
|
expect(mocks.hasTailscaleFunnelRouteForPort).toHaveBeenCalledWith(18789);
|
|
expect(mocks.enableTailscaleServe).not.toHaveBeenCalled();
|
|
expect(logTailscale.info.mock.calls).toEqual([
|
|
["serve skipped: preserving externally configured Tailscale Funnel for port 18789"],
|
|
]);
|
|
});
|
|
|
|
it("notes resetOnExit is a no-op when preserveFunnel skips Serve", async () => {
|
|
const logTailscale = createLogger();
|
|
mocks.hasTailscaleFunnelRouteForPort.mockResolvedValue(true);
|
|
|
|
await startGatewayTailscaleExposure({
|
|
tailscaleMode: "serve",
|
|
port: 18789,
|
|
preserveFunnel: true,
|
|
resetOnExit: true,
|
|
logTailscale,
|
|
});
|
|
|
|
expect(mocks.enableTailscaleServe).not.toHaveBeenCalled();
|
|
expect(logTailscale.info.mock.calls).toEqual([
|
|
[
|
|
"serve skipped: preserving externally configured Tailscale Funnel for port 18789; resetOnExit is a no-op because no Serve route was applied this run",
|
|
],
|
|
]);
|
|
});
|
|
|
|
it("falls back to enableTailscaleServe when preserveFunnel is true but no Funnel route exists for the port", async () => {
|
|
const logTailscale = createLogger();
|
|
mocks.hasTailscaleFunnelRouteForPort.mockResolvedValue(false);
|
|
|
|
await startGatewayTailscaleExposure({
|
|
tailscaleMode: "serve",
|
|
port: 18789,
|
|
preserveFunnel: true,
|
|
logTailscale,
|
|
});
|
|
|
|
expect(mocks.hasTailscaleFunnelRouteForPort).toHaveBeenCalledWith(18789);
|
|
expect(mocks.enableTailscaleServe).toHaveBeenCalledWith(18789);
|
|
});
|
|
|
|
it("never consults the Funnel route helper when running in funnel mode", async () => {
|
|
const logTailscale = createLogger();
|
|
|
|
await startGatewayTailscaleExposure({
|
|
tailscaleMode: "funnel",
|
|
port: 18789,
|
|
preserveFunnel: true,
|
|
logTailscale,
|
|
});
|
|
|
|
expect(mocks.hasTailscaleFunnelRouteForPort).not.toHaveBeenCalled();
|
|
expect(mocks.enableTailscaleFunnel).toHaveBeenCalledWith(18789);
|
|
});
|
|
});
|