feat(device-core): add project ownership schema
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import test from "node:test";
|
||||
|
||||
const migrationUrl = new URL(
|
||||
"../migrations/002_device_project_access.sql",
|
||||
import.meta.url,
|
||||
);
|
||||
const repositoryUrl = new URL("../src/postgres-repository.mjs", import.meta.url);
|
||||
|
||||
test("project access migration defines owner, project, collection and grant boundaries", async () => {
|
||||
const sql = await readFile(migrationUrl, "utf8");
|
||||
|
||||
for (const table of [
|
||||
"device_owner_scopes",
|
||||
"device_projects",
|
||||
"device_collections",
|
||||
"device_collection_members",
|
||||
"device_project_grants",
|
||||
]) {
|
||||
assert.match(sql, new RegExp(`create table if not exists ${table}`));
|
||||
}
|
||||
|
||||
assert.match(sql, /scope_kind in \('company', 'personal'\)/);
|
||||
assert.match(sql, /principal_kind in \('user', 'group'\)/);
|
||||
assert.match(
|
||||
sql,
|
||||
/project_role in \('viewer', 'operator', 'engineer', 'admin', 'owner'\)/,
|
||||
);
|
||||
assert.match(sql, /unique \(scope_kind, owner_ref\)/);
|
||||
assert.match(sql, /unique \(owner_scope_id, project_key\)/);
|
||||
assert.match(sql, /unique \(project_id, principal_kind, principal_ref\)/);
|
||||
assert.match(sql, /not \(capability_allow && capability_deny\)/);
|
||||
assert.match(
|
||||
sql,
|
||||
/foreign key \(collection_id, project_id\)\s+references device_collections\(id, project_id\)/,
|
||||
);
|
||||
assert.match(
|
||||
sql,
|
||||
/foreign key \(device_id, project_id\)\s+references device_instances\(id, project_id\)/,
|
||||
);
|
||||
});
|
||||
|
||||
test("project access migration contains no tenant, device or credential seed", async () => {
|
||||
const sql = await readFile(migrationUrl, "utf8");
|
||||
|
||||
assert.doesNotMatch(sql, /insert\s+into/i);
|
||||
assert.doesNotMatch(sql, /dcctouch|arusnavi|b2|imei/i);
|
||||
assert.doesNotMatch(sql, /password|secret|token|credential_ref/i);
|
||||
});
|
||||
|
||||
test("repository applies project access migration after the foundation", async () => {
|
||||
const source = await readFile(repositoryUrl, "utf8");
|
||||
const foundationIndex = source.indexOf("001_device_plane_foundation.sql");
|
||||
const projectAccessIndex = source.indexOf("002_device_project_access.sql");
|
||||
|
||||
assert.notEqual(foundationIndex, -1);
|
||||
assert.notEqual(projectAccessIndex, -1);
|
||||
assert.ok(foundationIndex < projectAccessIndex);
|
||||
});
|
||||
Reference in New Issue
Block a user