import { describe, expect, it } from 'vitest'; import type { CodingProjectAgent, CodingProjectConfig, } from '../../shared/coding-project-contracts'; import { hasReadyCodingProjectAgent, isCodingProjectAgentReady, isCodingProjectConversationReady, } from '../../shared/coding-project-contracts'; const createdAt = '2026-09-06T00:00:00.000Z'; function createAgent(overrides: Partial = {}): CodingProjectAgent { return { id: 'agent-1', avatarId: 'spark', roleName: '编程助手', name: '小洛', builtIn: false, enabled: true, skillIds: [], responsibility: { mission: '帮助完成项目', owns: [], boundaries: [], collaborators: [], principles: [], }, prompt: '', archivedAt: null, pinned: false, model: { accountId: 'account-1', modelId: 'model-1', thinkingLevel: 'off', }, modelResolution: 'resolved', createdAt, updatedAt: createdAt, ...overrides, }; } function createConfig(overrides: Partial = {}): CodingProjectConfig { return { schemaVersion: 2, projectType: 'custom', initialized: true, agents: [createAgent()], knowledgeDirectory: 'knowledge', createdAt, updatedAt: createdAt, ...overrides, }; } describe('coding project Conversation readiness', () => { it('accepts an enabled, unarchived, fully configured Agent', () => { const agent = createAgent(); const config = createConfig({ agents: [agent] }); expect(isCodingProjectAgentReady(agent)).toBe(true); expect(hasReadyCodingProjectAgent(config)).toBe(true); expect(isCodingProjectConversationReady(config)).toBe(true); }); it('rejects a project with no Agents', () => { const config = createConfig({ agents: [] }); expect(hasReadyCodingProjectAgent(config)).toBe(false); expect(isCodingProjectConversationReady(config)).toBe(false); }); it.each([ ['disabled', { enabled: false }], ['archived', { archivedAt: createdAt }], ] satisfies Array<[string, Partial]>)('rejects a %s Agent', (_label, overrides) => { const agent = createAgent(overrides); expect(isCodingProjectAgentReady(agent)).toBe(false); }); it('rejects an Agent whose model still requires resolution', () => { const agent = createAgent({ model: null, modelResolution: 'required' }); expect(isCodingProjectAgentReady(agent)).toBe(false); }); it('rejects an Agent with a resolved but missing model', () => { const agent = createAgent({ model: null }); expect(isCodingProjectAgentReady(agent)).toBe(false); }); it('rejects an Agent with an empty responsibility mission', () => { const agent = createAgent({ responsibility: { ...createAgent().responsibility, mission: ' ', }, }); expect(isCodingProjectAgentReady(agent)).toBe(false); }); it('requires the project to be initialized', () => { const config = createConfig({ initialized: false }); expect(hasReadyCodingProjectAgent(config)).toBe(true); expect(isCodingProjectConversationReady(config)).toBe(false); }); });