135 lines
4.3 KiB
TypeScript
135 lines
4.3 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
import { renderHook, waitFor } from '@testing-library/react'
|
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
import { ReactNode } from 'react'
|
|
import { useRealtimeData } from '../useRealtimeData'
|
|
|
|
const mockSubscribe = vi.fn(() => vi.fn())
|
|
const mockShowInfo = vi.fn()
|
|
const mockShowWarning = vi.fn()
|
|
|
|
vi.mock('../../components/WebSocketProvider', () => ({
|
|
useWebSocketContext: () => ({
|
|
isConnected: true,
|
|
lastMessage: null,
|
|
subscribe: mockSubscribe,
|
|
}),
|
|
}))
|
|
|
|
vi.mock('../../contexts/SnackbarContext', () => ({
|
|
useSnackbar: () => ({
|
|
showInfo: mockShowInfo,
|
|
showWarning: mockShowWarning,
|
|
showError: vi.fn(),
|
|
showSuccess: vi.fn(),
|
|
}),
|
|
}))
|
|
|
|
describe('useRealtimeData', () => {
|
|
let queryClient: QueryClient
|
|
|
|
beforeEach(() => {
|
|
queryClient = new QueryClient({
|
|
defaultOptions: {
|
|
queries: { retry: false },
|
|
},
|
|
})
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
const wrapper = ({ children }: { children: ReactNode }) => (
|
|
<QueryClientProvider client= { queryClient } > { children } </QueryClientProvider>
|
|
)
|
|
|
|
it('subscribes to all message types on mount', () => {
|
|
renderHook(() => useRealtimeData(), { wrapper })
|
|
|
|
expect(mockSubscribe).toHaveBeenCalledWith('order_update', expect.any(Function))
|
|
expect(mockSubscribe).toHaveBeenCalledWith('position_update', expect.any(Function))
|
|
expect(mockSubscribe).toHaveBeenCalledWith('price_update', expect.any(Function))
|
|
expect(mockSubscribe).toHaveBeenCalledWith('alert_triggered', expect.any(Function))
|
|
expect(mockSubscribe).toHaveBeenCalledWith('strategy_signal', expect.any(Function))
|
|
expect(mockSubscribe).toHaveBeenCalledWith('system_event', expect.any(Function))
|
|
})
|
|
|
|
it('handles order update messages', async () => {
|
|
const unsubscribeMock = vi.fn()
|
|
let orderHandler: ((message: any) => void) | undefined
|
|
|
|
mockSubscribe.mockImplementation((type: string, handler: any) => {
|
|
if (type === 'order_update') {
|
|
orderHandler = handler
|
|
}
|
|
return unsubscribeMock
|
|
})
|
|
|
|
const invalidateSpy = vi.spyOn(queryClient, 'invalidateQueries')
|
|
|
|
renderHook(() => useRealtimeData(), { wrapper })
|
|
|
|
// Simulate order filled message
|
|
if (orderHandler) {
|
|
orderHandler({ type: 'order_update', order_id: '123', status: 'filled' })
|
|
}
|
|
|
|
await waitFor(() => {
|
|
expect(invalidateSpy).toHaveBeenCalledWith({ queryKey: ['orders'] })
|
|
expect(invalidateSpy).toHaveBeenCalledWith({ queryKey: ['balance'] })
|
|
})
|
|
|
|
expect(mockShowInfo).toHaveBeenCalledWith('Order 123 filled')
|
|
})
|
|
|
|
it('handles alert triggered messages', async () => {
|
|
let alertHandler: ((message: any) => void) | undefined
|
|
|
|
mockSubscribe.mockImplementation((type: string, handler: any) => {
|
|
if (type === 'alert_triggered') {
|
|
alertHandler = handler
|
|
}
|
|
return vi.fn()
|
|
})
|
|
|
|
const invalidateSpy = vi.spyOn(queryClient, 'invalidateQueries')
|
|
|
|
renderHook(() => useRealtimeData(), { wrapper })
|
|
|
|
// Simulate alert triggered
|
|
if (alertHandler) {
|
|
alertHandler({ type: 'alert_triggered', alert_name: 'BTC Price Alert' })
|
|
}
|
|
|
|
await waitFor(() => {
|
|
expect(invalidateSpy).toHaveBeenCalledWith({ queryKey: ['alerts'] })
|
|
})
|
|
|
|
expect(mockShowWarning).toHaveBeenCalledWith('Alert triggered: BTC Price Alert')
|
|
})
|
|
|
|
it('unsubscribes from all message types on unmount', () => {
|
|
const unsubscribeMocks = {
|
|
order_update: vi.fn(),
|
|
position_update: vi.fn(),
|
|
price_update: vi.fn(),
|
|
alert_triggered: vi.fn(),
|
|
strategy_signal: vi.fn(),
|
|
system_event: vi.fn(),
|
|
}
|
|
|
|
mockSubscribe.mockImplementation((type: string) => {
|
|
return unsubscribeMocks[type as keyof typeof unsubscribeMocks] || vi.fn()
|
|
})
|
|
|
|
const { unmount } = renderHook(() => useRealtimeData(), { wrapper })
|
|
|
|
unmount()
|
|
|
|
expect(unsubscribeMocks.order_update).toHaveBeenCalled()
|
|
expect(unsubscribeMocks.position_update).toHaveBeenCalled()
|
|
expect(unsubscribeMocks.price_update).toHaveBeenCalled()
|
|
expect(unsubscribeMocks.alert_triggered).toHaveBeenCalled()
|
|
expect(unsubscribeMocks.strategy_signal).toHaveBeenCalled()
|
|
expect(unsubscribeMocks.system_event).toHaveBeenCalled()
|
|
})
|
|
})
|