mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-22 23:27:54 -05:00
Merge pull request #3367 from picklesrus/captcha-error-handling
Handle errors of captcha loading by setting error state on JoinFlow.
This commit is contained in:
commit
5f3d6506c0
5 changed files with 69 additions and 3 deletions
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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 {
|
|||
<EmailStep
|
||||
waiting={this.state.waiting}
|
||||
onNextStep={this.handlePrepareToRegister}
|
||||
onRegistrationError={this.handleRegistrationError}
|
||||
/>
|
||||
<WelcomeStep
|
||||
email={this.state.formData.email}
|
||||
|
|
|
@ -187,6 +187,7 @@
|
|||
"registration.selectCountry": "select country",
|
||||
"registration.studentPersonalStepDescription": "This information will not appear on the Scratch website.",
|
||||
"registration.showPassword": "Show password",
|
||||
"registration.troubleReload": "Scratch is having trouble finishing registration. Try reloading the page or try again in another browser.",
|
||||
"registration.usernameStepDescription": "Fill in the following forms to request an account. The approval process may take up to one day.",
|
||||
"registration.usernameStepDescriptionNonEducator": "Create projects, share ideas, make friends. It’s free!",
|
||||
"registration.usernameStepRealName": "Please do not use any portion of your real name in your username.",
|
||||
|
|
|
@ -50,6 +50,7 @@ describe('EmailStep test', () => {
|
|||
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(<EmailStep />);
|
||||
// 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(
|
||||
<EmailStep
|
||||
{...props}
|
||||
/>);
|
||||
|
||||
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(
|
||||
<EmailStep
|
||||
{...props}
|
||||
/>);
|
||||
|
||||
const formikWrapper = wrapper.dive();
|
||||
formikWrapper.instance().onCaptchaLoad();
|
||||
expect(props.onRegistrationError).toHaveBeenCalledWith('registation.troubleReload');
|
||||
});
|
||||
|
||||
test('validateEmail test email empty', () => {
|
||||
const wrapper = shallowWithIntl(
|
||||
<EmailStep />);
|
||||
|
@ -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(
|
||||
<EmailStep />);
|
||||
|
@ -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(
|
||||
<EmailStep />);
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue