Files
openclaw/src/shared/device-bootstrap-profile.test.ts
Jesse Merhi 64318d7624 Rework Android gateway onboarding setup (#98752)
* feat(android): rework gateway onboarding setup

* fix(android): restore protocol mismatch onboarding guidance

* fix(android): sync onboarding native i18n

* fix(android): preserve LAN manual setup prefill

* fix(android): refine onboarding node approval step

* fix(android): polish onboarding recovery actions

* test(android): cover onboarding protocol mismatch copy

* fix(android): separate onboarding node approval

* fix(android): guard onboarding node approval transitions

* fix(android): keep onboarding approval states reachable

* fix(android): wait for node access before onboarding continue

* fix(android): refresh node approval after operator handoff

* fix(android): refresh onboarding approval states

* fix(android): require approval after onboarding permission changes

* fix(android): keep onboarding approval gates active

* fix(android): preserve permission reapproval state

* fix(android): skip node approval on legacy gateways

* fix(android): wait for node approval refresh

* fix(android): preserve camera setting on upgrade

* fix(android): avoid stuck approval check spinner

* fix(android): request talk secrets on operator connects

* fix(android): avoid missed node approval completion

* fix(android): keep nearby LAN setup local

* fix(android): complete onboarding after node approval

* fix(android): reconcile onboarding with gateway auth plans

* chore(android): refresh native i18n inventory after rebase

* Fix Android onboarding review edge cases

* Fix native i18n onboarding sentinels
2026-07-03 21:20:12 +10:00

110 lines
3.4 KiB
TypeScript

// Device bootstrap profile tests cover profile normalization for paired devices.
import { describe, expect, test } from "vitest";
import {
BOOTSTRAP_HANDOFF_OPERATOR_SCOPES,
PAIRING_SETUP_BOOTSTRAP_PROFILE,
isPairingSetupBootstrapProfile,
normalizeDeviceBootstrapHandoffProfile,
resolveBootstrapProfileScopesForRole,
resolveBootstrapProfileScopesForRoles,
} from "./device-bootstrap-profile.js";
describe("device bootstrap profile", () => {
test("bounds bootstrap handoff scopes by role", () => {
expect(
resolveBootstrapProfileScopesForRole("operator", [
"node.exec",
"operator.admin",
"operator.approvals",
"operator.pairing",
"operator.read",
"operator.talk.secrets",
"operator.write",
]),
).toEqual(["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"]);
expect(
resolveBootstrapProfileScopesForRole("node", ["node.exec", "operator.approvals"]),
).toStrictEqual([]);
});
test("bounds bootstrap handoff scopes across profile roles", () => {
expect(
resolveBootstrapProfileScopesForRoles(
["node", "operator"],
[
"node.exec",
"operator.admin",
"operator.approvals",
"operator.pairing",
"operator.read",
"operator.talk.secrets",
"operator.write",
],
),
).toEqual(["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"]);
expect(
resolveBootstrapProfileScopesForRoles(["node"], ["node.exec", "operator.admin"]),
).toStrictEqual([]);
});
test("normalizes issued handoff profiles to the bootstrap allowlist", () => {
expect(
normalizeDeviceBootstrapHandoffProfile({
roles: ["node", "operator"],
scopes: [
"node.exec",
"operator.admin",
"operator.approvals",
"operator.pairing",
"operator.read",
"operator.talk.secrets",
"operator.write",
],
}),
).toEqual({
roles: ["node", "operator"],
scopes: ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"],
});
});
test("default setup profile carries node plus bounded operator handoff", () => {
expect(PAIRING_SETUP_BOOTSTRAP_PROFILE).toEqual({
roles: ["node", "operator"],
scopes: ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"],
});
});
test("recognizes only the current setup profile", () => {
expect(isPairingSetupBootstrapProfile(PAIRING_SETUP_BOOTSTRAP_PROFILE)).toBe(true);
expect(
isPairingSetupBootstrapProfile({
roles: ["node", "operator"],
scopes: ["operator.approvals", "operator.read", "operator.write"],
}),
).toBe(false);
expect(
isPairingSetupBootstrapProfile({
roles: ["node", "operator"],
scopes: ["operator.approvals", "operator.pairing", "operator.read", "operator.write"],
}),
).toBe(false);
expect(
isPairingSetupBootstrapProfile({
roles: ["node", "operator"],
scopes: ["operator.admin", "operator.approvals", "operator.read", "operator.write"],
}),
).toBe(false);
});
test("bootstrap handoff operator allowlist stays bounded", () => {
expect([...BOOTSTRAP_HANDOFF_OPERATOR_SCOPES]).toEqual([
"operator.approvals",
"operator.read",
"operator.talk.secrets",
"operator.write",
]);
});
});