Skip to content

Commit

Permalink
fix: checking error in individual email list
Browse files Browse the repository at this point in the history
  • Loading branch information
johnvente committed Jan 2, 2024
1 parent d9ada98 commit a6dfabb
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 11 deletions.
4 changes: 2 additions & 2 deletions plugins/communications-app/IndividualEmails/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ describe('getLearnersEmailInstructorTask', () => {
});
});

it('successfully fetches data', async () => {
test('successfully fetches data', async () => {
const data = await getLearnersEmailInstructorTask(mockCourseId, mockSearch);
expect(data).toEqual(mockResponseData);
expect(getAuthenticatedHttpClient().get).toHaveBeenCalledWith(
`http://localhost/platform-plugin-communications/${mockCourseId}/api/search_learners?query=${mockSearch}&page=1&page_size=10`,
);
});

it('handles an error', async () => {
test('handles an error', async () => {
getAuthenticatedHttpClient().get.mockRejectedValue(new Error('Network error'));

await expect(getLearnersEmailInstructorTask(mockCourseId, mockSearch)).rejects.toThrow('Network error');
Expand Down
22 changes: 21 additions & 1 deletion plugins/communications-app/IndividualEmails/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import {
Container,
} from '@edx/paragon';
import { Person, Close } from '@edx/paragon/icons';
import { useIntl } from '@edx/frontend-platform/i18n';
import { useIntl, FormattedMessage } from '@edx/frontend-platform/i18n';
import { logError } from '@edx/frontend-platform/logging';
import { useSelector } from '@communications-app/src/components/bulk-email-tool/bulk-email-form/BuildEmailFormExtensible/context';

import { getLearnersEmailInstructorTask } from './api';
import messages from './messages';
Expand All @@ -26,6 +27,8 @@ const IndividualEmails = ({
const [isLoading, setIsLoading] = useState(false);
const [options, setOptions] = useState([]);
const [inputValue] = useState([]);
const formData = useSelector((state) => state.form);
const { isFormSubmitted } = formData;

const handleSearchEmailLearners = async (userEmail) => {
setIsLoading(true);
Expand Down Expand Up @@ -57,6 +60,8 @@ const IndividualEmails = ({
}
};

const isIndividualEmailsInvalid = isFormSubmitted && emailList.length === 0;

return (
<Container className="col-12 my-5">
<Form.Label className="mt-3" data-testid="learners-email-input-label">
Expand All @@ -81,6 +86,21 @@ const IndividualEmails = ({
</span>
)}
/>

{ isIndividualEmailsInvalid && (
<Form.Control.Feedback
className="px-2 my-2"
type="invalid"
hasIcon
>
<FormattedMessage
id="bulk.email.form.email.learners.error"
defaultMessage="At least one email is required"
description="An Error message located under the recipients list. Visible only on failure"
/>
</Form.Control.Feedback>
)}

{emailList.length > 0 && (
<Container className="email-list">
<Form.Label className="col-12" data-testid="learners-email-list-label">
Expand Down
12 changes: 6 additions & 6 deletions plugins/communications-app/IndividualEmails/index.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ describe('IndividualEmails Component', () => {
</IntlProvider>
);

it('renders the component without errors', () => {
test('renders the component without errors', () => {
render(
<IntlProviderWrapper>
<IndividualEmails />
</IntlProviderWrapper>,
);
});

it('displays the correct internationalized messages', () => {
test('displays the correct internationalized messages', () => {
render(
<IntlProviderWrapper>
<IndividualEmails emailList={mockEmailList} />
Expand All @@ -62,7 +62,7 @@ describe('IndividualEmails Component', () => {
expect(screen.getByTestId('learners-email-list-label')).toHaveTextContent(individualEmailsLabelLearnersListLabel.defaultMessage);
});

it('renders the component with main components ', () => {
test('renders the component with main components ', () => {
render(
<IntlProviderWrapper>
<IndividualEmails courseId="123" emailList={mockEmailList} />
Expand All @@ -78,7 +78,7 @@ describe('IndividualEmails Component', () => {
expect(emailListLabel).toBeInTheDocument();
});

it('should render two email chips', () => {
test('should render two email chips', () => {
render(
<IntlProviderWrapper>
<IndividualEmails courseId="123" emailList={mockEmailList} />
Expand All @@ -89,7 +89,7 @@ describe('IndividualEmails Component', () => {
expect(emailChips).toHaveLength(2);
});

it('triggers search on typing in search box', async () => {
test('triggers search on typing in search box', async () => {
const mockHandleEmailSelected = jest.fn();
const mockCourseId = 'course123';
render(
Expand All @@ -111,7 +111,7 @@ describe('IndividualEmails Component', () => {
});
});

it('invokes handleDeleteEmail when clicking on delete icons', () => {
test('invokes handleDeleteEmail when clicking on delete icons', () => {
const mockHandleDeleteEmail = jest.fn();
render(
<IntlProviderWrapper>
Expand Down
16 changes: 15 additions & 1 deletion plugins/communications-app/RecipientsForm/index.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useState, useContext } from 'react';
import PropTypes from 'prop-types';
import useDeepCompareEffect from 'use-deep-compare-effect';
import { Form } from '@edx/paragon';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
import { useSelector, useDispatch } from '@communications-app/src/components/bulk-email-tool/bulk-email-form/BuildEmailFormExtensible/context';
import { actionCreators as formActions } from '@communications-app/src/components/bulk-email-tool/bulk-email-form/BuildEmailFormExtensible/context/reducer';
import PluggableComponent from '@communications-app/src/components/PluggableComponent';
import { BulkEmailContext } from '@communications-app/src/components/bulk-email-tool/bulk-email-context';

import './styles.scss';

Expand All @@ -13,6 +15,7 @@ const recipientsFormDescription = 'A selectable choice from a list of potential

const RecipientsForm = ({ cohorts: additionalCohorts, courseId }) => {
const formData = useSelector((state) => state.form);
const [{ editor }] = useContext(BulkEmailContext);
const dispatch = useDispatch();
const {
isEditMode,
Expand Down Expand Up @@ -62,6 +65,17 @@ const RecipientsForm = ({ cohorts: additionalCohorts, courseId }) => {
setSelectedGroups(emailRecipients);
}, [isEditMode, emailRecipients.length, emailRecipients]);

useDeepCompareEffect(() => {
if (!editor.editMode) {
const newSubjectValue = editor.emailSubject;
const newBodyValue = editor.emailBody;
dispatch(formActions.updateForm({
subject: newSubjectValue,
body: newBodyValue,
}));
}
}, [editor, dispatch]);

return (
<Form.Group>
<Form.Label>
Expand Down
3 changes: 3 additions & 0 deletions plugins/communications-app/RecipientsForm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"use-deep-compare-effect": "^1.8.1"
},
"peerDependencies": {
"@edx/frontend-app-communications": "*",
"@edx/frontend-platform": "*",
Expand Down
4 changes: 3 additions & 1 deletion plugins/communications-app/TaskAlertModalForm/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,10 @@ const TaskAlertModalForm = ({

const createEmailTask = async () => {
const isScheduleValid = isScheduled ? scheduleDate.length > 0 && scheduleTime.length > 0 : true;
const isIndividualEmailsValid = (emailRecipients.includes('individual-learners') && emailLearnersList.length > 0)
|| !emailRecipients.includes('individual-learners');
const isFormValid = emailRecipients.length > 0 && subject.length > 0
&& body.length > 0 && isScheduleValid;
&& body.length > 0 && isScheduleValid && isIndividualEmailsValid;

if (isFormValid && isEditMode) {
await handlePatchEmailTask();
Expand Down

0 comments on commit a6dfabb

Please sign in to comment.