diff --git a/test/unit/components/email-step.test.jsx b/test/unit/components/email-step.test.jsx
index 73a84e857..b787802d4 100644
--- a/test/unit/components/email-step.test.jsx
+++ b/test/unit/components/email-step.test.jsx
@@ -1,11 +1,30 @@
const React = require('react');
const {shallowWithIntl} = require('../../helpers/intl-helpers.jsx');
-const EmailStep = require('../../../src/components/join-flow/email-step.jsx');
const JoinFlowStep = require('../../../src/components/join-flow/join-flow-step.jsx');
const FormikInput = require('../../../src/components/formik-forms/formik-input.jsx');
const FormikCheckbox = require('../../../src/components/formik-forms/formik-checkbox.jsx');
+const mockedValidateEmailRemotely = jest.fn(() => (
+ /* eslint-disable no-undef */
+ Promise.resolve({valid: false, errMsgId: 'registration.validationEmailInvalid'})
+ /* eslint-enable no-undef */
+));
+
+jest.mock('../../../src/lib/validate.js', () => (
+ {
+ ...(jest.requireActual('../../../src/lib/validate.js')),
+ validateEmailRemotely: mockedValidateEmailRemotely
+ }
+));
+
+// must come after validation mocks, so validate.js will be mocked before it is required
+const EmailStep = require('../../../src/components/join-flow/email-step.jsx');
+
describe('EmailStep test', () => {
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+
test('send correct props to formik', () => {
const wrapper = shallowWithIntl();
@@ -174,4 +193,66 @@ describe('EmailStep test', () => {
const val = formikWrapper.instance().validateEmail();
expect(val).toBe('general.required');
});
+
+ test('validateEmailRemotelyWithCache calls validate.validateEmailRemotely', done => {
+ const wrapper = shallowWithIntl(
+ );
+ const instance = wrapper.dive().instance();
+
+ instance.validateEmailRemotelyWithCache('some-email@some-domain.com')
+ .then(response => {
+ expect(mockedValidateEmailRemotely).toHaveBeenCalled();
+ expect(response.valid).toBe(false);
+ expect(response.errMsgId).toBe('registration.validationEmailInvalid');
+ done();
+ });
+ });
+
+ test('validateEmailRemotelyWithCache, called twice with different data, makes two remote requests', done => {
+ const wrapper = shallowWithIntl(
+
+ );
+ const instance = wrapper.dive().instance();
+
+ instance.validateEmailRemotelyWithCache('some-email@some-domain.com')
+ .then(response => {
+ expect(mockedValidateEmailRemotely).toHaveBeenCalledTimes(1);
+ expect(response.valid).toBe(false);
+ expect(response.errMsgId).toBe('registration.validationEmailInvalid');
+ })
+ .then(() => {
+ // make the same request a second time
+ instance.validateEmailRemotelyWithCache('different-email@some-domain.org')
+ .then(response => {
+ expect(mockedValidateEmailRemotely).toHaveBeenCalledTimes(2);
+ expect(response.valid).toBe(false);
+ expect(response.errMsgId).toBe('registration.validationEmailInvalid');
+ done();
+ });
+ });
+ });
+
+ test('validateEmailRemotelyWithCache, called twice with same data, only makes one remote request', done => {
+ const wrapper = shallowWithIntl(
+
+ );
+ const instance = wrapper.dive().instance();
+
+ instance.validateEmailRemotelyWithCache('some-email@some-domain.com')
+ .then(response => {
+ expect(mockedValidateEmailRemotely).toHaveBeenCalledTimes(1);
+ expect(response.valid).toBe(false);
+ expect(response.errMsgId).toBe('registration.validationEmailInvalid');
+ })
+ .then(() => {
+ // make the same request a second time
+ instance.validateEmailRemotelyWithCache('some-email@some-domain.com')
+ .then(response => {
+ expect(mockedValidateEmailRemotely).toHaveBeenCalledTimes(1);
+ expect(response.valid).toBe(false);
+ expect(response.errMsgId).toBe('registration.validationEmailInvalid');
+ done();
+ });
+ });
+ });
});
diff --git a/test/unit/components/username-step.test.jsx b/test/unit/components/username-step.test.jsx
new file mode 100644
index 000000000..74cde0ef0
--- /dev/null
+++ b/test/unit/components/username-step.test.jsx
@@ -0,0 +1,118 @@
+const React = require('react');
+const {shallowWithIntl} = require('../../helpers/intl-helpers.jsx');
+
+const mockedValidateUsernameRemotely = jest.fn(() => (
+ /* eslint-disable no-undef */
+ Promise.resolve({valid: false, errMsgId: 'registration.validationUsernameNotAllowed'})
+ /* eslint-enable no-undef */
+));
+
+jest.mock('../../../src/lib/validate.js', () => (
+ {
+ ...(jest.requireActual('../../../src/lib/validate.js')),
+ validateUsernameRemotely: mockedValidateUsernameRemotely
+ }
+));
+
+// 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');
+
+describe('UsernameStep test', () => {
+
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+
+ test('send correct props to formik', () => {
+ const wrapper = shallowWithIntl();
+ const formikWrapper = wrapper.dive();
+ expect(formikWrapper.props().initialValues.username).toBe('');
+ expect(formikWrapper.props().initialValues.password).toBe('');
+ expect(formikWrapper.props().initialValues.passwordConfirm).toBe('');
+ expect(formikWrapper.props().initialValues.showPassword).toBe(false);
+ expect(formikWrapper.props().validateOnBlur).toBe(false);
+ expect(formikWrapper.props().validateOnChange).toBe(false);
+ expect(formikWrapper.props().validate).toBe(formikWrapper.instance().validateForm);
+ expect(formikWrapper.props().onSubmit).toBe(formikWrapper.instance().handleValidSubmit);
+ });
+
+ test('handleValidSubmit passes formData to next step', () => {
+ const formikBag = {
+ setSubmitting: jest.fn()
+ };
+ const formData = {item1: 'thing', item2: 'otherthing'};
+ const mockedOnNextStep = jest.fn();
+ const wrapper = shallowWithIntl(
+
+ );
+ const instance = wrapper.dive().instance();
+
+ instance.handleValidSubmit(formData, formikBag);
+ expect(formikBag.setSubmitting).toHaveBeenCalledWith(false);
+ expect(mockedOnNextStep).toHaveBeenCalledWith(formData);
+ });
+
+ test('validateUsernameRemotelyWithCache calls validate.validateUsernameRemotely', done => {
+ const wrapper = shallowWithIntl(
+ );
+ const instance = wrapper.dive().instance();
+
+ instance.validateUsernameRemotelyWithCache('newUniqueUsername55')
+ .then(response => {
+ expect(mockedValidateUsernameRemotely).toHaveBeenCalled();
+ expect(response.valid).toBe(false);
+ expect(response.errMsgId).toBe('registration.validationUsernameNotAllowed');
+ done();
+ });
+ });
+
+ test('validateUsernameRemotelyWithCache, called twice with different data, makes two remote requests', done => {
+ const wrapper = shallowWithIntl(
+
+ );
+ const instance = wrapper.dive().instance();
+
+ instance.validateUsernameRemotelyWithCache('newUniqueUsername55')
+ .then(response => {
+ expect(mockedValidateUsernameRemotely).toHaveBeenCalledTimes(1);
+ expect(response.valid).toBe(false);
+ expect(response.errMsgId).toBe('registration.validationUsernameNotAllowed');
+ })
+ .then(() => {
+ // make the same request a second time
+ instance.validateUsernameRemotelyWithCache('secondDifferent66')
+ .then(response => {
+ expect(mockedValidateUsernameRemotely).toHaveBeenCalledTimes(2);
+ expect(response.valid).toBe(false);
+ expect(response.errMsgId).toBe('registration.validationUsernameNotAllowed');
+ done();
+ });
+ });
+ });
+
+ test('validateUsernameRemotelyWithCache, called twice with same data, only makes one remote request', done => {
+ const wrapper = shallowWithIntl(
+
+ );
+ const instance = wrapper.dive().instance();
+
+ instance.validateUsernameRemotelyWithCache('newUniqueUsername55')
+ .then(response => {
+ expect(mockedValidateUsernameRemotely).toHaveBeenCalledTimes(1);
+ expect(response.valid).toBe(false);
+ expect(response.errMsgId).toBe('registration.validationUsernameNotAllowed');
+ })
+ .then(() => {
+ // make the same request a second time
+ instance.validateUsernameRemotelyWithCache('newUniqueUsername55')
+ .then(response => {
+ expect(mockedValidateUsernameRemotely).toHaveBeenCalledTimes(1);
+ expect(response.valid).toBe(false);
+ expect(response.errMsgId).toBe('registration.validationUsernameNotAllowed');
+ done();
+ });
+ });
+ });
+});