mirror of https://github.com/openclaw/openclaw.git
test: refine gateway auth helper coverage
This commit is contained in:
parent
91f1894372
commit
e25fa446e8
|
|
@ -1,29 +1,69 @@
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import { buildDeviceAuthPayloadV3, normalizeDeviceMetadataForAuth } from "./device-auth.js";
|
import {
|
||||||
|
buildDeviceAuthPayload,
|
||||||
|
buildDeviceAuthPayloadV3,
|
||||||
|
normalizeDeviceMetadataForAuth,
|
||||||
|
} from "./device-auth.js";
|
||||||
|
|
||||||
describe("device-auth payload vectors", () => {
|
describe("device-auth payload vectors", () => {
|
||||||
it("builds canonical v3 payload", () => {
|
it.each([
|
||||||
const payload = buildDeviceAuthPayloadV3({
|
{
|
||||||
deviceId: "dev-1",
|
name: "builds canonical v2 payloads",
|
||||||
clientId: "openclaw-macos",
|
build: () =>
|
||||||
clientMode: "ui",
|
buildDeviceAuthPayload({
|
||||||
role: "operator",
|
deviceId: "dev-1",
|
||||||
scopes: ["operator.admin", "operator.read"],
|
clientId: "openclaw-macos",
|
||||||
signedAtMs: 1_700_000_000_000,
|
clientMode: "ui",
|
||||||
token: "tok-123",
|
role: "operator",
|
||||||
nonce: "nonce-abc",
|
scopes: ["operator.admin", "operator.read"],
|
||||||
platform: " IOS ",
|
signedAtMs: 1_700_000_000_000,
|
||||||
deviceFamily: " iPhone ",
|
token: null,
|
||||||
});
|
nonce: "nonce-abc",
|
||||||
|
}),
|
||||||
expect(payload).toBe(
|
expected:
|
||||||
"v3|dev-1|openclaw-macos|ui|operator|operator.admin,operator.read|1700000000000|tok-123|nonce-abc|ios|iphone",
|
"v2|dev-1|openclaw-macos|ui|operator|operator.admin,operator.read|1700000000000||nonce-abc",
|
||||||
);
|
},
|
||||||
|
{
|
||||||
|
name: "builds canonical v3 payloads",
|
||||||
|
build: () =>
|
||||||
|
buildDeviceAuthPayloadV3({
|
||||||
|
deviceId: "dev-1",
|
||||||
|
clientId: "openclaw-macos",
|
||||||
|
clientMode: "ui",
|
||||||
|
role: "operator",
|
||||||
|
scopes: ["operator.admin", "operator.read"],
|
||||||
|
signedAtMs: 1_700_000_000_000,
|
||||||
|
token: "tok-123",
|
||||||
|
nonce: "nonce-abc",
|
||||||
|
platform: " IOS ",
|
||||||
|
deviceFamily: " iPhone ",
|
||||||
|
}),
|
||||||
|
expected:
|
||||||
|
"v3|dev-1|openclaw-macos|ui|operator|operator.admin,operator.read|1700000000000|tok-123|nonce-abc|ios|iphone",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "keeps empty metadata slots in v3 payloads",
|
||||||
|
build: () =>
|
||||||
|
buildDeviceAuthPayloadV3({
|
||||||
|
deviceId: "dev-2",
|
||||||
|
clientId: "openclaw-ios",
|
||||||
|
clientMode: "ui",
|
||||||
|
role: "operator",
|
||||||
|
scopes: ["operator.read"],
|
||||||
|
signedAtMs: 1_700_000_000_001,
|
||||||
|
nonce: "nonce-def",
|
||||||
|
}),
|
||||||
|
expected: "v3|dev-2|openclaw-ios|ui|operator|operator.read|1700000000001||nonce-def||",
|
||||||
|
},
|
||||||
|
])("$name", ({ build, expected }) => {
|
||||||
|
expect(build()).toBe(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("normalizes metadata with ASCII-only lowercase", () => {
|
it.each([
|
||||||
expect(normalizeDeviceMetadataForAuth(" İOS ")).toBe("İos");
|
{ input: " İOS ", expected: "İos" },
|
||||||
expect(normalizeDeviceMetadataForAuth(" MAC ")).toBe("mac");
|
{ input: " MAC ", expected: "mac" },
|
||||||
expect(normalizeDeviceMetadataForAuth(undefined)).toBe("");
|
{ input: undefined, expected: "" },
|
||||||
|
])("normalizes metadata %j", ({ input, expected }) => {
|
||||||
|
expect(normalizeDeviceMetadataForAuth(input)).toBe(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,9 @@ import {
|
||||||
} from "./probe-auth.js";
|
} from "./probe-auth.js";
|
||||||
|
|
||||||
describe("resolveGatewayProbeAuthSafe", () => {
|
describe("resolveGatewayProbeAuthSafe", () => {
|
||||||
it("returns probe auth credentials when available", () => {
|
it.each([
|
||||||
const result = resolveGatewayProbeAuthSafe({
|
{
|
||||||
|
name: "returns probe auth credentials when available",
|
||||||
cfg: {
|
cfg: {
|
||||||
gateway: {
|
gateway: {
|
||||||
auth: {
|
auth: {
|
||||||
|
|
@ -15,20 +16,17 @@ describe("resolveGatewayProbeAuthSafe", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as OpenClawConfig,
|
} as OpenClawConfig,
|
||||||
mode: "local",
|
mode: "local" as const,
|
||||||
env: {} as NodeJS.ProcessEnv,
|
env: {} as NodeJS.ProcessEnv,
|
||||||
});
|
expected: {
|
||||||
|
auth: {
|
||||||
expect(result).toEqual({
|
token: "token-value",
|
||||||
auth: {
|
password: undefined,
|
||||||
token: "token-value",
|
},
|
||||||
password: undefined,
|
|
||||||
},
|
},
|
||||||
});
|
},
|
||||||
});
|
{
|
||||||
|
name: "returns warning and empty auth when a local token SecretRef is unresolved",
|
||||||
it("returns warning and empty auth when token SecretRef is unresolved", () => {
|
|
||||||
const result = resolveGatewayProbeAuthSafe({
|
|
||||||
cfg: {
|
cfg: {
|
||||||
gateway: {
|
gateway: {
|
||||||
auth: {
|
auth: {
|
||||||
|
|
@ -42,17 +40,15 @@ describe("resolveGatewayProbeAuthSafe", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as OpenClawConfig,
|
} as OpenClawConfig,
|
||||||
mode: "local",
|
mode: "local" as const,
|
||||||
env: {} as NodeJS.ProcessEnv,
|
env: {} as NodeJS.ProcessEnv,
|
||||||
});
|
expected: {
|
||||||
|
auth: {},
|
||||||
expect(result.auth).toEqual({});
|
warningIncludes: ["gateway.auth.token", "unresolved"],
|
||||||
expect(result.warning).toContain("gateway.auth.token");
|
},
|
||||||
expect(result.warning).toContain("unresolved");
|
},
|
||||||
});
|
{
|
||||||
|
name: "does not fall through to remote token when the local SecretRef is unresolved",
|
||||||
it("does not fall through to remote token when local token SecretRef is unresolved", () => {
|
|
||||||
const result = resolveGatewayProbeAuthSafe({
|
|
||||||
cfg: {
|
cfg: {
|
||||||
gateway: {
|
gateway: {
|
||||||
mode: "local",
|
mode: "local",
|
||||||
|
|
@ -70,17 +66,15 @@ describe("resolveGatewayProbeAuthSafe", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as OpenClawConfig,
|
} as OpenClawConfig,
|
||||||
mode: "local",
|
mode: "local" as const,
|
||||||
env: {} as NodeJS.ProcessEnv,
|
env: {} as NodeJS.ProcessEnv,
|
||||||
});
|
expected: {
|
||||||
|
auth: {},
|
||||||
expect(result.auth).toEqual({});
|
warningIncludes: ["gateway.auth.token", "unresolved"],
|
||||||
expect(result.warning).toContain("gateway.auth.token");
|
},
|
||||||
expect(result.warning).toContain("unresolved");
|
},
|
||||||
});
|
{
|
||||||
|
name: "ignores unresolved local token SecretRefs in remote mode",
|
||||||
it("ignores unresolved local token SecretRef in remote mode when remote-only auth is requested", () => {
|
|
||||||
const result = resolveGatewayProbeAuthSafe({
|
|
||||||
cfg: {
|
cfg: {
|
||||||
gateway: {
|
gateway: {
|
||||||
mode: "remote",
|
mode: "remote",
|
||||||
|
|
@ -98,16 +92,22 @@ describe("resolveGatewayProbeAuthSafe", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as OpenClawConfig,
|
} as OpenClawConfig,
|
||||||
mode: "remote",
|
mode: "remote" as const,
|
||||||
env: {} as NodeJS.ProcessEnv,
|
env: {} as NodeJS.ProcessEnv,
|
||||||
});
|
expected: {
|
||||||
|
auth: {
|
||||||
expect(result).toEqual({
|
token: undefined,
|
||||||
auth: {
|
password: undefined,
|
||||||
token: undefined,
|
},
|
||||||
password: undefined,
|
|
||||||
},
|
},
|
||||||
});
|
},
|
||||||
|
])("$name", ({ cfg, mode, env, expected }) => {
|
||||||
|
const result = resolveGatewayProbeAuthSafe({ cfg, mode, env });
|
||||||
|
|
||||||
|
expect(result.auth).toEqual(expected.auth);
|
||||||
|
for (const fragment of expected.warningIncludes ?? []) {
|
||||||
|
expect(result.warning).toContain(fragment);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue