import '@testing-library/jest-dom'; import { screen } from '@testing-library/react'; import Dashboard from '../../pages/Dashboard'; import { renderWithProviders } from '../setup/helpers'; // Mock Recharts — it requires a real DOM measurement layer jest.mock('recharts', () => { const OriginalModule = jest.requireActual('recharts'); return { ...OriginalModule, ResponsiveContainer: ({ children }) => (
{children}
), LineChart: ({ children }) => (
{children}
), PieChart: ({ children }) => (
{children}
), Line: () => null, Pie: ({ children }) =>
{children}
, Cell: () => null, CartesianGrid: () => null, XAxis: () => null, YAxis: () => null, Tooltip: () => null, Legend: () => null, }; }); // Mock RTK Query hooks to control data states jest.mock('../../features/summary/summaryApi', () => ({ useGetSummaryQuery: jest.fn(), useGetRevenueChartQuery: jest.fn(), useGetIntentsPerformanceQuery: jest.fn(), })); jest.mock('../../features/campaigns/campaignsApi', () => ({ useGetCampaignsQuery: jest.fn(), })); jest.mock('../../features/products/productsApi', () => ({ useGetProductsQuery: jest.fn(), })); const { useGetSummaryQuery, useGetRevenueChartQuery, useGetIntentsPerformanceQuery, } = require('../../features/summary/summaryApi'); const { useGetCampaignsQuery, } = require('../../features/campaigns/campaignsApi'); const { useGetProductsQuery } = require('../../features/products/productsApi'); // Helper to set all hooks to a specific state function setHooksState(state) { const hookReturn = { data: undefined, isLoading: false, isFetching: false, ...state, }; useGetSummaryQuery.mockReturnValue(hookReturn); useGetRevenueChartQuery.mockReturnValue(hookReturn); useGetIntentsPerformanceQuery.mockReturnValue(hookReturn); useGetCampaignsQuery.mockReturnValue(hookReturn); useGetProductsQuery.mockReturnValue(hookReturn); } describe('Dashboard', () => { afterEach(() => { jest.clearAllMocks(); }); describe('Rendering', () => { it('renders the dashboard heading', () => { setHooksState({ isLoading: true }); renderWithProviders(); expect(screen.getByText('Analytics Dashboard')).toBeInTheDocument(); }); it('renders all summary card titles', () => { useGetSummaryQuery.mockReturnValue({ data: { data: { active_campaigns: { current: 12, trend: 'up', change_percent: 10, }, net_sales: { current: 45000, trend: 'up', change_percent: 18.6, }, discount_sales: { current: 12000, trend: 'up', change_percent: 22, }, total_orders: { current: 342, trend: 'up', change_percent: 17.9, }, disco_orders: { current: 156, trend: 'down', change_percent: -13, }, customers: { current: 98, trend: 'up', change_percent: 15, }, }, }, isLoading: false, isFetching: false, }); useGetRevenueChartQuery.mockReturnValue({ data: { data: [], interval: 'day' }, isLoading: false, }); useGetIntentsPerformanceQuery.mockReturnValue({ data: { data: [ { intent: 'Product', revenue: 1000, orders: 10, percentage: 100, }, ], total_revenue: 1000, }, isLoading: false, }); useGetCampaignsQuery.mockReturnValue({ data: { data: [ { campaign_id: 1, campaign_name: 'Sale', revenue: 5000, }, ], }, isLoading: false, isFetching: false, }); useGetProductsQuery.mockReturnValue({ data: { data: [ { id: 1, name: 'Prod', image: '', total_revenue: 3000 }, ], }, isLoading: false, isFetching: false, }); renderWithProviders(); expect(screen.getByText('Active Campaigns')).toBeInTheDocument(); expect(screen.getByText('Net Sale')).toBeInTheDocument(); expect(screen.getByText('Discount Sale')).toBeInTheDocument(); expect(screen.getByText('Total Orders')).toBeInTheDocument(); expect( screen.getByText('Orders with Discount') ).toBeInTheDocument(); expect(screen.getByText('Customers')).toBeInTheDocument(); }); it('renders chart sections', () => { useGetSummaryQuery.mockReturnValue({ data: { data: {} }, isLoading: false, isFetching: false, }); useGetRevenueChartQuery.mockReturnValue({ data: { data: [ { date: '2025-05-01', net_sales: 1000, discount_sales: 300, }, ], interval: 'day', }, isLoading: false, }); useGetIntentsPerformanceQuery.mockReturnValue({ data: { data: [ { intent: 'Product', revenue: 5000, orders: 50, percentage: 100, }, ], total_revenue: 5000, }, isLoading: false, }); useGetCampaignsQuery.mockReturnValue({ data: { data: [ { campaign_id: 1, campaign_name: 'Sale A', revenue: 5000, }, ], }, isLoading: false, isFetching: false, }); useGetProductsQuery.mockReturnValue({ data: { data: [ { id: 1, name: 'Prod A', image: '', total_revenue: 3000, }, ], }, isLoading: false, isFetching: false, }); renderWithProviders(); expect(screen.getByText('Revenue over time')).toBeInTheDocument(); expect(screen.getByText('Revenue by intent')).toBeInTheDocument(); }); it('renders top campaigns and top products sections', () => { useGetSummaryQuery.mockReturnValue({ data: { data: {} }, isLoading: false, isFetching: false, }); useGetRevenueChartQuery.mockReturnValue({ data: { data: [], interval: 'day' }, isLoading: false, }); useGetIntentsPerformanceQuery.mockReturnValue({ data: { data: [ { intent: 'Product', revenue: 1000, orders: 10, percentage: 100, }, ], total_revenue: 1000, }, isLoading: false, }); useGetCampaignsQuery.mockReturnValue({ data: { data: [ { campaign_id: 1, campaign_name: 'Sale A', revenue: 5000, }, ], }, isLoading: false, isFetching: false, }); useGetProductsQuery.mockReturnValue({ data: { data: [ { id: 1, name: 'Prod A', image: '', total_revenue: 3000, }, ], }, isLoading: false, isFetching: false, }); renderWithProviders(); expect(screen.getByText('Top campaigns')).toBeInTheDocument(); expect( screen.getByText('Top products by revenue') ).toBeInTheDocument(); }); }); describe('Loading states', () => { it('shows loading skeletons for all sections', () => { setHooksState({ isLoading: true }); const { container } = renderWithProviders(); const pulseElements = container.querySelectorAll( '.disco\\:animate-pulse' ); expect(pulseElements.length).toBeGreaterThan(0); }); }); describe('Empty states', () => { it('shows empty state when campaigns data is empty', () => { useGetSummaryQuery.mockReturnValue({ data: { data: {} }, isLoading: false, isFetching: false, }); useGetRevenueChartQuery.mockReturnValue({ data: { data: [], interval: 'day' }, isLoading: false, }); useGetIntentsPerformanceQuery.mockReturnValue({ data: { data: [ { intent: 'Product', revenue: 0, orders: 0, percentage: 0, }, ], total_revenue: 0, }, isLoading: false, }); useGetCampaignsQuery.mockReturnValue({ data: { data: [] }, isLoading: false, isFetching: false, }); useGetProductsQuery.mockReturnValue({ data: { data: [] }, isLoading: false, isFetching: false, }); renderWithProviders(); // Empty state for campaigns/products expect(screen.getAllByText(/Not Found!/i).length).toBeGreaterThan(0); }); }); });