Skip to content

Commit

Permalink
refactor: added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
PKulkoRaccoonGang committed Nov 11, 2024
1 parent 35fa2d4 commit ca1c499
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 11 deletions.
15 changes: 15 additions & 0 deletions src/course-checklist/CourseChecklist.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,5 +149,20 @@ describe('CourseChecklistPage', () => {
});
});
});

it('displays an alert and sets status to DENIED when API responds with 403', async () => {
const courseLaunchApiUrl = getCourseLaunchApiUrl({
courseId, gradedOnly: true, validateOras: true, all: true,
});
axiosMock.onGet(courseLaunchApiUrl).reply(403);

renderComponent();

await waitFor(() => {
const { launchChecklistStatus } = store.getState().courseChecklist.loadingStatus;
expect(launchChecklistStatus).toEqual(RequestStatus.DENIED);
expect(screen.getByRole('alert')).toBeInTheDocument();
});
});
});
});
14 changes: 14 additions & 0 deletions src/course-outline/CourseOutline.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2291,4 +2291,18 @@ describe('<CourseOutline />', () => {
expect(await screen.findByText('Please wait. Creating export file for course tags...')).toBeInTheDocument();
expect(await screen.findByText('An error has occurred creating the file')).toBeInTheDocument();
});

it('displays an alert and sets status to DENIED when API responds with 403', async () => {
axiosMock
.onGet(getCourseOutlineIndexApiUrl(courseId))
.reply(403);

const { getByRole } = render(<RootWrapper />);

await waitFor(() => {
expect(getByRole('alert')).toBeInTheDocument();
const { outlineIndexLoadingStatus } = store.getState().courseOutline.loadingStatus;
expect(outlineIndexLoadingStatus).toEqual(RequestStatus.DENIED);
});
});
});
29 changes: 28 additions & 1 deletion src/course-team/CourseTeam.test.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react';
import {
render,
fireEvent,
Expand All @@ -18,6 +17,7 @@ import CourseTeam from './CourseTeam';
import messages from './messages';
import { USER_ROLES } from '../constants';
import { executeThunk } from '../utils';
import { RequestStatus } from '../data/constants';
import { changeRoleTeamUserQuery, deleteCourseTeamQuery } from './data/thunk';

let axiosMock;
Expand Down Expand Up @@ -219,4 +219,31 @@ describe('<CourseTeam />', () => {
await executeThunk(changeRoleTeamUserQuery(courseId, '[email protected]', { role: USER_ROLES.admin }), store.dispatch);
expect(getAllByText('Admin')).toHaveLength(1);
});

it('displays an alert and sets status to DENIED when API responds with 403', async () => {
axiosMock
.onGet(getCourseTeamApiUrl(courseId))
.reply(403);

const { getByRole } = render(<RootWrapper />);

await waitFor(() => {
expect(getByRole('alert')).toBeInTheDocument();
const { loadingCourseTeamStatus } = store.getState().courseTeam;
expect(loadingCourseTeamStatus).toEqual(RequestStatus.DENIED);
});
});

it('sets loading status to FAILED upon receiving a 404 response from the API', async () => {
axiosMock
.onGet(getCourseTeamApiUrl(courseId))
.reply(404);

render(<RootWrapper />);

await waitFor(() => {
const { loadingCourseTeamStatus } = store.getState().courseTeam;
expect(loadingCourseTeamStatus).toEqual(RequestStatus.FAILED);
});
});
});
24 changes: 22 additions & 2 deletions src/course-updates/CourseUpdates.test.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { render, waitFor, fireEvent } from '@testing-library/react';
import {
render, waitFor, fireEvent,
} from '@testing-library/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { AppProvider } from '@edx/frontend-platform/react';
import { initializeMockApp } from '@edx/frontend-platform';
Expand All @@ -19,6 +20,7 @@ import {
} from './data/thunk';
import initializeStore from '../store';
import { executeThunk } from '../utils';
import { RequestStatus } from '../data/constants';
import { courseUpdatesMock, courseHandoutsMock } from './__mocks__';
import CourseUpdates from './CourseUpdates';
import messages from './messages';
Expand Down Expand Up @@ -278,6 +280,24 @@ describe('<CourseUpdates />', () => {
expect(getByTestId('course-handouts-edit-button')).toBeDisabled();
});
});

it('displays an alert and sets status to DENIED when API responds with 403', async () => {
axiosMock
.onGet(getCourseUpdatesApiUrl(courseId))
.reply(403, courseUpdatesMock);
axiosMock
.onGet(getCourseHandoutApiUrl(courseId))
.reply(403);

const { getByTestId } = render(<RootWrapper />);

await waitFor(() => {
expect(getByTestId('connectionErrorAlert')).toBeInTheDocument();
const { loadingStatuses } = store.getState().courseUpdates;
Object.values(loadingStatuses)
.some(status => expect(status).toEqual(RequestStatus.DENIED));
});
});
});

describe('saving failure API responses', () => {
Expand Down
30 changes: 28 additions & 2 deletions src/export-page/CourseExportPage.test.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React from 'react';
import { getConfig, initializeMockApp } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n';
import { AppProvider } from '@edx/frontend-platform/react';
import { fireEvent, render, waitFor } from '@testing-library/react';
import MockAdapter from 'axios-mock-adapter';
import { Helmet } from 'react-helmet';

import Cookies from 'universal-cookie';

import initializeStore from '../store';
import { RequestStatus } from '../data/constants';
import stepperMessages from './export-stepper/messages';
import modalErrorMessages from './export-modal-error/messages';
import { getExportStatusApiUrl, postExportCourseApiUrl } from './data/api';
Expand Down Expand Up @@ -137,4 +137,30 @@ describe('<CourseExportPage />', () => {
expect(downloadButton).toBeInTheDocument();
expect(downloadButton.getAttribute('href')).toEqual('http://test-download-path.test');
});
it('displays an alert and sets status to DENIED when API responds with 403', async () => {
axiosMock
.onGet(getExportStatusApiUrl(courseId))
.reply(403);
const { getByRole, container } = render(<RootWrapper />);
const startExportButton = container.querySelector('.btn-primary');
fireEvent.click(startExportButton);
// eslint-disable-next-line no-promise-executor-return
await new Promise((r) => setTimeout(r, 3500));
expect(getByRole('alert')).toBeInTheDocument();
const { loadingStatus } = store.getState().courseExport;
expect(loadingStatus).toEqual(RequestStatus.DENIED);
});

it('sets loading status to FAILED upon receiving a 404 response from the API', async () => {
axiosMock
.onGet(getExportStatusApiUrl(courseId))
.reply(404);
const { container } = render(<RootWrapper />);
const startExportButton = container.querySelector('.btn-primary');
fireEvent.click(startExportButton);
// eslint-disable-next-line no-promise-executor-return
await new Promise((r) => setTimeout(r, 3500));
const { loadingStatus } = store.getState().courseExport;
expect(loadingStatus).toEqual(RequestStatus.FAILED);
});
});
5 changes: 3 additions & 2 deletions src/grading-settings/GradingSettings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
useGradingSettings,
useGradingSettingUpdater,
} from 'CourseAuthoring/grading-settings/data/apiHooks';
import { RequestStatus } from 'CourseAuthoring/data/constants';
import PropTypes from 'prop-types';
import React, { useEffect, useState } from 'react';
import { Helmet } from 'react-helmet';
Expand All @@ -34,10 +33,12 @@ const GradingSettings = ({ courseId }) => {
const {
data: gradingSettings,
isLoading: isGradingSettingsLoading,
isError: isGradingSettingsError,
} = useGradingSettings(courseId);
const {
data: courseSettingsData,
isLoading: isCourseSettingsLoading,
isError: isCourseSettingsError,
} = useCourseSettings(courseId);
const {
mutate: updateGradingSettings,
Expand All @@ -48,7 +49,7 @@ const GradingSettings = ({ courseId }) => {

const courseAssignmentLists = gradingSettings?.courseAssignmentLists;
const courseGradingDetails = gradingSettings?.courseDetails;
const isLoadingDenied = isCourseSettingsLoading === RequestStatus.DENIED;
const isLoadingDenied = isGradingSettingsError || isCourseSettingsError;
const [showSuccessAlert, setShowSuccessAlert] = useState(false);
const isLoading = isCourseSettingsLoading || isGradingSettingsLoading;
const [isQueryPending, setIsQueryPending] = useState(false);
Expand Down
17 changes: 17 additions & 0 deletions src/group-configurations/GroupConfigurations.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,21 @@ describe('<GroupConfigurations />', () => {
RequestStatus.FAILED,
);
});

it('displays an alert and sets status to DENIED when API responds with 403', async () => {
axiosMock
.onGet(getContentStoreApiUrl(courseId))
.reply(403);

await executeThunk(fetchGroupConfigurationsQuery(courseId), store.dispatch);

const { getByTestId } = renderComponent();

await waitFor(() => {
expect(getByTestId('connectionErrorAlert')).toBeInTheDocument();
expect(store.getState().groupConfigurations.loadingStatus).toBe(
RequestStatus.DENIED,
);
});
});
});
29 changes: 27 additions & 2 deletions src/import-page/CourseImportPage.test.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React from 'react';
import { initializeMockApp } from '@edx/frontend-platform';
import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n';
import { AppProvider } from '@edx/frontend-platform/react';
import { render, waitFor } from '@testing-library/react';
import { Helmet } from 'react-helmet';

import MockAdapter from 'axios-mock-adapter';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';

import Cookies from 'universal-cookie';
import initializeStore from '../store';
import { RequestStatus } from '../data/constants';
import messages from './messages';
import CourseImportPage from './CourseImportPage';
import { getImportStatusApiUrl } from './data/api';
Expand Down Expand Up @@ -108,4 +108,29 @@ describe('<CourseImportPage />', () => {
await new Promise((r) => setTimeout(r, 3500));
expect(getByText(stepperMessages.viewOutlineButton.defaultMessage)).toBeInTheDocument();
});

it('displays an alert and sets status to DENIED when API responds with 403', async () => {
axiosMock
.onGet(getImportStatusApiUrl(courseId, 'testFileName.tar.gz'))
.reply(403);
cookies.get.mockReturnValue({ date: 1679787000, completed: false, fileName: 'testFileName.tar.gz' });
const { getByRole } = render(<RootWrapper />);
// eslint-disable-next-line no-promise-executor-return
await new Promise((r) => setTimeout(r, 3500));
expect(getByRole('alert')).toBeInTheDocument();
const { loadingStatus } = store.getState().courseImport;
expect(loadingStatus).toEqual(RequestStatus.DENIED);
});

it('sets loading status to FAILED upon receiving a 404 response from the API', async () => {
axiosMock
.onGet(getImportStatusApiUrl(courseId, 'testFileName.tar.gz'))
.reply(404);
cookies.get.mockReturnValue({ date: 1679787000, completed: false, fileName: 'testFileName.tar.gz' });
render(<RootWrapper />);
// eslint-disable-next-line no-promise-executor-return
await new Promise((r) => setTimeout(r, 3500));
const { loadingStatus } = store.getState().courseImport;
expect(loadingStatus).toEqual(RequestStatus.FAILED);
});
});
7 changes: 5 additions & 2 deletions src/import-page/data/thunks.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable import/prefer-default-export */
import Cookies from 'universal-cookie';
import moment from 'moment';

Expand Down Expand Up @@ -32,7 +31,11 @@ export function fetchImportStatus(courseId, fileName) {
dispatch(updateLoadingStatus(RequestStatus.SUCCESSFUL));
return true;
} catch (error) {
dispatch(updateLoadingStatus(RequestStatus.FAILED));
if (error.response && error.response.status === 403) {
dispatch(updateLoadingStatus(RequestStatus.DENIED));
} else {
dispatch(updateLoadingStatus(RequestStatus.FAILED));
}
return false;
}
};
Expand Down
16 changes: 16 additions & 0 deletions src/textbooks/Textbook.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { initializeMockApp } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import userEvent from '@testing-library/user-event';

import { RequestStatus } from '../data/constants';
import initializeStore from '../store';
import { executeThunk } from '../utils';
import { getTextbooksApiUrl } from './data/api';
Expand Down Expand Up @@ -84,4 +85,19 @@ describe('<Textbooks />', () => {
expect(queryAllByTestId('textbook-card')).toHaveLength(0);
});
});

it('displays an alert and sets status to FAILED when API responds with 403', async () => {
axiosMock
.onGet(getTextbooksApiUrl(courseId))
.reply(403);
await executeThunk(fetchTextbooksQuery(courseId), store.dispatch);
const { getByTestId } = renderComponent();

await waitFor(() => {
expect(getByTestId('connectionErrorAlert')).toBeInTheDocument();
expect(store.getState().textbooks.loadingStatus).toBe(
RequestStatus.FAILED,
);
});
});
});

0 comments on commit ca1c499

Please sign in to comment.