import { beforeEach, describe, expect, it, vi } from 'vitest' import { fireEvent, render, screen, waitFor } from '@testing-library/react' import '@testing-library/jest-dom' import { Settings } from '../pages/Settings' import { useSettingsStore } from '../stores/settingsStore' import { useUIStore } from '../stores/uiStore' const diagnosticsApiMock = vi.hoisted(() => ({ getStatus: vi.fn(), getEvents: vi.fn(), exportBundle: vi.fn(), openLogDir: vi.fn(), clear: vi.fn(), })) vi.mock('../api/diagnostics', () => ({ diagnosticsApi: diagnosticsApiMock, })) vi.mock('../stores/providerStore', () => ({ useProviderStore: () => ({ providers: [], activeId: null, hasLoadedProviders: true, presets: [], isLoading: false, isPresetsLoading: false, fetchProviders: vi.fn(), fetchPresets: vi.fn(), deleteProvider: vi.fn(), activateProvider: vi.fn(), activateOfficial: vi.fn(), testProvider: vi.fn(), createProvider: vi.fn(), updateProvider: vi.fn(), testConfig: vi.fn(), }), })) vi.mock('../api/providers', () => ({ providersApi: { getSettings: vi.fn().mockResolvedValue({}), updateSettings: vi.fn().mockResolvedValue({}), }, })) vi.mock('../components/settings/ClaudeOfficialLogin', () => ({ ClaudeOfficialLogin: () =>
, })) vi.mock('../pages/AdapterSettings', () => ({ AdapterSettings: () => , })) vi.mock('../stores/agentStore', () => ({ useAgentStore: () => ({ activeAgents: [], allAgents: [], isLoading: false, error: null, selectedAgent: null, fetchAgents: vi.fn(), selectAgent: vi.fn(), }), })) vi.mock('../stores/skillStore', () => ({ useSkillStore: () => ({ skills: [], selectedSkill: null, isLoading: false, isDetailLoading: false, error: null, fetchSkills: vi.fn(), fetchSkillDetail: vi.fn(), clearSelection: vi.fn(), }), })) vi.mock('../components/chat/CodeViewer', () => ({ CodeViewer: ({ code }: { code: string }) =>{code},
}))
describe('Settings > Diagnostics tab', () => {
beforeEach(() => {
diagnosticsApiMock.getStatus.mockResolvedValue({
logDir: '/tmp/claude/cc-haha/diagnostics',
diagnosticsPath: '/tmp/claude/cc-haha/diagnostics/diagnostics.jsonl',
cliDiagnosticsPath: '/tmp/claude/cc-haha/diagnostics/cli-diagnostics.jsonl',
runtimeErrorsPath: '/tmp/claude/cc-haha/diagnostics/runtime-errors.log',
exportDir: '/tmp/claude/cc-haha/diagnostics/exports',
retentionDays: 7,
maxBytes: 50 * 1024 * 1024,
totalBytes: 4096,
eventCount: 2,
recentErrorCount: 1,
lastEventAt: '2026-05-02T00:00:00.000Z',
})
diagnosticsApiMock.getEvents.mockResolvedValue({
events: [{
id: 'event-1',
timestamp: '2026-05-02T00:00:00.000Z',
type: 'cli_start_failed',
severity: 'error',
summary: 'CLI exited during startup with code 1',
sessionId: 'session-1',
details: {
exitCode: 1,
capturedOutput: 'stderr:\nprovider rejected request',
},
}],
})
diagnosticsApiMock.exportBundle.mockResolvedValue({
bundle: {
path: '/tmp/claude/cc-haha/diagnostics/exports/cc-haha-diagnostics.tar.gz',
fileName: 'cc-haha-diagnostics.tar.gz',
bytes: 1024,
},
})
diagnosticsApiMock.openLogDir.mockResolvedValue({ ok: true })
diagnosticsApiMock.clear.mockResolvedValue({ ok: true })
useSettingsStore.setState({ locale: 'en' })
useUIStore.setState({ pendingSettingsTab: null, toasts: [] })
})
it('shows diagnostics status, actions, and recent events', async () => {
render(