Path: blob/main/extensions/copilot/src/extension/chatSessions/claude/node/test/claudeRuntimeDataService.spec.ts
13406 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import type { AgentInfo, Query } from '@anthropic-ai/claude-agent-sdk';6import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';7import { ILogService } from '../../../../../platform/log/common/logService';8import { mock } from '../../../../../util/common/test/simpleMock';9import { DisposableStore } from '../../../../../util/vs/base/common/lifecycle';10import { ClaudeRuntimeDataService } from '../claudeRuntimeDataService';1112class TestLogService extends mock<ILogService>() {13override trace() { }14override error() { }15}1617function createMockQuery(agents: AgentInfo[]): Pick<Query, 'supportedAgents'> {18return {19supportedAgents: vi.fn().mockResolvedValue(agents),20};21}2223describe('ClaudeRuntimeDataService', () => {24let disposables: DisposableStore;25let service: ClaudeRuntimeDataService;2627beforeEach(() => {28disposables = new DisposableStore();29service = disposables.add(new ClaudeRuntimeDataService(new TestLogService()));30});3132afterEach(() => {33disposables.dispose();34});3536it('returns empty agents before first update', () => {37expect(service.getAgents()).toEqual([]);38});3940it('caches agents after update', async () => {41const agents: AgentInfo[] = [42{ name: 'Explore', description: 'Fast exploration' },43{ name: 'Review', description: 'Code review', model: 'claude-3.5-sonnet' },44];45await service.update(createMockQuery(agents) as Query);4647expect(service.getAgents()).toEqual(agents);48});4950it('fires onDidChange after update', async () => {51let fired = false;52disposables.add(service.onDidChange(() => { fired = true; }));5354await service.update(createMockQuery([]) as Query);55expect(fired).toBe(true);56});5758it('fires onDidChange even when supportedAgents fails', async () => {59let fired = false;60disposables.add(service.onDidChange(() => { fired = true; }));6162const query = {63supportedAgents: vi.fn().mockRejectedValue(new Error('SDK error')),64};65await service.update(query as unknown as Query);6667expect(fired).toBe(true);68// Previous cache should be preserved (empty in this case)69expect(service.getAgents()).toEqual([]);70});7172it('preserves previous cache on error', async () => {73const agents: AgentInfo[] = [{ name: 'Explore', description: 'Agent' }];74await service.update(createMockQuery(agents) as Query);7576const failingQuery = {77supportedAgents: vi.fn().mockRejectedValue(new Error('fail')),78};79await service.update(failingQuery as unknown as Query);8081expect(service.getAgents()).toEqual(agents);82});8384it('overwrites cache on subsequent updates', async () => {85await service.update(createMockQuery([{ name: 'A', description: 'First' }]) as Query);86expect(service.getAgents()).toHaveLength(1);8788await service.update(createMockQuery([{ name: 'B', description: 'Second' }, { name: 'C', description: 'Third' }]) as Query);89expect(service.getAgents()).toHaveLength(2);90expect(service.getAgents()[0].name).toBe('B');91});92});939495