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();