fix: country field error is updated (#1108)
This commit is contained in:
@@ -3,6 +3,7 @@ import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { useIntl } from '@edx/frontend-platform/i18n';
|
||||
import { FormAutosuggest, FormAutosuggestOption, FormControlFeedback } from '@edx/paragon';
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import validateCountryField, { COUNTRY_CODE_KEY, COUNTRY_DISPLAY_KEY } from './validator';
|
||||
@@ -60,7 +61,7 @@ const CountryField = (props) => {
|
||||
const { value } = event.target;
|
||||
|
||||
const { countryCode, displayValue, error } = validateCountryField(
|
||||
value.trim(), countryList, formatMessage(messages['empty.country.field.error']),
|
||||
value.trim(), countryList, formatMessage(messages['empty.country.field.error']), formatMessage(messages['invalid.country.field.error']),
|
||||
);
|
||||
|
||||
onChangeHandler({ target: { name: 'country' } }, { countryCode, displayValue });
|
||||
@@ -94,6 +95,7 @@ const CountryField = (props) => {
|
||||
aria-label="form autosuggest"
|
||||
name="country"
|
||||
value={selectedCountry.displayValue || ''}
|
||||
className={classNames({ 'form-field-error': props.errorMessage })}
|
||||
onSelected={(value) => handleSelected(value)}
|
||||
onFocus={(e) => handleOnFocus(e)}
|
||||
onBlur={(e) => handleOnBlur(e)}
|
||||
|
||||
@@ -91,6 +91,16 @@ 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' } });
|
||||
expect(props.handleErrorChange).toHaveBeenCalledTimes(1);
|
||||
expect(props.handleErrorChange).toHaveBeenCalledWith(
|
||||
'country',
|
||||
'Country must match with an option available in the dropdown.',
|
||||
);
|
||||
});
|
||||
|
||||
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', {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
export const COUNTRY_CODE_KEY = 'code';
|
||||
export const COUNTRY_DISPLAY_KEY = 'name';
|
||||
|
||||
const validateCountryField = (value, countryList, errorMessage) => {
|
||||
const validateCountryField = (value, countryList, emptyErrorMessage, invalidCountryErrorMessage) => {
|
||||
let countryCode = '';
|
||||
let displayValue = value;
|
||||
let error = errorMessage;
|
||||
let error = '';
|
||||
|
||||
if (value) {
|
||||
const normalizedValue = value.toLowerCase();
|
||||
@@ -20,8 +20,11 @@ const validateCountryField = (value, countryList, errorMessage) => {
|
||||
if (selectedCountry) {
|
||||
countryCode = selectedCountry[COUNTRY_CODE_KEY];
|
||||
displayValue = selectedCountry[COUNTRY_DISPLAY_KEY];
|
||||
error = '';
|
||||
} else {
|
||||
error = invalidCountryErrorMessage;
|
||||
}
|
||||
} else {
|
||||
error = emptyErrorMessage;
|
||||
}
|
||||
return { error, countryCode, displayValue };
|
||||
};
|
||||
|
||||
@@ -285,6 +285,26 @@ describe('ConfigurableRegistrationForm', () => {
|
||||
expect(registrationPage.find('div[feedback-for="country"]').text()).toEqual(countryError);
|
||||
expect(registrationPage.find('#confirm_email-error').last().text()).toEqual(confirmEmailError);
|
||||
});
|
||||
|
||||
it('should show country field validation when country name is invalid', () => {
|
||||
const invalidCountryError = 'Country must match with an option available in the dropdown.';
|
||||
|
||||
store = mockStore({
|
||||
...initialState,
|
||||
commonComponents: {
|
||||
...initialState.commonComponents,
|
||||
fieldDescriptions: {
|
||||
country: { name: 'country' },
|
||||
},
|
||||
},
|
||||
});
|
||||
const registrationPage = mount(routerWrapper(reduxWrapper(<IntlRegistrationPage {...props} />)));
|
||||
registrationPage.find('input[name="country"]').simulate('blur', { target: { value: 'Pak', name: 'country' } });
|
||||
|
||||
registrationPage.find('button.btn-brand').simulate('click');
|
||||
expect(registrationPage.find('div[feedback-for="country"]').text()).toEqual(invalidCountryError);
|
||||
});
|
||||
|
||||
it('should show error if email and confirm email fields do not match', () => {
|
||||
store = mockStore({
|
||||
...initialState,
|
||||
|
||||
@@ -48,6 +48,9 @@ export const isFormValid = (
|
||||
if (!configurableFormFields?.country?.displayValue) {
|
||||
fieldErrors.country = formatMessage(messages['empty.country.field.error']);
|
||||
isValid = false;
|
||||
} else if (!configurableFormFields?.country?.countryCode) {
|
||||
fieldErrors.country = formatMessage(messages['invalid.country.field.error']);
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
Object.keys(fieldDescriptions).forEach(key => {
|
||||
|
||||
@@ -111,6 +111,11 @@ const messages = defineMessages({
|
||||
defaultMessage: 'Select your country or region of residence',
|
||||
description: 'Error message when no country/region is selected',
|
||||
},
|
||||
'invalid.country.field.error': {
|
||||
id: 'invalid.country.field.error',
|
||||
defaultMessage: 'Country must match with an option available in the dropdown.',
|
||||
description: 'Error message when country is invalid',
|
||||
},
|
||||
'email.do.not.match': {
|
||||
id: 'email.do.not.match',
|
||||
defaultMessage: 'The email addresses do not match.',
|
||||
|
||||
@@ -107,3 +107,11 @@
|
||||
right: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.form-field-error {
|
||||
border: 2px solid var(--danger-300, #CA3A2F) !important;
|
||||
|
||||
input {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user