67 lines
3.5 KiB
JavaScript
67 lines
3.5 KiB
JavaScript
// Row 171: diagnostic file reads stay in fixture config; project creation uses a real broker.
|
|
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
import { hostDir, hostFile, startTimeOf } from '../src/host.mjs';
|
|
import { join } from 'node:path';
|
|
import { run } from '../src/cli.mjs';
|
|
import { broker, BUSINESSES, fixture, io, tmp } from './helpers.mjs';
|
|
|
|
function setup(t) {
|
|
const root = tmp(t), config = fixture(root, 'demo');
|
|
const s = broker(t, { demo: { ...BUSINESSES.demo, projects: { stack: {} } } });
|
|
const reads = [];
|
|
const transport = business => async (verb, args) => {
|
|
reads.push(verb);
|
|
if (verb === 'plugins') return { business, revision: 'a'.repeat(64), plugins: { channel: ['cli', 'webui'] } };
|
|
return s.transport(business)(verb, args);
|
|
};
|
|
const cli = async (args, explicit = true) => {
|
|
const x = io(config.env);
|
|
const code = await run([...args, ...(explicit ? ['--business', 'demo'] : [])], x, { system: { dataRoot: config.dataRoot }, transport });
|
|
return { code, out: x.out.text, err: x.err.text };
|
|
};
|
|
return { ...s, root, config, reads, cli };
|
|
}
|
|
|
|
test('threads project resolution explains a business repository and falls back if its file cannot load', async t => {
|
|
const s = setup(t);
|
|
const args = ['threads', '--project', 'stack'];
|
|
assert.deepEqual(await s.cli(args), {
|
|
code: 2, out: '',
|
|
err: 'mosaic: "stack" is a repository in the business file, not a thread project yet; mosaic project create stack --repo stack makes one\n',
|
|
});
|
|
assert.deepEqual(s.reads, ['plugins', 'project.list']);
|
|
// A stand-in host state names this test process; no host or unit is started.
|
|
mkdirSync(hostDir(s.config.dataRoot), { recursive: true, mode: 0o700 });
|
|
writeFileSync(hostFile(s.config.dataRoot), JSON.stringify({ pid: process.pid, startTime: startTimeOf(process.pid), business: 'demo' }), { mode: 0o600 });
|
|
s.reads.length = 0;
|
|
const implicit = await s.cli(args, false);
|
|
assert.equal(implicit.code, 2);
|
|
assert.equal(implicit.err, 'mosaic: "stack" is a repository in the business file, not a thread project yet; mosaic project create stack --repo stack makes one\n');
|
|
assert.deepEqual(s.reads, ['plugins', 'project.list']);
|
|
const existing = setup(t);
|
|
assert.equal((await existing.cli(['project', 'create', 'stack', '--repo', 'stack'])).code, 0);
|
|
writeFileSync(join(existing.root, 'config/businesses/demo.json'), '{broken json');
|
|
assert.deepEqual(await existing.cli(args), { code: 0, out: 'no threads\n', err: '' });
|
|
assert.deepEqual(await existing.cli(['threads', '--project', 'other']), {
|
|
code: 2, out: '', err: 'mosaic: no project is named or numbered "other"; see mosaic project list\n',
|
|
});
|
|
s.reads.length = 0;
|
|
rmSync(join(s.root, 'config/businesses/demo.json'));
|
|
assert.deepEqual(await s.cli(args), {
|
|
code: 2, out: '', err: 'mosaic: no project is named or numbered "stack"; see mosaic project list\n',
|
|
});
|
|
assert.deepEqual(s.reads, ['plugins', 'project.list']);
|
|
});
|
|
|
|
test('project create prints the repository-name refusal and exits two without writing', async t => {
|
|
const s = setup(t);
|
|
assert.deepEqual(await s.cli(['project', 'create', 'stack']), {
|
|
code: 2, out: '',
|
|
err: 'mosaic: "stack" is a repository in the business file; add --repo stack to make its thread project, or pick another name\n',
|
|
});
|
|
assert.deepEqual(s.b.request(s.human, { verb: 'project.list' }), []);
|
|
assert.equal((await s.cli(['project', 'create', 'stack', '--repo', 'stack'])).code, 0);
|
|
});
|