Skip to content

Commit

Permalink
feat: error message on reach limit seats in enrollment feature
Browse files Browse the repository at this point in the history
  • Loading branch information
01001110J committed Jul 4, 2024
1 parent c4105a8 commit 8a5e772
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 8 deletions.
42 changes: 42 additions & 0 deletions src/features/Classes/EnrollStudent/__test__/index.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import '@testing-library/jest-dom/extend-expect';

import EnrollStudent from 'features/Classes/EnrollStudent';

import * as api from 'features/Students/data/api';

jest.mock('react-router-dom', () => ({
useParams: jest.fn(() => ({ courseName: 'Demo course', className: 'demo class' })),
useLocation: jest.fn().mockReturnValue({ search: '?classId=demo class' }),
Expand Down Expand Up @@ -39,6 +41,14 @@ describe('EnrollStudent', () => {
{ preloadedState: {} },
);

const handleEnrollmentsMock = jest.spyOn(api, 'handleEnrollments').mockResolvedValue({
data: {
results: [{
tags: 'success',
}],
},
});

const emailInput = getByPlaceholderText('Enter email of the student to enroll');
fireEvent.change(emailInput, { target: { value: '[email protected]' } });

Expand All @@ -48,5 +58,37 @@ describe('EnrollStudent', () => {
await waitFor(() => {
expect(getByText('Email invite has been sent successfully')).toBeInTheDocument();
});

expect(handleEnrollmentsMock).toHaveBeenCalledTimes(1);
handleEnrollmentsMock.mockRestore();
});

test('Should handle form submission and show error toast', async () => {
const onCloseMock = jest.fn();

const handleEnrollmentsMock = jest.spyOn(api, 'handleEnrollments').mockResolvedValue({
data: {
results: [{ tags: 'error', message: 'Enrollment limit reached' }],
},
});

const { getByPlaceholderText, getByText } = renderWithProviders(
<EnrollStudent isOpen onClose={onCloseMock} />,
{ preloadedState: {} },
);

const emailInput = getByPlaceholderText('Enter email of the student to enroll');
fireEvent.change(emailInput, { target: { value: '[email protected]' } });

const submitButton = getByText('Send invite');
fireEvent.click(submitButton);

await waitFor(() => {
expect(getByText('Enrollment limit reached')).toBeInTheDocument();
});

expect(handleEnrollmentsMock).toHaveBeenCalledTimes(1);

handleEnrollmentsMock.mockRestore();
});
});
26 changes: 20 additions & 6 deletions src/features/Classes/EnrollStudent/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@ import { initialPage } from 'features/constants';

import 'features/Classes/EnrollStudent/index.scss';

const successToastMessage = 'Email invite has been sent successfully';

const EnrollStudent = ({ isOpen, onClose, queryClassId }) => {
const dispatch = useDispatch();

const { courseName, className } = useParams();
const [showToast, setShowToast] = useState(false);
const [isLoading, setLoading] = useState(false);
const [toastMessage, setToastMessage] = useState('');
const institution = useSelector((state) => state.main.selectedInstitution);
const courseNameDecoded = decodeURIComponent(courseName);
const classNameDecoded = decodeURIComponent(className);
Expand All @@ -47,7 +46,21 @@ const EnrollStudent = ({ isOpen, onClose, queryClassId }) => {

try {
setLoading(true);
await handleEnrollments(formData, queryClassId);
const response = await handleEnrollments(formData, queryClassId);

/**
* This is because the service that checks the enrollment status is a different
* endpoint, and that endpoint always returns a status 200, so the error cannot be
* caught with a .catch.
*/
if (response?.data?.results[0]?.tags === 'error') {
setToastMessage(response?.data?.results[0]?.message);
setShowToast(true);

return onClose();
}

setToastMessage('Email invite has been sent successfully');

const params = {
course_name: courseNameDecoded,
Expand All @@ -59,10 +72,11 @@ const EnrollStudent = ({ isOpen, onClose, queryClassId }) => {

// Get the classes info updated with the new number of students enrolled.
dispatch(fetchAllClassesData(institution.id, courseNameDecoded));

setShowToast(true);
onClose();
return onClose();
} catch (error) {
logError(error);
return logError(error);
} finally {
setLoading(false);
}
Expand All @@ -71,7 +85,7 @@ const EnrollStudent = ({ isOpen, onClose, queryClassId }) => {
return (
<>
<Toast onClose={() => setShowToast(false)} show={showToast}>
{successToastMessage}
{toastMessage}
</Toast>
<ModalDialog
title="Invite student to enroll"
Expand Down
3 changes: 2 additions & 1 deletion src/features/Students/data/_test_/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ describe('getStudentbyInstitutionAdmin', () => {
describe('handleEnrollments', () => {
test('should call getAuthenticatedHttpClient with the correct parameters', () => {
const httpClientMock = {
post: jest.fn(),
post: jest.fn().mockResolvedValue({}),
get: jest.fn().mockResolvedValue({}),
};
const courseId = 'course123';
const data = new FormData();
Expand Down
4 changes: 3 additions & 1 deletion src/features/Students/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ function handleEnrollments(data, courseId) {
return getAuthenticatedHttpClient().post(
`${INSTRUCTOR_API_URL.replace(courseIdSearchPattern, courseId)}/students_update_enrollment`,
data,
);
).then(() => getAuthenticatedHttpClient().get(
`${getConfig().LMS_BASE_URL}/pearson_course_operation/api/messages/get-messages/`,
));
}

function getStudentsMetrics(institutionId, days) {
Expand Down

0 comments on commit 8a5e772

Please sign in to comment.