197 lines
5.7 KiB
TypeScript
197 lines
5.7 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
import { render, screen, waitFor, fireEvent } from '@testing-library/react'
|
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
import DashboardPage from '../DashboardPage'
|
|
import * as autopilotApi from '../../api/autopilot'
|
|
import { AutopilotSettingsProvider } from '../../contexts/AutopilotSettingsContext'
|
|
import { BrowserRouter } from 'react-router-dom'
|
|
|
|
vi.mock('../../api/autopilot')
|
|
vi.mock('../../api/trading')
|
|
vi.mock('../../api/marketData')
|
|
vi.mock('../../api/strategies')
|
|
vi.mock('../../components/WebSocketProvider', () => ({
|
|
useWebSocketContext: () => ({ isConnected: true, lastMessage: null, subscribe: vi.fn(() => vi.fn()) }),
|
|
}))
|
|
vi.mock('../../contexts/SnackbarContext', () => ({
|
|
useSnackbar: () => ({
|
|
showError: vi.fn(),
|
|
showSuccess: vi.fn(),
|
|
showWarning: vi.fn(),
|
|
showInfo: vi.fn(),
|
|
}),
|
|
}))
|
|
|
|
describe('DashboardPage - Autopilot Section', () => {
|
|
let queryClient: QueryClient
|
|
|
|
beforeEach(() => {
|
|
queryClient = new QueryClient({
|
|
defaultOptions: { queries: { retry: false } },
|
|
})
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
// Helper to wrap component with all required providers
|
|
const renderDashboard = () => {
|
|
return render(
|
|
<QueryClientProvider client={queryClient}>
|
|
<BrowserRouter>
|
|
<AutopilotSettingsProvider>
|
|
<DashboardPage />
|
|
</AutopilotSettingsProvider>
|
|
</BrowserRouter>
|
|
</QueryClientProvider>
|
|
)
|
|
}
|
|
|
|
it('renders autopilot configuration section', async () => {
|
|
const mockModeInfo = {
|
|
modes: {
|
|
pattern: { name: 'Pattern-Based', description: 'Test' },
|
|
intelligent: { name: 'ML-Based', description: 'Test' },
|
|
},
|
|
comparison: {},
|
|
}
|
|
|
|
vi.mocked(autopilotApi.autopilotApi.getModes).mockResolvedValue(mockModeInfo as any)
|
|
|
|
renderDashboard()
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Autopilot Configuration')).toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
it('displays mode selector', async () => {
|
|
const mockModeInfo = {
|
|
modes: {
|
|
pattern: { name: 'Pattern-Based', description: 'Test' },
|
|
intelligent: { name: 'ML-Based', description: 'Test' },
|
|
},
|
|
comparison: {},
|
|
}
|
|
|
|
vi.mocked(autopilotApi.autopilotApi.getModes).mockResolvedValue(mockModeInfo as any)
|
|
|
|
renderDashboard()
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Select Autopilot Mode')).toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
it('shows auto-execute toggle', async () => {
|
|
const mockModeInfo = {
|
|
modes: {
|
|
pattern: { name: 'Pattern-Based', description: 'Test' },
|
|
intelligent: { name: 'ML-Based', description: 'Test' },
|
|
},
|
|
comparison: {},
|
|
}
|
|
|
|
vi.mocked(autopilotApi.autopilotApi.getModes).mockResolvedValue(mockModeInfo as any)
|
|
|
|
renderDashboard()
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText(/Auto-Execute/)).toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
it('shows start button when autopilot is not running', async () => {
|
|
const mockModeInfo = {
|
|
modes: {
|
|
pattern: { name: 'Pattern-Based', description: 'Test' },
|
|
intelligent: { name: 'ML-Based', description: 'Test' },
|
|
},
|
|
comparison: {},
|
|
}
|
|
|
|
vi.mocked(autopilotApi.autopilotApi.getModes).mockResolvedValue(mockModeInfo as any)
|
|
vi.mocked(autopilotApi.autopilotApi.getUnifiedStatus).mockResolvedValue({
|
|
running: false,
|
|
mode: 'pattern',
|
|
} as any)
|
|
|
|
renderDashboard()
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Start AutoPilot')).toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
it('shows stop button when autopilot is running', async () => {
|
|
const mockModeInfo = {
|
|
modes: {
|
|
pattern: { name: 'Pattern-Based', description: 'Test' },
|
|
intelligent: { name: 'ML-Based', description: 'Test' },
|
|
},
|
|
comparison: {},
|
|
}
|
|
|
|
vi.mocked(autopilotApi.autopilotApi.getModes).mockResolvedValue(mockModeInfo as any)
|
|
vi.mocked(autopilotApi.autopilotApi.getUnifiedStatus).mockResolvedValue({
|
|
running: true,
|
|
mode: 'pattern',
|
|
} as any)
|
|
|
|
renderDashboard()
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Stop AutoPilot')).toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
it('calls startUnified when start button is clicked', async () => {
|
|
const mockModeInfo = {
|
|
modes: {
|
|
pattern: { name: 'Pattern-Based', description: 'Test' },
|
|
intelligent: { name: 'ML-Based', description: 'Test' },
|
|
},
|
|
comparison: {},
|
|
}
|
|
|
|
const startUnifiedMock = vi.fn().mockResolvedValue({ status: 'started' })
|
|
vi.mocked(autopilotApi.autopilotApi.getModes).mockResolvedValue(mockModeInfo as any)
|
|
vi.mocked(autopilotApi.autopilotApi.getUnifiedStatus).mockResolvedValue({
|
|
running: false,
|
|
mode: 'pattern',
|
|
} as any)
|
|
vi.mocked(autopilotApi.autopilotApi.startUnified).mockImplementation(startUnifiedMock)
|
|
|
|
renderDashboard()
|
|
|
|
await waitFor(() => {
|
|
const startButton = screen.getByText('Start AutoPilot')
|
|
fireEvent.click(startButton)
|
|
})
|
|
|
|
await waitFor(() => {
|
|
expect(startUnifiedMock).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
it('displays current mode in status chip', async () => {
|
|
const mockModeInfo = {
|
|
modes: {
|
|
pattern: { name: 'Pattern-Based', description: 'Test' },
|
|
intelligent: { name: 'ML-Based', description: 'Test' },
|
|
},
|
|
comparison: {},
|
|
}
|
|
|
|
vi.mocked(autopilotApi.autopilotApi.getModes).mockResolvedValue(mockModeInfo as any)
|
|
vi.mocked(autopilotApi.autopilotApi.getUnifiedStatus).mockResolvedValue({
|
|
running: true,
|
|
mode: 'intelligent',
|
|
} as any)
|
|
|
|
renderDashboard()
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText(/AutoPilot Active \(intelligent\)/)).toBeInTheDocument()
|
|
})
|
|
})
|
|
})
|