test(#792): cover roster guard and installer heading
This commit is contained in:
@@ -60,6 +60,7 @@ import {
|
|||||||
type SleepFn,
|
type SleepFn,
|
||||||
} from './fleet.js';
|
} from './fleet.js';
|
||||||
import { registerAgentCommand } from './agent.js';
|
import { registerAgentCommand } from './agent.js';
|
||||||
|
import { parseFleetRosterDocument, readFleetRosterText } from '../fleet/fleet-roster-v1.js';
|
||||||
|
|
||||||
function buildProgram(): Command {
|
function buildProgram(): Command {
|
||||||
const program = new Command();
|
const program = new Command();
|
||||||
@@ -166,6 +167,55 @@ describe('registerFleetCommand', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('fleet roster configuration failures', () => {
|
||||||
|
it('reports a missing roster with an actionable initialization hint', async () => {
|
||||||
|
const home = await tempDir();
|
||||||
|
try {
|
||||||
|
const program = buildProgram();
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
program.parseAsync(['node', 'mosaic', 'fleet', '--mosaic-home', home, 'ps']),
|
||||||
|
).rejects.toThrow(
|
||||||
|
`No fleet roster found at ${join(home, 'fleet', 'roster.json')}. Run \`mosaic fleet init\``,
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await rm(home, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('reports a malformed roster with the path and repair hint', async () => {
|
||||||
|
const home = await tempDir();
|
||||||
|
const rosterPath = join(home, 'fleet', 'roster.json');
|
||||||
|
try {
|
||||||
|
await mkdir(dirname(rosterPath), { recursive: true });
|
||||||
|
await writeFile(rosterPath, '{not valid json');
|
||||||
|
|
||||||
|
await expect(loadFleetRoster(rosterPath)).rejects.toThrow(
|
||||||
|
`Fleet roster at ${rosterPath} is invalid. Fix the file or run \`mosaic fleet init --force\``,
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await rm(home, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('reports an unreadable roster without exposing the filesystem error', async () => {
|
||||||
|
const home = await tempDir();
|
||||||
|
try {
|
||||||
|
await expect(readFleetRosterText(home)).rejects.toThrow(
|
||||||
|
`Could not read fleet roster at ${home}. Check the file exists and is readable.`,
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await rm(home, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('reports a malformed roster while selecting the v1/v2 command path', () => {
|
||||||
|
expect(() => parseFleetRosterDocument('version: [', '/srv/mosaic/fleet/roster.yaml')).toThrow(
|
||||||
|
'Fleet roster at /srv/mosaic/fleet/roster.yaml is invalid. Fix the file or run `mosaic fleet init --force`.',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('fleet roster parsing', () => {
|
describe('fleet roster parsing', () => {
|
||||||
let cleanup: string | undefined;
|
let cleanup: string | undefined;
|
||||||
|
|
||||||
|
|||||||
17
packages/mosaic/src/commands/install-heading.spec.ts
Normal file
17
packages/mosaic/src/commands/install-heading.spec.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { readFile } from 'node:fs/promises';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
|
const INSTALLER_PATH = fileURLToPath(new URL('../../../../tools/install.sh', import.meta.url));
|
||||||
|
|
||||||
|
describe('installer CLI package heading', () => {
|
||||||
|
it('renders the scoped package name intact', async () => {
|
||||||
|
const installer = await readFile(INSTALLER_PATH, 'utf8');
|
||||||
|
const step = installer.match(/^step\(\)\s*\{.*\}$/m)?.[0];
|
||||||
|
|
||||||
|
expect(step).toBeDefined();
|
||||||
|
|
||||||
|
expect(step).toContain('printf \'\\n%s%s%s\\n\' "$BOLD" "$*" "$RESET"');
|
||||||
|
expect(installer).toContain('step "@mosaicstack/mosaic (npm package)"');
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user