import { describe, it, expect, vi, beforeEach } from 'vitest'; import { createCreateCommand } from '../../src/commands/create.js'; import { createGetCommand } from '../../src/commands/get.js'; import { createDescribeCommand } from '../../src/commands/describe.js'; import { type ApiClient, ApiError } from '../../src/api-client.js'; function mockClient(): ApiClient { return { get: vi.fn(async () => []), post: vi.fn(async () => ({ id: 'new-id', name: 'test' })), put: vi.fn(async () => ({})), delete: vi.fn(async () => {}), } as unknown as ApiClient; } describe('project with new fields', () => { let client: ReturnType; let output: string[]; const log = (...args: unknown[]) => output.push(args.map(String).join(' ')); beforeEach(() => { client = mockClient(); output = []; }); describe('create project with enhanced options', () => { it('creates project with proxy mode and servers', async () => { const cmd = createCreateCommand({ client, log }); await cmd.parseAsync([ 'project', 'smart-home', '-d', 'Smart home project', '--proxy-mode', 'filtered', '--llm-provider', 'gemini-cli', '--llm-model', 'gemini-2.0-flash', '--server', 'my-grafana', '--server', 'my-ha', ], { from: 'user' }); expect(client.post).toHaveBeenCalledWith('/api/v1/projects', expect.objectContaining({ name: 'smart-home', description: 'Smart home project', proxyMode: 'filtered', llmProvider: 'gemini-cli', llmModel: 'gemini-2.0-flash', servers: ['my-grafana', 'my-ha'], })); }); it('defaults proxy mode to direct', async () => { const cmd = createCreateCommand({ client, log }); await cmd.parseAsync(['project', 'basic'], { from: 'user' }); expect(client.post).toHaveBeenCalledWith('/api/v1/projects', expect.objectContaining({ proxyMode: 'direct', })); }); }); describe('get projects shows new columns', () => { it('shows MODE and SERVERS columns', async () => { const deps = { output: [] as string[], fetchResource: vi.fn(async () => [{ id: 'proj-1', name: 'smart-home', description: 'Test', proxyMode: 'filtered', ownerId: 'user-1', servers: [{ server: { name: 'grafana' } }, { server: { name: 'ha' } }], }]), log: (...args: string[]) => deps.output.push(args.join(' ')), }; const cmd = createGetCommand(deps); await cmd.parseAsync(['node', 'test', 'projects']); const text = deps.output.join('\n'); expect(text).toContain('MODE'); expect(text).toContain('SERVERS'); expect(text).toContain('smart-home'); }); }); describe('describe project shows full detail', () => { it('shows servers and proxy config', async () => { const deps = { output: [] as string[], client: mockClient(), fetchResource: vi.fn(async () => ({ id: 'proj-1', name: 'smart-home', description: 'Smart home', proxyMode: 'filtered', llmProvider: 'gemini-cli', llmModel: 'gemini-2.0-flash', ownerId: 'user-1', servers: [ { server: { name: 'my-grafana' } }, { server: { name: 'my-ha' } }, ], createdAt: '2025-01-01', updatedAt: '2025-01-01', })), log: (...args: string[]) => deps.output.push(args.join(' ')), }; const cmd = createDescribeCommand(deps); await cmd.parseAsync(['node', 'test', 'project', 'proj-1']); const text = deps.output.join('\n'); expect(text).toContain('=== Project: smart-home ==='); expect(text).toContain('filtered'); expect(text).toContain('gemini-cli'); expect(text).toContain('my-grafana'); expect(text).toContain('my-ha'); }); }); });