mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
Supersedes #301 by @VassagoDevteam, ported onto the current component layout with fixes from review. Verified before merge: format, package boundaries, unit suite, build, and the browser tracking suite; a browser harness for the change where one applies; adversarial review applied. Co-authored-by: Vassago DevTeam <[email protected]>
96 lines
5.4 KiB
JavaScript
96 lines
5.4 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs/promises';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { execFile } from 'node:child_process';
|
|
import { promisify } from 'node:util';
|
|
import { makeFixtureRoot } from './tooling/fixtureRoot.mjs';
|
|
|
|
const run = promisify(execFile);
|
|
const bashTest = process.platform === 'win32' ? test.skip : test;
|
|
|
|
async function launch(overrides = {}, dotenv = '', omitCctv = false) {
|
|
// Physical path: the launched process reports its cwd resolved, and macOS
|
|
// reaches the temp directory through a symlink.
|
|
const root = await makeFixtureRoot('gev-cctv-launch-');
|
|
try {
|
|
await fs.mkdir(path.join(root, 'scripts'));
|
|
await fs.mkdir(path.join(root, 'bin'));
|
|
await fs.mkdir(path.join(root, 'src', 'data'), { recursive: true });
|
|
await fs.copyFile(new URL('./data/cctv.js', import.meta.url), path.join(root, 'src', 'data', 'cctv.js'));
|
|
for (const name of ['dev-cctv.sh', 'dev-fresh.sh', 'read-dotenv-value.mjs']) {
|
|
await fs.copyFile(new URL(`../scripts/${name}`, import.meta.url), path.join(root, 'scripts', name));
|
|
}
|
|
await fs.mkdir(path.join(root, 'src', 'standalone'), { recursive: true });
|
|
const catalog = await fs.readFile(new URL('./standalone/catalog.js', import.meta.url), 'utf8');
|
|
await fs.writeFile(path.join(root, 'src', 'standalone', 'catalog.js'), catalog);
|
|
await fs.mkdir(path.join(root, 'src', 'app'), { recursive: true });
|
|
const assembly = await fs.readFile(new URL('./app/constructCatalog.js', import.meta.url), 'utf8');
|
|
await fs.writeFile(path.join(root, 'src', 'app', 'constructCatalog.js'), omitCctv ? assembly.replace(/^\s*createApplicationCctv\(.*$/m, '') : assembly);
|
|
await fs.mkdir(path.join(root, 'node_modules'));
|
|
await fs.symlink(fileURLToPath(new URL('.', import.meta.resolve('vite/package.json'))), path.join(root, 'node_modules', 'vite'), 'dir');
|
|
await fs.writeFile(path.join(root, '.env'), dotenv);
|
|
// Stub only external programs; both production launchers and dotenv parsing run.
|
|
for (const command of ['security', 'pkill', 'lsof']) {
|
|
await fs.writeFile(path.join(root, 'bin', command), '#!/bin/sh\nexit 1\n', { mode: 0o755 });
|
|
}
|
|
await fs.writeFile(path.join(root, 'bin', 'npm'), `#!/usr/bin/env node
|
|
const fs = require('node:fs');
|
|
fs.writeFileSync(process.env.CCTV_TEST_CAPTURE, JSON.stringify({ args: process.argv.slice(2), env: process.env, cwd: process.cwd() }));
|
|
`, { mode: 0o755 });
|
|
const capture = path.join(root, 'capture.json');
|
|
const result = await run('bash', [path.join(root, 'scripts', 'dev-cctv.sh')], {
|
|
cwd: os.tmpdir(),
|
|
env: { PATH: `${path.join(root, 'bin')}${path.delimiter}${process.env.PATH}`, CCTV_TEST_CAPTURE: capture, ...overrides },
|
|
timeout: 30_000,
|
|
});
|
|
return { ...JSON.parse(await fs.readFile(capture, 'utf8')), output: result.stdout + result.stderr, root };
|
|
} finally {
|
|
await fs.rm(root, { recursive: true, force: true });
|
|
}
|
|
}
|
|
|
|
bashTest('CCTV preset starts keyless on localhost through the normal launcher', async () => {
|
|
const result = await launch();
|
|
assert.deepEqual(result.args, ['run', 'dev', '--', '--host', 'localhost', '--port', '4173', '--force']);
|
|
assert.equal(result.cwd, result.root);
|
|
assert.equal(result.env.CCTV_SOURCES_FILE, 'config/cctv_sources.austin.json');
|
|
assert.equal(result.env.CCTV_PREFER_AUSTIN, '1');
|
|
assert.equal(result.env.CCTV_AUSTIN_MAX_SOURCES, '36');
|
|
assert.equal(result.env.CCTV_MAX_SOURCES, '48');
|
|
assert.equal(result.env.GEV_LAUNCHER, 'dev-fresh');
|
|
assert.equal(result.env.GEV_KEY_SETUP_EXTERNAL_KEYS, '');
|
|
assert.equal(result.env.GOOGLE_MAPS_API_KEY, undefined);
|
|
assert.match(result.output, /Startup map: Esri World Imagery/);
|
|
assert.doesNotMatch(result.output, /!! WARNING/);
|
|
});
|
|
|
|
bashTest('CCTV preset preserves explicit LAN and source overrides with a warning', async () => {
|
|
const result = await launch({ HOST: '0.0.0.0', PORT: '4999', CCTV_SOURCES_FILE: 'config/custom.json', CCTV_PREFER_AUSTIN: '0', CCTV_AUSTIN_MAX_SOURCES: '5', CCTV_MAX_SOURCES: '9', CCTV_CALTRANS_DISTRICTS: '', CCTV_TFL_ENABLED: '0' });
|
|
assert.deepEqual(result.args.slice(-5), ['--host', '0.0.0.0', '--port', '4999', '--force']);
|
|
assert.equal(result.env.CCTV_SOURCES_FILE, 'config/custom.json');
|
|
assert.equal(result.env.CCTV_PREFER_AUSTIN, '0');
|
|
assert.equal(result.env.CCTV_AUSTIN_MAX_SOURCES, '5');
|
|
assert.equal(result.env.CCTV_MAX_SOURCES, '9');
|
|
assert.equal(result.env.CCTV_CALTRANS_DISTRICTS, '');
|
|
assert.equal(result.env.CCTV_TFL_ENABLED, '0');
|
|
assert.match(result.output, /!! WARNING: HOST=0\.0\.0\.0/);
|
|
});
|
|
|
|
bashTest('CCTV preset shares dotenv precedence and names-only credential provenance', async () => {
|
|
const result = await launch({ GOOGLE_MAPS_API_KEY: 'fixture-shell-maps' }, 'GOOGLE_MAPS_API_KEY=fixture-file-maps\nOPENAI_API_KEY=fixture-file-voice\n');
|
|
assert.equal(result.env.GOOGLE_MAPS_API_KEY, 'fixture-shell-maps');
|
|
assert.equal(result.env.OPENAI_API_KEY, 'fixture-file-voice');
|
|
assert.equal(result.env.GEV_KEY_SETUP_EXTERNAL_KEYS, 'GOOGLE_MAPS_API_KEY');
|
|
assert.doesNotMatch(result.output, /fixture-shell-maps|fixture-file-maps|fixture-file-voice/);
|
|
});
|
|
|
|
bashTest('CCTV preset refuses a catalog that no longer registers its layer', async () => {
|
|
await assert.rejects(launch({}, '', true), (error) => {
|
|
assert.match(error.stdout, /CCTV layer not wired in src\/standalone\/catalog.js/);
|
|
return true;
|
|
});
|
|
});
|