Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
65 lines
2.2 KiB
TypeScript
65 lines
2.2 KiB
TypeScript
import { promises as fs } from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
|
|
import { describe, expect, it } from 'vitest';
|
|
|
|
import { createMission, loadMission, missionFilePath } from '../src/mission.js';
|
|
|
|
describe('mission lifecycle', () => {
|
|
it('creates and loads mission state files', async () => {
|
|
const projectDir = await fs.mkdtemp(path.join(os.tmpdir(), 'coord-mission-'));
|
|
|
|
try {
|
|
const mission = await createMission({
|
|
name: 'Wave 3 Mission',
|
|
projectPath: projectDir,
|
|
milestones: ['Phase One', 'Phase Two'],
|
|
qualityGates: 'pnpm lint && pnpm typecheck && pnpm test',
|
|
description: 'Wave 3 implementation',
|
|
});
|
|
|
|
expect(mission.id).toMatch(/^wave-3-mission-\d{8}$/);
|
|
expect(mission.status).toBe('active');
|
|
expect(mission.milestones).toHaveLength(2);
|
|
|
|
await expect(fs.stat(missionFilePath(projectDir, mission))).resolves.toBeDefined();
|
|
await expect(fs.stat(path.join(projectDir, 'docs/TASKS.md'))).resolves.toBeDefined();
|
|
await expect(
|
|
fs.stat(path.join(projectDir, '.mosaic/orchestrator/mission.json')),
|
|
).resolves.toBeDefined();
|
|
|
|
const loaded = await loadMission(projectDir);
|
|
expect(loaded.id).toBe(mission.id);
|
|
expect(loaded.name).toBe('Wave 3 Mission');
|
|
expect(loaded.qualityGates).toBe('pnpm lint && pnpm typecheck && pnpm test');
|
|
} finally {
|
|
await fs.rm(projectDir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
it('rejects inactive missions on load', async () => {
|
|
const projectDir = await fs.mkdtemp(path.join(os.tmpdir(), 'coord-mission-inactive-'));
|
|
|
|
try {
|
|
const mission = await createMission({
|
|
name: 'Inactive Mission',
|
|
projectPath: projectDir,
|
|
});
|
|
|
|
const missionPath = missionFilePath(projectDir, mission);
|
|
const payload = JSON.parse(await fs.readFile(missionPath, 'utf8')) as {
|
|
status: string;
|
|
};
|
|
payload.status = 'inactive';
|
|
await fs.writeFile(missionPath, `${JSON.stringify(payload, null, 2)}\n`, 'utf8');
|
|
|
|
await expect(loadMission(projectDir)).rejects.toThrow(
|
|
'Mission exists but is inactive',
|
|
);
|
|
} finally {
|
|
await fs.rm(projectDir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
});
|