Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DESENG-483: Added Unit test for Public Dashboard
Browse files Browse the repository at this point in the history
ratheesh-aot committed Feb 22, 2024
1 parent 91edcd9 commit ba96181
Showing 5 changed files with 343 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React from 'react';
import { render, waitFor, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import ProjectLocation from 'components/publicDashboard/KPI/ProjectLocation';
import * as mapService from 'services/analytics/mapService';
import { closedEngagement } from '../factory';

jest.mock('@mui/material', () => ({
...jest.requireActual('@mui/material'),
useMediaQuery: jest.fn(() => true),
}));

jest.mock('components/map', () => () => <div>Mocked Map Component</div>);

const mockEngagement = closedEngagement;

const getMapDataMock = jest.spyOn(mapService, 'getMapData');

describe('ProjectLocation Component Tests', () => {
const mockHandleProjectMapData = jest.fn();

beforeEach(() => {
jest.resetAllMocks();
});

test('displays loading indicator while fetching data', () => {
getMapDataMock.mockReturnValue(new Promise(() => { }));
render(
<ProjectLocation
engagement={mockEngagement}
engagementIsLoading={true}
handleProjectMapData={mockHandleProjectMapData}
/>,
);
expect(screen.getByRole('progressbar')).toBeInTheDocument();
});

test('renders map correctly on successful data fetch', async () => {

const geoJson = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {
name: 'Example Point',
},
geometry: {
type: 'Point',
coordinates: [-123.3656, 48.4284],
},
},
],
};

const mockData = {
latitude: 123,
longitude: 456,
geojson: JSON.stringify(geoJson),
marker_label: 'Test Location',
};
getMapDataMock.mockResolvedValue(mockData);
render(
<ProjectLocation
engagement={mockEngagement}
engagementIsLoading={false}
handleProjectMapData={mockHandleProjectMapData}
/>,
);
await waitFor(() => {
expect(screen.getByText('Mocked Map Component')).toBeInTheDocument();
});
});

test('displays error message on fetch failure', async () => {
getMapDataMock.mockRejectedValue(new Error('Fetch Error'));
render(
<ProjectLocation
engagement={mockEngagement}
engagementIsLoading={false}
handleProjectMapData={mockHandleProjectMapData}
/>,
);
await waitFor(() => {
expect(screen.getByText('Error')).toBeInTheDocument();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { render, waitFor, screen } from '@testing-library/react';
import React from 'react';
import '@testing-library/jest-dom';
import Dashboard from 'components/publicDashboard/Dashboard';
import { setupEnv } from '../setEnvVars';
import { DashboardContext } from 'components/publicDashboard/DashboardContext';
import * as reactRedux from 'react-redux';
import { closedEngagement } from '../factory';
import userEvent from '@testing-library/user-event';
import { BrowserRouter } from 'react-router-dom';

jest.mock('axios');
jest.mock('components/common', () => ({
...jest.requireActual('components/common'),
PrimaryButton: ({ children, ...rest }: { children: React.ReactNode }) => {
return <button {...rest}>{children}</button>;
},
}));

jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useLocation: jest.fn(() => ({ search: '' })),
useParams: jest.fn(() => {
return { slug: '' };
}),
useNavigate: () => jest.fn(),
}));

jest.mock('hooks', () => ({
useAppTranslation: () => ({
t: (key: string) => key, // return the key itself
}),
useAppSelector: jest.fn(() => true),
}));

jest.mock('@mui/material', () => ({
...jest.requireActual('@mui/material'),
useMediaQuery: jest.fn(() => true),
}));

jest.mock('maplibre-gl/dist/maplibre-gl', () => ({
Map: () => ({}),
}));

describe('Public Dashboard page tests', () => {
jest.spyOn(reactRedux, 'useDispatch').mockImplementation(() => jest.fn());
beforeEach(() => {
setupEnv();
render(
<BrowserRouter>
<DashboardContext.Provider
value={{
engagement: closedEngagement,
isEngagementLoading: false,
dashboardType: 'public',
}}
>
<Dashboard />
</DashboardContext.Provider>
</BrowserRouter>,
);
});

test('Public Dashboard is rendered correctly', async () => {
await waitFor(() => {
const elements = screen.getAllByText(closedEngagement.name);
expect(elements.length).toBeGreaterThan(1);
});
});

test('Navigation links work correctly', async () => {
const returnLink = screen.getByText(`<< Return to ${closedEngagement.name} Engagement`);
expect(returnLink).toBeInTheDocument();
userEvent.click(returnLink);
expect(window.location.pathname).toBe(`/engagements/${closedEngagement.id}/view`);
});

test('Public Dashboard has sub components', async () => {
expect(screen.getByText('Survey Emails Sent')).toBeInTheDocument();
expect(screen.getByText('Surveys Completed')).toBeInTheDocument();
expect(screen.getByText('Project Location')).toBeInTheDocument();
expect(screen.getByText('Live Activity - Engagement')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from 'react';
import { render, waitFor, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import SubmissionTrend from 'components/publicDashboard/SubmissionTrend/SubmissionTrend';
import * as userResponseDetailService from 'services/analytics/userResponseDetailService';
import { closedEngagement } from '../factory';
import { UserResponseDetailByMonth } from 'models/analytics/userResponseDetail';

jest.mock('@mui/material', () => ({
...jest.requireActual('@mui/material'),
useMediaQuery: jest.fn(() => false),
}));

// Setting the mock ResizeObserver on the global window object
window.ResizeObserver = jest.fn().mockImplementation(() => {
return {
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn(),
};
});

const mockEngagement = closedEngagement;

const getMonthlyDataMock = jest.spyOn(userResponseDetailService, 'getUserResponseDetailByMonth');

describe('SubmissionTrend Component Tests', () => {

test('displays loading indicator while fetching data', () => {
getMonthlyDataMock.mockReturnValueOnce(
Promise.resolve({
showdataby: '',
responses: 0,
}),
);
render(<SubmissionTrend engagement={mockEngagement} engagementIsLoading={true} />);
expect(screen.getByRole('progressbar')).toBeInTheDocument();
});

test('renders correctly on successful monthly data fetch', async () => {
const mockData: UserResponseDetailByMonth = { showdataby: 'January', responses: 100 };
getMonthlyDataMock.mockResolvedValue(Promise.resolve(mockData));
render(<SubmissionTrend engagement={mockEngagement} engagementIsLoading={false} />);
await waitFor(() => {
expect(screen.getByText('Select Date Range')).toBeInTheDocument();
// Check if the "Weekly" toggle button is present
const weeklyToggleButton = screen.getByText('Weekly');
expect(weeklyToggleButton).toBeInTheDocument();

// Check if the "Monthly" toggle button is present
const monthlyToggleButton = screen.getByText('Monthly');
expect(monthlyToggleButton).toBeInTheDocument();

// Check if the "Reset All Filters" toggle button is present
const resetFilterButton = screen.getByText('Reset All Filters');
expect(resetFilterButton).toBeInTheDocument();
});
});

test('displays error message on fetch failure', async () => {
getMonthlyDataMock.mockRejectedValue(new Error('Fetch Error'));
render(<SubmissionTrend engagement={mockEngagement} engagementIsLoading={false} />);
await waitFor(() => {
expect(screen.getByText('No Data Available')).toBeInTheDocument();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import { render, waitFor, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import SurveyEmailsSent from 'components/publicDashboard/KPI/SurveyEmailsSent';
import * as aggregatorService from 'services/analytics/aggregatorService';
import { closedEngagement } from '../factory';

jest.mock('@mui/material', () => ({
...jest.requireActual('@mui/material'),
useMediaQuery: jest.fn(() => true),
}));
const mockEngagement = closedEngagement;

const renderComponent = () => {
render(<SurveyEmailsSent engagement={mockEngagement} engagementIsLoading={false} />);
};

describe('SurveyEmailsSent Component Tests', () => {
const getAggregatorMock = jest.spyOn(aggregatorService, 'getAggregatorData');

test('displays loading indicator while fetching data', () => {
getAggregatorMock.mockReturnValueOnce(
Promise.resolve({
key: '',
value: 0,
}),
);
render(<SurveyEmailsSent engagement={mockEngagement} engagementIsLoading={true} />);
expect(screen.getByRole('progressbar')).toBeInTheDocument();
});

test('displays data correctly on successful fetch', async () => {
const mockData = { key: 'email_verification', value: 200 };
getAggregatorMock.mockReturnValueOnce(Promise.resolve(mockData));
renderComponent();
await waitFor(() => {
expect(screen.getByText(mockData.value.toString())).toBeInTheDocument();
});
});

test('displays error message on fetch failure', async () => {
getAggregatorMock.mockRejectedValue(new Error('Fetch Error'));
renderComponent();
await waitFor(() => {
expect(screen.getByText('No Data Available')).toBeInTheDocument();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import { render, waitFor, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import SurveysCompleted from 'components/publicDashboard/KPI/SurveysCompleted';
import * as aggregatorService from 'services/analytics/aggregatorService';
import { closedEngagement } from '../factory';

jest.mock('@mui/material', () => ({
...jest.requireActual('@mui/material'),
useMediaQuery: jest.fn(() => true),
}));
const mockEngagement = closedEngagement;

const renderComponent = () => {
render(<SurveysCompleted engagement={mockEngagement} engagementIsLoading={false} />);
};

describe('SurveysCompleted Component Tests', () => {
const getAggregatorMock = jest.spyOn(aggregatorService, 'getAggregatorData');

beforeEach(() => {
jest.resetAllMocks();
});

test('displays loading indicator while fetching data', () => {
getAggregatorMock.mockReturnValueOnce(
Promise.resolve({
key: '',
value: 0,
}),
);
render(<SurveysCompleted engagement={mockEngagement} engagementIsLoading={true} />);
expect(screen.getByRole('progressbar')).toBeInTheDocument();
});

test('displays data correctly on successful fetch', async () => {
const mockSurveyData = { key: 'survey_completed', value: 200 };
const mockEmailData = { key: 'email_verification', value: 100 };

getAggregatorMock.mockResolvedValueOnce(mockSurveyData).mockResolvedValueOnce(mockEmailData);

renderComponent();
await waitFor(() => {
expect(screen.getByText(mockSurveyData.value.toString())).toBeInTheDocument();
});
});

test('displays error message on fetch failure', async () => {
getAggregatorMock.mockRejectedValueOnce(new Error('Fetch Error'));

renderComponent();
await waitFor(() => {
expect(screen.getByText('No Data Available')).toBeInTheDocument();
});
});
});

0 comments on commit ba96181

Please sign in to comment.