diff --git a/src/components/join-flow/email-step.jsx b/src/components/join-flow/email-step.jsx
index f2d1e42a3..803bd1bf8 100644
--- a/src/components/join-flow/email-step.jsx
+++ b/src/components/join-flow/email-step.jsx
@@ -56,7 +56,11 @@ class EmailStep extends React.Component {
this.emailInput = emailInputRef;
}
onCaptchaError () {
- // TODO send user to error step once we have one.
+ this.props.onRegistrationError(
+ this.props.intl.formatMessage({
+ id: 'registation.troubleReload'
+ })
+ );
}
onCaptchaLoad () {
this.setState({captchaIsLoading: false});
@@ -64,9 +68,9 @@ class EmailStep extends React.Component {
if (!this.grecaptcha) {
// According to the reCaptcha documentation, this callback shouldn't get
// called unless window.grecaptcha exists. This is just here to be extra defensive.
- // TODO: Put up the error screen when we have one.
+ this.onCaptchaError();
+ return;
}
- // TODO: Add in error callback for render once we have an error screen.
this.widgetId = this.grecaptcha.render(this.captchaRef,
{
callback: this.captchaSolved,
@@ -208,6 +212,7 @@ class EmailStep extends React.Component {
EmailStep.propTypes = {
intl: intlShape,
onNextStep: PropTypes.func,
+ onRegistrationError: PropTypes.func,
waiting: PropTypes.bool
};
diff --git a/src/components/join-flow/join-flow.jsx b/src/components/join-flow/join-flow.jsx
index 6b18d6a40..6849531e6 100644
--- a/src/components/join-flow/join-flow.jsx
+++ b/src/components/join-flow/join-flow.jsx
@@ -23,6 +23,7 @@ class JoinFlow extends React.Component {
super(props);
bindAll(this, [
'handleAdvanceStep',
+ 'handleRegistrationError',
'handlePrepareToRegister',
'handleRegistrationResponse',
'handleSubmitRegistration'
@@ -34,6 +35,14 @@ class JoinFlow extends React.Component {
waiting: false
};
}
+ handleRegistrationError (message) {
+ if (!message) {
+ message = this.props.intl.formatMessage({
+ id: 'registration.generalError'
+ });
+ }
+ this.setState({registrationError: message});
+ }
handlePrepareToRegister (newFormData) {
newFormData = newFormData || {};
const newState = {
@@ -143,6 +152,7 @@ class JoinFlow extends React.Component {
{
expect(emailInputWrapper.props().onSetRef).toEqual(formikWrapper.instance().handleSetEmailRef);
expect(emailInputWrapper.props().validate).toEqual(formikWrapper.instance().validateEmail);
});
+
test('props sent to FormikCheckbox for subscribe', () => {
const wrapper = shallowWithIntl();
// Dive to get past the intl wrapper
@@ -63,6 +64,7 @@ describe('EmailStep test', () => {
expect(checkboxWrapper.first().props().label).toEqual('registration.receiveEmails');
expect(checkboxWrapper.first().props().name).toEqual('subscribe');
});
+
test('handleValidSubmit passes formData to next step', () => {
const formikBag = {
setSubmitting: jest.fn()
@@ -82,6 +84,7 @@ describe('EmailStep test', () => {
expect(formikBag.setSubmitting).toHaveBeenCalledWith(false);
expect(global.grecaptcha.execute).toHaveBeenCalled();
});
+
test('captchaSolved sets token and goes to next step', () => {
const props = {
onNextStep: jest.fn()
@@ -116,6 +119,38 @@ describe('EmailStep test', () => {
}));
expect(formikBag.setSubmitting).toHaveBeenCalledWith(true);
});
+
+ test('onCaptchaError calls error function with correct message', () => {
+ const props = {
+ onRegistrationError: jest.fn()
+ };
+
+ const wrapper = shallowWithIntl(
+ );
+
+ const formikWrapper = wrapper.dive();
+ formikWrapper.instance().onCaptchaError();
+ expect(props.onRegistrationError).toHaveBeenCalledWith('registation.troubleReload');
+ });
+
+ test('Captcha load error calls error function', () => {
+ const props = {
+ onRegistrationError: jest.fn()
+ };
+ // Set this to null to force an error.
+ global.grecaptcha = null;
+ const wrapper = shallowWithIntl(
+ );
+
+ const formikWrapper = wrapper.dive();
+ formikWrapper.instance().onCaptchaLoad();
+ expect(props.onRegistrationError).toHaveBeenCalledWith('registation.troubleReload');
+ });
+
test('validateEmail test email empty', () => {
const wrapper = shallowWithIntl(
);
@@ -123,6 +158,7 @@ describe('EmailStep test', () => {
const val = formikWrapper.instance().validateEmail('');
expect(val).toBe('general.required');
});
+
test('validateEmail test email null', () => {
const wrapper = shallowWithIntl(
);
@@ -130,6 +166,7 @@ describe('EmailStep test', () => {
const val = formikWrapper.instance().validateEmail(null);
expect(val).toBe('general.required');
});
+
test('validateEmail test email undefined', () => {
const wrapper = shallowWithIntl(
);
diff --git a/test/unit/components/join-flow.test.jsx b/test/unit/components/join-flow.test.jsx
index 80dfe5a14..04cb1a6dc 100644
--- a/test/unit/components/join-flow.test.jsx
+++ b/test/unit/components/join-flow.test.jsx
@@ -126,6 +126,19 @@ describe('JoinFlow', () => {
expect(joinFlowInstance.props.refreshSession).not.toHaveBeenCalled();
expect(joinFlowInstance.state.registrationError).toBe('registration.generalError (400)');
});
+ test('handleRegistrationError with no message ', () => {
+ const joinFlowInstance = getJoinFlowWrapper().instance();
+ joinFlowInstance.setState({});
+ joinFlowInstance.handleRegistrationError();
+ expect(joinFlowInstance.state.registrationError).toBe('registration.generalError');
+ });
+
+ test('handleRegistrationError with message ', () => {
+ const joinFlowInstance = getJoinFlowWrapper().instance();
+ joinFlowInstance.setState({});
+ joinFlowInstance.handleRegistrationError('my message');
+ expect(joinFlowInstance.state.registrationError).toBe('my message');
+ });
test('handleAdvanceStep', () => {
const joinFlowInstance = getJoinFlowWrapper().instance();