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("Device Core client merges workspace and ontology projections", async () => { const calls = []; const client = createDeviceCoreClient({ baseUrl: "http://127.0.0.1:3210", token, fetchImpl: async (url) => { calls.push(String(url)); if (String(url).endsWith("/ontology")) { return jsonResponse(200, { ok: true, projection: { ontology: { catalogHash: "229c61c02a790906", packages: [] }, assets: [], assetBindings: [], hosts: [], endpoints: [], deployments: [], serviceInstances: [], policies: {}, }, }); } return jsonResponse(200, { ok: true, workspace: { project: { projectRef: "project:test" } } }); }, }); const workspace = await client.getWorkspace( actor, "project:11111111-1111-4111-8111-111111111111", ); assert.equal(workspace.ontology.ontology.catalogHash, "229c61c02a790906"); assert.equal(calls.length, 2); assert.ok(calls.some((value) => value.endsWith("/workspace"))); assert.ok(calls.some((value) => value.endsWith("/ontology"))); }); 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; const host = await client.execute("infrastructure-hosts:ensure", actor, { projectRef, hostKey: "preview-vps", displayName: "Preview VPS", providerRef: "provider:preview", externalRef: "provider-resource:preview-vps", managementCredentialRef: "secret-ref:device-core/preview-vps", lifecycleState: "active", }); const deployment = await client.execute("infrastructure-deployments:ensure", actor, { projectRef, hostRef: host.result.host.hostRef, deploymentKey: "preview-edge", displayName: "Preview Edge deployment", artifactRef: "artifact:device-edge/1.0.0", artifactDigest: `sha256:${"c".repeat(64)}`, lifecycleState: "active", }); await client.execute("infrastructure-service-instances:ensure", actor, { projectRef, hostRef: host.result.host.hostRef, deploymentRef: deployment.result.deployment.deploymentRef, edgeRef: null, serviceKey: "device-edge", displayName: "Device Edge", serviceRole: "device.edge", lifecycleState: "active", }); await client.execute("health-observations:record", actor, { projectRef, subjectKind: "host", subjectRef: host.result.host.hostRef, observedState: "reachable", evidenceClass: "manual", sourceRef: "test:preview", schemaRef: "nodedc.health.test.v1", evidence: {}, observedAt: new Date().toISOString(), expiresAt: new Date(Date.now() + 60_000).toISOString(), }); 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.equal(workspace.ontology.hosts[0].health.state, "reachable"); assert.equal(workspace.ontology.serviceInstances[0].serviceRole, "device.edge"); assert.equal(workspace.ontology.hosts[0].managementCredentialConfigured, true); assert.equal(JSON.stringify(workspace).includes("secret-ref:device-core/preview-vps"), false); 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" }, }); }