mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-01 13:53:54 +08:00
feat: add Discuss and Explore subagents for dynamic critique and code exploration
- Implement Discuss Subagent for multi-perspective critique with dynamic perspectives. - Create Explore Subagent for shared codebase exploration with centralized caching. - Add tests for CcwToolsMcpCard component to ensure enabled tools are preserved on config save. - Introduce SessionPreviewPanel component for previewing and selecting sessions for Memory V2 extraction. - Develop CommandCreateDialog component for creating/importing commands with import and CLI generate modes.
This commit is contained in:
102
ccw/frontend/src/components/mcp/CcwToolsMcpCard.test.tsx
Normal file
102
ccw/frontend/src/components/mcp/CcwToolsMcpCard.test.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
// ========================================
|
||||
// CcwToolsMcpCard Component Tests
|
||||
// ========================================
|
||||
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||
import { render, screen, waitFor } from '@/test/i18n';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
import { CcwToolsMcpCard } from './CcwToolsMcpCard';
|
||||
import { updateCcwConfig, updateCcwConfigForCodex } from '@/lib/api';
|
||||
|
||||
vi.mock('@/lib/api', () => ({
|
||||
installCcwMcp: vi.fn(),
|
||||
uninstallCcwMcp: vi.fn(),
|
||||
updateCcwConfig: vi.fn(),
|
||||
installCcwMcpToCodex: vi.fn(),
|
||||
uninstallCcwMcpFromCodex: vi.fn(),
|
||||
updateCcwConfigForCodex: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('@/hooks/useNotifications', () => ({
|
||||
useNotifications: () => ({
|
||||
success: vi.fn(),
|
||||
error: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
describe('CcwToolsMcpCard', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('preserves enabledTools when saving config (Codex)', async () => {
|
||||
const updateCodexMock = vi.mocked(updateCcwConfigForCodex);
|
||||
updateCodexMock.mockResolvedValue({
|
||||
isInstalled: true,
|
||||
enabledTools: [],
|
||||
installedScopes: ['global'],
|
||||
});
|
||||
|
||||
render(
|
||||
<CcwToolsMcpCard
|
||||
target="codex"
|
||||
isInstalled={true}
|
||||
enabledTools={['write_file', 'read_many_files']}
|
||||
onToggleTool={vi.fn()}
|
||||
onUpdateConfig={vi.fn()}
|
||||
onInstall={vi.fn()}
|
||||
/>,
|
||||
{ locale: 'en' }
|
||||
);
|
||||
|
||||
const user = userEvent.setup();
|
||||
await user.click(screen.getByText(/CCW MCP Server|mcp\.ccw\.title/i));
|
||||
await user.click(
|
||||
screen.getByRole('button', { name: /Save Configuration|mcp\.ccw\.actions\.saveConfig/i })
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(updateCodexMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
enabledTools: ['write_file', 'read_many_files'],
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('preserves enabledTools when saving config (Claude)', async () => {
|
||||
const updateClaudeMock = vi.mocked(updateCcwConfig);
|
||||
updateClaudeMock.mockResolvedValue({
|
||||
isInstalled: true,
|
||||
enabledTools: [],
|
||||
installedScopes: ['global'],
|
||||
});
|
||||
|
||||
render(
|
||||
<CcwToolsMcpCard
|
||||
isInstalled={true}
|
||||
enabledTools={['write_file', 'smart_search']}
|
||||
onToggleTool={vi.fn()}
|
||||
onUpdateConfig={vi.fn()}
|
||||
onInstall={vi.fn()}
|
||||
/>,
|
||||
{ locale: 'en' }
|
||||
);
|
||||
|
||||
const user = userEvent.setup();
|
||||
await user.click(screen.getByText(/CCW MCP Server|mcp\.ccw\.title/i));
|
||||
await user.click(
|
||||
screen.getByRole('button', { name: /Save Configuration|mcp\.ccw\.actions\.saveConfig/i })
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(updateClaudeMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
enabledTools: ['write_file', 'smart_search'],
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user