Files
NODEDC_DEVICE_CORE/apps/device-manager/server/device-core-client.test.mjs
T

250 lines
9.4 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import {
createDeviceCoreClient,
createLocalPreviewDeviceCore,
} from "./device-core-client.mjs";
const token = "device-core-test-token-that-is-never-exposed";
const actor = Object.freeze({
userRef: "user:device-admin",
hubRole: "admin",
groupRefs: ["group:device-engineers"],
ownerScopes: [{ scopeKind: "personal", ownerRef: "user:device-admin" }],
});
const platformActor = Object.freeze({ ...actor, hubRole: "owner" });
test("Device Core client creates trusted actor headers and keeps its token server-side", async () => {
const calls = [];
const client = createDeviceCoreClient({
baseUrl: "http://device-control-core:3210",
token,
fetchImpl: async (url, init) => {
calls.push({ url: String(url), init });
return jsonResponse(200, { ok: true, projects: [] });
},
});
assert.deepEqual(await client.listProjects(actor), []);
assert.equal(calls.length, 1);
assert.equal(calls[0].init.headers.Authorization, `Bearer ${token}`);
assert.equal(calls[0].init.headers["X-NODEDC-User-Ref"], actor.userRef);
assert.equal(calls[0].init.headers["X-NODEDC-Hub-Role"], "admin");
assert.equal(calls[0].init.headers["X-NODEDC-Group-Refs"], "group:device-engineers");
assert.equal(
calls[0].init.headers["X-NODEDC-Owner-Scopes"],
"personal=user:device-admin",
);
assert.equal(JSON.stringify(await client.listProjects(actor)).includes(token), false);
});
test("Device Core client accepts only canonical commands and entity refs", async () => {
const client = createDeviceCoreClient({
baseUrl: "http://127.0.0.1:3210",
token,
fetchImpl: async () => jsonResponse(200, { ok: true, replayed: false, result: {} }),
});
await assert.rejects(
client.execute("raw:proxy", actor, {}, "device-manager-12345678"),
/device_manager_command_invalid/,
);
await assert.rejects(
client.getWorkspace(actor, "project:not-a-uuid"),
/device_project_ref_invalid/,
);
await assert.rejects(
client.execute("projects:ensure", actor, {}, "short"),
/device_idempotency_key_invalid/,
);
});
test("local preview is empty and creates resources only through canonical commands", async () => {
const client = createLocalPreviewDeviceCore();
assert.deepEqual(await client.listProjects(actor), []);
const owner = await client.execute("owner-scopes:ensure", actor, {
scopeKind: "personal",
ownerRef: actor.userRef,
displayName: "Device Admin",
});
assert.equal(owner.result.created, true);
const created = await client.execute("projects:ensure", actor, {
scopeKind: "personal",
ownerRef: actor.userRef,
projectKey: "sandbox",
name: "Device sandbox",
description: null,
});
assert.equal(created.result.created, true);
const projectRef = created.result.project.projectRef;
await client.execute("collections:ensure", actor, {
projectRef,
collectionKey: "field-devices",
name: "Field devices",
description: null,
});
const adapterPackage = await client.execute("adapter-packages:ensure", platformActor, {
packageKey: "generic-tracker",
displayName: "Generic tracker",
publisherRef: "publisher:nodedc",
lifecycleState: "active",
});
const adapterVersion = await client.execute("adapter-versions:register", platformActor, {
adapterPackageRef: adapterPackage.result.adapterPackage.adapterPackageRef,
version: "1.0.0",
runtimePackageRef: "artifact:generic-tracker:1.0.0",
contentDigest: `sha256:${"a".repeat(64)}`,
contractVersion: "device-adapter.v1",
capabilities: ["telemetry"],
lifecycleState: "draft",
});
const modelProfile = await client.execute("model-profiles:register", platformActor, {
adapterVersionRef: adapterVersion.result.adapterVersion.adapterVersionRef,
profileRef: "generic.tracker.v1",
schemaVersion: "1.0.0",
vendor: "Generic",
model: "Tracker",
deviceType: "tracker",
protocol: "INTERNAL",
schemaArtifactRef: "schema:generic.tracker.v1",
profileDigest: `sha256:${"b".repeat(64)}`,
capabilities: ["telemetry"],
lifecycleState: "draft",
});
const edge = await client.execute("edges:ensure", platformActor, {
edgeKey: "preview-edge",
displayName: "Preview Edge",
deploymentRef: "deployment:preview-edge",
lifecycleState: "provisioning",
});
const route = await client.execute("routes:ensure", actor, {
projectRef,
routeKey: "preview-route",
displayName: "Preview route",
edgeRef: edge.result.edge.edgeRef,
modelProfileRef: modelProfile.result.modelProfile.modelProfileRef,
listenerRef: "listener:preview",
protocol: "INTERNAL",
direction: "telemetry",
lifecycleState: "draft",
});
await client.execute("adapter-versions:register", platformActor, {
adapterPackageRef: adapterPackage.result.adapterPackage.adapterPackageRef,
version: "1.0.0",
runtimePackageRef: "artifact:generic-tracker:1.0.0",
contentDigest: `sha256:${"a".repeat(64)}`,
contractVersion: "device-adapter.v1",
capabilities: ["telemetry"],
lifecycleState: "active",
});
await client.execute("model-profiles:register", platformActor, {
adapterVersionRef: adapterVersion.result.adapterVersion.adapterVersionRef,
profileRef: "generic.tracker.v1",
schemaVersion: "1.0.0",
vendor: "Generic",
model: "Tracker",
deviceType: "tracker",
protocol: "INTERNAL",
schemaArtifactRef: "schema:generic.tracker.v1",
profileDigest: `sha256:${"b".repeat(64)}`,
capabilities: ["telemetry"],
lifecycleState: "active",
});
await client.execute("edges:ensure", platformActor, {
edgeKey: "preview-edge",
displayName: "Preview Edge",
deploymentRef: "deployment:preview-edge",
lifecycleState: "active",
});
await client.execute("routes:ensure", actor, {
projectRef,
routeKey: "preview-route",
displayName: "Preview route",
edgeRef: edge.result.edge.edgeRef,
modelProfileRef: modelProfile.result.modelProfile.modelProfileRef,
listenerRef: "listener:preview",
protocol: "INTERNAL",
direction: "telemetry",
lifecycleState: "active",
});
const enrollment = await client.execute("enrollment-intents:ensure", actor, {
projectRef,
enrollmentKey: "preview-device",
routeRef: route.result.route.routeRef,
modelProfileRef: modelProfile.result.modelProfile.modelProfileRef,
displayName: "Preview device",
identifier: { kind: "imei", value: "123456789012345" },
expiresAt: null,
});
assert.equal(enrollment.result.enrollmentIntent.identifier.masked, "***********2345");
assert.equal(JSON.stringify(enrollment).includes("123456789012345"), false);
const collectionRef = (await client.getWorkspace(actor, projectRef))
.collections[0].collectionRef;
await client.execute("device-bindings:ensure", actor, {
projectRef,
bindingKey: "preview-binding",
displayName: "Preview binding",
source: { kind: "collection", ref: collectionRef },
targetKind: "foundry.application",
targetRef: "application:preview-map",
capabilities: ["observe"],
});
await client.execute("project-grants:upsert", actor, {
projectRef,
principalKind: "group",
principalRef: "group:preview-viewers",
projectRole: "viewer",
capabilityAllow: [],
capabilityDeny: [],
lifecycleState: "active",
});
const projects = await client.listProjects(actor);
assert.equal(projects.length, 1);
assert.equal(projects[0].counts.collections, 1);
const workspace = await client.getWorkspace(actor, projectRef);
assert.equal(workspace.collections[0].collectionKey, "field-devices");
assert.equal(workspace.adapterPackages[0].packageKey, "generic-tracker");
assert.equal(workspace.routes[0].routeKey, "preview-route");
assert.equal(workspace.routes[0].lifecycleState, "active");
assert.equal(workspace.enrollments[0].expectedIdentifier.masked, "***********2345");
assert.equal(workspace.bindings[0].lifecycleState, "pending_external_approval");
assert.equal(workspace.grants.length, 2);
assert.ok(workspace.auditEvents.some((event) => event.eventType === "device_binding.created"));
assert.equal(workspace.policies.commandTransport, "disabled");
assert.deepEqual(workspace.devices, []);
});
test("explicit B2 preview fixture is isolated from the empty canonical preview", async () => {
const client = createLocalPreviewDeviceCore({ fixture: "arusnavi-b2" });
const projects = await client.listProjects(actor);
assert.equal(projects.length, 1);
assert.equal(projects[0].counts.devices, 1);
const workspace = await client.getWorkspace(actor, projects[0].projectRef);
assert.equal(workspace.devices[0].modelProfileRef, "arusnavi.b2.internal.v1");
assert.equal(workspace.devices[0].identifier.masked, "***********1088");
assert.equal(workspace.devices[0].identifier.value, "863151070211088");
assert.equal(workspace.devices[0].integrationDeviceId, "8028");
assert.equal(workspace.sessions[0].lifecycleState, "online");
assert.equal(workspace.policies.commandTransport, "typed-service-ping-v1");
assert.equal(workspace.policies.identifierProjection, "authorized-full");
assert.equal(JSON.stringify(workspace).includes("123456789012345"), false);
assert.throws(
() => createLocalPreviewDeviceCore({ fixture: "unknown" }),
/device_manager_preview_fixture_invalid/,
);
});
function jsonResponse(status, body) {
return new Response(JSON.stringify(body), {
status,
headers: { "content-type": "application/json" },
});
}