feat: add unit tests for filter functionality

This commit is contained in:
Muhammad Faraz Maqsood
2025-05-07 14:14:59 +05:00
committed by Muhammad Faraz Maqsood
parent 36277d8ef5
commit c77c4f3c91
3 changed files with 185 additions and 97 deletions

View File

@@ -37,6 +37,24 @@ const OptimizerPage = () => (
</AppProvider>
);
const setupOptimizerPage = async () => {
axiosMock.onGet(getLinkCheckStatusApiUrl(courseId)).reply(200, mockApiResponse);
const optimizerPage = render(<OptimizerPage />);
// Click the scan button
fireEvent.click(optimizerPage.getByText(messages.buttonTitle.defaultMessage));
// Wait for the scan results to load
await waitFor(() => {
expect(optimizerPage.getByText('Introduction to Programming')).toBeInTheDocument();
});
// Click on filters button
fireEvent.click(optimizerPage.getByText(scanResultsMessages.filterButtonLabel.defaultMessage));
return optimizerPage;
};
describe('CourseOptimizerPage', () => {
describe('pollLinkCheckDuringScan', () => {
let mockFetchLinkCheckStatus;
@@ -71,6 +89,7 @@ describe('CourseOptimizerPage', () => {
pollLinkCheckDuringScan(linkCheckInProgress, interval, dispatch, courseId);
expect(interval.current).toBeTruthy();
});
it('should not start polling if link check is not in progress', () => {
const linkCheckInProgress = false;
const interval = { current: null };
@@ -79,6 +98,7 @@ describe('CourseOptimizerPage', () => {
pollLinkCheckDuringScan(linkCheckInProgress, interval, dispatch, courseId);
expect(interval.current).toBeFalsy();
});
it('should clear the interval if link check is finished', () => {
const linkCheckInProgress = false;
const interval = { current: 1 };
@@ -127,53 +147,6 @@ describe('CourseOptimizerPage', () => {
});
});
it('should list broken links results', async () => {
const {
getByText, queryAllByText, getAllByText, container,
} = render(<OptimizerPage />);
expect(getByText(messages.headingTitle.defaultMessage)).toBeInTheDocument();
fireEvent.click(getByText(messages.buttonTitle.defaultMessage));
await waitFor(() => {
expect(getByText('5 broken links')).toBeInTheDocument();
expect(getByText('5 locked links')).toBeInTheDocument();
});
const collapsibleTrigger = container.querySelector('.collapsible-trigger');
expect(collapsibleTrigger).toBeInTheDocument();
fireEvent.click(collapsibleTrigger);
await waitFor(() => {
expect(getAllByText(scanResultsMessages.brokenLinkStatus.defaultMessage)[0]).toBeInTheDocument();
expect(queryAllByText(scanResultsMessages.lockedLinkStatus.defaultMessage)[0]).toBeInTheDocument();
expect(queryAllByText(scanResultsMessages.recommendedManualCheckText.defaultMessage)[0]).toBeInTheDocument();
const brokenLinks = getAllByText('https://example.com/broken-link-algo');
expect(brokenLinks.length).toBeGreaterThan(0);
fireEvent.click(brokenLinks[0]);
const lockedLinks = getAllByText('https://example.com/locked-link-algo');
expect(lockedLinks.length).toBeGreaterThan(0);
fireEvent.click(lockedLinks[0]);
fireEvent.click((getAllByText('Go to Block'))[0]);
});
});
it('should not list locked links results when show locked links is unchecked', async () => {
const {
getByText, getAllByText, getByLabelText, queryAllByText, queryByText, container,
} = render(<OptimizerPage />);
expect(getByText(messages.headingTitle.defaultMessage)).toBeInTheDocument();
fireEvent.click(getByText(messages.buttonTitle.defaultMessage));
await waitFor(() => {
expect(getByText('5 broken links')).toBeInTheDocument();
});
fireEvent.click(getByLabelText(scanResultsMessages.lockedCheckboxLabel.defaultMessage));
const collapsibleTrigger = container.querySelector('.collapsible-trigger');
expect(collapsibleTrigger).toBeInTheDocument();
fireEvent.click(collapsibleTrigger);
await waitFor(() => {
expect(queryByText('5 locked links')).not.toBeInTheDocument();
expect(getAllByText(scanResultsMessages.brokenLinkStatus.defaultMessage)[0]).toBeInTheDocument();
expect(queryAllByText(scanResultsMessages.lockedLinkStatus.defaultMessage)?.[0]).toBeUndefined();
});
});
it('should show no broken links found message', async () => {
axiosMock
.onGet(getLinkCheckStatusApiUrl(courseId))
@@ -197,5 +170,102 @@ describe('CourseOptimizerPage', () => {
expect(screen.getByText(generalMessages.supportText.defaultMessage)).toBeInTheDocument();
});
});
it('should show only broken links when brokenLinks filter is selected', async () => {
const {
getByText,
getByLabelText,
queryByText,
container,
} = await setupOptimizerPage();
// Check if the modal is opened
expect(getByText('Broken')).toBeInTheDocument();
// Select the broken links checkbox
fireEvent.click(getByLabelText(scanResultsMessages.brokenLabel.defaultMessage));
const collapsibleTrigger = container.querySelector('.collapsible-trigger');
expect(collapsibleTrigger).toBeInTheDocument();
fireEvent.click(collapsibleTrigger);
await waitFor(() => {
expect(getByText('Test Broken Links')).toBeInTheDocument();
expect(queryByText('Test Locked Links')).not.toBeInTheDocument();
expect(queryByText('Test Manual Links')).not.toBeInTheDocument();
});
});
it('should show only manual links when manualLinks filter is selected', async () => {
const {
getByText,
getByLabelText,
queryByText,
container,
} = await setupOptimizerPage();
// Check if the modal is opened
expect(getByText('Manual')).toBeInTheDocument();
// Select the manual links checkbox
fireEvent.click(getByLabelText(scanResultsMessages.manualLabel.defaultMessage));
const collapsibleTrigger = container.querySelector('.collapsible-trigger');
expect(collapsibleTrigger).toBeInTheDocument();
fireEvent.click(collapsibleTrigger);
await waitFor(() => {
expect(getByText('Test Manual Links')).toBeInTheDocument();
expect(queryByText('Test Broken Links')).not.toBeInTheDocument();
expect(queryByText('Test Locked Links')).not.toBeInTheDocument();
});
});
it('should show only manual & locked links when manual & locked Links filters are selected, ignore broken links', async () => {
const {
getByText,
getByLabelText,
queryByText,
container,
} = await setupOptimizerPage();
// Check if the modal is opened
expect(getByText('Manual')).toBeInTheDocument();
expect(getByText('Locked')).toBeInTheDocument();
// Select the manual & locked links checkbox
fireEvent.click(getByLabelText(scanResultsMessages.manualLabel.defaultMessage));
fireEvent.click(getByLabelText(scanResultsMessages.lockedLabel.defaultMessage));
const collapsibleTrigger = container.querySelector('.collapsible-trigger');
expect(collapsibleTrigger).toBeInTheDocument();
fireEvent.click(collapsibleTrigger);
await waitFor(() => {
expect(getByText('Test Manual Links')).toBeInTheDocument();
expect(getByText('Test Locked Links')).toBeInTheDocument();
expect(queryByText('Test Broken Links')).not.toBeInTheDocument();
});
});
it('should show all links when all filters are selected', async () => {
const {
getByText,
getByLabelText,
container,
} = await setupOptimizerPage();
// Check if the modal is opened
expect(getByText('Broken')).toBeInTheDocument();
expect(getByText('Manual')).toBeInTheDocument();
expect(getByText('Locked')).toBeInTheDocument();
// Select the all checkboxes
fireEvent.click(getByLabelText(scanResultsMessages.brokenLabel.defaultMessage));
fireEvent.click(getByLabelText(scanResultsMessages.lockedLabel.defaultMessage));
fireEvent.click(getByLabelText(scanResultsMessages.manualLabel.defaultMessage));
const collapsibleTrigger = container.querySelector('.collapsible-trigger');
expect(collapsibleTrigger).toBeInTheDocument();
fireEvent.click(collapsibleTrigger);
await waitFor(() => {
expect(getByText('Test Broken Links')).toBeInTheDocument();
expect(getByText('Test Manual Links')).toBeInTheDocument();
expect(getByText('Test Locked Links')).toBeInTheDocument();
});
});
});
});

View File

@@ -13,56 +13,40 @@ const mockApiResponse = {
units: [
{
id: 'unit-1-1-1',
displayName: 'Welcome Video',
displayName: 'Test Broken Links',
blocks: [
{
id: 'block-1-1-1-5',
url: 'https://example.com/welcome-video',
brokenLinks: ['https://example.com/broken-link-algo1'],
lockedLinks: [],
externalForbiddenLinks: [],
},
],
},
{
id: 'unit-1-1-3',
displayName: 'Test Manual Links',
blocks: [
{
id: 'block-1-1-1-1',
url: 'https://example.com/welcome-video',
brokenLinks: ['https://example.com/broken-link-algo'],
lockedLinks: ['https://example.com/locked-link-algo'],
},
{
id: 'block-1-1-1-2',
url: 'https://example.com/intro-guide',
brokenLinks: ['https://example.com/broken-link-algo'],
lockedLinks: ['https://example.com/locked-link-algo'],
brokenLinks: [],
lockedLinks: [],
externalForbiddenLinks: ['https://outsider.com/forbidden-link-algo'],
},
],
},
{
id: 'unit-1-1-2',
displayName: 'Course Overview',
displayName: 'Test Locked Links',
blocks: [
{
id: 'block-1-1-2-1',
url: 'https://example.com/course-overview',
brokenLinks: ['https://example.com/broken-link-algo'],
lockedLinks: ['https://example.com/locked-link-algo'],
},
],
},
],
},
{
id: 'subsection-1-2',
displayName: 'Basic Concepts',
units: [
{
id: 'unit-1-2-1',
displayName: 'Variables and Data Types',
blocks: [
{
id: 'block-1-2-1-1',
url: 'https://example.com/variables',
brokenLinks: ['https://example.com/broken-link-algo'],
lockedLinks: ['https://example.com/locked-link-algo'],
},
{
id: 'block-1-2-1-2',
url: 'https://example.com/broken-link',
brokenLinks: ['https://example.com/broken-link'],
brokenLinks: [],
lockedLinks: ['https://example.com/locked-link-algo'],
externalForbiddenLinks: [],
},
],
},
@@ -72,26 +56,60 @@ const mockApiResponse = {
},
{
id: 'section-2',
displayName: 'Advanced Topics',
displayName: 'Introduction to Programming 2',
subsections: [
{
id: 'subsection-2-1',
displayName: 'Algorithms and Data Structures',
id: 'subsection-1-2',
displayName: 'Getting Started 2',
units: [
{
id: 'unit-2-1-1',
displayName: 'Sorting Algorithms',
id: 'unit-2-2-2',
displayName: 'unit',
blocks: [
{
id: 'block-2-1-1-1',
url: 'https://example.com/sorting-algorithms',
brokenLinks: ['https://example.com/broken-link-algo'],
lockedLinks: ['https://example.com/locked-link-algo'],
id: 'block-1-1-1-6',
url: 'https://example.com/welcome-video',
brokenLinks: ['https://example.com/broken-link-algo1'],
lockedLinks: [],
externalForbiddenLinks: [],
},
{
id: 'block-2-1-1-2',
url: 'https://example.com/broken-link-algo',
brokenLinks: ['https://example.com/broken-link-algo'],
id: 'block-1-1-1-6',
url: 'https://example.com/welcome-video',
brokenLinks: ['https://example.com/broken-link-algo1'],
lockedLinks: ['https://example.com/locked-link-algo'],
externalForbiddenLinks: [],
},
{
id: 'block-1-1-1-6',
url: 'https://example.com/welcome-video',
brokenLinks: ['https://example.com/broken-link-algo1'],
lockedLinks: [],
externalForbiddenLinks: ['https://outsider.com/forbidden-link-algo'],
},
],
},
{
id: 'unit-2-2-3',
displayName: 'unit',
blocks: [
{
id: 'block-1-1-1-7',
url: 'https://example.com/welcome-video',
brokenLinks: ['https://example.com/broken-link-algo1'],
lockedLinks: [],
externalForbiddenLinks: ['https://outsider.com/forbidden-link-algo'],
},
],
},
{
id: 'unit-2-2-4',
displayName: 'Test Locked Links',
blocks: [
{
id: 'block-1-1-7-1',
url: 'https://example.com/course-overview',
brokenLinks: ['https://example.com/broken-link-algo1'],
lockedLinks: ['https://example.com/locked-link-algo'],
externalForbiddenLinks: ['https://outsider.com/forbidden-link-algo'],
},

View File

@@ -6,9 +6,9 @@ describe('countBrokenLinks', () => {
const data = mockApiResponse.LinkCheckOutput;
expect(countBrokenLinks(data)).toStrictEqual(
{
brokenLinksCounts: [5, 2],
lockedLinksCounts: [5, 2],
externalForbiddenLinksCounts: [1, 1],
brokenLinksCounts: [1, 5],
lockedLinksCounts: [1, 2],
externalForbiddenLinksCounts: [1, 3],
},
);
});