diff --git a/src/features/Classes/EnrollStudent/__test__/index.test.jsx b/src/features/Classes/EnrollStudent/__test__/index.test.jsx
index bca7cfc7..4c42cb31 100644
--- a/src/features/Classes/EnrollStudent/__test__/index.test.jsx
+++ b/src/features/Classes/EnrollStudent/__test__/index.test.jsx
@@ -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' }),
@@ -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: 'test@example.com' } });
@@ -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(
+ ,
+ { preloadedState: {} },
+ );
+
+ const emailInput = getByPlaceholderText('Enter email of the student to enroll');
+ fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
+
+ const submitButton = getByText('Send invite');
+ fireEvent.click(submitButton);
+
+ await waitFor(() => {
+ expect(getByText('Enrollment limit reached')).toBeInTheDocument();
+ });
+
+ expect(handleEnrollmentsMock).toHaveBeenCalledTimes(1);
+
+ handleEnrollmentsMock.mockRestore();
});
});
diff --git a/src/features/Classes/EnrollStudent/index.jsx b/src/features/Classes/EnrollStudent/index.jsx
index 36bd99c7..468321d7 100644
--- a/src/features/Classes/EnrollStudent/index.jsx
+++ b/src/features/Classes/EnrollStudent/index.jsx
@@ -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);
@@ -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,
@@ -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);
}
@@ -71,7 +85,7 @@ const EnrollStudent = ({ isOpen, onClose, queryClassId }) => {
return (
<>
setShowToast(false)} show={showToast}>
- {successToastMessage}
+ {toastMessage}
{
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();
diff --git a/src/features/Students/data/api.js b/src/features/Students/data/api.js
index a425a1cc..c03cd071 100644
--- a/src/features/Students/data/api.js
+++ b/src/features/Students/data/api.js
@@ -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) {