refactor(core): extract shared dedup helpers

This commit is contained in:
Peter Steinberger
2026-03-07 10:40:49 +00:00
parent 14c61bb33f
commit 3c71e2bd48
114 changed files with 3400 additions and 2040 deletions

View File

@@ -72,6 +72,32 @@ function createTailscaleRemoteRefConfig() {
};
}
function createDefaultSecretProvider() {
return {
providers: {
default: { source: "env" as const },
},
};
}
function createLocalGatewayConfigWithAuth(auth: Record<string, unknown>) {
return {
secrets: createDefaultSecretProvider(),
gateway: {
bind: "custom",
customBindHost: "gateway.local",
auth,
},
};
}
function createLocalGatewayPasswordRefAuth(secretId: string) {
return {
mode: "password",
password: { source: "env", provider: "default", id: secretId },
};
}
describe("registerQrCli", () => {
function createProgram() {
const program = new Command();
@@ -88,6 +114,23 @@ describe("registerQrCli", () => {
await expect(runQr(args)).rejects.toThrow("exit");
}
function parseLastLoggedQrJson() {
return JSON.parse(String(runtime.log.mock.calls.at(-1)?.[0] ?? "{}")) as {
setupCode?: string;
gatewayUrl?: string;
auth?: string;
urlSource?: string;
};
}
function mockTailscaleStatusLookup() {
runCommandWithTimeout.mockResolvedValue({
code: 0,
stdout: '{"Self":{"DNSName":"ts-host.tailnet.ts.net."}}',
stderr: "",
});
}
beforeEach(() => {
vi.clearAllMocks();
vi.stubEnv("OPENCLAW_GATEWAY_TOKEN", "");
@@ -157,21 +200,11 @@ describe("registerQrCli", () => {
});
it("skips local password SecretRef resolution when --token override is provided", async () => {
loadConfig.mockReturnValue({
secrets: {
providers: {
default: { source: "env" },
},
},
gateway: {
bind: "custom",
customBindHost: "gateway.local",
auth: {
mode: "password",
password: { source: "env", provider: "default", id: "MISSING_LOCAL_GATEWAY_PASSWORD" },
},
},
});
loadConfig.mockReturnValue(
createLocalGatewayConfigWithAuth(
createLocalGatewayPasswordRefAuth("MISSING_LOCAL_GATEWAY_PASSWORD"),
),
);
await runQr(["--setup-code-only", "--token", "override-token"]);
@@ -184,21 +217,11 @@ describe("registerQrCli", () => {
it("resolves local gateway auth password SecretRefs before setup code generation", async () => {
vi.stubEnv("QR_LOCAL_GATEWAY_PASSWORD", "local-password-secret");
loadConfig.mockReturnValue({
secrets: {
providers: {
default: { source: "env" },
},
},
gateway: {
bind: "custom",
customBindHost: "gateway.local",
auth: {
mode: "password",
password: { source: "env", provider: "default", id: "QR_LOCAL_GATEWAY_PASSWORD" },
},
},
});
loadConfig.mockReturnValue(
createLocalGatewayConfigWithAuth(
createLocalGatewayPasswordRefAuth("QR_LOCAL_GATEWAY_PASSWORD"),
),
);
await runQr(["--setup-code-only"]);
@@ -212,21 +235,11 @@ describe("registerQrCli", () => {
it("uses OPENCLAW_GATEWAY_PASSWORD without resolving local password SecretRef", async () => {
vi.stubEnv("OPENCLAW_GATEWAY_PASSWORD", "password-from-env");
loadConfig.mockReturnValue({
secrets: {
providers: {
default: { source: "env" },
},
},
gateway: {
bind: "custom",
customBindHost: "gateway.local",
auth: {
mode: "password",
password: { source: "env", provider: "default", id: "MISSING_LOCAL_GATEWAY_PASSWORD" },
},
},
});
loadConfig.mockReturnValue(
createLocalGatewayConfigWithAuth(
createLocalGatewayPasswordRefAuth("MISSING_LOCAL_GATEWAY_PASSWORD"),
),
);
await runQr(["--setup-code-only"]);
@@ -239,22 +252,13 @@ describe("registerQrCli", () => {
});
it("does not resolve local password SecretRef when auth mode is token", async () => {
loadConfig.mockReturnValue({
secrets: {
providers: {
default: { source: "env" },
},
},
gateway: {
bind: "custom",
customBindHost: "gateway.local",
auth: {
mode: "token",
token: "token-123",
password: { source: "env", provider: "default", id: "MISSING_LOCAL_GATEWAY_PASSWORD" },
},
},
});
loadConfig.mockReturnValue(
createLocalGatewayConfigWithAuth({
mode: "token",
token: "token-123",
password: { source: "env", provider: "default", id: "MISSING_LOCAL_GATEWAY_PASSWORD" },
}),
);
await runQr(["--setup-code-only"]);
@@ -268,20 +272,11 @@ describe("registerQrCli", () => {
it("resolves local password SecretRef when auth mode is inferred", async () => {
vi.stubEnv("QR_INFERRED_GATEWAY_PASSWORD", "inferred-password");
loadConfig.mockReturnValue({
secrets: {
providers: {
default: { source: "env" },
},
},
gateway: {
bind: "custom",
customBindHost: "gateway.local",
auth: {
password: { source: "env", provider: "default", id: "QR_INFERRED_GATEWAY_PASSWORD" },
},
},
});
loadConfig.mockReturnValue(
createLocalGatewayConfigWithAuth({
password: { source: "env", provider: "default", id: "QR_INFERRED_GATEWAY_PASSWORD" },
}),
);
await runQr(["--setup-code-only"]);
@@ -390,20 +385,11 @@ describe("registerQrCli", () => {
{ name: "when tailscale is configured", withTailscale: true },
])("reports gateway.remote.url as source in --remote json output ($name)", async (testCase) => {
loadConfig.mockReturnValue(createRemoteQrConfig({ withTailscale: testCase.withTailscale }));
runCommandWithTimeout.mockResolvedValue({
code: 0,
stdout: '{"Self":{"DNSName":"ts-host.tailnet.ts.net."}}',
stderr: "",
});
mockTailscaleStatusLookup();
await runQr(["--json", "--remote"]);
const payload = JSON.parse(String(runtime.log.mock.calls.at(-1)?.[0] ?? "{}")) as {
setupCode?: string;
gatewayUrl?: string;
auth?: string;
urlSource?: string;
};
const payload = parseLastLoggedQrJson();
expect(payload.gatewayUrl).toBe("wss://remote.example.com:444");
expect(payload.auth).toBe("token");
expect(payload.urlSource).toBe("gateway.remote.url");
@@ -416,20 +402,11 @@ describe("registerQrCli", () => {
resolvedConfig: createRemoteQrConfig(),
diagnostics: ["gateway.remote.password inactive"] as string[],
});
runCommandWithTimeout.mockResolvedValue({
code: 0,
stdout: '{"Self":{"DNSName":"ts-host.tailnet.ts.net."}}',
stderr: "",
});
mockTailscaleStatusLookup();
await runQr(["--json", "--remote"]);
const payload = JSON.parse(String(runtime.log.mock.calls.at(-1)?.[0] ?? "{}")) as {
setupCode?: string;
gatewayUrl?: string;
auth?: string;
urlSource?: string;
};
const payload = parseLastLoggedQrJson();
expect(payload.gatewayUrl).toBe("wss://remote.example.com:444");
expect(
runtime.error.mock.calls.some((call) =>