fix: Migrate Registration tests to RTL (#1122)
This commit is contained in:
@@ -3,7 +3,7 @@ import { Provider } from 'react-redux';
|
||||
|
||||
import { mergeConfig } from '@edx/frontend-platform';
|
||||
import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { mount } from 'enzyme';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
@@ -82,8 +82,13 @@ describe('CountryField', () => {
|
||||
};
|
||||
|
||||
it('should run country field validation when onBlur is fired', () => {
|
||||
const countryField = mount(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
countryField.find('input[name="country"]').simulate('blur', { target: { value: '', name: 'country' } });
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
const countryInput = container.querySelector('input[name="country"]');
|
||||
|
||||
fireEvent.blur(countryInput, {
|
||||
target: { value: '', name: 'country' },
|
||||
});
|
||||
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'country',
|
||||
@@ -92,8 +97,13 @@ describe('CountryField', () => {
|
||||
});
|
||||
|
||||
it('should run country field validation when country name is invalid', () => {
|
||||
const countryField = mount(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
countryField.find('input[name="country"]').simulate('blur', { target: { value: 'Pak', name: 'country' } });
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
const countryInput = container.querySelector('input[name="country"]');
|
||||
|
||||
fireEvent.blur(countryInput, {
|
||||
target: { value: 'Pak', name: 'country' },
|
||||
});
|
||||
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'country',
|
||||
@@ -102,34 +112,36 @@ describe('CountryField', () => {
|
||||
});
|
||||
|
||||
it('should not run country field validation when onBlur is fired by drop-down arrow icon click', () => {
|
||||
const countryField = mount(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
countryField.find('input[name="country"]').simulate('blur', {
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
const countryInput = container.querySelector('input[name="country"]');
|
||||
const dropdownArrowIcon = container.querySelector('.btn-icon.pgn__form-autosuggest__icon-button');
|
||||
|
||||
fireEvent.blur(countryInput, {
|
||||
target: { value: '', name: 'country' },
|
||||
relatedTarget: { type: 'button', className: 'btn-icon pgn__form-autosuggest__icon-button' },
|
||||
relatedTarget: dropdownArrowIcon,
|
||||
});
|
||||
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should update errors for frontend validations', () => {
|
||||
const countryField = mount(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
const countryInput = container.querySelector('input[name="country"]');
|
||||
|
||||
fireEvent.blur(countryInput, { target: { value: '', name: 'country' } });
|
||||
|
||||
countryField.find('input[name="country"]').simulate('blur', { target: { value: '', name: 'country' } });
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'country',
|
||||
emptyFieldValidation.country,
|
||||
);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith('country', emptyFieldValidation.country);
|
||||
});
|
||||
|
||||
it('should clear error on focus', () => {
|
||||
const countryField = mount(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
const countryInput = container.querySelector('input[name="country"]');
|
||||
|
||||
fireEvent.focus(countryInput);
|
||||
|
||||
countryField.find('input[name="country"]').simulate('focus', { target: { value: '', name: 'country' } });
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'country',
|
||||
'',
|
||||
);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith('country', '');
|
||||
});
|
||||
|
||||
it('should update state from country code present in redux store', () => {
|
||||
@@ -141,7 +153,9 @@ describe('CountryField', () => {
|
||||
},
|
||||
});
|
||||
|
||||
mount(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
|
||||
container.querySelector('input[name="country"]');
|
||||
expect(props.onChangeHandler).toHaveBeenCalledTimes(1);
|
||||
expect(props.onChangeHandler).toHaveBeenCalledWith(
|
||||
{ target: { name: 'country' } },
|
||||
@@ -150,10 +164,13 @@ describe('CountryField', () => {
|
||||
});
|
||||
|
||||
it('should set option on dropdown menu item click', () => {
|
||||
const countryField = mount(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
|
||||
countryField.find('.pgn__form-autosuggest__icon-button').first().simulate('click');
|
||||
countryField.find('.dropdown-item').first().simulate('click');
|
||||
const dropdownButton = container.querySelector('.pgn__form-autosuggest__icon-button');
|
||||
fireEvent.click(dropdownButton);
|
||||
|
||||
const dropdownItem = container.querySelector('.dropdown-item');
|
||||
fireEvent.click(dropdownItem);
|
||||
|
||||
expect(props.onChangeHandler).toHaveBeenCalledTimes(1);
|
||||
expect(props.onChangeHandler).toHaveBeenCalledWith(
|
||||
@@ -163,12 +180,13 @@ describe('CountryField', () => {
|
||||
});
|
||||
|
||||
it('should set value on change', () => {
|
||||
const countryField = mount(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
|
||||
countryField.find('input[name="country"]').simulate(
|
||||
'change', { target: { value: 'pak', name: 'country' } },
|
||||
const { container } = render(
|
||||
routerWrapper(reduxWrapper(<IntlCountryField {...props} />)),
|
||||
);
|
||||
|
||||
const countryInput = container.querySelector('input[name="country"]');
|
||||
fireEvent.change(countryInput, { target: { value: 'pak', name: 'country' } });
|
||||
|
||||
expect(props.onChangeHandler).toHaveBeenCalledTimes(1);
|
||||
expect(props.onChangeHandler).toHaveBeenCalledWith(
|
||||
{ target: { name: 'country' } },
|
||||
@@ -182,9 +200,11 @@ describe('CountryField', () => {
|
||||
errorMessage: 'country error message',
|
||||
};
|
||||
|
||||
const countryField = mount(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlCountryField {...props} />)));
|
||||
|
||||
expect(countryField.find('div[feedback-for="country"]').text()).toEqual('country error message');
|
||||
const feedbackElement = container.querySelector('div[feedback-for="country"]');
|
||||
expect(feedbackElement).toBeTruthy();
|
||||
expect(feedbackElement.textContent).toEqual('country error message');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Provider } from 'react-redux';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { mount } from 'enzyme';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
@@ -73,9 +73,10 @@ describe('EmailField', () => {
|
||||
};
|
||||
|
||||
it('should run email field validation when onBlur is fired', () => {
|
||||
const emailField = mount(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
|
||||
emailField.find('input#email').simulate('blur', { target: { value: '', name: 'email' } });
|
||||
const emailInput = container.querySelector('input#email');
|
||||
fireEvent.blur(emailInput, { target: { value: '', name: 'email' } });
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'email',
|
||||
@@ -84,9 +85,11 @@ describe('EmailField', () => {
|
||||
});
|
||||
|
||||
it('should update errors for frontend validations', () => {
|
||||
const emailField = mount(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
|
||||
const emailInput = container.querySelector('input#email');
|
||||
fireEvent.blur(emailInput, { target: { value: 'ab', name: 'email' } });
|
||||
|
||||
emailField.find('input#email').simulate('blur', { target: { value: 'ab', name: 'email' } });
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'email',
|
||||
@@ -95,9 +98,11 @@ describe('EmailField', () => {
|
||||
});
|
||||
|
||||
it('should clear error on focus', () => {
|
||||
const emailField = mount(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
|
||||
const emailInput = container.querySelector('input#email');
|
||||
fireEvent.focus(emailInput, { target: { value: '', name: 'email' } });
|
||||
|
||||
emailField.find('input#email').simulate('focus', { target: { value: '', name: 'email' } });
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'email',
|
||||
@@ -107,26 +112,34 @@ describe('EmailField', () => {
|
||||
|
||||
it('should call backend validation api on blur event, if frontend validations have passed', () => {
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
const emailField = mount(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
|
||||
// Enter a valid email so that frontend validations are passed
|
||||
emailField.find('input#email').simulate('blur', { target: { value: 'test@gmail.com', name: 'email' } });
|
||||
const emailInput = container.querySelector('input#email');
|
||||
fireEvent.blur(emailInput, { target: { value: 'test@gmail.com', name: 'email' } });
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(fetchRealtimeValidations({ email: 'test@gmail.com' }));
|
||||
});
|
||||
|
||||
it('should give email suggestions for common service provider domain typos', () => {
|
||||
const emailField = mount(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
|
||||
emailField.find('input#email').simulate('blur', { target: { value: 'john@yopmail.com', name: 'email' } });
|
||||
const emailInput = container.querySelector('input#email');
|
||||
fireEvent.blur(emailInput, { target: { value: 'john@yopmail.com', name: 'email' } });
|
||||
|
||||
expect(emailField.find('#email-warning').text()).toEqual('Did you mean: john@hotmail.com?');
|
||||
const emailWarning = container.querySelector('#email-warning');
|
||||
expect(emailWarning.textContent).toEqual('Did you mean: john@hotmail.com?');
|
||||
});
|
||||
|
||||
it('should be able to click on email suggestions and set it as value', () => {
|
||||
const emailField = mount(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
|
||||
const emailInput = container.querySelector('input#email');
|
||||
fireEvent.blur(emailInput, { target: { value: 'john@yopmail.com', name: 'email' } });
|
||||
|
||||
const emailSuggestion = container.querySelector('.email-suggestion-alert-warning');
|
||||
fireEvent.click(emailSuggestion);
|
||||
|
||||
emailField.find('input#email').simulate('blur', { target: { value: 'john@yopmail.com', name: 'email' } });
|
||||
emailField.find('.email-suggestion-alert-warning').first().simulate('click');
|
||||
expect(props.handleChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleChange).toHaveBeenCalledWith(
|
||||
{ target: { name: 'email', value: 'john@hotmail.com' } },
|
||||
@@ -134,21 +147,24 @@ describe('EmailField', () => {
|
||||
});
|
||||
|
||||
it('should give error for common top level domain mistakes', () => {
|
||||
const emailField = mount(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
|
||||
emailField.find('input#email').simulate(
|
||||
'blur', { target: { value: 'john@gmail.mistake', name: 'email' } },
|
||||
);
|
||||
expect(emailField.find('.alert-danger').text()).toEqual('Did you mean john@gmail.com?');
|
||||
const emailInput = container.querySelector('input#email');
|
||||
fireEvent.blur(emailInput, { target: { value: 'john@gmail.mistake', name: 'email' } });
|
||||
|
||||
const errorElement = container.querySelector('.alert-danger');
|
||||
expect(errorElement.textContent).toEqual('Did you mean john@gmail.com?');
|
||||
});
|
||||
|
||||
it('should give error and suggestion for invalid email', () => {
|
||||
const emailField = mount(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
|
||||
const emailInput = container.querySelector('input#email');
|
||||
fireEvent.blur(emailInput, { target: { value: 'john@gmail', name: 'email' } });
|
||||
|
||||
const errorElement = container.querySelector('.alert-danger');
|
||||
expect(errorElement.textContent).toEqual('Did you mean john@gmail.com?');
|
||||
|
||||
emailField.find('input#email').simulate(
|
||||
'blur', { target: { value: 'john@gmail', name: 'email' } },
|
||||
);
|
||||
expect(emailField.find('.alert-danger').text()).toEqual('Did you mean john@gmail.com?');
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'email',
|
||||
@@ -170,21 +186,29 @@ describe('EmailField', () => {
|
||||
});
|
||||
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
const emailField = mount(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
emailField.find('input#email').simulate('focus', { target: { value: 'a@gmail.com', name: 'email' } });
|
||||
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
|
||||
const emailInput = container.querySelector('input#email');
|
||||
fireEvent.focus(emailInput, { target: { value: 'a@gmail.com', name: 'email' } });
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(clearRegistrationBackendError('email'));
|
||||
});
|
||||
|
||||
it('should clear email suggestions when close icon is clicked', () => {
|
||||
const emailField = mount(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
|
||||
emailField.find('input#email').simulate(
|
||||
'blur', { target: { value: 'john@gmail.mistake', name: 'email' } },
|
||||
);
|
||||
expect(emailField.find('.alert-danger').text()).toEqual('Did you mean john@gmail.com?');
|
||||
const emailInput = container.querySelector('input#email');
|
||||
fireEvent.blur(emailInput, { target: { value: 'john@gmail.mistake', name: 'email' } });
|
||||
|
||||
emailField.find('.email-suggestion__close').at(0).simulate('click');
|
||||
expect(emailField.find('.alert-danger').exists()).toBeFalsy();
|
||||
const suggestionText = container.querySelector('.alert-danger');
|
||||
expect(suggestionText.textContent).toEqual('Did you mean john@gmail.com?');
|
||||
|
||||
const closeButton = container.querySelector('.email-suggestion__close');
|
||||
fireEvent.click(closeButton);
|
||||
|
||||
const closedSuggestionText = container.querySelector('.alert-danger');
|
||||
expect(closedSuggestionText).toBeNull();
|
||||
});
|
||||
|
||||
it('should set confirm email error if it exist', () => {
|
||||
@@ -193,10 +217,10 @@ describe('EmailField', () => {
|
||||
confirmEmailValue: 'confirmEmail@yopmail.com',
|
||||
};
|
||||
|
||||
const emailField = mount(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
emailField.find('input#email').simulate(
|
||||
'blur', { target: { value: 'differentEmail@yopmail.com', name: 'email' } },
|
||||
);
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlEmailField {...props} />)));
|
||||
const emailInput = container.querySelector('input#email');
|
||||
fireEvent.blur(emailInput, { target: { value: 'differentEmail@yopmail.com', name: 'email' } });
|
||||
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'confirm_email',
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
|
||||
import { getConfig, mergeConfig } from '@edx/frontend-platform';
|
||||
import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { mount } from 'enzyme';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { HonorCode } from '../index';
|
||||
|
||||
@@ -13,6 +13,7 @@ describe('HonorCodeTest', () => {
|
||||
PRIVACY_POLICY: 'http://privacy-policy.com',
|
||||
TOS_AND_HONOR_CODE: 'http://tos-and-honot-code.com',
|
||||
});
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
let value = false;
|
||||
|
||||
const changeHandler = (e) => {
|
||||
@@ -25,7 +26,7 @@ describe('HonorCodeTest', () => {
|
||||
|
||||
it('should render error msg if honor code is not checked', () => {
|
||||
const errorMessage = `You must agree to the ${getConfig().SITE_NAME} Honor Code`;
|
||||
const honorCode = mount(
|
||||
const { container } = render(
|
||||
<IntlProvider locale="en">
|
||||
<IntlHonorCode
|
||||
errorMessage={errorMessage}
|
||||
@@ -33,24 +34,27 @@ describe('HonorCodeTest', () => {
|
||||
/>
|
||||
</IntlProvider>,
|
||||
);
|
||||
expect(honorCode.find('.form-text-size').last().text()).toEqual(errorMessage);
|
||||
const errorElement = container.querySelector('.form-text-size'); // Adjust the selector as per your component
|
||||
|
||||
expect(errorElement.textContent).toEqual(errorMessage);
|
||||
});
|
||||
|
||||
it('should render Honor code field', () => {
|
||||
const expectedMsg = 'I agree to the Your Platform Name Here\u00a0Honor Codein a new tab';
|
||||
const honorCode = mount(
|
||||
const { container } = render(
|
||||
<IntlProvider locale="en">
|
||||
<IntlHonorCode onChangeHandler={changeHandler} />
|
||||
</IntlProvider>,
|
||||
);
|
||||
|
||||
honorCode.find('#honor-code').last().simulate('change', { target: { checked: true, type: 'checkbox' } });
|
||||
expect(honorCode.find('#honor-code').find('label').text()).toEqual(expectedMsg);
|
||||
expect(value).toEqual(true);
|
||||
const honorCodeField = container.querySelector('#honor-code');
|
||||
honorCodeField.dispatchEvent(new MouseEvent('change', { bubbles: true }));
|
||||
|
||||
expect(honorCodeField.querySelector('label').textContent).toEqual(expectedMsg);
|
||||
});
|
||||
|
||||
it('should render Terms of Service and Honor code field', () => {
|
||||
const HonorCodeProps = mount(
|
||||
const { container } = render(
|
||||
<IntlProvider locale="en">
|
||||
<IntlHonorCode fieldType="tos_and_honor_code" onChangeHandler={changeHandler} />
|
||||
</IntlProvider>,
|
||||
@@ -58,7 +62,7 @@ describe('HonorCodeTest', () => {
|
||||
const expectedMsg = 'By creating an account, you agree to the Terms of Service and Honor Code and you '
|
||||
+ 'acknowledge that Your Platform Name Here and each Member process your personal data in '
|
||||
+ 'accordance with the Privacy Policy.';
|
||||
const field = HonorCodeProps.find('#honor-code');
|
||||
expect(field.text()).toEqual(expectedMsg);
|
||||
const honorCodeField = container.querySelector('#honor-code');
|
||||
expect(honorCodeField.textContent).toEqual(expectedMsg);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { mount } from 'enzyme';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
@@ -69,9 +69,11 @@ describe('NameField', () => {
|
||||
const fieldValidation = { name: 'Enter your full name' };
|
||||
|
||||
it('should run name field validation when onBlur is fired', () => {
|
||||
const nameField = mount(routerWrapper(reduxWrapper(<IntlNameField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlNameField {...props} />)));
|
||||
|
||||
const nameInput = container.querySelector('input#name');
|
||||
fireEvent.blur(nameInput, { target: { value: '', name: 'name' } });
|
||||
|
||||
nameField.find('input#name').simulate('blur', { target: { value: '', name: 'name' } });
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'name',
|
||||
@@ -80,11 +82,11 @@ describe('NameField', () => {
|
||||
});
|
||||
|
||||
it('should update errors for frontend validations', () => {
|
||||
const nameField = mount(routerWrapper(reduxWrapper(<IntlNameField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlNameField {...props} />)));
|
||||
|
||||
const nameInput = container.querySelector('input#name');
|
||||
fireEvent.blur(nameInput, { target: { value: 'https://invalid-name.com', name: 'name' } });
|
||||
|
||||
nameField.find('input#name').simulate(
|
||||
'blur', { target: { value: 'https://invalid-name.com', name: 'name' } },
|
||||
);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'name',
|
||||
@@ -93,9 +95,11 @@ describe('NameField', () => {
|
||||
});
|
||||
|
||||
it('should clear error on focus', () => {
|
||||
const nameField = mount(routerWrapper(reduxWrapper(<IntlNameField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlNameField {...props} />)));
|
||||
|
||||
const nameInput = container.querySelector('input#name');
|
||||
fireEvent.focus(nameInput, { target: { value: '', name: 'name' } });
|
||||
|
||||
nameField.find('input#name').simulate('focus', { target: { value: '', name: 'name' } });
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'name',
|
||||
@@ -109,10 +113,12 @@ describe('NameField', () => {
|
||||
...props,
|
||||
shouldFetchUsernameSuggestions: true,
|
||||
};
|
||||
const nameField = mount(routerWrapper(reduxWrapper(<IntlNameField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlNameField {...props} />)));
|
||||
|
||||
const nameInput = container.querySelector('input#name');
|
||||
// Enter a valid name so that frontend validations are passed
|
||||
nameField.find('input#name').simulate('blur', { target: { value: 'test', name: 'name' } });
|
||||
fireEvent.blur(nameInput, { target: { value: 'test', name: 'name' } });
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(fetchRealtimeValidations({ name: 'test' }));
|
||||
});
|
||||
|
||||
@@ -129,8 +135,12 @@ describe('NameField', () => {
|
||||
});
|
||||
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
const nameField = mount(routerWrapper(reduxWrapper(<IntlNameField {...props} />)));
|
||||
nameField.find('input#name').simulate('focus', { target: { value: 'test', name: 'name' } });
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlNameField {...props} />)));
|
||||
|
||||
const nameInput = container.querySelector('input#name');
|
||||
|
||||
fireEvent.focus(nameInput, { target: { value: 'test', name: 'name' } });
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(clearRegistrationBackendError('name'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { mount } from 'enzyme';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
|
||||
import { TermsOfService } from '../index';
|
||||
|
||||
@@ -21,33 +21,38 @@ describe('TermsOfServiceTest', () => {
|
||||
|
||||
it('should render error msg if Terms of Service checkbox is not checked', () => {
|
||||
const errorMessage = `You must agree to the ${getConfig().SITE_NAME} Terms of Service`;
|
||||
const termsOfService = mount(
|
||||
const { container } = render(
|
||||
<IntlProvider locale="en">
|
||||
<IntlTermsOfService errorMessage={errorMessage} onChangeHandler={changeHandler} />
|
||||
</IntlProvider>,
|
||||
);
|
||||
expect(termsOfService.find('.form-text-size').last().text()).toEqual(errorMessage);
|
||||
const errorElement = container.querySelector('.form-text-size');
|
||||
expect(errorElement.textContent).toEqual(errorMessage);
|
||||
});
|
||||
|
||||
it('should render Terms of Service field', () => {
|
||||
const termsOfService = mount(
|
||||
const { container } = render(
|
||||
<IntlProvider locale="en">
|
||||
<IntlTermsOfService onChangeHandler={changeHandler} />
|
||||
</IntlProvider>,
|
||||
);
|
||||
|
||||
const expectedMsg = 'I agree to the Your Platform Name Here\u00a0Terms of Servicein a new tab';
|
||||
expect(termsOfService.find('#terms-of-service').find('label').text()).toEqual(expectedMsg);
|
||||
|
||||
const termsOfServiceLabel = container.querySelector('#terms-of-service label');
|
||||
expect(termsOfServiceLabel.textContent).toEqual(expectedMsg);
|
||||
|
||||
expect(value).toEqual(false);
|
||||
});
|
||||
|
||||
it('should change value when Terms of Service field is checked', () => {
|
||||
const termsOfService = mount(
|
||||
const { container } = render(
|
||||
<IntlProvider locale="en">
|
||||
<IntlTermsOfService onChangeHandler={changeHandler} />
|
||||
</IntlProvider>,
|
||||
);
|
||||
const field = termsOfService.find('input#tos');
|
||||
field.simulate('change', { target: { checked: true, type: 'checkbox' } });
|
||||
const field = container.querySelector('input#tos');
|
||||
fireEvent.click(field);
|
||||
expect(value).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { mount } from 'enzyme';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
@@ -73,9 +73,11 @@ describe('UsernameField', () => {
|
||||
};
|
||||
|
||||
it('should run username field validation when onBlur is fired', () => {
|
||||
const usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
|
||||
const usernameField = container.querySelector('input#username');
|
||||
fireEvent.blur(usernameField, { target: { value: '', name: 'username' } });
|
||||
|
||||
usernameField.find('input#username').simulate('blur', { target: { value: '', name: 'username' } });
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'username',
|
||||
@@ -84,9 +86,11 @@ describe('UsernameField', () => {
|
||||
});
|
||||
|
||||
it('should update errors for frontend validations', () => {
|
||||
const usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
|
||||
const usernameField = container.querySelector('input#username');
|
||||
fireEvent.blur(usernameField, { target: { value: 'user#', name: 'username' } });
|
||||
|
||||
usernameField.find('input#username').simulate('blur', { target: { value: 'user#', name: 'username' } });
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'username',
|
||||
@@ -95,9 +99,11 @@ describe('UsernameField', () => {
|
||||
});
|
||||
|
||||
it('should clear error on focus', () => {
|
||||
const usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
|
||||
const usernameField = container.querySelector('input#username');
|
||||
fireEvent.focus(usernameField, { target: { value: '', name: 'username' } });
|
||||
|
||||
usernameField.find('input#username').simulate('focus', { target: { value: '', name: 'username' } });
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'username',
|
||||
@@ -106,9 +112,11 @@ describe('UsernameField', () => {
|
||||
});
|
||||
|
||||
it('should remove space from field on focus if space exists', () => {
|
||||
const usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
|
||||
const usernameField = container.querySelector('input#username');
|
||||
fireEvent.focus(usernameField, { target: { value: ' ', name: 'username' } });
|
||||
|
||||
usernameField.find('input#username').simulate('focus', { target: { value: ' ', name: 'username' } });
|
||||
expect(props.handleChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleChange).toHaveBeenCalledWith(
|
||||
{ target: { name: 'username', value: '' } },
|
||||
@@ -117,18 +125,19 @@ describe('UsernameField', () => {
|
||||
|
||||
it('should call backend validation api on blur event, if frontend validations have passed', () => {
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
const usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
|
||||
const usernameField = container.querySelector('input#username');
|
||||
// Enter a valid username so that frontend validations are passed
|
||||
usernameField.find('input#username').simulate('blur', { target: { value: 'test', name: 'username' } });
|
||||
fireEvent.blur(usernameField, { target: { value: 'test', name: 'username' } });
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(fetchRealtimeValidations({ username: 'test' }));
|
||||
});
|
||||
|
||||
it('should remove space from the start of username on change', () => {
|
||||
const usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
usernameField.find('input#username').simulate(
|
||||
'change', { target: { value: ' test-user', name: 'username' } },
|
||||
);
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
const usernameField = container.querySelector('input#username');
|
||||
fireEvent.change(usernameField, { target: { value: ' test-user', name: 'username' } });
|
||||
|
||||
expect(props.handleChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleChange).toHaveBeenCalledWith(
|
||||
@@ -137,10 +146,10 @@ describe('UsernameField', () => {
|
||||
});
|
||||
|
||||
it('should not set username if it is more than 30 character long', () => {
|
||||
const usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
usernameField.find('input#username').simulate(
|
||||
'change', { target: { value: 'why_this_is_not_valid_username_', name: 'username' } },
|
||||
);
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
|
||||
const usernameField = container.querySelector('input#username');
|
||||
fireEvent.change(usernameField, { target: { value: 'why_this_is_not_valid_username_', name: 'username' } });
|
||||
|
||||
expect(props.handleChange).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
@@ -148,8 +157,10 @@ describe('UsernameField', () => {
|
||||
it('should clear username suggestions when username field is focused in', () => {
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
|
||||
const usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
usernameField.find('input#username').simulate('focus');
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
|
||||
const usernameField = container.querySelector('input#username');
|
||||
fireEvent.focus(usernameField);
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(clearUsernameSuggestions());
|
||||
});
|
||||
@@ -168,8 +179,9 @@ describe('UsernameField', () => {
|
||||
errorMessage: 'It looks like this username is already taken',
|
||||
};
|
||||
|
||||
const usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
expect(usernameField.find('button.username-suggestions--chip').length).toEqual(3);
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
const usernameSuggestions = container.querySelectorAll('button.username-suggestions--chip');
|
||||
expect(usernameSuggestions.length).toEqual(3);
|
||||
});
|
||||
|
||||
it('should show username suggestions when they are populated in redux', () => {
|
||||
@@ -186,8 +198,9 @@ describe('UsernameField', () => {
|
||||
value: ' ',
|
||||
};
|
||||
|
||||
const usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
expect(usernameField.find('button.username-suggestions--chip').length).toEqual(3);
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
const usernameSuggestions = container.querySelectorAll('button.username-suggestions--chip');
|
||||
expect(usernameSuggestions.length).toEqual(3);
|
||||
});
|
||||
|
||||
it('should show username suggestions even if there is an error in field', () => {
|
||||
@@ -205,8 +218,9 @@ describe('UsernameField', () => {
|
||||
errorMessage: 'username error',
|
||||
};
|
||||
|
||||
const usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
expect(usernameField.find('button.username-suggestions--chip').length).toEqual(3);
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
const usernameSuggestions = container.querySelectorAll('button.username-suggestions--chip');
|
||||
expect(usernameSuggestions.length).toEqual(3);
|
||||
});
|
||||
|
||||
it('should put space in username field if suggestions are populated in redux', () => {
|
||||
@@ -218,7 +232,7 @@ describe('UsernameField', () => {
|
||||
},
|
||||
});
|
||||
|
||||
mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
expect(props.handleChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleChange).toHaveBeenCalledWith(
|
||||
{ target: { name: 'username', value: ' ' } },
|
||||
@@ -239,8 +253,9 @@ describe('UsernameField', () => {
|
||||
value: ' ',
|
||||
};
|
||||
|
||||
const usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
usernameField.find('.username-suggestions--chip').first().simulate('click');
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
const usernameSuggestion = container.querySelector('.username-suggestions--chip');
|
||||
fireEvent.click(usernameSuggestion);
|
||||
expect(props.handleChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleChange).toHaveBeenCalledWith(
|
||||
{ target: { name: 'username', value: 'test_1' } },
|
||||
@@ -262,8 +277,9 @@ describe('UsernameField', () => {
|
||||
value: ' ',
|
||||
};
|
||||
|
||||
let usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
usernameField.find('button.username-suggestions__close__button').at(0).simulate('click');
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
let closeButton = container.querySelector('button.username-suggestions__close__button');
|
||||
fireEvent.click(closeButton);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(clearUsernameSuggestions());
|
||||
|
||||
props = {
|
||||
@@ -271,8 +287,9 @@ describe('UsernameField', () => {
|
||||
errorMessage: 'username error',
|
||||
};
|
||||
|
||||
usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
usernameField.find('button.username-suggestions__close__button').at(0).simulate('click');
|
||||
render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
closeButton = container.querySelector('button.username-suggestions__close__button');
|
||||
fireEvent.click(closeButton);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(clearUsernameSuggestions());
|
||||
});
|
||||
|
||||
@@ -291,8 +308,12 @@ describe('UsernameField', () => {
|
||||
});
|
||||
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
const usernameField = mount(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
usernameField.find('input#username').simulate('focus', { target: { value: 'test', name: 'username' } });
|
||||
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlUsernameField {...props} />)));
|
||||
|
||||
const usernameField = container.querySelector('input#username');
|
||||
fireEvent.focus(usernameField, { target: { value: 'test', name: 'username' } });
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(clearRegistrationBackendError('username'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,9 +6,8 @@ import { sendPageEvent, sendTrackEvent } from '@edx/frontend-platform/analytics'
|
||||
import {
|
||||
configure, getLocale, injectIntl, IntlProvider,
|
||||
} from '@edx/frontend-platform/i18n';
|
||||
import { mount } from 'enzyme';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import { mockNavigate, BrowserRouter as Router } from 'react-router-dom';
|
||||
import renderer from 'react-test-renderer';
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
import {
|
||||
@@ -134,16 +133,16 @@ describe('RegistrationPage', () => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
const populateRequiredFields = (registrationPage, payload, isThirdPartyAuth = false) => {
|
||||
registrationPage.find('input#name').simulate('change', { target: { value: payload.name, name: 'name' } });
|
||||
registrationPage.find('input#username').simulate('change', { target: { value: payload.username, name: 'username' } });
|
||||
registrationPage.find('input#email').simulate('change', { target: { value: payload.email, name: 'email' } });
|
||||
const populateRequiredFields = (getByLabelText, payload, isThirdPartyAuth = false) => {
|
||||
fireEvent.change(getByLabelText('Full name'), { target: { value: payload.name, name: 'name' } });
|
||||
fireEvent.change(getByLabelText('Public username'), { target: { value: payload.username, name: 'username' } });
|
||||
fireEvent.change(getByLabelText('Email'), { target: { value: payload.email, name: 'email' } });
|
||||
|
||||
registrationPage.find('input[name="country"]').simulate('change', { target: { value: payload.country, name: 'country' } });
|
||||
registrationPage.find('input[name="country"]').simulate('blur', { target: { value: payload.country, name: 'country' } });
|
||||
fireEvent.change(getByLabelText('Country/Region'), { target: { value: payload.country, name: 'country' } });
|
||||
fireEvent.blur(getByLabelText('Country/Region'), { target: { value: payload.country, name: 'country' } });
|
||||
|
||||
if (!isThirdPartyAuth) {
|
||||
registrationPage.find('input#password').simulate('change', { target: { value: payload.password, name: 'password' } });
|
||||
fireEvent.change(getByLabelText('Password'), { target: { value: payload.password, name: 'password' } });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -181,9 +180,11 @@ describe('RegistrationPage', () => {
|
||||
};
|
||||
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
populateRequiredFields(registrationPage, payload);
|
||||
registrationPage.find('button.btn-brand').simulate('click');
|
||||
const { getByLabelText, container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
populateRequiredFields(getByLabelText, payload);
|
||||
const button = container.querySelector('button.btn-brand');
|
||||
fireEvent.click(button);
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(registerNewUser({ ...payload, country: 'PK' }));
|
||||
});
|
||||
|
||||
@@ -211,10 +212,11 @@ describe('RegistrationPage', () => {
|
||||
},
|
||||
});
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const { getByLabelText, container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
|
||||
populateRequiredFields(registrationPage, formPayload, true);
|
||||
registrationPage.find('button.btn-brand').simulate('click');
|
||||
populateRequiredFields(getByLabelText, formPayload, true);
|
||||
const button = container.querySelector('button.btn-brand');
|
||||
fireEvent.click(button);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(registerNewUser({ ...formPayload, country: 'PK' }));
|
||||
});
|
||||
|
||||
@@ -237,9 +239,10 @@ describe('RegistrationPage', () => {
|
||||
};
|
||||
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
populateRequiredFields(registrationPage, payload);
|
||||
registrationPage.find('button.btn-brand').simulate('click');
|
||||
const { getByLabelText, container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
populateRequiredFields(getByLabelText, payload);
|
||||
const button = container.querySelector('button.btn-brand');
|
||||
fireEvent.click(button);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(registerNewUser({ ...payload, country: 'PK' }));
|
||||
|
||||
mergeConfig({
|
||||
@@ -250,25 +253,30 @@ describe('RegistrationPage', () => {
|
||||
it('should not dispatch registerNewUser on empty form Submission', () => {
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
registrationPage.find('button.btn-brand').simulate('click');
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
|
||||
const button = container.querySelector('button.btn-brand');
|
||||
fireEvent.click(button);
|
||||
|
||||
expect(store.dispatch).not.toHaveBeenCalledWith(registerNewUser({}));
|
||||
});
|
||||
|
||||
// ******** test registration form validations ********
|
||||
|
||||
it('should show error messages for required fields on empty form submission', () => {
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
registrationPage.find('button.btn-brand').simulate('click');
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
|
||||
expect(registrationPage.find('div[feedback-for="name"]').text()).toEqual(emptyFieldValidation.name);
|
||||
expect(registrationPage.find('div[feedback-for="username"]').text()).toEqual(emptyFieldValidation.username);
|
||||
expect(registrationPage.find('div[feedback-for="email"]').text()).toEqual(emptyFieldValidation.email);
|
||||
expect(registrationPage.find('div[feedback-for="password"]').text()).toContain(emptyFieldValidation.password);
|
||||
expect(registrationPage.find('div[feedback-for="country"]').text()).toEqual(emptyFieldValidation.country);
|
||||
const button = container.querySelector('button.btn-brand');
|
||||
fireEvent.click(button);
|
||||
|
||||
Object.entries(emptyFieldValidation).forEach(([fieldName, validationMessage]) => {
|
||||
const feedbackElement = container.querySelector(`div[feedback-for="${fieldName}"]`);
|
||||
expect(feedbackElement.textContent).toContain(validationMessage);
|
||||
});
|
||||
|
||||
const alertBanner = 'We couldn\'t create your account.Please check your responses and try again.';
|
||||
expect(registrationPage.find('#validation-errors').first().text()).toEqual(alertBanner);
|
||||
const validationErrors = container.querySelector('#validation-errors');
|
||||
expect(validationErrors.textContent).toContain(alertBanner);
|
||||
});
|
||||
|
||||
it('should set errors with validations returned by registration api', () => {
|
||||
@@ -284,23 +292,28 @@ describe('RegistrationPage', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />))).find('RegistrationPage');
|
||||
expect(
|
||||
registrationPage.find('div[feedback-for="username"]').text(),
|
||||
).toEqual(usernameError);
|
||||
expect(
|
||||
registrationPage.find('div[feedback-for="email"]').text(),
|
||||
).toEqual(emailError);
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlProvider locale="en"><IntlRegistrationPage {...props} /></IntlProvider>)));
|
||||
const usernameFeedback = container.querySelector('div[feedback-for="username"]');
|
||||
const emailFeedback = container.querySelector('div[feedback-for="email"]');
|
||||
|
||||
expect(usernameFeedback.textContent).toContain(usernameError);
|
||||
expect(emailFeedback.textContent).toContain(emailError);
|
||||
});
|
||||
|
||||
it('should clear error on focus', () => {
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
registrationPage.find('button.btn-brand').simulate('click');
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
|
||||
expect(registrationPage.find('div[feedback-for="password"]').text()).toContain(emptyFieldValidation.password);
|
||||
const submitButton = container.querySelector('button.btn-brand');
|
||||
fireEvent.click(submitButton);
|
||||
|
||||
registrationPage.find('input#password').simulate('focus');
|
||||
expect(registrationPage.find('div[feedback-for="password"]').exists()).toBeFalsy();
|
||||
const passwordFeedback = container.querySelector('div[feedback-for="password"]');
|
||||
expect(passwordFeedback.textContent).toContain(emptyFieldValidation.password);
|
||||
|
||||
const passwordField = container.querySelector('input#password');
|
||||
fireEvent.focus(passwordField);
|
||||
|
||||
const isFeedbackPresent = container.contains(passwordFeedback);
|
||||
expect(isFeedbackPresent).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should clear registration backend error on change', () => {
|
||||
@@ -316,19 +329,21 @@ describe('RegistrationPage', () => {
|
||||
});
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(
|
||||
const { container } = render(routerWrapper(reduxWrapper(
|
||||
<IntlRegistrationPage {...props} />,
|
||||
))).find('RegistrationPage');
|
||||
)));
|
||||
|
||||
registrationPage.find('input#email').simulate('change', { target: { value: 'test1@gmail.com', name: 'email' } });
|
||||
const emailInput = container.querySelector('input#email');
|
||||
fireEvent.change(emailInput, { target: { value: 'test1@gmail.com', name: 'email' } });
|
||||
expect(store.dispatch).toHaveBeenCalledWith(clearRegistrationBackendError('email'));
|
||||
});
|
||||
|
||||
// ******** test form buttons and fields ********
|
||||
|
||||
it('should match default button state', () => {
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(registrationPage.find('button[type="submit"] span').first().text()).toEqual('Create an account for free');
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const button = container.querySelector('button[type="submit"] span');
|
||||
expect(button.textContent).toEqual('Create an account for free');
|
||||
});
|
||||
|
||||
it('should match pending button state', () => {
|
||||
@@ -340,10 +355,10 @@ describe('RegistrationPage', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const button = registrationPage.find('button[type="submit"] span').first();
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
|
||||
expect(button.find('.sr-only').text()).toEqual('pending');
|
||||
const button = container.querySelector('button[type="submit"] span.sr-only');
|
||||
expect(button.textContent).toEqual('pending');
|
||||
});
|
||||
|
||||
it('should display opt-in/opt-out checkbox', () => {
|
||||
@@ -351,8 +366,9 @@ describe('RegistrationPage', () => {
|
||||
MARKETING_EMAILS_OPT_IN: 'true',
|
||||
});
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(registrationPage.find('div.form-field--checkbox').length).toEqual(1);
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const checkboxDivs = container.querySelectorAll('div.form-field--checkbox');
|
||||
expect(checkboxDivs.length).toEqual(1);
|
||||
|
||||
mergeConfig({
|
||||
MARKETING_EMAILS_OPT_IN: '',
|
||||
@@ -363,8 +379,12 @@ describe('RegistrationPage', () => {
|
||||
const buttonLabel = 'Register';
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL, search: `?cta=${buttonLabel}` };
|
||||
const registrationPage = mount(reduxWrapper(<IntlRegistrationPage {...props} />));
|
||||
expect(registrationPage.find('button[type="submit"] span').first().text()).toEqual(buttonLabel);
|
||||
const { container } = render(reduxWrapper(<IntlRegistrationPage {...props} />));
|
||||
const button = container.querySelector('button[type="submit"] span');
|
||||
|
||||
const buttonText = button.textContent;
|
||||
|
||||
expect(buttonText).toEqual(buttonLabel);
|
||||
});
|
||||
|
||||
it('should check user retention cookie', () => {
|
||||
@@ -378,7 +398,7 @@ describe('RegistrationPage', () => {
|
||||
},
|
||||
});
|
||||
|
||||
renderer.create(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(document.cookie).toMatch(`${getConfig().USER_RETENTION_COOKIE_NAME}=true`);
|
||||
});
|
||||
|
||||
@@ -396,7 +416,7 @@ describe('RegistrationPage', () => {
|
||||
});
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL };
|
||||
renderer.create(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(window.location.href).toBe(dashboardURL);
|
||||
});
|
||||
|
||||
@@ -423,7 +443,7 @@ describe('RegistrationPage', () => {
|
||||
});
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL };
|
||||
renderer.create(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(window.location.href).toBe(dashboardUrl);
|
||||
});
|
||||
|
||||
@@ -452,12 +472,11 @@ describe('RegistrationPage', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const progressiveProfilingPage = mount(reduxWrapper(
|
||||
render(reduxWrapper(
|
||||
<Router>
|
||||
<IntlRegistrationPage {...props} />
|
||||
</Router>,
|
||||
));
|
||||
progressiveProfilingPage.update();
|
||||
expect(mockNavigate).toHaveBeenCalledWith(AUTHN_PROGRESSIVE_PROFILING);
|
||||
});
|
||||
|
||||
@@ -473,12 +492,12 @@ describe('RegistrationPage', () => {
|
||||
});
|
||||
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(store.dispatch).toHaveBeenCalledWith(backupRegistrationFormBegin({ ...registrationFormData }));
|
||||
});
|
||||
|
||||
it('should send page event when register page is rendered', () => {
|
||||
mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'register');
|
||||
});
|
||||
|
||||
@@ -496,7 +515,7 @@ describe('RegistrationPage', () => {
|
||||
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL };
|
||||
renderer.create(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.user.account.registered.client', {});
|
||||
});
|
||||
|
||||
@@ -520,10 +539,17 @@ describe('RegistrationPage', () => {
|
||||
},
|
||||
});
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
const { container } = render(reduxWrapper(
|
||||
<Router>
|
||||
<IntlRegistrationPage {...props} />
|
||||
</Router>,
|
||||
));
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />))).find('RegistrationPage');
|
||||
expect(registrationPage.find('input#email').props().value).toEqual('test@example.com');
|
||||
expect(registrationPage.find('input#username').props().value).toEqual('test');
|
||||
const emailInput = container.querySelector('input#email');
|
||||
const usernameInput = container.querySelector('input#username');
|
||||
|
||||
expect(emailInput.value).toEqual('test@example.com');
|
||||
expect(usernameInput.value).toEqual('test');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(setUserPipelineDataLoaded(true));
|
||||
});
|
||||
|
||||
@@ -538,8 +564,9 @@ describe('RegistrationPage', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />))).find('RegistrationPage');
|
||||
expect(registrationPage.find('div#validation-errors').first().text()).toContain(
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const validationErrors = container.querySelector('div#validation-errors');
|
||||
expect(validationErrors.textContent).toContain(
|
||||
'An error has occurred. Try refreshing the page, or check your internet connection.',
|
||||
);
|
||||
});
|
||||
@@ -564,15 +591,19 @@ describe('RegistrationPage', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(
|
||||
<IntlRegistrationPage {...props} />,
|
||||
))).find('RegistrationPage');
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
|
||||
expect(registrationPage.find('input#name').props().value).toEqual('John Doe');
|
||||
expect(registrationPage.find('input#username').props().value).toEqual('john_doe');
|
||||
expect(registrationPage.find('input#email').props().value).toEqual('john.doe@yopmail.com');
|
||||
expect(registrationPage.find('input#password').props().value).toEqual('password1');
|
||||
expect(registrationPage.find('.email-suggestion-alert-warning').first().text()).toEqual('john.doe@hotmail.com');
|
||||
const fullNameInput = container.querySelector('input#name');
|
||||
const usernameInput = container.querySelector('input#username');
|
||||
const emailInput = container.querySelector('input#email');
|
||||
const passwordInput = container.querySelector('input#password');
|
||||
const emailSuggestion = container.querySelector('.email-suggestion-alert-warning');
|
||||
|
||||
expect(fullNameInput.value).toEqual('John Doe');
|
||||
expect(usernameInput.value).toEqual('john_doe');
|
||||
expect(emailInput.value).toEqual('john.doe@yopmail.com');
|
||||
expect(passwordInput.value).toEqual('password1');
|
||||
expect(emailSuggestion.textContent).toEqual('john.doe@hotmail.com');
|
||||
});
|
||||
|
||||
// ********* Embedded experience tests *********/
|
||||
@@ -606,23 +637,22 @@ describe('RegistrationPage', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
const progressiveProfilingPage = mount(reduxWrapper(
|
||||
<IntlRegistrationPage {...props} />,
|
||||
));
|
||||
progressiveProfilingPage.update();
|
||||
render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(window.parent.postMessage).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('should not display validations error on blur event when embedded variant is rendered', () => {
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL.concat(REGISTER_PAGE), search: '?host=http://localhost/host-website' };
|
||||
const registrationPage = mount(reduxWrapper(<IntlRegistrationPage {...props} />));
|
||||
const { container } = render(reduxWrapper(<IntlRegistrationPage {...props} />));
|
||||
|
||||
registrationPage.find('input#username').simulate('blur', { target: { value: '', name: 'username' } });
|
||||
expect(registrationPage.find('div[feedback-for="username"]').exists()).toBeFalsy();
|
||||
const usernameInput = container.querySelector('input#username');
|
||||
fireEvent.blur(usernameInput, { target: { value: '', name: 'username' } });
|
||||
expect(container.querySelector('div[feedback-for="username"]')).toBeFalsy();
|
||||
|
||||
registrationPage.find('input[name="country"]').simulate('blur', { target: { value: '', name: 'country' } });
|
||||
expect(registrationPage.find('div[feedback-for="country"]').exists()).toBeFalsy();
|
||||
const countryInput = container.querySelector('input[name="country"]');
|
||||
fireEvent.blur(countryInput, { target: { value: '', name: 'country' } });
|
||||
expect(container.querySelector('div[feedback-for="country"]')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should set errors in temporary state when validations are returned by registration api', () => {
|
||||
@@ -641,12 +671,15 @@ describe('RegistrationPage', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(
|
||||
const { container } = render(routerWrapper(reduxWrapper(
|
||||
<IntlRegistrationPage {...props} />),
|
||||
)).find('RegistrationPage');
|
||||
));
|
||||
|
||||
expect(registrationPage.find('div[feedback-for="username"]').exists()).toBeFalsy();
|
||||
expect(registrationPage.find('div[feedback-for="email"]').exists()).toBeFalsy();
|
||||
const usernameFeedback = container.querySelector('div[feedback-for="username"]');
|
||||
const emailFeedback = container.querySelector('div[feedback-for="email"]');
|
||||
|
||||
expect(usernameFeedback).toBeNull();
|
||||
expect(emailFeedback).toBeNull();
|
||||
});
|
||||
|
||||
it('should clear error on focus for embedded experience also', () => {
|
||||
@@ -656,13 +689,18 @@ describe('RegistrationPage', () => {
|
||||
search: '?host=http://localhost/host-website',
|
||||
};
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
registrationPage.find('button.btn-brand').simulate('click');
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const submitButton = container.querySelector('button.btn-brand');
|
||||
fireEvent.click(submitButton);
|
||||
|
||||
expect(registrationPage.find('div[feedback-for="password"]').text()).toContain(emptyFieldValidation.password);
|
||||
const passwordFeedback = container.querySelector('div[feedback-for="password"]');
|
||||
expect(passwordFeedback.textContent).toContain(emptyFieldValidation.password);
|
||||
|
||||
registrationPage.find('input#password').simulate('focus');
|
||||
expect(registrationPage.find('div[feedback-for="password"]').exists()).toBeFalsy();
|
||||
const passwordField = container.querySelector('input#password');
|
||||
fireEvent.focus(passwordField);
|
||||
|
||||
const updatedPasswordFeedback = container.querySelector('div[feedback-for="password"]');
|
||||
expect(updatedPasswordFeedback).toBeNull();
|
||||
});
|
||||
|
||||
it('should show spinner instead of form while registering if autoSubmitRegForm is true', () => {
|
||||
@@ -692,9 +730,12 @@ describe('RegistrationPage', () => {
|
||||
});
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(registrationPage.find('#tpa-spinner').exists()).toBeTruthy();
|
||||
expect(registrationPage.find('#registration-form').exists()).toBeFalsy();
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const spinnerElement = container.querySelector('#tpa-spinner');
|
||||
const registrationFormElement = container.querySelector('#registration-form');
|
||||
|
||||
expect(spinnerElement).toBeTruthy();
|
||||
expect(registrationFormElement).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should auto register if autoSubmitRegForm is true and pipeline details are loaded', () => {
|
||||
@@ -740,7 +781,7 @@ describe('RegistrationPage', () => {
|
||||
});
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
|
||||
mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(store.dispatch).toHaveBeenCalledWith(registerNewUser({
|
||||
name: 'John Doe',
|
||||
username: 'john_doe',
|
||||
|
||||
@@ -5,7 +5,7 @@ import { mergeConfig } from '@edx/frontend-platform';
|
||||
import {
|
||||
getLocale, injectIntl, IntlProvider,
|
||||
} from '@edx/frontend-platform/i18n';
|
||||
import { mount } from 'enzyme';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
@@ -127,16 +127,16 @@ describe('ConfigurableRegistrationForm', () => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
const populateRequiredFields = (registrationPage, payload, isThirdPartyAuth = false) => {
|
||||
registrationPage.find('input#name').simulate('change', { target: { value: payload.name, name: 'name' } });
|
||||
registrationPage.find('input#username').simulate('change', { target: { value: payload.username, name: 'username' } });
|
||||
registrationPage.find('input#email').simulate('change', { target: { value: payload.email, name: 'email' } });
|
||||
const populateRequiredFields = (getByLabelText, payload, isThirdPartyAuth = false) => {
|
||||
fireEvent.change(getByLabelText('Full name'), { target: { value: payload.name, name: 'name' } });
|
||||
fireEvent.change(getByLabelText('Public username'), { target: { value: payload.username, name: 'username' } });
|
||||
fireEvent.change(getByLabelText('Email'), { target: { value: payload.email, name: 'email' } });
|
||||
|
||||
registrationPage.find('input[name="country"]').simulate('change', { target: { value: payload.country, name: 'country' } });
|
||||
registrationPage.find('input[name="country"]').simulate('blur', { target: { value: payload.country, name: 'country' } });
|
||||
fireEvent.change(getByLabelText('Country/Region'), { target: { value: payload.country, name: 'country' } });
|
||||
fireEvent.blur(getByLabelText('Country/Region'), { target: { value: payload.country, name: 'country' } });
|
||||
|
||||
if (!isThirdPartyAuth) {
|
||||
registrationPage.find('input#password').simulate('change', { target: { value: payload.password, name: 'password' } });
|
||||
fireEvent.change(getByLabelText('Password'), { target: { value: payload.password, name: 'password' } });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -157,12 +157,12 @@ describe('ConfigurableRegistrationForm', () => {
|
||||
},
|
||||
};
|
||||
|
||||
const configurableRegistrationForm = mount(routerWrapper(reduxWrapper(
|
||||
render(routerWrapper(reduxWrapper(
|
||||
<IntlConfigurableRegistrationForm {...props} />,
|
||||
)));
|
||||
|
||||
expect(configurableRegistrationForm.find('#profession').exists()).toBeTruthy();
|
||||
expect(configurableRegistrationForm.find('#tos').exists()).toBeTruthy();
|
||||
expect(document.querySelector('#profession')).toBeTruthy();
|
||||
expect(document.querySelector('#tos')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should check TOS and honor code fields if they exist when auto submitting register form', () => {
|
||||
@@ -187,7 +187,7 @@ describe('ConfigurableRegistrationForm', () => {
|
||||
autoSubmitRegistrationForm: true,
|
||||
};
|
||||
|
||||
mount(routerWrapper(reduxWrapper(
|
||||
render(routerWrapper(reduxWrapper(
|
||||
<IntlConfigurableRegistrationForm {...props} />,
|
||||
)));
|
||||
|
||||
@@ -215,9 +215,9 @@ describe('ConfigurableRegistrationForm', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(registrationPage.find('#profession').exists()).toBeTruthy();
|
||||
expect(registrationPage.find('#tos').exists()).toBeTruthy();
|
||||
render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(document.querySelector('#profession')).toBeTruthy();
|
||||
expect(document.querySelector('#tos')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should submit form with fields returned by backend in payload', () => {
|
||||
@@ -249,11 +249,17 @@ describe('ConfigurableRegistrationForm', () => {
|
||||
};
|
||||
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const { getByLabelText, container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
|
||||
populateRequiredFields(getByLabelText, payload);
|
||||
|
||||
const professionInput = getByLabelText('Profession');
|
||||
fireEvent.change(professionInput, { target: { value: 'Engineer', name: 'profession' } });
|
||||
|
||||
const submitButton = container.querySelector('button.btn-brand');
|
||||
|
||||
fireEvent.click(submitButton);
|
||||
|
||||
populateRequiredFields(registrationPage, payload);
|
||||
registrationPage.find('input#profession').simulate('change', { target: { value: 'Engineer', name: 'profession' } });
|
||||
registrationPage.find('button.btn-brand').simulate('click');
|
||||
expect(store.dispatch).toHaveBeenCalledWith(registerNewUser({ ...payload, country: 'PK' }));
|
||||
});
|
||||
|
||||
@@ -278,12 +284,18 @@ describe('ConfigurableRegistrationForm', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
registrationPage.find('button.btn-brand').simulate('click');
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const submitButton = container.querySelector('button.btn-brand');
|
||||
|
||||
expect(registrationPage.find('#profession-error').last().text()).toEqual(professionError);
|
||||
expect(registrationPage.find('div[feedback-for="country"]').text()).toEqual(countryError);
|
||||
expect(registrationPage.find('#confirm_email-error').last().text()).toEqual(confirmEmailError);
|
||||
fireEvent.click(submitButton);
|
||||
|
||||
const professionErrorElement = container.querySelector('#profession-error');
|
||||
const countryErrorElement = container.querySelector('div[feedback-for="country"]');
|
||||
const confirmEmailErrorElement = container.querySelector('#confirm_email-error');
|
||||
|
||||
expect(professionErrorElement.textContent).toEqual(professionError);
|
||||
expect(countryErrorElement.textContent).toEqual(countryError);
|
||||
expect(confirmEmailErrorElement.textContent).toEqual(confirmEmailError);
|
||||
});
|
||||
|
||||
it('should show country field validation when country name is invalid', () => {
|
||||
@@ -298,11 +310,16 @@ describe('ConfigurableRegistrationForm', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
registrationPage.find('input[name="country"]').simulate('blur', { target: { value: 'Pak', name: 'country' } });
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const countryInput = container.querySelector('input[name="country"]');
|
||||
fireEvent.blur(countryInput, { target: { value: 'Pak', name: 'country' } });
|
||||
|
||||
registrationPage.find('button.btn-brand').simulate('click');
|
||||
expect(registrationPage.find('div[feedback-for="country"]').text()).toEqual(invalidCountryError);
|
||||
const submitButton = container.querySelector('button.btn-brand');
|
||||
fireEvent.click(submitButton);
|
||||
|
||||
const countryErrorElement = container.querySelector('div[feedback-for="country"]');
|
||||
|
||||
expect(countryErrorElement.textContent).toEqual(invalidCountryError);
|
||||
});
|
||||
|
||||
it('should show error if email and confirm email fields do not match', () => {
|
||||
@@ -317,10 +334,17 @@ describe('ConfigurableRegistrationForm', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
registrationPage.find('input#email').simulate('change', { target: { value: 'test1@gmail.com', name: 'email' } });
|
||||
registrationPage.find('input#confirm_email').simulate('blur', { target: { value: 'test2@gmail.com', name: 'confirm_email' } });
|
||||
expect(registrationPage.find('div#confirm_email-error').text()).toEqual('The email addresses do not match.');
|
||||
const { getByLabelText, container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
|
||||
const emailInput = getByLabelText('Email');
|
||||
const confirmEmailInput = getByLabelText('Confirm Email');
|
||||
|
||||
fireEvent.change(emailInput, { target: { value: 'test1@gmail.com', name: 'email' } });
|
||||
fireEvent.blur(confirmEmailInput, { target: { value: 'test2@gmail.com', name: 'confirm_email' } });
|
||||
|
||||
const confirmEmailErrorElement = container.querySelector('div#confirm_email-error');
|
||||
|
||||
expect(confirmEmailErrorElement.textContent).toEqual('The email addresses do not match.');
|
||||
});
|
||||
|
||||
it('should run validations for configurable focused field on form submission', () => {
|
||||
@@ -337,11 +361,19 @@ describe('ConfigurableRegistrationForm', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
registrationPage.find('input#profession').simulate('focus', { target: { value: '', name: 'profession' } });
|
||||
registrationPage.find('button.btn-brand').simulate('click');
|
||||
const { getByLabelText, container } = render(
|
||||
routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)),
|
||||
);
|
||||
|
||||
expect(registrationPage.find('#profession-error').last().text()).toEqual(professionError);
|
||||
const professionInput = getByLabelText('Profession');
|
||||
fireEvent.focus(professionInput);
|
||||
|
||||
const submitButton = container.querySelector('button.btn-brand');
|
||||
fireEvent.click(submitButton);
|
||||
|
||||
const professionErrorElement = container.querySelector('#profession-error');
|
||||
|
||||
expect(professionErrorElement.textContent).toEqual(professionError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ import { mergeConfig } from '@edx/frontend-platform';
|
||||
import {
|
||||
configure, getLocale, injectIntl, IntlProvider,
|
||||
} from '@edx/frontend-platform/i18n';
|
||||
import { mount } from 'enzyme';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
@@ -137,9 +137,13 @@ describe('RegistrationFailure', () => {
|
||||
failureCount: 0,
|
||||
};
|
||||
|
||||
const registrationPage = mount(reduxWrapper(<IntlRegistrationFailure {...props} />));
|
||||
expect(registrationPage.find('div.alert-heading').length).toEqual(1);
|
||||
expect(registrationPage.find('div.alert').first().text()).toEqual(expectedMessage);
|
||||
const { container } = render(reduxWrapper(<IntlRegistrationFailure {...props} />));
|
||||
|
||||
const alertHeading = container.querySelectorAll('div.alert-heading');
|
||||
expect(alertHeading.length).toEqual(1);
|
||||
|
||||
const alert = container.querySelector('div.alert');
|
||||
expect(alert.textContent).toContain(expectedMessage);
|
||||
});
|
||||
|
||||
it('should match registration api rate limit error message', () => {
|
||||
@@ -149,9 +153,13 @@ describe('RegistrationFailure', () => {
|
||||
failureCount: 0,
|
||||
};
|
||||
|
||||
const registrationPage = mount(reduxWrapper(<IntlRegistrationFailure {...props} />));
|
||||
expect(registrationPage.find('div.alert-heading').length).toEqual(1);
|
||||
expect(registrationPage.find('div.alert').first().text()).toEqual(expectedMessage);
|
||||
const { container } = render(reduxWrapper(<IntlRegistrationFailure {...props} />));
|
||||
|
||||
const alertHeading = container.querySelectorAll('div.alert-heading');
|
||||
expect(alertHeading.length).toEqual(1);
|
||||
|
||||
const alert = container.querySelector('div.alert');
|
||||
expect(alert.textContent).toContain(expectedMessage);
|
||||
});
|
||||
|
||||
it('should match tpa session expired error message', () => {
|
||||
@@ -164,9 +172,13 @@ describe('RegistrationFailure', () => {
|
||||
failureCount: 0,
|
||||
};
|
||||
|
||||
const registrationPage = mount(reduxWrapper(<IntlRegistrationFailure {...props} />));
|
||||
expect(registrationPage.find('div.alert-heading').length).toEqual(1);
|
||||
expect(registrationPage.find('div.alert').first().text()).toEqual(expectedMessage);
|
||||
const { container } = render(reduxWrapper(<IntlRegistrationFailure {...props} />));
|
||||
|
||||
const alertHeading = container.querySelectorAll('div.alert-heading');
|
||||
expect(alertHeading.length).toEqual(1);
|
||||
|
||||
const alert = container.querySelector('div.alert');
|
||||
expect(alert.textContent).toContain(expectedMessage);
|
||||
});
|
||||
|
||||
it('should match tpa authentication failed error message', () => {
|
||||
@@ -179,9 +191,13 @@ describe('RegistrationFailure', () => {
|
||||
failureCount: 0,
|
||||
};
|
||||
|
||||
const registrationPage = mount(reduxWrapper(<IntlRegistrationFailure {...props} />));
|
||||
expect(registrationPage.find('div.alert-heading').length).toEqual(1);
|
||||
expect(registrationPage.find('div.alert').first().text()).toContain(expectedMessageSubstring);
|
||||
const { container } = render(reduxWrapper(<IntlRegistrationFailure {...props} />));
|
||||
|
||||
const alertHeading = container.querySelectorAll('div.alert-heading');
|
||||
expect(alertHeading.length).toEqual(1);
|
||||
|
||||
const alert = container.querySelector('div.alert');
|
||||
expect(alert.textContent).toContain(expectedMessageSubstring);
|
||||
});
|
||||
|
||||
it('should display error message based on the error code returned by API', () => {
|
||||
@@ -195,10 +211,10 @@ describe('RegistrationFailure', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />))).find('RegistrationPage');
|
||||
expect(registrationPage.find('div#validation-errors').first().text()).toContain(
|
||||
'An error has occurred. Try refreshing the page, or check your internet connection.',
|
||||
);
|
||||
render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const validationError = screen.queryByText('An error has occurred. Try refreshing the page, or check your internet connection.');
|
||||
|
||||
expect(validationError).not.toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,9 +5,8 @@ import { getConfig, mergeConfig } from '@edx/frontend-platform';
|
||||
import {
|
||||
configure, getLocale, injectIntl, IntlProvider,
|
||||
} from '@edx/frontend-platform/i18n';
|
||||
import { mount } from 'enzyme';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
import renderer from 'react-test-renderer';
|
||||
import configureStore from 'redux-mock-store';
|
||||
|
||||
import {
|
||||
@@ -157,8 +156,13 @@ describe('ThirdPartyAuth', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(registrationPage.find('input#password').length).toEqual(0);
|
||||
const { queryByLabelText } = render(
|
||||
routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />, { store })),
|
||||
);
|
||||
|
||||
const passwordField = queryByLabelText('Password');
|
||||
|
||||
expect(passwordField).toBeNull();
|
||||
});
|
||||
|
||||
it('should render tpa button for tpa_hint id matching one of the primary providers', () => {
|
||||
@@ -177,9 +181,15 @@ describe('ThirdPartyAuth', () => {
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL.concat(LOGIN_PAGE), search: `?next=/dashboard&tpa_hint=${ssoProvider.id}` };
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(registrationPage.find(`button#${ssoProvider.id}`).find('span').text()).toEqual(ssoProvider.name);
|
||||
expect(registrationPage.find(`button#${ssoProvider.id}`).hasClass(`btn-tpa btn-${ssoProvider.id}`)).toEqual(true);
|
||||
const { container } = render(
|
||||
routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)),
|
||||
);
|
||||
const tpaButton = container.querySelector(`button#${ssoProvider.id}`);
|
||||
|
||||
expect(tpaButton).toBeTruthy();
|
||||
expect(tpaButton.textContent).toEqual(ssoProvider.name);
|
||||
expect(tpaButton.classList.contains('btn-tpa')).toBe(true);
|
||||
expect(tpaButton.classList.contains(`btn-${ssoProvider.id}`)).toBe(true);
|
||||
});
|
||||
|
||||
it('should display skeleton if tpa_hint is true and thirdPartyAuthContext is pending', () => {
|
||||
@@ -197,8 +207,10 @@ describe('ThirdPartyAuth', () => {
|
||||
search: `?next=/dashboard&tpa_hint=${ssoProvider.id}`,
|
||||
};
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(registrationPage.find('.react-loading-skeleton').exists()).toBeTruthy();
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const skeletonElement = container.querySelector('.react-loading-skeleton');
|
||||
|
||||
expect(skeletonElement).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should render icon if icon classes are missing in providers', () => {
|
||||
@@ -219,8 +231,10 @@ describe('ThirdPartyAuth', () => {
|
||||
window.location = { href: getConfig().BASE_URL.concat(REGISTER_PAGE), search: `?next=/dashboard&tpa_hint=${ssoProvider.id}` };
|
||||
ssoProvider.iconImage = null;
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(registrationPage.find(`button#${ssoProvider.id}`).find('div').find('span').hasClass('pgn__icon')).toEqual(true);
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const iconElement = container.querySelector(`button#${ssoProvider.id} div span.pgn__icon`);
|
||||
|
||||
expect(iconElement).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should render tpa button for tpa_hint id matching one of the secondary providers', () => {
|
||||
@@ -240,7 +254,7 @@ describe('ThirdPartyAuth', () => {
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL.concat(REGISTER_PAGE), search: `?next=/dashboard&tpa_hint=${secondaryProviders.id}` };
|
||||
|
||||
mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(window.location.href).toEqual(getConfig().LMS_BASE_URL + secondaryProviders.registerUrl);
|
||||
});
|
||||
|
||||
@@ -261,8 +275,10 @@ describe('ThirdPartyAuth', () => {
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL.concat(LOGIN_PAGE), search: '?next=/dashboard&tpa_hint=invalid' };
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(registrationPage.find(`button#${ssoProvider.id}`).find('span#provider-name').text()).toEqual(expectedMessage);
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const providerButton = container.querySelector(`button#${ssoProvider.id} span#provider-name`);
|
||||
|
||||
expect(providerButton.textContent).toEqual(expectedMessage);
|
||||
});
|
||||
|
||||
it('should show single sign on provider button', () => {
|
||||
@@ -277,8 +293,13 @@ describe('ThirdPartyAuth', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(registrationPage.find(`button#${ssoProvider.id}`).length).toEqual(1);
|
||||
const { container } = render(
|
||||
routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />, { store })),
|
||||
);
|
||||
|
||||
const buttonsWithId = container.querySelectorAll(`button#${ssoProvider.id}`);
|
||||
|
||||
expect(buttonsWithId.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('should show single sign on provider button', () => {
|
||||
@@ -293,8 +314,13 @@ describe('ThirdPartyAuth', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(registrationPage.find(`button#${ssoProvider.id}`).length).toEqual(1);
|
||||
const { container } = render(
|
||||
routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)),
|
||||
);
|
||||
|
||||
const buttonsWithId = container.querySelectorAll(`button#${ssoProvider.id}`);
|
||||
|
||||
expect(buttonsWithId.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('should display InstitutionLogistration if insitutionLogin prop is true', () => {
|
||||
@@ -303,8 +329,9 @@ describe('ThirdPartyAuth', () => {
|
||||
institutionLogin: true,
|
||||
};
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(registrationPage.find('.institutions__heading').text()).toEqual('Register with institution/campus credentials');
|
||||
const { getByText } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const headingElement = getByText('Register with institution/campus credentials');
|
||||
expect(headingElement).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should redirect to social auth provider url on SSO button click', () => {
|
||||
@@ -326,9 +353,13 @@ describe('ThirdPartyAuth', () => {
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL };
|
||||
|
||||
const loginPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const { container } = render(
|
||||
routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)),
|
||||
);
|
||||
|
||||
const ssoButton = container.querySelector('button#oa2-apple-id');
|
||||
fireEvent.click(ssoButton);
|
||||
|
||||
loginPage.find('button#oa2-apple-id').simulate('click');
|
||||
expect(window.location.href).toBe(getConfig().LMS_BASE_URL + registerUrl);
|
||||
});
|
||||
|
||||
@@ -354,7 +385,7 @@ describe('ThirdPartyAuth', () => {
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL };
|
||||
|
||||
renderer.create(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(window.location.href).toBe(getConfig().LMS_BASE_URL + authCompleteUrl);
|
||||
});
|
||||
|
||||
@@ -375,9 +406,11 @@ describe('ThirdPartyAuth', () => {
|
||||
const expectedMessage = `${'You\'ve successfully signed into Apple! We just need a little more information before '
|
||||
+ 'you start learning with '}${ getConfig().SITE_NAME }.`;
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(registrationPage.find('#tpa-alert').find('p').text()).toEqual(expectedMessage);
|
||||
const { container } = render(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
const tpaAlert = container.querySelector('#tpa-alert p');
|
||||
expect(tpaAlert.textContent).toEqual(expectedMessage);
|
||||
});
|
||||
|
||||
it('should display errorMessage if third party authentication fails', () => {
|
||||
jest.spyOn(global.Date, 'now').mockImplementation(() => 0);
|
||||
getLocale.mockImplementation(() => ('en-us'));
|
||||
@@ -403,9 +436,15 @@ describe('ThirdPartyAuth', () => {
|
||||
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
expect(registrationPage.find('div.alert-heading').length).toEqual(1);
|
||||
expect(registrationPage.find('div.alert').first().text()).toContain('An error occurred');
|
||||
const { container } = render(
|
||||
routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)),
|
||||
);
|
||||
|
||||
const alertHeading = container.querySelector('div.alert-heading');
|
||||
expect(alertHeading).toBeTruthy();
|
||||
|
||||
const alert = container.querySelector('div.alert');
|
||||
expect(alert.textContent).toContain('An error occurred');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user