import test from 'node:test'; import assert from 'node:assert/strict'; import {spawnSync} from 'node:child_process'; import {writeFileSync,chmodSync,unlinkSync,existsSync} from 'node:fs'; import {join} from 'node:path'; import {fileURLToPath} from 'node:url'; import {makeRoot,makeRepo,makeDeployment} from './helpers.mjs'; const CLI=fileURLToPath(new URL('../src/cli.mjs',import.meta.url)); function setup(){ const root=makeRoot(),repo=makeRepo(root),d=makeDeployment(root,{}, {tokenContent:'MTAw.abcdefghijklmnopqrstuvwxyz0123456789'}),calls=join(root,'network-called'),preload=join(root,'no-network.mjs'); writeFileSync(preload,`import {writeFileSync} from 'node:fs';const refuse=()=>{writeFileSync(${JSON.stringify(calls)},'called');throw Error('fixture refuses network')};globalThis.fetch=refuse;globalThis.WebSocket=class{constructor(){refuse()}};`); const run=(command='check',args=[])=>spawnSync(process.execPath,['--import',preload,CLI,command,d.raw.name,'--config',d.config,'--repo',repo,...args],{encoding:'utf8',timeout:5000}); return {root,repo,d,calls,run}; } test('check --offline validates local fixture without REST or gateway calls',()=>{ const s=setup(),r=s.run('check',['--offline']);assert.equal(r.status,0,r.stderr);assert.match(r.stdout,/token file mode 0600 ok; STOP absent/);assert.match(r.stdout,/offline check passed; no REST or gateway calls were made\n$/);assert.ok(!existsSync(s.calls)); // Online check still reaches REST: the trap fails it immediately. const online=s.run();assert.equal(online.status,1);assert.ok(existsSync(s.calls));assert.match(online.stderr,/fixture refuses network/); }); test('check --offline refuses token mode and missing context under the selected repo',()=>{ const s=setup();chmodSync(s.d.tokenFile,0o644);const bad=s.run('check',['--offline']);assert.equal(bad.status,2,bad.stderr);assert.match(bad.stderr,/0600/);assert.ok(!existsSync(s.calls)); chmodSync(s.d.tokenFile,0o600);unlinkSync(join(s.repo,'contracts/CONSTITUTION.md'));const context=s.run('check',['--offline']);assert.equal(context.status,2,context.stderr);assert.ok(!existsSync(s.calls)); }); test('run --offline is a usage refusal before reading config or networking',()=>{ const s=setup();unlinkSync(s.d.config);const r=s.run('run',['--offline']);assert.equal(r.status,4,r.stderr);assert.match(r.stderr,/--offline/);assert.ok(!existsSync(s.calls)); });