95 lines
3.6 KiB
JavaScript
95 lines
3.6 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import { createLocalPreviewDeviceCore } from "./device-core-client.mjs";
|
|
import { createDeviceManagerAuth } from "./device-manager-auth.mjs";
|
|
import { createDeviceManagerServer } from "./device-manager-server.mjs";
|
|
|
|
test("Device Manager BFF exposes an empty, mutation-driven project workspace", async (t) => {
|
|
const auth = createDeviceManagerAuth({
|
|
env: { NODEDC_DEVICE_MANAGER_AUTH_REQUIRED: "false" },
|
|
});
|
|
const coreClient = createLocalPreviewDeviceCore();
|
|
const server = createDeviceManagerServer({ auth, coreClient });
|
|
await new Promise((resolve, reject) => {
|
|
server.once("error", reject);
|
|
server.listen(0, "127.0.0.1", resolve);
|
|
});
|
|
t.after(() => new Promise((resolve) => server.close(resolve)));
|
|
const address = server.address();
|
|
const baseUrl = `http://127.0.0.1:${address.port}`;
|
|
|
|
const session = await getJson(`${baseUrl}/api/device-manager/session`);
|
|
assert.equal(session.session.actor.hubRole, "owner");
|
|
assert.equal(session.session.actor.userRef, "user:local-device-admin");
|
|
assert.deepEqual((await getJson(`${baseUrl}/api/device-manager/projects`)).projects, []);
|
|
|
|
await postJson(`${baseUrl}/api/device-manager/owner-scopes:ensure`, {
|
|
scopeKind: "personal",
|
|
ownerRef: "user:local-device-admin",
|
|
displayName: "Local Device Admin",
|
|
}, {
|
|
"X-NODEDC-Hub-Role": "viewer",
|
|
"X-NODEDC-User-Ref": "user:spoofed-browser",
|
|
});
|
|
const created = await postJson(`${baseUrl}/api/device-manager/projects:ensure`, {
|
|
scopeKind: "personal",
|
|
ownerRef: "user:local-device-admin",
|
|
projectKey: "device-sandbox",
|
|
name: "Device sandbox",
|
|
description: "Created only through the canonical command path",
|
|
});
|
|
const projectRef = created.result.project.projectRef;
|
|
|
|
const projects = (await getJson(`${baseUrl}/api/device-manager/projects`)).projects;
|
|
assert.equal(projects.length, 1);
|
|
assert.equal(projects[0].projectKey, "device-sandbox");
|
|
assert.equal(projects[0].ownerScope.ownerRef, "user:local-device-admin");
|
|
|
|
await postJson(`${baseUrl}/api/device-manager/collections:ensure`, {
|
|
projectRef,
|
|
collectionKey: "pilot-devices",
|
|
name: "Pilot devices",
|
|
description: null,
|
|
});
|
|
const workspace = await getJson(
|
|
`${baseUrl}/api/device-manager/projects/${encodeURIComponent(projectRef)}/workspace`,
|
|
);
|
|
assert.equal(workspace.workspace.project.projectRef, projectRef);
|
|
assert.equal(workspace.workspace.collections[0].collectionKey, "pilot-devices");
|
|
assert.deepEqual(workspace.workspace.devices, []);
|
|
|
|
const missingKey = await fetch(`${baseUrl}/api/device-manager/projects:ensure`, {
|
|
method: "POST",
|
|
headers: { "content-type": "application/json" },
|
|
body: JSON.stringify({}),
|
|
});
|
|
assert.equal(missingKey.status, 400);
|
|
assert.equal((await missingKey.json()).error, "device_idempotency_key_invalid");
|
|
});
|
|
|
|
async function getJson(url) {
|
|
const response = await fetch(url, { headers: { accept: "application/json" } });
|
|
const body = await response.json();
|
|
assert.equal(response.status, 200, JSON.stringify(body));
|
|
assert.equal(body.ok, true);
|
|
return body;
|
|
}
|
|
|
|
async function postJson(url, body, headers = {}) {
|
|
const response = await fetch(url, {
|
|
method: "POST",
|
|
headers: {
|
|
accept: "application/json",
|
|
"content-type": "application/json",
|
|
"idempotency-key": `device-manager-test-${crypto.randomUUID()}`,
|
|
...headers,
|
|
},
|
|
body: JSON.stringify(body),
|
|
});
|
|
const payload = await response.json();
|
|
assert.equal(response.status, 200, JSON.stringify(payload));
|
|
assert.equal(payload.ok, true);
|
|
return payload;
|
|
}
|