65 lines
2.5 KiB
TypeScript
65 lines
2.5 KiB
TypeScript
import { expect, test } from "bun:test";
|
|
import { readdirSync, readFileSync } from "node:fs";
|
|
import { join, relative, resolve } from "node:path";
|
|
|
|
function walkSourceFiles(dir: string): string[] {
|
|
const files: string[] = [];
|
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
const path = join(dir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
files.push(...walkSourceFiles(path));
|
|
continue;
|
|
}
|
|
if (/\.(ts|tsx)$/.test(entry.name)) files.push(path);
|
|
}
|
|
return files;
|
|
}
|
|
|
|
const webRoot = resolve(import.meta.dir, "..");
|
|
const srcRoot = resolve(webRoot, "src");
|
|
|
|
const axiosAllowed = new Set([
|
|
"services/api/request.ts",
|
|
"services/api/channel-transport.ts",
|
|
"services/api/image-response.ts",
|
|
"services/api/video-response.ts",
|
|
"services/diagnostics/client-diagnostics.ts",
|
|
]);
|
|
|
|
test("business API modules call http instead of axios or request(apiClient)", () => {
|
|
const offenders = walkSourceFiles(resolve(srcRoot, "services"))
|
|
.filter((file) => {
|
|
const rel = relative(srcRoot, file);
|
|
if (axiosAllowed.has(rel)) return false;
|
|
const source = readFileSync(file, "utf8");
|
|
return /from ["']axios["']/.test(source) || /request\s*(?:<[^>]+>)?\s*\(\s*apiClient\./.test(source) || /const api = apiClient/.test(source);
|
|
})
|
|
.map((file) => relative(srcRoot, file));
|
|
expect(offenders).toEqual([]);
|
|
});
|
|
|
|
test("axios.create stays in the shared request client", () => {
|
|
const offenders = walkSourceFiles(srcRoot)
|
|
.filter((file) => {
|
|
if (relative(srcRoot, file) === "services/api/request.ts") return false;
|
|
return readFileSync(file, "utf8").includes("axios.create(");
|
|
})
|
|
.map((file) => relative(srcRoot, file));
|
|
expect(offenders).toEqual([]);
|
|
});
|
|
|
|
test("copied flush Modal padding lives only in AppModal", () => {
|
|
const banned = [
|
|
'styles={{ container: { padding: 0, overflow: "hidden" }, body: { padding: 0 } }}',
|
|
"styles={{ container: { padding: 0 }, body: { padding: 0 } }}",
|
|
];
|
|
const offenders = walkSourceFiles(srcRoot)
|
|
.filter((file) => {
|
|
if (relative(srcRoot, file) === "components/ui/product/app-modal/app-modal.tsx") return false;
|
|
const source = readFileSync(file, "utf8");
|
|
return banned.some((snippet) => source.includes(snippet));
|
|
})
|
|
.map((file) => relative(srcRoot, file));
|
|
expect(offenders).toEqual([]);
|
|
});
|