test: guard broad plugin resolver fixtures

This commit is contained in:
Peter Steinberger
2026-04-29 06:45:57 +01:00
parent 83df409d94
commit 358b4f24cd
4 changed files with 63 additions and 0 deletions

View File

@@ -9,6 +9,12 @@ const ALLOWED_EXTENSION_PUBLIC_SURFACE_BASENAMES = new Set(
GUARDED_EXTENSION_PUBLIC_SURFACE_BASENAMES,
);
const CHANNEL_CONTRACT_TEST_HELPERS_PREFIX = "src/channels/plugins/contracts/test-helpers/";
const BUNDLED_PLUGIN_RESOLVER_TEST_FILES = [
"src/plugin-sdk/facade-loader.test.ts",
"src/plugins/public-surface-loader.test.ts",
"src/plugins/public-surface-runtime.test.ts",
] as const;
const BROAD_PUBLIC_SOURCE_ARTIFACT_BASENAMES = new Set(["api.js", "runtime-api.js"]);
const ROOTDIR_BOUNDARY_CANARY_RE =
/(^|\/)__rootdir_boundary_canary__\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/u;
@@ -93,6 +99,41 @@ function getImportBasename(importPath: string): string {
return importPath.split("/").at(-1) ?? importPath;
}
function collectBundledPluginIds(): Set<string> {
return new Set(
fs
.readdirSync(path.join(repoRoot, "extensions"), { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => entry.name),
);
}
function getLineNumber(source: string, index: number): number {
return source.slice(0, index).split("\n").length;
}
function findRealBroadSourceApiResolverReferences(
source: string,
pluginIds: Set<string>,
): string[] {
const offenders: string[] = [];
for (const match of source.matchAll(/\{[^{}]*\bdirName:\s*["'][^"']+["'][^{}]*\}/g)) {
const objectLiteral = match[0];
const dirName = objectLiteral.match(/\bdirName:\s*["']([^"']+)["']/)?.[1];
const artifactBasename = objectLiteral.match(/\bartifactBasename:\s*["']([^"']+)["']/)?.[1];
if (
dirName &&
artifactBasename &&
pluginIds.has(dirName) &&
BROAD_PUBLIC_SOURCE_ARTIFACT_BASENAMES.has(artifactBasename)
) {
offenders.push(`${dirName}/${artifactBasename}:${getLineNumber(source, match.index ?? 0)}`);
}
}
return offenders;
}
function isAllowedCoreContractSuite(file: string, imports: readonly string[]): boolean {
return (
file.startsWith("src/channels/plugins/contracts/") &&
@@ -190,6 +231,18 @@ describe("non-extension test boundaries", () => {
expect(offenders).toEqual([]);
});
it("keeps resolver tests on generated fixtures for broad bundled plugin source APIs", () => {
const bundledPluginIds = collectBundledPluginIds();
const offenders = BUNDLED_PLUGIN_RESOLVER_TEST_FILES.flatMap((file) => {
const source = fs.readFileSync(path.join(repoRoot, file), "utf8");
return findRealBroadSourceApiResolverReferences(source, bundledPluginIds).map(
(reference) => `${file}: ${reference}`,
);
});
expect(offenders).toEqual([]);
});
it("keeps bundled channel security collector coverage under extension tests", () => {
const files = [...walk(path.join(repoRoot, "src")), ...walk(path.join(repoRoot, "test"))]
.filter((file) => !file.startsWith(BUNDLED_PLUGIN_PATH_PREFIX))