test: share pairing setup resolution assertions

This commit is contained in:
Peter Steinberger 2026-03-13 23:02:30 +00:00
parent a56e620777
commit 0da9a25818
1 changed files with 70 additions and 91 deletions

View File

@ -10,6 +10,25 @@ vi.mock("../infra/device-bootstrap.js", () => ({
})); }));
describe("pairing setup code", () => { describe("pairing setup code", () => {
type ResolvedSetup = Awaited<ReturnType<typeof resolvePairingSetupFromConfig>>;
const defaultEnvSecretProviderConfig = {
secrets: {
providers: {
default: { source: "env" },
},
},
} as const;
const gatewayPasswordSecretRef: SecretInput = {
source: "env",
provider: "default",
id: "GW_PASSWORD",
};
const missingGatewayTokenSecretRef: SecretInput = {
source: "env",
provider: "default",
id: "MISSING_GW_TOKEN",
};
function createTailnetDnsRunner() { function createTailnetDnsRunner() {
return vi.fn(async () => ({ return vi.fn(async () => ({
code: 0, code: 0,
@ -18,6 +37,36 @@ describe("pairing setup code", () => {
})); }));
} }
function expectResolvedSetupOk(
resolved: ResolvedSetup,
params: {
authLabel: string;
url?: string;
urlSource?: string;
},
) {
expect(resolved.ok).toBe(true);
if (!resolved.ok) {
throw new Error("expected setup resolution to succeed");
}
expect(resolved.authLabel).toBe(params.authLabel);
expect(resolved.payload.bootstrapToken).toBe("bootstrap-123");
if (params.url) {
expect(resolved.payload.url).toBe(params.url);
}
if (params.urlSource) {
expect(resolved.urlSource).toBe(params.urlSource);
}
}
function expectResolvedSetupError(resolved: ResolvedSetup, snippet: string) {
expect(resolved.ok).toBe(false);
if (resolved.ok) {
throw new Error("expected setup resolution to fail");
}
expect(resolved.error).toContain(snippet);
}
beforeEach(() => { beforeEach(() => {
vi.stubEnv("OPENCLAW_GATEWAY_TOKEN", ""); vi.stubEnv("OPENCLAW_GATEWAY_TOKEN", "");
vi.stubEnv("CLAWDBOT_GATEWAY_TOKEN", ""); vi.stubEnv("CLAWDBOT_GATEWAY_TOKEN", "");
@ -69,14 +118,10 @@ describe("pairing setup code", () => {
customBindHost: "gateway.local", customBindHost: "gateway.local",
auth: { auth: {
mode: "password", mode: "password",
password: { source: "env", provider: "default", id: "GW_PASSWORD" }, password: gatewayPasswordSecretRef,
},
},
secrets: {
providers: {
default: { source: "env" },
}, },
}, },
...defaultEnvSecretProviderConfig,
}, },
{ {
env: { env: {
@ -85,12 +130,7 @@ describe("pairing setup code", () => {
}, },
); );
expect(resolved.ok).toBe(true); expectResolvedSetupOk(resolved, { authLabel: "password" });
if (!resolved.ok) {
throw new Error("expected setup resolution to succeed");
}
expect(resolved.payload.bootstrapToken).toBe("bootstrap-123");
expect(resolved.authLabel).toBe("password");
}); });
it("uses OPENCLAW_GATEWAY_PASSWORD without resolving configured password SecretRef", async () => { it("uses OPENCLAW_GATEWAY_PASSWORD without resolving configured password SecretRef", async () => {
@ -104,11 +144,7 @@ describe("pairing setup code", () => {
password: { source: "env", provider: "default", id: "MISSING_GW_PASSWORD" }, password: { source: "env", provider: "default", id: "MISSING_GW_PASSWORD" },
}, },
}, },
secrets: { ...defaultEnvSecretProviderConfig,
providers: {
default: { source: "env" },
},
},
}, },
{ {
env: { env: {
@ -117,12 +153,7 @@ describe("pairing setup code", () => {
}, },
); );
expect(resolved.ok).toBe(true); expectResolvedSetupOk(resolved, { authLabel: "password" });
if (!resolved.ok) {
throw new Error("expected setup resolution to succeed");
}
expect(resolved.payload.bootstrapToken).toBe("bootstrap-123");
expect(resolved.authLabel).toBe("password");
}); });
it("does not resolve gateway.auth.password SecretRef in token mode", async () => { it("does not resolve gateway.auth.password SecretRef in token mode", async () => {
@ -137,23 +168,14 @@ describe("pairing setup code", () => {
password: { source: "env", provider: "missing", id: "GW_PASSWORD" }, password: { source: "env", provider: "missing", id: "GW_PASSWORD" },
}, },
}, },
secrets: { ...defaultEnvSecretProviderConfig,
providers: {
default: { source: "env" },
},
},
}, },
{ {
env: {}, env: {},
}, },
); );
expect(resolved.ok).toBe(true); expectResolvedSetupOk(resolved, { authLabel: "token" });
if (!resolved.ok) {
throw new Error("expected setup resolution to succeed");
}
expect(resolved.authLabel).toBe("token");
expect(resolved.payload.bootstrapToken).toBe("bootstrap-123");
}); });
it("resolves gateway.auth.token SecretRef for pairing payload", async () => { it("resolves gateway.auth.token SecretRef for pairing payload", async () => {
@ -167,11 +189,7 @@ describe("pairing setup code", () => {
token: { source: "env", provider: "default", id: "GW_TOKEN" }, token: { source: "env", provider: "default", id: "GW_TOKEN" },
}, },
}, },
secrets: { ...defaultEnvSecretProviderConfig,
providers: {
default: { source: "env" },
},
},
}, },
{ {
env: { env: {
@ -180,12 +198,7 @@ describe("pairing setup code", () => {
}, },
); );
expect(resolved.ok).toBe(true); expectResolvedSetupOk(resolved, { authLabel: "token" });
if (!resolved.ok) {
throw new Error("expected setup resolution to succeed");
}
expect(resolved.authLabel).toBe("token");
expect(resolved.payload.bootstrapToken).toBe("bootstrap-123");
}); });
it("errors when gateway.auth.token SecretRef is unresolved in token mode", async () => { it("errors when gateway.auth.token SecretRef is unresolved in token mode", async () => {
@ -197,14 +210,10 @@ describe("pairing setup code", () => {
customBindHost: "gateway.local", customBindHost: "gateway.local",
auth: { auth: {
mode: "token", mode: "token",
token: { source: "env", provider: "default", id: "MISSING_GW_TOKEN" }, token: missingGatewayTokenSecretRef,
},
},
secrets: {
providers: {
default: { source: "env" },
}, },
}, },
...defaultEnvSecretProviderConfig,
}, },
{ {
env: {}, env: {},
@ -221,11 +230,7 @@ describe("pairing setup code", () => {
customBindHost: "gateway.local", customBindHost: "gateway.local",
auth: { token }, auth: { token },
}, },
secrets: { ...defaultEnvSecretProviderConfig,
providers: {
default: { source: "env" },
},
},
}, },
{ {
env: { env: {
@ -242,23 +247,13 @@ describe("pairing setup code", () => {
id: "MISSING_GW_TOKEN", id: "MISSING_GW_TOKEN",
}); });
expect(resolved.ok).toBe(true); expectResolvedSetupOk(resolved, { authLabel: "password" });
if (!resolved.ok) {
throw new Error("expected setup resolution to succeed");
}
expect(resolved.authLabel).toBe("password");
expect(resolved.payload.bootstrapToken).toBe("bootstrap-123");
}); });
it("does not treat env-template token as plaintext in inferred mode", async () => { it("does not treat env-template token as plaintext in inferred mode", async () => {
const resolved = await resolveInferredModeWithPasswordEnv("${MISSING_GW_TOKEN}"); const resolved = await resolveInferredModeWithPasswordEnv("${MISSING_GW_TOKEN}");
expect(resolved.ok).toBe(true); expectResolvedSetupOk(resolved, { authLabel: "password" });
if (!resolved.ok) {
throw new Error("expected setup resolution to succeed");
}
expect(resolved.authLabel).toBe("password");
expect(resolved.payload.bootstrapToken).toBe("bootstrap-123");
}); });
it("requires explicit auth mode when token and password are both configured", async () => { it("requires explicit auth mode when token and password are both configured", async () => {
@ -270,14 +265,10 @@ describe("pairing setup code", () => {
customBindHost: "gateway.local", customBindHost: "gateway.local",
auth: { auth: {
token: { source: "env", provider: "default", id: "GW_TOKEN" }, token: { source: "env", provider: "default", id: "GW_TOKEN" },
password: { source: "env", provider: "default", id: "GW_PASSWORD" }, password: gatewayPasswordSecretRef,
},
},
secrets: {
providers: {
default: { source: "env" },
}, },
}, },
...defaultEnvSecretProviderConfig,
}, },
{ {
env: { env: {
@ -297,15 +288,11 @@ describe("pairing setup code", () => {
bind: "custom", bind: "custom",
customBindHost: "gateway.local", customBindHost: "gateway.local",
auth: { auth: {
token: { source: "env", provider: "default", id: "MISSING_GW_TOKEN" }, token: missingGatewayTokenSecretRef,
password: { source: "env", provider: "default", id: "GW_PASSWORD" }, password: gatewayPasswordSecretRef,
},
},
secrets: {
providers: {
default: { source: "env" },
}, },
}, },
...defaultEnvSecretProviderConfig,
}, },
{ {
env: { env: {
@ -332,11 +319,7 @@ describe("pairing setup code", () => {
}, },
); );
expect(resolved.ok).toBe(true); expectResolvedSetupOk(resolved, { authLabel: "token" });
if (!resolved.ok) {
throw new Error("expected setup resolution to succeed");
}
expect(resolved.payload.bootstrapToken).toBe("bootstrap-123");
}); });
it("errors when gateway is loopback only", async () => { it("errors when gateway is loopback only", async () => {
@ -347,11 +330,7 @@ describe("pairing setup code", () => {
}, },
}); });
expect(resolved.ok).toBe(false); expectResolvedSetupError(resolved, "only bound to loopback");
if (resolved.ok) {
throw new Error("expected setup resolution to fail");
}
expect(resolved.error).toContain("only bound to loopback");
}); });
it("uses tailscale serve DNS when available", async () => { it("uses tailscale serve DNS when available", async () => {