import assert from "node:assert/strict"; import { readdirSync, readFileSync, statSync } from "node:fs"; import { join, relative } from "node:path"; import { fileURLToPath } from "node:url"; import test from "node:test"; // BUG-1140: deploy/railway-web.Dockerfile copies frontend/src and frontend/scripts but not // frontend/tests, and `next build` type-checks every *.ts under frontend/. A runtime or script // file that imports from tests/ builds locally and then fails the staging image build. const frontend = fileURLToPath(new URL("..", import.meta.url)); const roots = ["src", "scripts"]; const importsTests = /(?:from\s+|import\s*\(\s*|new URL\(\s*)["'](?:\.\.?\/)+(?:[^"']*\/)?tests\//; function sources(directory: string): string[] { return readdirSync(directory).flatMap((name) => { const path = join(directory, name); if (statSync(path).isDirectory()) return sources(path); return /\.(?:ts|tsx|mts|mjs|js)$/.test(name) ? [path] : []; }); } test("files copied into the web image never import from frontend/tests", () => { const offenders = roots .flatMap((root) => sources(join(frontend, root))) .filter((path) => importsTests.test(readFileSync(path, "utf8"))) .map((path) => relative(frontend, path)); assert.deepEqual(offenders, []); }); test("the guard recognises the shapes that broke the build", () => { for (const line of [ 'import { startPostgresFixture } from "../tests/helpers/postgres-fixture.ts";', "const fixture = await import('../../tests/helpers/postgres-fixture.ts');", 'new URL("../tests/fixtures/x.json", import.meta.url)', ]) assert.ok(importsTests.test(line), line); assert.equal(importsTests.test('import { x } from "../src/lib/tests-helpers.ts";'), false); });