Track HiveGrid Cloud planning reference
This commit is contained in:
1 parent
b3d5ea6764
commit
e341c5938a
5784 files changed
+1104929
-3
No files matched your search
@@ -0,0 +1,134 @@
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import assert from "node:assert/strict";
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { afterEach, describe, it } from "vitest";
|
||||
|
||||
import { buildInventory, hasInventoryIntegrityFailure, renderText } from "./verify-api-auth-surface.mjs";
|
||||
|
||||
const fixtures = [];
|
||||
|
||||
function writeFile(rootDir, relativePath, content) {
|
||||
const absolutePath = path.join(rootDir, relativePath);
|
||||
fs.mkdirSync(path.dirname(absolutePath), { recursive: true });
|
||||
fs.writeFileSync(absolutePath, content);
|
||||
}
|
||||
|
||||
function createFixture() {
|
||||
const rootDir = fs.mkdtempSync(path.join(os.tmpdir(), "api-auth-surface-"));
|
||||
fixtures.push(rootDir);
|
||||
return rootDir;
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
while (fixtures.length > 0) {
|
||||
fs.rmSync(fixtures.pop(), { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
describe("verify-api-auth-surface", () => {
|
||||
it("builds stable JSON inventory for apiService imports and callsites", async () => {
|
||||
const rootDir = createFixture();
|
||||
writeFile(
|
||||
rootDir,
|
||||
"apps/api/src/entity-route.ts",
|
||||
`import { validateApiKey } from "~/utils/services/apiService";
|
||||
export async function loader({ request, params }) {
|
||||
return validateApiKey(request, params);
|
||||
}
|
||||
`,
|
||||
);
|
||||
writeFile(
|
||||
rootDir,
|
||||
"apps/api/src/usage-route.ts",
|
||||
`import { validateTenantApiKey, getEntityApiKeyFromRequest } from "~/utils/services/apiService";
|
||||
export async function loader({ request, params }) {
|
||||
await validateTenantApiKey(request, params);
|
||||
return getEntityApiKeyFromRequest(request, params);
|
||||
}
|
||||
`,
|
||||
);
|
||||
writeFile(
|
||||
rootDir,
|
||||
"apps/api/src/relationships-route.ts",
|
||||
`import { getRelationshipApiKeyFromRequest } from "~/utils/services/apiService";
|
||||
export async function action({ request, params }) {
|
||||
return getRelationshipApiKeyFromRequest(request, params);
|
||||
}
|
||||
`,
|
||||
);
|
||||
writeFile(
|
||||
rootDir,
|
||||
"apps/api/src/workflows-route.ts",
|
||||
`import { getWorkflowApiKeyFromRequest } from "~/utils/services/apiService";
|
||||
export async function action({ request, params }) {
|
||||
return getWorkflowApiKeyFromRequest(request, params);
|
||||
}
|
||||
`,
|
||||
);
|
||||
|
||||
const inventory = await buildInventory(rootDir);
|
||||
|
||||
assert.deepEqual(inventory.scannedFiles, [
|
||||
"apps/api/src/entity-route.ts",
|
||||
"apps/api/src/relationships-route.ts",
|
||||
"apps/api/src/usage-route.ts",
|
||||
"apps/api/src/workflows-route.ts",
|
||||
]);
|
||||
assert.deepEqual(inventory.scannedRoots, ["apps/api/src"]);
|
||||
assert.deepEqual(inventory.missingRoots, ["apps/web/app/routes/internal/api"]);
|
||||
assert.deepEqual(inventory.requiredMissingRoots, []);
|
||||
assert.equal(hasInventoryIntegrityFailure(inventory), false);
|
||||
assert.deepEqual(
|
||||
inventory.directValidateApiKeyCallsites.map((entry) => `${entry.file}:${entry.line}:${entry.symbol}`),
|
||||
["apps/api/src/entity-route.ts:3:validateApiKey"],
|
||||
);
|
||||
assert.deepEqual(
|
||||
inventory.tenantValidateCallsites.map((entry) => `${entry.file}:${entry.line}:${entry.symbol}`),
|
||||
["apps/api/src/usage-route.ts:3:validateTenantApiKey"],
|
||||
);
|
||||
assert.deepEqual(
|
||||
inventory.entityResolverCallsites.map((entry) => `${entry.file}:${entry.line}:${entry.symbol}`),
|
||||
["apps/api/src/usage-route.ts:4:getEntityApiKeyFromRequest"],
|
||||
);
|
||||
assert.deepEqual(
|
||||
inventory.relationshipHelperCallsites.map((entry) => `${entry.file}:${entry.line}:${entry.symbol}`),
|
||||
["apps/api/src/relationships-route.ts:3:getRelationshipApiKeyFromRequest"],
|
||||
);
|
||||
assert.deepEqual(
|
||||
inventory.workflowHelperCallsites.map((entry) => `${entry.file}:${entry.line}:${entry.symbol}`),
|
||||
["apps/api/src/workflows-route.ts:3:getWorkflowApiKeyFromRequest"],
|
||||
);
|
||||
assert.equal(inventory.apiServiceImports.length, 4);
|
||||
assert.equal(inventory.centralResolverFile, "apps/web/app/utils/services/apiService.ts");
|
||||
assert.doesNotThrow(() => JSON.parse(JSON.stringify(inventory)));
|
||||
const text = renderText(inventory);
|
||||
assert.match(text, /API Auth Surface API auth surface inventory/);
|
||||
assert.match(text, /getRelationshipApiKeyFromRequest callsites/);
|
||||
assert.match(text, /getWorkflowApiKeyFromRequest callsites/);
|
||||
});
|
||||
|
||||
it("CLI exits 2 for unknown flags", () => {
|
||||
const scriptPath = path.resolve("scripts/verify-api-auth-surface.mjs");
|
||||
|
||||
assert.throws(
|
||||
() => execFileSync(process.execPath, [scriptPath, "--bogus"], { encoding: "utf8", stdio: "pipe" }),
|
||||
(error) => {
|
||||
assert.equal(error.status, 2);
|
||||
assert.match(error.stderr, /Unknown flag: --bogus/);
|
||||
return true;
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("marks missing required API source roots as inventory failures", async () => {
|
||||
const rootDir = createFixture();
|
||||
|
||||
const inventory = await buildInventory(rootDir);
|
||||
|
||||
assert.deepEqual(inventory.scannedFiles, []);
|
||||
assert.deepEqual(inventory.requiredMissingRoots, ["apps/api/src"]);
|
||||
assert.equal(hasInventoryIntegrityFailure(inventory), true);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user