import '@testing-library/jest-dom'; import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import Customers from '../../pages/Customers'; import { createMockCustomersList, renderWithProviders } from '../setup/helpers'; jest.mock('../../features/customers/customersApi', () => ({ useGetCustomersQuery: jest.fn(), })); const { useGetCustomersQuery, } = require('../../features/customers/customersApi'); const mockData = createMockCustomersList(3); describe('Customers', () => { afterEach(() => { jest.clearAllMocks(); }); function setupLoaded(data = mockData) { useGetCustomersQuery.mockReturnValue({ data, isLoading: false, isFetching: false, }); } describe('Rendering', () => { it('renders page heading and subtitle', () => { setupLoaded(); renderWithProviders(); expect(screen.getByText('Customers')).toBeInTheDocument(); expect( screen.getByText( 'Customers who used at least one Disco campaign' ) ).toBeInTheDocument(); }); it('renders customer names', () => { setupLoaded(); renderWithProviders(); expect(screen.getByText('Customer 1')).toBeInTheDocument(); expect(screen.getByText('Customer 2')).toBeInTheDocument(); }); it('renders customer emails', () => { setupLoaded(); renderWithProviders(); expect( screen.getByText('customer1@example.com') ).toBeInTheDocument(); }); it('renders table headers', () => { setupLoaded(); renderWithProviders(); expect(screen.getByText('Customer')).toBeInTheDocument(); expect(screen.getByText('State')).toBeInTheDocument(); expect(screen.getByText('Campaigns Used')).toBeInTheDocument(); expect(screen.getByText(/Orders/)).toBeInTheDocument(); expect(screen.getByText(/Spent/)).toBeInTheDocument(); }); }); describe('Loading states', () => { it('shows loading skeletons', () => { useGetCustomersQuery.mockReturnValue({ data: undefined, isLoading: true, isFetching: true, }); const { container } = renderWithProviders(); const pulseElements = container.querySelectorAll( '.disco\\:animate-pulse' ); expect(pulseElements.length).toBeGreaterThan(0); }); }); describe('Empty states', () => { it('shows empty state when no customers', () => { useGetCustomersQuery.mockReturnValue({ data: { data: [], collection: { count: 0, total: 0, total_pages: 1 }, }, isLoading: false, isFetching: false, }); renderWithProviders(); expect( screen.getByText('Customers Not Found!') ).toBeInTheDocument(); }); }); describe('Sorting', () => { it('default sort is by spent descending', () => { setupLoaded(); renderWithProviders(); const firstCall = useGetCustomersQuery.mock.calls[0][0]; expect(firstCall.sort_by).toBe('total_spent'); expect(firstCall.order).toBe('desc'); }); }); describe('Search', () => { it('resets page and passes search to hook', async () => { setupLoaded(); const user = userEvent.setup(); renderWithProviders(); const searchInput = screen.getByPlaceholderText( 'Search Customers...' ); await user.type(searchInput, 'jane'); const lastCall = useGetCustomersQuery.mock.calls.at(-1)[0]; expect(lastCall.search).toBe('jane'); expect(lastCall.page).toBe(1); }); }); });