/** * Source-boundary tests for scripts/sync-design-system.mjs. * * The design system used to live in its own directory inside the marketplace * monorepo, so the sync script could copy its whole source tree. After the * polyrepo split the source tree is this repo's root, which also holds * STATE.md (gitignored, must never reach a public mirror), .git/, docs/ and * playground-examples/. These tests pin the boundary: only the delivered * files may be vendored. * * Run with: node --test tests/ */ import { test } from 'node:test'; import assert from 'node:assert/strict'; import { promises as fs } from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { execFile } from 'node:child_process'; import { promisify } from 'node:util'; import { pathToFileURL } from 'node:url'; const execFileAsync = promisify(execFile); const REPO_ROOT = path.resolve(import.meta.dirname, '..'); const SCRIPT = path.join(REPO_ROOT, 'scripts', 'sync-design-system.mjs'); const VENDOR_SUBPATH = path.join('playground', 'vendor', 'playground-design-system'); const DELIVERED_COUNT = 27; // --target is the PLUGIN root; the script appends playground/vendor/... itself, // and refuses to run if the plugin root does not already exist. async function makePluginDir() { const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'pds-sync-test-')); return dir; } async function listFiles(dir) { const out = []; async function walk(current) { const entries = await fs.readdir(current, { withFileTypes: true }); for (const e of entries) { const full = path.join(current, e.name); if (e.isDirectory()) await walk(full); else out.push(path.relative(dir, full)); } } await walk(dir); return out.sort(); } async function exists(p) { try { await fs.stat(p); return true; } catch { return false; } } test('sync copies only the delivered files, never the repo apparatus', async (t) => { const pluginDir = await makePluginDir(); t.after(() => fs.rm(pluginDir, { recursive: true, force: true })); await execFileAsync('node', [ SCRIPT, 'test-plugin', '--source', REPO_ROOT, '--target', pluginDir, ]); const vendorDir = path.join(pluginDir, VENDOR_SUBPATH); // Known-positive control: the assertions below are worthless unless this // proves the sync actually wrote to the path being inspected. assert.ok( await exists(path.join(vendorDir, 'tokens.css')), 'tokens.css must be vendored — without it the leak assertions prove nothing', ); // The leak this test exists for. STATE.md is gitignored precisely because // this repo's remote is public; vendoring it into a consumer publishes it. for (const leak of ['STATE.md', '.git', 'playground-examples', 'docs', 'LICENSE', 'SECURITY.md', '.gitignore']) { assert.equal( await exists(path.join(vendorDir, leak)), false, `${leak} must not be vendored`, ); } const files = await listFiles(vendorDir); assert.equal( files.length, DELIVERED_COUNT + 1, `expected ${DELIVERED_COUNT} delivered files + MANIFEST.json, got ${files.length}`, ); const manifest = JSON.parse(await fs.readFile(path.join(vendorDir, 'MANIFEST.json'), 'utf8')); assert.equal(manifest.file_count, DELIVERED_COUNT); }); test('sync refuses to run when the source holds a design-system file the allowlist does not name', async (t) => { const pluginDir = await makePluginDir(); const sourceDir = await fs.mkdtemp(path.join(os.tmpdir(), 'pds-sync-src-')); t.after(() => Promise.all([ fs.rm(pluginDir, { recursive: true, force: true }), fs.rm(sourceDir, { recursive: true, force: true }), ])); // A minimal but complete source: every delivered file present, empty. const { DELIVERED_FILES } = await import(pathToFileURL(SCRIPT).href); for (const rel of DELIVERED_FILES) { const p = path.join(sourceDir, rel); await fs.mkdir(path.dirname(p), { recursive: true }); await fs.writeFile(p, '', 'utf8'); } // Baseline: the complete source syncs cleanly. Known-positive control for // the failure asserted below. await execFileAsync('node', [SCRIPT, 'test-plugin', '--source', sourceDir, '--target', pluginDir]); // A new stylesheet added to the design system but not to the allowlist is // the failure mode this repo already lived through once // (components-tier4-project-view.css, added v0.6.0, missing from docs until // 2026-08-18). It must be loud, not silent: --check hashes target against // MANIFEST and would stay green forever. await fs.writeFile(path.join(sourceDir, 'components-tier5.css'), '', 'utf8'); await assert.rejects( execFileAsync('node', [SCRIPT, 'test-plugin', '--source', sourceDir, '--target', pluginDir]), (err) => { assert.match(err.stderr, /components-tier5\.css/); return true; }, 'an unlisted stylesheet in the source must fail the sync', ); });