import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import test from "node:test"; const paths = { api: "src/lib/api.ts", capabilities: "src/server/services/container-capabilities.service.ts", deploymentService: "src/server/services/deployment.service.ts", routes: "src/server/routes/containers.ts", environmentPage: "src/app/projects/[projectId]/environments/[environmentId]/page.tsx", environmentToolbar: "src/app/projects/[projectId]/environments/[environmentId]/components/toolbar/EnvironmentContainersToolbar.tsx", environmentTable: "src/app/projects/[projectId]/environments/[environmentId]/components/containers/EnvironmentContainersTable.tsx", detailPage: "src/app/projects/[projectId]/environments/[environmentId]/containers/[containerId]/page.tsx", detailHeader: "src/app/projects/[projectId]/environments/[environmentId]/containers/[containerId]/components/header/AppDetailHeader.tsx", actionConstants: "src/app/projects/[projectId]/environments/[environmentId]/containers/[containerId]/data/app-detail-constants.ts", deploymentsPanel: "src/app/projects/[projectId]/environments/[environmentId]/containers/[containerId]/components/deployments/DeploymentsTabPanel.tsx", configurationModal: "src/app/projects/[projectId]/environments/[environmentId]/containers/[containerId]/components/configuration/EditContainerConfigurationModal.tsx", } as const; function read(path: (typeof paths)[keyof typeof paths]) { return readFileSync(path, "utf8"); } test("container list and detail expose the same backend-derived capability contract", () => { const routes = read(paths.routes); const api = read(paths.api); assert.ok( (routes.match(/capabilities:\s*buildContainerCapabilities\(/g) ?? []) .length >= 2, "list and detail responses must both build capabilities", ); assert.ok( (routes.match(/const \{ deploymentSource, \.\.\.publicContainer \} = container;/g) ?? []) .length >= 2, "internal deployment source metadata must not be copied to public responses", ); assert.match(routes, /hasDeploymentHistory:\s*Boolean\(deploymentSummary\?\.latestAttempt\)/); assert.match(routes, /redeployAvailable:\s*deploymentSummary\?\.redeployAvailable \?\? false/); assert.match(routes, /rollbackAvailable:\s*deploymentSummary\?\.rollbackAvailable \?\? false/); assert.match(api, /capabilities\?: ContainerCapabilities/); assert.match(api, /mode: "ORCHESTRATED_SINGLE_CONTAINER" \| "COMPOSE_RECREATE" \| null/); }); test("redeploy capability belongs to the active eligible revision", () => { const service = read(paths.deploymentService); assert.match( service, /redeployAvailable:\s*rollbackEligibleRevisions\.some\(\s*\(revision\) => revision\.id === activeRevision\?\.id,?\s*\)/, ); assert.match( service, /rollbackAvailable:\s*rollbackEligibleRevisions\.some\([\s\S]*?revision\.id !== activeRevision\?\.id/, ); }); test("detail actions combine backend capability with frontend role gating", () => { const detailPage = read(paths.detailPage); const deploymentsPanel = read(paths.deploymentsPanel); const detailHeader = read(paths.detailHeader); assert.match(detailPage, /getRoleCapabilities\(currentUser\?\.role/); assert.match(detailPage, /canMutateContainers/); assert.match(detailPage, /capabilities\?\.editConfiguration\.available/); assert.match(detailPage, /capabilities\?\.redeploy\.available/); assert.match(detailPage, /capabilities\?\.rebuild\.available/); assert.match(detailPage, /allowRollback=\{canMutateContainers\}/); assert.match(deploymentsPanel, /allowRollback && deployment\.canRollback/); assert.match(detailHeader, /menuActions\.length > 0/); assert.match(detailHeader, /disabled=\{actionBusy \|\| action\.disabled\}/); }); test("viewer cannot open environment mutation controls", () => { const environmentPage = read(paths.environmentPage); const toolbar = read(paths.environmentToolbar); assert.match(environmentPage, /canManageContainers && showDeploy/); assert.match(environmentPage, /canManageContainers && showDeployDatabase/); assert.match(environmentPage, /canManageContainers && showImportFromSync/); assert.match(environmentPage, /canManage=\{canManageContainers\}/); assert.match(toolbar, /canManage: boolean/); assert.match(toolbar, /\{canManage \?