diff --git a/src/register/RegistrationFailure.jsx b/src/register/RegistrationFailure.jsx
index d53e6e5b..2a3de062 100644
--- a/src/register/RegistrationFailure.jsx
+++ b/src/register/RegistrationFailure.jsx
@@ -1,47 +1,55 @@
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
-import { FormattedMessage } from '@edx/frontend-platform/i18n';
+import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { Alert } from '@edx/paragon';
-
-const hasNoErrors = (userErrors) => (
- userErrors.every((errorList) => (!errorList[0]))
-);
+import { INTERNAL_SERVER_ERROR } from '../login/data/constants';
+import messages from './messages';
const RegistrationFailureMessage = (props) => {
const errorMessage = props.errors;
+ const { errorCode } = props.errors;
const userErrors = [];
useEffect(() => {
window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });
}, [props.submitCount]);
- Object.keys(errorMessage).forEach((key) => {
- const errors = errorMessage[key];
- const errorList = errors.map((error) => (
- (error.user_message) ? (
-
- {error.user_message}
+ let serverError;
+ switch (errorCode) {
+ case INTERNAL_SERVER_ERROR:
+ serverError = (
+
+ {props.intl.formatMessage(messages['registration.request.server.error'])}
- ) : null
- ));
- userErrors.push(errorList);
- });
+ );
+ userErrors.push(serverError);
+ break;
+
+ default:
+ Object.keys(errorMessage).forEach((key) => {
+ const errors = errorMessage[key];
+ const errorList = errors.map((error) => (
+ (error.user_message) ? (
+
+ {error.user_message}
+
+ ) : null
+ ));
+ userErrors.push(errorList);
+ });
+ }
return (
- hasNoErrors(userErrors) ? null : (
+ !userErrors.length ? null : (
-
+ {props.intl.formatMessage(messages['registration.request.failure.header'])}
-
+
+
+
)
);
@@ -56,8 +64,10 @@ RegistrationFailureMessage.propTypes = {
errors: PropTypes.shape({
email: PropTypes.array,
username: PropTypes.array,
+ errorCode: PropTypes.string,
}),
submitCount: PropTypes.number,
+ intl: intlShape.isRequired,
};
-export default RegistrationFailureMessage;
+export default injectIntl(RegistrationFailureMessage);
diff --git a/src/register/data/sagas.js b/src/register/data/sagas.js
index f1c55427..00165df4 100644
--- a/src/register/data/sagas.js
+++ b/src/register/data/sagas.js
@@ -24,6 +24,7 @@ import {
getRegistrationForm,
registerRequest,
} from './service';
+import { INTERNAL_SERVER_ERROR } from '../../login/data/constants';
export function* handleNewUserRegistration(action) {
try {
@@ -39,6 +40,8 @@ export function* handleNewUserRegistration(action) {
const statusCodes = [400, 409, 403];
if (e.response && statusCodes.includes(e.response.status)) {
yield put(registerNewUserFailure(e.response.data));
+ } else {
+ yield put(registerNewUserFailure({ errorCode: INTERNAL_SERVER_ERROR }));
}
logError(e);
}
diff --git a/src/register/data/tests/sagas.test.js b/src/register/data/tests/sagas.test.js
index a2d5457b..94cb83ee 100644
--- a/src/register/data/tests/sagas.test.js
+++ b/src/register/data/tests/sagas.test.js
@@ -1,5 +1,6 @@
import { runSaga } from 'redux-saga';
+import { camelCaseObject } from '@edx/frontend-platform';
import * as actions from '../actions';
import {
fetchRealtimeValidations,
@@ -188,6 +189,32 @@ describe('handleNewUserRegistration', () => {
registerRequest.mockClear();
});
+ it('should handle 500 error code', async () => {
+ const registerErrorResponse = {
+ response: {
+ status: 500,
+ data: {
+ errorCode: 'internal-server-error',
+ },
+ },
+ };
+
+ const registerRequest = jest.spyOn(api, 'registerRequest').mockImplementation(() => Promise.reject(registerErrorResponse));
+
+ const dispatched = [];
+ await runSaga(
+ { dispatch: (action) => dispatched.push(action) },
+ handleNewUserRegistration,
+ params,
+ );
+
+ expect(dispatched).toEqual([
+ actions.registerNewUserBegin(),
+ actions.registerNewUserFailure(camelCaseObject(registerErrorResponse.response.data)),
+ ]);
+ registerRequest.mockClear();
+ });
+
it('should call service and dispatch error action', async () => {
const loginErrorResponse = {
response: {
diff --git a/src/register/messages.jsx b/src/register/messages.jsx
index a3c60915..dcd892f8 100644
--- a/src/register/messages.jsx
+++ b/src/register/messages.jsx
@@ -116,6 +116,16 @@ const messages = defineMessages({
defaultMessage: '(optional)',
description: 'Text that appears with optional field labels',
},
+ 'registration.request.server.error': {
+ id: 'registration.request.server.error',
+ defaultMessage: 'An error has occurred. Try refreshing the page, or check your Internet connection.',
+ description: 'error message on server error.',
+ },
+ 'registration.request.failure.header': {
+ id: 'registration.request.failure.header',
+ defaultMessage: 'We couldn\'t create your account.',
+ description: 'error message when registration failure.',
+ },
});
export default messages;
diff --git a/src/register/tests/RegistrationPage.test.jsx b/src/register/tests/RegistrationPage.test.jsx
index 706324c1..0d02c4d6 100644
--- a/src/register/tests/RegistrationPage.test.jsx
+++ b/src/register/tests/RegistrationPage.test.jsx
@@ -9,7 +9,9 @@ import * as analytics from '@edx/frontend-platform/analytics';
import RegistrationPage from '../RegistrationPage';
import { RenderInstitutionButton } from '../../common-components';
+import RegistrationFailureMessage from '../RegistrationFailure';
import { PENDING_STATE } from '../../data/constants';
+import { INTERNAL_SERVER_ERROR } from '../../login/data/constants';
import { fetchRegistrationForm, fetchRealtimeValidations, registerNewUser } from '../data/actions';
jest.mock('@edx/frontend-platform/analytics');
@@ -18,6 +20,7 @@ analytics.sendTrackEvent = jest.fn();
analytics.sendPageEvent = jest.fn();
const IntlRegistrationPage = injectIntl(RegistrationPage);
+const IntlRegistrationFailure = injectIntl(RegistrationFailureMessage);
const mockStore = configureStore();
describe('./RegistrationPage.js', () => {
@@ -326,6 +329,19 @@ describe('./RegistrationPage.js', () => {
expect(tree.toJSON()).toMatchSnapshot();
});
+ it('should match internal server error message', () => {
+ props = {
+ errors: {
+ errorCode: INTERNAL_SERVER_ERROR,
+ },
+ };
+
+ const registrationPage = mount(reduxWrapper());
+ expect(registrationPage.find('div.alert-heading').length).toEqual(1);
+ const expectedMessage = 'We couldn\'t create your account.An error has occurred. Try refreshing the page, or check your Internet connection.';
+ expect(registrationPage.find('div.alert').first().text()).toEqual(expectedMessage);
+ });
+
it('should match pending button state snapshot', () => {
store = mockStore({
...initialState,
diff --git a/src/register/tests/__snapshots__/RegistrationPage.test.jsx.snap b/src/register/tests/__snapshots__/RegistrationPage.test.jsx.snap
index bd5603d9..e6b8da4b 100644
--- a/src/register/tests/__snapshots__/RegistrationPage.test.jsx.snap
+++ b/src/register/tests/__snapshots__/RegistrationPage.test.jsx.snap
@@ -976,24 +976,20 @@ exports[`./RegistrationPage.js should show error message on 409 1`] = `
-
- We couldn't create your account.
-
-
-
-
- -
- It looks like test@gmail.com belongs to an existing account. Try again with a different email address.
-
- -
- It looks like test belongs to an existing account. Try again with a different username.
-
-
+ We couldn't create your account.
+
+ -
+ It looks like test@gmail.com belongs to an existing account. Try again with a different email address.
+
+ -
+ It looks like test belongs to an existing account. Try again with a different username.
+
+