import { getPortfolios } from '@/api/getPortfolios'; import type { Portfolio, PortfolioTokenWithFiatValue } from '@/api/types'; import { RequestContext } from '@/core/network/constants'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { renderHook, waitFor } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { usePortfolio } from './usePortfolio'; vi.mock('@/api/getPortfolios'); const mockAddress: `0x${string}` = '0x123'; const mockTokens: PortfolioTokenWithFiatValue[] = [ { address: '0x123', chainId: 8453, decimals: 6, image: '', name: 'Token', symbol: 'TOKEN', cryptoBalance: 100, fiatBalance: 100, }, ]; const mockPortfolio: Portfolio = { address: mockAddress, portfolioBalanceInUsd: 100, tokenBalances: mockTokens, }; const createWrapper = () => { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, }, }, }); const TestWrapper = ({ children }: { children: React.ReactNode }) => ( {children} ); TestWrapper.displayName = 'TestWrapper'; return TestWrapper; }; describe('usePortfolio', () => { beforeEach(() => { vi.clearAllMocks(); }); it('should fetch token balances successfully', async () => { vi.mocked(getPortfolios).mockResolvedValueOnce({ portfolios: [mockPortfolio], }); const { result } = renderHook( () => usePortfolio({ address: mockAddress }), { wrapper: createWrapper() }, ); expect(result.current.isLoading).toBe(true); await waitFor(() => expect(result.current.isSuccess).toBe(true)); expect(getPortfolios).toHaveBeenCalledWith( { addresses: [mockAddress], }, RequestContext.Hook, ); expect(result.current.data).toEqual(mockPortfolio); }); it('should handle API errors', async () => { vi.mocked(getPortfolios).mockResolvedValueOnce({ code: 'API Error', error: 'API Error', message: 'API Error', }); const { result } = renderHook( () => usePortfolio({ address: mockAddress }), { wrapper: createWrapper() }, ); await waitFor(() => expect(result.current.isError).toBe(true)); expect(result.current.error).toBeInstanceOf(Error); expect(result.current.error?.message).toBe('API Error'); }); it('should not fetch when address is empty', () => { renderHook(() => usePortfolio({ address: '' as `0x${string}` }), { wrapper: createWrapper(), }); expect(getPortfolios).not.toHaveBeenCalled(); }); it('should not fetch when enabled is false', () => { renderHook(() => usePortfolio({ address: mockAddress, enabled: false }), { wrapper: createWrapper(), }); expect(getPortfolios).not.toHaveBeenCalled(); }); it('should not fetch when address is undefined', () => { renderHook(() => usePortfolio({ address: undefined }), { wrapper: createWrapper(), }); expect(getPortfolios).not.toHaveBeenCalled(); }); it('should return empty data when portfolios is empty', async () => { vi.mocked(getPortfolios).mockResolvedValueOnce({ portfolios: [], }); const { result } = renderHook( () => usePortfolio({ address: mockAddress }), { wrapper: createWrapper() }, ); await waitFor(() => expect(result.current.isSuccess).toBe(true)); expect(result.current.data).toEqual({ address: '0x123', portfolioBalanceInUsd: 0, tokenBalances: [], }); }); });