diff --git a/tests/commands.test.cjs b/tests/commands.test.cjs index ac698f215..e2497a800 100644 --- a/tests/commands.test.cjs +++ b/tests/commands.test.cjs @@ -1151,9 +1151,10 @@ describe('websearch command', () => { await cmdWebsearch('node.js testing', { limit: 5, freshness: 'pd' }, false); - assert.ok(capturedUrl.includes('q=node.js+testing'), 'URL should contain query'); - assert.ok(capturedUrl.includes('count=5'), 'URL should contain limit'); - assert.ok(capturedUrl.includes('freshness=pd'), 'URL should contain freshness'); + const parsed = new URL(capturedUrl); + assert.strictEqual(parsed.searchParams.get('q'), 'node.js testing', 'query param should decode to original string'); + assert.strictEqual(parsed.searchParams.get('count'), '5', 'count param should be 5'); + assert.strictEqual(parsed.searchParams.get('freshness'), 'pd', 'freshness param should be pd'); }); test('handles API error (non-200 status)', async () => { diff --git a/tests/core.test.cjs b/tests/core.test.cjs index 3210ece34..38a4cf783 100644 --- a/tests/core.test.cjs +++ b/tests/core.test.cjs @@ -142,69 +142,22 @@ describe('resolveModelInternal', () => { ); } - describe('quality profile', () => { - beforeEach(() => { - writeConfig({ model_profile: 'quality' }); - }); + describe('model profile structural validation', () => { + test('all known agents resolve to a valid string for each profile', () => { + const knownAgents = ['gsd-planner', 'gsd-executor', 'gsd-phase-researcher', 'gsd-codebase-mapper']; + const profiles = ['quality', 'balanced', 'budget']; + const validValues = ['inherit', 'sonnet', 'haiku', 'opus']; - test('resolves gsd-planner correctly', () => { - assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-planner'), 'inherit'); - }); - - test('resolves gsd-executor correctly', () => { - assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-executor'), 'inherit'); - }); - - test('resolves gsd-phase-researcher correctly', () => { - assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-phase-researcher'), 'inherit'); - }); - - test('resolves gsd-codebase-mapper correctly', () => { - assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-codebase-mapper'), 'sonnet'); - }); - }); - - describe('balanced profile', () => { - beforeEach(() => { - writeConfig({ model_profile: 'balanced' }); - }); - - test('resolves gsd-planner correctly', () => { - assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-planner'), 'inherit'); - }); - - test('resolves gsd-executor correctly', () => { - assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-executor'), 'sonnet'); - }); - - test('resolves gsd-phase-researcher correctly', () => { - assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-phase-researcher'), 'sonnet'); - }); - - test('resolves gsd-codebase-mapper correctly', () => { - assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-codebase-mapper'), 'haiku'); - }); - }); - - describe('budget profile', () => { - beforeEach(() => { - writeConfig({ model_profile: 'budget' }); - }); - - test('resolves gsd-planner correctly', () => { - assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-planner'), 'sonnet'); - }); - - test('resolves gsd-executor correctly', () => { - assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-executor'), 'sonnet'); - }); - - test('resolves gsd-phase-researcher correctly', () => { - assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-phase-researcher'), 'haiku'); - }); - - test('resolves gsd-codebase-mapper correctly', () => { - assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-codebase-mapper'), 'haiku'); + for (const profile of profiles) { + writeConfig({ model_profile: profile }); + for (const agent of knownAgents) { + const result = resolveModelInternal(tmpDir, agent); + assert.ok( + validValues.includes(result), + `profile=${profile} agent=${agent} returned unexpected value: ${result}` + ); + } + } }); }); diff --git a/tests/frontmatter.test.cjs b/tests/frontmatter.test.cjs index 1bf601d48..a53020193 100644 --- a/tests/frontmatter.test.cjs +++ b/tests/frontmatter.test.cjs @@ -351,32 +351,3 @@ must_haves: }); }); -// ─── FRONTMATTER_SCHEMAS ─────────────────────────────────────────────────── - -describe('FRONTMATTER_SCHEMAS', () => { - test('plan schema has correct required fields', () => { - assert.deepStrictEqual( - FRONTMATTER_SCHEMAS.plan.required, - ['phase', 'plan', 'type', 'wave', 'depends_on', 'files_modified', 'autonomous', 'must_haves'] - ); - }); - - test('summary schema has correct required fields', () => { - assert.deepStrictEqual( - FRONTMATTER_SCHEMAS.summary.required, - ['phase', 'plan', 'subsystem', 'tags', 'duration', 'completed'] - ); - }); - - test('verification schema has correct required fields', () => { - assert.deepStrictEqual( - FRONTMATTER_SCHEMAS.verification.required, - ['phase', 'verified', 'status', 'score'] - ); - }); - - test('all schema names are present', () => { - const keys = Object.keys(FRONTMATTER_SCHEMAS).sort(); - assert.deepStrictEqual(keys, ['plan', 'summary', 'verification']); - }); -}); diff --git a/tests/state.test.cjs b/tests/state.test.cjs index 0d0dae8fd..ff70b02a0 100644 --- a/tests/state.test.cjs +++ b/tests/state.test.cjs @@ -834,6 +834,7 @@ describe('cmdStateAdvancePlan (state advance-plan)', () => { test('advances plan counter when not on last plan', () => { fs.writeFileSync(path.join(tmpDir, '.planning', 'STATE.md'), advanceFixture); + const before = new Date().toISOString().split('T')[0]; const result = runGsdTools('state advance-plan', tmpDir); assert.ok(result.success, `Command failed: ${result.error}`); @@ -846,8 +847,11 @@ describe('cmdStateAdvancePlan (state advance-plan)', () => { const updated = fs.readFileSync(path.join(tmpDir, '.planning', 'STATE.md'), 'utf-8'); assert.ok(updated.includes('**Current Plan:** 2'), 'Current Plan should be updated to 2'); assert.ok(updated.includes('**Status:** Ready to execute'), 'Status should be Ready to execute'); - const today = new Date().toISOString().split('T')[0]; - assert.ok(updated.includes(`**Last Activity:** ${today}`), 'Last Activity should be updated to today'); + const after = new Date().toISOString().split('T')[0]; + assert.ok( + updated.includes(`**Last Activity:** ${before}`) || updated.includes(`**Last Activity:** ${after}`), + `Last Activity should be today (${before}) or next day if midnight boundary (${after})` + ); }); test('marks phase complete on last plan', () => {