mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-02-17 00:21:20 -05:00
Merge pull request #3503 from picklesrus/join-ga
Add analytics logging to join flow.
This commit is contained in:
commit
b845010025
12 changed files with 182 additions and 20 deletions
|
@ -54,6 +54,12 @@ class BirthDateStep extends React.Component {
|
||||||
'validateSelect'
|
'validateSelect'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
componentDidMount () {
|
||||||
|
if (this.props.sendAnalytics) {
|
||||||
|
this.props.sendAnalytics('join-birthdate');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
validateSelect (selection) {
|
validateSelect (selection) {
|
||||||
if (selection === 'null') {
|
if (selection === 'null') {
|
||||||
return this.props.intl.formatMessage({id: 'general.required'});
|
return this.props.intl.formatMessage({id: 'general.required'});
|
||||||
|
@ -162,7 +168,8 @@ class BirthDateStep extends React.Component {
|
||||||
|
|
||||||
BirthDateStep.propTypes = {
|
BirthDateStep.propTypes = {
|
||||||
intl: intlShape,
|
intl: intlShape,
|
||||||
onNextStep: PropTypes.func
|
onNextStep: PropTypes.func,
|
||||||
|
sendAnalytics: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const IntlBirthDateStep = injectIntl(BirthDateStep);
|
const IntlBirthDateStep = injectIntl(BirthDateStep);
|
||||||
|
|
|
@ -23,6 +23,9 @@ class CountryStep extends React.Component {
|
||||||
this.countryOptions = [];
|
this.countryOptions = [];
|
||||||
}
|
}
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
|
if (this.props.sendAnalytics) {
|
||||||
|
this.props.sendAnalytics('join-country');
|
||||||
|
}
|
||||||
this.setCountryOptions();
|
this.setCountryOptions();
|
||||||
}
|
}
|
||||||
setCountryOptions () {
|
setCountryOptions () {
|
||||||
|
@ -120,7 +123,8 @@ class CountryStep extends React.Component {
|
||||||
|
|
||||||
CountryStep.propTypes = {
|
CountryStep.propTypes = {
|
||||||
intl: intlShape,
|
intl: intlShape,
|
||||||
onNextStep: PropTypes.func
|
onNextStep: PropTypes.func,
|
||||||
|
sendAnalytics: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const IntlCountryStep = injectIntl(CountryStep);
|
const IntlCountryStep = injectIntl(CountryStep);
|
||||||
|
|
|
@ -35,6 +35,9 @@ class EmailStep extends React.Component {
|
||||||
this.emailRemoteCache = {};
|
this.emailRemoteCache = {};
|
||||||
}
|
}
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
|
if (this.props.sendAnalytics) {
|
||||||
|
this.props.sendAnalytics('join-email');
|
||||||
|
}
|
||||||
// automatically start with focus on username field
|
// automatically start with focus on username field
|
||||||
if (this.emailInput) this.emailInput.focus();
|
if (this.emailInput) this.emailInput.focus();
|
||||||
|
|
||||||
|
@ -231,6 +234,7 @@ EmailStep.propTypes = {
|
||||||
intl: intlShape,
|
intl: intlShape,
|
||||||
onCaptchaError: PropTypes.func,
|
onCaptchaError: PropTypes.func,
|
||||||
onNextStep: PropTypes.func,
|
onNextStep: PropTypes.func,
|
||||||
|
sendAnalytics: PropTypes.func.isRequired,
|
||||||
waiting: PropTypes.bool
|
waiting: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,11 @@ class GenderStep extends React.Component {
|
||||||
'handleValidSubmit'
|
'handleValidSubmit'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
componentDidMount () {
|
||||||
|
if (this.props.sendAnalytics) {
|
||||||
|
this.props.sendAnalytics('join-gender');
|
||||||
|
}
|
||||||
|
}
|
||||||
handleSetCustomRef (customInputRef) {
|
handleSetCustomRef (customInputRef) {
|
||||||
this.customInput = customInputRef;
|
this.customInput = customInputRef;
|
||||||
}
|
}
|
||||||
|
@ -180,7 +185,8 @@ class GenderStep extends React.Component {
|
||||||
|
|
||||||
GenderStep.propTypes = {
|
GenderStep.propTypes = {
|
||||||
intl: intlShape,
|
intl: intlShape,
|
||||||
onNextStep: PropTypes.func
|
onNextStep: PropTypes.func,
|
||||||
|
sendAnalytics: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = injectIntl(GenderStep);
|
module.exports = injectIntl(GenderStep);
|
||||||
|
|
|
@ -215,6 +215,18 @@ class JoinFlow extends React.Component {
|
||||||
resetState () {
|
resetState () {
|
||||||
this.setState(this.initialState);
|
this.setState(this.initialState);
|
||||||
}
|
}
|
||||||
|
sendAnalytics (path) {
|
||||||
|
const gaID = window.GA_ID;
|
||||||
|
if (!window.ga) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.ga('send', {
|
||||||
|
hitType: 'pageview',
|
||||||
|
page: path,
|
||||||
|
tid: gaID
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
|
@ -222,17 +234,33 @@ class JoinFlow extends React.Component {
|
||||||
<RegistrationErrorStep
|
<RegistrationErrorStep
|
||||||
canTryAgain={this.canTryAgain()}
|
canTryAgain={this.canTryAgain()}
|
||||||
errorMsg={this.state.registrationError.errorMsg}
|
errorMsg={this.state.registrationError.errorMsg}
|
||||||
|
sendAnalytics={this.sendAnalytics}
|
||||||
/* eslint-disable react/jsx-no-bind */
|
/* eslint-disable react/jsx-no-bind */
|
||||||
onSubmit={this.handleErrorNext}
|
onSubmit={this.handleErrorNext}
|
||||||
/* eslint-enable react/jsx-no-bind */
|
/* eslint-enable react/jsx-no-bind */
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Progression step={this.state.step}>
|
<Progression step={this.state.step}>
|
||||||
<UsernameStep onNextStep={this.handleAdvanceStep} />
|
<UsernameStep
|
||||||
<CountryStep onNextStep={this.handleAdvanceStep} />
|
sendAnalytics={this.sendAnalytics}
|
||||||
<BirthDateStep onNextStep={this.handleAdvanceStep} />
|
onNextStep={this.handleAdvanceStep}
|
||||||
<GenderStep onNextStep={this.handleAdvanceStep} />
|
/>
|
||||||
|
<CountryStep
|
||||||
|
sendAnalytics={this.sendAnalytics}
|
||||||
|
onNextStep={this.handleAdvanceStep}
|
||||||
|
/>
|
||||||
|
<BirthDateStep
|
||||||
|
sendAnalytics={this.sendAnalytics}
|
||||||
|
onNextStep={this.handleAdvanceStep}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<GenderStep
|
||||||
|
sendAnalytics={this.sendAnalytics}
|
||||||
|
onNextStep={this.handleAdvanceStep}
|
||||||
|
/>
|
||||||
|
|
||||||
<EmailStep
|
<EmailStep
|
||||||
|
sendAnalytics={this.sendAnalytics}
|
||||||
waiting={this.state.waiting}
|
waiting={this.state.waiting}
|
||||||
onCaptchaError={this.handleCaptchaError}
|
onCaptchaError={this.handleCaptchaError}
|
||||||
onNextStep={this.handlePrepareToRegister}
|
onNextStep={this.handlePrepareToRegister}
|
||||||
|
@ -240,6 +268,7 @@ class JoinFlow extends React.Component {
|
||||||
<WelcomeStep
|
<WelcomeStep
|
||||||
createProjectOnComplete={this.props.createProjectOnComplete}
|
createProjectOnComplete={this.props.createProjectOnComplete}
|
||||||
email={this.state.formData.email}
|
email={this.state.formData.email}
|
||||||
|
sendAnalytics={this.sendAnalytics}
|
||||||
username={this.state.formData.username}
|
username={this.state.formData.username}
|
||||||
onNextStep={this.props.onCompleteRegistration}
|
onNextStep={this.props.onCompleteRegistration}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -15,6 +15,11 @@ class RegistrationErrorStep extends React.Component {
|
||||||
'handleSubmit'
|
'handleSubmit'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
componentDidMount () {
|
||||||
|
if (this.props.sendAnalytics) {
|
||||||
|
this.props.sendAnalytics('join-error');
|
||||||
|
}
|
||||||
|
}
|
||||||
handleSubmit (e) {
|
handleSubmit (e) {
|
||||||
// JoinFlowStep includes a <form> that handles a submit action.
|
// JoinFlowStep includes a <form> that handles a submit action.
|
||||||
// But here, we're not really submitting, so we need to prevent
|
// But here, we're not really submitting, so we need to prevent
|
||||||
|
@ -60,7 +65,8 @@ RegistrationErrorStep.propTypes = {
|
||||||
canTryAgain: PropTypes.bool.isRequired,
|
canTryAgain: PropTypes.bool.isRequired,
|
||||||
errorMsg: PropTypes.string,
|
errorMsg: PropTypes.string,
|
||||||
intl: intlShape,
|
intl: intlShape,
|
||||||
onSubmit: PropTypes.func.isRequired
|
onSubmit: PropTypes.func.isRequired,
|
||||||
|
sendAnalytics: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
RegistrationErrorStep.defaultProps = {
|
RegistrationErrorStep.defaultProps = {
|
||||||
|
|
|
@ -37,6 +37,14 @@ class UsernameStep extends React.Component {
|
||||||
this.usernameRemoteCache = {};
|
this.usernameRemoteCache = {};
|
||||||
}
|
}
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
|
// Send info to analytics when we aren't on the standalone page.
|
||||||
|
// If we are on the standalone join page, the page load will take care of this.
|
||||||
|
if (!window.location.pathname.includes('/join')) {
|
||||||
|
if (this.props.sendAnalytics) {
|
||||||
|
this.props.sendAnalytics('join-username-modal');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// automatically start with focus on username field
|
// automatically start with focus on username field
|
||||||
if (this.usernameInput) this.usernameInput.focus();
|
if (this.usernameInput) this.usernameInput.focus();
|
||||||
}
|
}
|
||||||
|
@ -282,7 +290,8 @@ class UsernameStep extends React.Component {
|
||||||
|
|
||||||
UsernameStep.propTypes = {
|
UsernameStep.propTypes = {
|
||||||
intl: intlShape,
|
intl: intlShape,
|
||||||
onNextStep: PropTypes.func
|
onNextStep: PropTypes.func,
|
||||||
|
sendAnalytics: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const IntlUsernameStep = injectIntl(UsernameStep);
|
const IntlUsernameStep = injectIntl(UsernameStep);
|
||||||
|
|
|
@ -17,6 +17,12 @@ class WelcomeStep extends React.Component {
|
||||||
'validateForm'
|
'validateForm'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
componentDidMount () {
|
||||||
|
if (this.props.sendAnalytics) {
|
||||||
|
this.props.sendAnalytics('join-welcome');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
validateForm () {
|
validateForm () {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -87,6 +93,7 @@ WelcomeStep.propTypes = {
|
||||||
email: PropTypes.string,
|
email: PropTypes.string,
|
||||||
intl: intlShape,
|
intl: intlShape,
|
||||||
onNextStep: PropTypes.func,
|
onNextStep: PropTypes.func,
|
||||||
|
sendAnalytics: PropTypes.func,
|
||||||
username: PropTypes.string
|
username: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const {shallowWithIntl} = require('../../helpers/intl-helpers.jsx');
|
const {shallowWithIntl} = require('../../helpers/intl-helpers.jsx');
|
||||||
|
const {mountWithIntl} = require('../../helpers/intl-helpers.jsx');
|
||||||
const JoinFlowStep = require('../../../src/components/join-flow/join-flow-step.jsx');
|
const JoinFlowStep = require('../../../src/components/join-flow/join-flow-step.jsx');
|
||||||
const FormikInput = require('../../../src/components/formik-forms/formik-input.jsx');
|
const FormikInput = require('../../../src/components/formik-forms/formik-input.jsx');
|
||||||
const FormikCheckbox = require('../../../src/components/formik-forms/formik-checkbox.jsx');
|
const FormikCheckbox = require('../../../src/components/formik-forms/formik-checkbox.jsx');
|
||||||
|
@ -36,13 +37,17 @@ jest.mock('../../../src/lib/validate.js', () => (
|
||||||
const EmailStep = require('../../../src/components/join-flow/email-step.jsx');
|
const EmailStep = require('../../../src/components/join-flow/email-step.jsx');
|
||||||
|
|
||||||
describe('EmailStep test', () => {
|
describe('EmailStep test', () => {
|
||||||
|
const defaultProps = () => ({
|
||||||
|
sendAnalytics: jest.fn()
|
||||||
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('send correct props to formik', () => {
|
test('send correct props to formik', () => {
|
||||||
const intlWrapper = shallowWithIntl(<EmailStep />);
|
const intlWrapper = shallowWithIntl(<EmailStep
|
||||||
|
{...defaultProps()}
|
||||||
|
/>);
|
||||||
const emailStepWrapper = intlWrapper.dive();
|
const emailStepWrapper = intlWrapper.dive();
|
||||||
expect(emailStepWrapper.props().initialValues.subscribe).toBe(false);
|
expect(emailStepWrapper.props().initialValues.subscribe).toBe(false);
|
||||||
expect(emailStepWrapper.props().initialValues.email).toBe('');
|
expect(emailStepWrapper.props().initialValues.email).toBe('');
|
||||||
|
@ -53,7 +58,9 @@ describe('EmailStep test', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('props sent to JoinFlowStep', () => {
|
test('props sent to JoinFlowStep', () => {
|
||||||
const intlWrapper = shallowWithIntl(<EmailStep />);
|
const intlWrapper = shallowWithIntl(<EmailStep
|
||||||
|
{...defaultProps()}
|
||||||
|
/>);
|
||||||
// Dive to get past the intl wrapper
|
// Dive to get past the intl wrapper
|
||||||
const emailStepWrapper = intlWrapper.dive();
|
const emailStepWrapper = intlWrapper.dive();
|
||||||
// Dive to get past the anonymous component.
|
// Dive to get past the anonymous component.
|
||||||
|
@ -69,7 +76,9 @@ describe('EmailStep test', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('props sent to FormikInput for email', () => {
|
test('props sent to FormikInput for email', () => {
|
||||||
const intlWrapper = shallowWithIntl(<EmailStep />);
|
const intlWrapper = shallowWithIntl(<EmailStep
|
||||||
|
{...defaultProps()}
|
||||||
|
/>);
|
||||||
// Dive to get past the intl wrapper
|
// Dive to get past the intl wrapper
|
||||||
const emailStepWrapper = intlWrapper.dive();
|
const emailStepWrapper = intlWrapper.dive();
|
||||||
// Dive to get past the anonymous component.
|
// Dive to get past the anonymous component.
|
||||||
|
@ -86,7 +95,10 @@ describe('EmailStep test', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('props sent to FormikCheckbox for subscribe', () => {
|
test('props sent to FormikCheckbox for subscribe', () => {
|
||||||
const intlWrapper = shallowWithIntl(<EmailStep />);
|
const intlWrapper = shallowWithIntl(<EmailStep
|
||||||
|
{...defaultProps()}
|
||||||
|
/>);
|
||||||
|
|
||||||
// Dive to get past the intl wrapper
|
// Dive to get past the intl wrapper
|
||||||
const emailStepWrapper = intlWrapper.dive();
|
const emailStepWrapper = intlWrapper.dive();
|
||||||
// Dive to get past the anonymous component.
|
// Dive to get past the anonymous component.
|
||||||
|
@ -109,7 +121,10 @@ describe('EmailStep test', () => {
|
||||||
};
|
};
|
||||||
const formData = {item1: 'thing', item2: 'otherthing'};
|
const formData = {item1: 'thing', item2: 'otherthing'};
|
||||||
const intlWrapper = shallowWithIntl(
|
const intlWrapper = shallowWithIntl(
|
||||||
<EmailStep />);
|
<EmailStep
|
||||||
|
{...defaultProps()}
|
||||||
|
/>);
|
||||||
|
|
||||||
|
|
||||||
const emailStepWrapper = intlWrapper.dive();
|
const emailStepWrapper = intlWrapper.dive();
|
||||||
emailStepWrapper.instance().onCaptchaLoad(); // to setup catpcha state
|
emailStepWrapper.instance().onCaptchaLoad(); // to setup catpcha state
|
||||||
|
@ -133,6 +148,7 @@ describe('EmailStep test', () => {
|
||||||
const formData = {item1: 'thing', item2: 'otherthing'};
|
const formData = {item1: 'thing', item2: 'otherthing'};
|
||||||
const intlWrapper = shallowWithIntl(
|
const intlWrapper = shallowWithIntl(
|
||||||
<EmailStep
|
<EmailStep
|
||||||
|
{...defaultProps()}
|
||||||
{...props}
|
{...props}
|
||||||
/>);
|
/>);
|
||||||
|
|
||||||
|
@ -162,6 +178,7 @@ describe('EmailStep test', () => {
|
||||||
global.grecaptcha = null;
|
global.grecaptcha = null;
|
||||||
const intlWrapper = shallowWithIntl(
|
const intlWrapper = shallowWithIntl(
|
||||||
<EmailStep
|
<EmailStep
|
||||||
|
{...defaultProps()}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -171,9 +188,20 @@ describe('EmailStep test', () => {
|
||||||
expect(props.onCaptchaError).toHaveBeenCalled();
|
expect(props.onCaptchaError).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Component logs analytics', () => {
|
||||||
|
const sendAnalyticsFn = jest.fn();
|
||||||
|
mountWithIntl(
|
||||||
|
<EmailStep
|
||||||
|
sendAnalytics={sendAnalyticsFn}
|
||||||
|
/>);
|
||||||
|
expect(sendAnalyticsFn).toHaveBeenCalledWith('join-email');
|
||||||
|
});
|
||||||
|
|
||||||
test('validateEmail test email empty', () => {
|
test('validateEmail test email empty', () => {
|
||||||
const intlWrapper = shallowWithIntl(
|
const intlWrapper = shallowWithIntl(
|
||||||
<EmailStep />);
|
<EmailStep
|
||||||
|
{...defaultProps()}
|
||||||
|
/>);
|
||||||
const emailStepWrapper = intlWrapper.dive();
|
const emailStepWrapper = intlWrapper.dive();
|
||||||
const val = emailStepWrapper.instance().validateEmail('');
|
const val = emailStepWrapper.instance().validateEmail('');
|
||||||
expect(val).toBe('general.required');
|
expect(val).toBe('general.required');
|
||||||
|
@ -181,7 +209,9 @@ describe('EmailStep test', () => {
|
||||||
|
|
||||||
test('validateEmail test email null', () => {
|
test('validateEmail test email null', () => {
|
||||||
const intlWrapper = shallowWithIntl(
|
const intlWrapper = shallowWithIntl(
|
||||||
<EmailStep />);
|
<EmailStep
|
||||||
|
{...defaultProps()}
|
||||||
|
/>);
|
||||||
const emailStepWrapper = intlWrapper.dive();
|
const emailStepWrapper = intlWrapper.dive();
|
||||||
const val = emailStepWrapper.instance().validateEmail(null);
|
const val = emailStepWrapper.instance().validateEmail(null);
|
||||||
expect(val).toBe('general.required');
|
expect(val).toBe('general.required');
|
||||||
|
@ -189,7 +219,9 @@ describe('EmailStep test', () => {
|
||||||
|
|
||||||
test('validateEmail test email undefined', () => {
|
test('validateEmail test email undefined', () => {
|
||||||
const intlWrapper = shallowWithIntl(
|
const intlWrapper = shallowWithIntl(
|
||||||
<EmailStep />);
|
<EmailStep
|
||||||
|
{...defaultProps()}
|
||||||
|
/>);
|
||||||
const emailStepWrapper = intlWrapper.dive();
|
const emailStepWrapper = intlWrapper.dive();
|
||||||
const val = emailStepWrapper.instance().validateEmail();
|
const val = emailStepWrapper.instance().validateEmail();
|
||||||
expect(val).toBe('general.required');
|
expect(val).toBe('general.required');
|
||||||
|
@ -204,7 +236,8 @@ describe('validateEmailRemotelyWithCache test with successful requests', () => {
|
||||||
|
|
||||||
test('validateEmailRemotelyWithCache calls validate.validateEmailRemotely', done => {
|
test('validateEmailRemotelyWithCache calls validate.validateEmailRemotely', done => {
|
||||||
const intlWrapper = shallowWithIntl(
|
const intlWrapper = shallowWithIntl(
|
||||||
<EmailStep />);
|
<EmailStep />
|
||||||
|
);
|
||||||
const instance = intlWrapper.dive().instance();
|
const instance = intlWrapper.dive().instance();
|
||||||
|
|
||||||
instance.validateEmailRemotelyWithCache('some-email@some-domain.com')
|
instance.validateEmailRemotelyWithCache('some-email@some-domain.com')
|
||||||
|
|
|
@ -67,6 +67,19 @@ describe('JoinFlow', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('sendAnalytics calls google analytics with correct params', () => {
|
||||||
|
const joinFlowInstance = getJoinFlowWrapper().instance();
|
||||||
|
global.window.ga = jest.fn();
|
||||||
|
global.window.GA_ID = '1234';
|
||||||
|
joinFlowInstance.sendAnalytics('page-path');
|
||||||
|
const obj = {
|
||||||
|
hitType: 'pageview',
|
||||||
|
page: 'page-path',
|
||||||
|
tid: '1234'
|
||||||
|
};
|
||||||
|
expect(global.window.ga).toHaveBeenCalledWith('send', obj);
|
||||||
|
});
|
||||||
|
|
||||||
test('handleAdvanceStep', () => {
|
test('handleAdvanceStep', () => {
|
||||||
const joinFlowInstance = getJoinFlowWrapper().instance();
|
const joinFlowInstance = getJoinFlowWrapper().instance();
|
||||||
joinFlowInstance.setState({formData: {username: 'ScratchCat123'}, step: 2});
|
joinFlowInstance.setState({formData: {username: 'ScratchCat123'}, step: 2});
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {shallowWithIntl} from '../../helpers/intl-helpers.jsx';
|
import {shallowWithIntl} from '../../helpers/intl-helpers.jsx';
|
||||||
|
import {mountWithIntl} from '../../helpers/intl-helpers.jsx';
|
||||||
import JoinFlowStep from '../../../src/components/join-flow/join-flow-step';
|
import JoinFlowStep from '../../../src/components/join-flow/join-flow-step';
|
||||||
import RegistrationErrorStep from '../../../src/components/join-flow/registration-error-step';
|
import RegistrationErrorStep from '../../../src/components/join-flow/registration-error-step';
|
||||||
|
|
||||||
|
@ -9,6 +10,7 @@ describe('RegistrationErrorStep', () => {
|
||||||
const getRegistrationErrorStepWrapper = props => {
|
const getRegistrationErrorStepWrapper = props => {
|
||||||
const wrapper = shallowWithIntl(
|
const wrapper = shallowWithIntl(
|
||||||
<RegistrationErrorStep
|
<RegistrationErrorStep
|
||||||
|
sendAnalytics={jest.fn()}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -61,6 +63,14 @@ describe('RegistrationErrorStep', () => {
|
||||||
expect(errMsgElement).toHaveLength(0);
|
expect(errMsgElement).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('logs to analytics', () => {
|
||||||
|
const analyticsFn = jest.fn();
|
||||||
|
mountWithIntl(
|
||||||
|
<RegistrationErrorStep
|
||||||
|
sendAnalytics={analyticsFn}
|
||||||
|
/>);
|
||||||
|
expect(analyticsFn).toHaveBeenCalledWith('join-error');
|
||||||
|
});
|
||||||
test('when canTryAgain is true, show tryAgain message', () => {
|
test('when canTryAgain is true, show tryAgain message', () => {
|
||||||
const props = {
|
const props = {
|
||||||
canTryAgain: true,
|
canTryAgain: true,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const {shallowWithIntl} = require('../../helpers/intl-helpers.jsx');
|
const {shallowWithIntl} = require('../../helpers/intl-helpers.jsx');
|
||||||
|
const {mountWithIntl} = require('../../helpers/intl-helpers.jsx');
|
||||||
|
|
||||||
const requestSuccessResponse = {
|
const requestSuccessResponse = {
|
||||||
requestSucceeded: true,
|
requestSucceeded: true,
|
||||||
|
@ -22,6 +23,7 @@ let mockedValidateUsernameRemotely = jest.fn(() => (
|
||||||
/* eslint-enable no-undef */
|
/* eslint-enable no-undef */
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
jest.mock('../../../src/lib/validate.js', () => (
|
jest.mock('../../../src/lib/validate.js', () => (
|
||||||
{
|
{
|
||||||
...(jest.requireActual('../../../src/lib/validate.js')),
|
...(jest.requireActual('../../../src/lib/validate.js')),
|
||||||
|
@ -32,10 +34,19 @@ jest.mock('../../../src/lib/validate.js', () => (
|
||||||
// must come after validation mocks, so validate.js will be mocked before it is required
|
// must come after validation mocks, so validate.js will be mocked before it is required
|
||||||
const UsernameStep = require('../../../src/components/join-flow/username-step.jsx');
|
const UsernameStep = require('../../../src/components/join-flow/username-step.jsx');
|
||||||
|
|
||||||
|
|
||||||
describe('UsernameStep tests', () => {
|
describe('UsernameStep tests', () => {
|
||||||
|
const defaultProps = () => ({
|
||||||
|
sendAnalytics: jest.fn()
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
test('send correct props to formik', () => {
|
test('send correct props to formik', () => {
|
||||||
const wrapper = shallowWithIntl(<UsernameStep />);
|
const wrapper = shallowWithIntl(<UsernameStep
|
||||||
|
{...defaultProps()}
|
||||||
|
/>);
|
||||||
const formikWrapper = wrapper.dive();
|
const formikWrapper = wrapper.dive();
|
||||||
expect(formikWrapper.props().initialValues.username).toBe('');
|
expect(formikWrapper.props().initialValues.username).toBe('');
|
||||||
expect(formikWrapper.props().initialValues.password).toBe('');
|
expect(formikWrapper.props().initialValues.password).toBe('');
|
||||||
|
@ -47,6 +58,28 @@ describe('UsernameStep tests', () => {
|
||||||
expect(formikWrapper.props().onSubmit).toBe(formikWrapper.instance().handleValidSubmit);
|
expect(formikWrapper.props().onSubmit).toBe(formikWrapper.instance().handleValidSubmit);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Component does not log if path is /join', () => {
|
||||||
|
const sendAnalyticsFn = jest.fn();
|
||||||
|
|
||||||
|
global.window.history.pushState({}, '', '/join');
|
||||||
|
mountWithIntl(
|
||||||
|
<UsernameStep
|
||||||
|
sendAnalytics={sendAnalyticsFn}
|
||||||
|
/>);
|
||||||
|
expect(sendAnalyticsFn).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Component logs analytics', () => {
|
||||||
|
// Make sure '/join' is NOT in the path
|
||||||
|
global.window.history.pushState({}, '', '/');
|
||||||
|
const sendAnalyticsFn = jest.fn();
|
||||||
|
mountWithIntl(
|
||||||
|
<UsernameStep
|
||||||
|
sendAnalytics={sendAnalyticsFn}
|
||||||
|
/>);
|
||||||
|
expect(sendAnalyticsFn).toHaveBeenCalledWith('join-username-modal');
|
||||||
|
});
|
||||||
|
|
||||||
test('handleValidSubmit passes formData to next step', () => {
|
test('handleValidSubmit passes formData to next step', () => {
|
||||||
const formikBag = {
|
const formikBag = {
|
||||||
setSubmitting: jest.fn()
|
setSubmitting: jest.fn()
|
||||||
|
@ -55,6 +88,7 @@ describe('UsernameStep tests', () => {
|
||||||
const mockedOnNextStep = jest.fn();
|
const mockedOnNextStep = jest.fn();
|
||||||
const wrapper = shallowWithIntl(
|
const wrapper = shallowWithIntl(
|
||||||
<UsernameStep
|
<UsernameStep
|
||||||
|
{...defaultProps()}
|
||||||
onNextStep={mockedOnNextStep}
|
onNextStep={mockedOnNextStep}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue