import assert from 'node:assert/strict'; import { execFileSync } from 'node:child_process'; import { readFileSync } from 'node:fs'; import { test } from 'node:test'; const installer = new URL('../scripts/install.sh', import.meta.url); const source = readFileSync(installer, 'utf8'); test('one-click installer has safe lifecycle commands and pinned production defaults', () => { execFileSync('/bin/sh', ['-n', installer.pathname]); const help = execFileSync('/bin/sh', [installer.pathname, 'help'], { encoding: 'utf8' }); for (const command of ['install', 'start', 'stop', 'restart', 'status', 'uninstall']) { assert.match(help, new RegExp(`\\b${command}\\b`)); } assert.match(source, /PNPM_VERSION="11\.13\.0"/); assert.match(source, /API_HOST=127\.0\.0\.1/); assert.match(source, /API_PORT=8790/); assert.match(source, /MULTI_SIMADMIN_GATEWAY_HOST=0\.0\.0\.0/); assert.match(source, /CANARY_UPSTREAM_PORT=8790/); assert.doesNotMatch(source, /CANARY_PORT=8789/); assert.match(source, /umask 077/); assert.match(source, /install -m 600/); assert.match(source, /--frozen-lockfile/); assert.match(source, /trap 'rollback_start' EXIT HUP INT TERM/); assert.match(source, /保留 PID 文件/); assert.match(source, /node --import tsx .*production-cli\.ts/); assert.match(source, /node --import tsx .*production-gateway-cli\.ts/); assert.doesNotMatch(source, /nohup corepack pnpm/); }); test('installer refuses unsupported platforms and preserves data by default on uninstall', () => { assert.match(source, /Darwin/); assert.match(source, /当前生产版仅支持 macOS/); assert.match(source, /默认保留数据/); assert.doesNotMatch(source, /rm -rf "\$DATA_ROOT"/); assert.doesNotMatch(source, /git reset --hard|git clean -fdx/); }); test('README exposes the token-free Gitea one-click command', () => { const readme = readFileSync(new URL('../README.md', import.meta.url), 'utf8'); assert.match( readme, /curl -fsSL https:\/\/gitea\.chickliu\.fun\/Hermes\/multi-simadmin\/raw\/branch\/main\/scripts\/install\.sh \| sh/, ); assert.doesNotMatch(readme, /https:\/\/[^\s/]+:[^\s@]+@gitea\.chickliu\.fun/); });