consolidated country-data and contry-list

This commit is contained in:
Ben Wheeler 2019-08-05 23:33:05 -04:00
parent 50e706efa8
commit 51aa38fb34
6 changed files with 1192 additions and 1227 deletions

View file

@ -33,29 +33,20 @@ require('./steps.scss');
const DEFAULT_COUNTRY = 'us'; const DEFAULT_COUNTRY = 'us';
/** /**
* Return a list of options to give to frc select * Return a list of options to give to select
* @param {object} reactIntl react-intl, used to localize strings * @param {object} reactIntl react-intl, used to localize strings
* @param {string} defaultCountry optional string of default country to put at top of list * @return {object} ordered set of county options formatted for select
* @return {object} ordered set of county options formatted for frc select
*/ */
const getCountryOptions = (reactIntl, defaultCountry) => { const getCountryOptions = reactIntl => (
const options = countryData.countryOptions.concat({ [
label: reactIntl.formatMessage({id: 'registration.selectCountry'}), {
disabled: true, label: reactIntl.formatMessage({id: 'registration.selectCountry'}),
value: '' disabled: true,
}); value: ''
},
if (typeof defaultCountry !== 'undefined') { ...countryData.registrationCountryOptions
return options.sort((a, b) => { ]
if (a.disabled) return -1; );
if (b.disabled) return 1;
if (a.value === defaultCountry) return -1;
if (b.value === defaultCountry) return 1;
return 0;
});
}
return options;
};
const NextStepButton = props => ( const NextStepButton = props => (
<Button <Button
@ -445,6 +436,13 @@ class DemographicsStep extends React.Component {
this.setState({otherDisabled: gender !== 'other'}); this.setState({otherDisabled: gender !== 'other'});
} }
handleValidSubmit (formData) { handleValidSubmit (formData) {
// look up country name using user's country code selection
if (formData.countryCode) {
const countryInfo = countryData.lookupCountryInfo(formData.countryCode);
if (countryInfo) {
formData.user.country = countryInfo.name;
}
}
return this.props.onNextStep(formData); return this.props.onNextStep(formData);
} }
isValidBirthdate (year, month) { isValidBirthdate (year, month) {
@ -460,7 +458,7 @@ class DemographicsStep extends React.Component {
return isValid ? true : this.props.intl.formatMessage({id: 'teacherRegistration.validationAge'}); return isValid ? true : this.props.intl.formatMessage({id: 'teacherRegistration.validationAge'});
} }
render () { render () {
const countryOptions = getCountryOptions(this.props.intl, DEFAULT_COUNTRY); const countryOptions = getCountryOptions(this.props.intl);
return ( return (
<Slide className="registration-step demographics-step"> <Slide className="registration-step demographics-step">
<h2> <h2>
@ -539,7 +537,7 @@ class DemographicsStep extends React.Component {
<Select <Select
required required
label={this.props.intl.formatMessage({id: 'general.country'})} label={this.props.intl.formatMessage({id: 'general.country'})}
name="user.country" name="countryCode"
options={countryOptions} options={countryOptions}
value={countryOptions[0].value} value={countryOptions[0].value}
/> />
@ -948,6 +946,7 @@ class AddressStep extends React.Component {
render () { render () {
let stateOptions = countryData.subdivisionOptions[this.state.countryChoice]; let stateOptions = countryData.subdivisionOptions[this.state.countryChoice];
stateOptions = [{}].concat(stateOptions); stateOptions = [{}].concat(stateOptions);
const countryOptions = getCountryOptions(this.props.intl);
return ( return (
<Slide className="registration-step address-step"> <Slide className="registration-step address-step">
<h2> <h2>
@ -970,7 +969,7 @@ class AddressStep extends React.Component {
this.props.intl.formatMessage({id: 'general.country'}) this.props.intl.formatMessage({id: 'general.country'})
} }
name="address.country" name="address.country"
options={getCountryOptions(this.props.intl)} options={countryOptions}
value={this.props.defaultCountry} value={this.props.defaultCountry}
onChange={this.handleChangeCountry} onChange={this.handleChangeCountry}
/> />

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -115,9 +115,7 @@ class TeacherRegistration extends React.Component {
onNextStep={this.handleAdvanceStep} onNextStep={this.handleAdvanceStep}
/> />
<Steps.PhoneNumberStep <Steps.PhoneNumberStep
defaultCountry={ defaultCountry={this.state.formData.countryCode}
this.state.formData.user && this.state.formData.user.country
}
waiting={this.state.waiting} waiting={this.state.waiting}
onNextStep={this.handleAdvanceStep} onNextStep={this.handleAdvanceStep}
/> />
@ -126,9 +124,7 @@ class TeacherRegistration extends React.Component {
onNextStep={this.handleAdvanceStep} onNextStep={this.handleAdvanceStep}
/> />
<Steps.AddressStep <Steps.AddressStep
defaultCountry={ defaultCountry={this.state.formData.countryCode}
this.state.formData.user && this.state.formData.user.country
}
waiting={this.state.waiting} waiting={this.state.waiting}
onNextStep={this.handleAdvanceStep} onNextStep={this.handleAdvanceStep}
/> />

View file

@ -1,28 +1,99 @@
const { const {
countryInfo,
countryOptions, countryOptions,
lookupCountryInfo,
dupeCommonCountries,
registrationCountryOptions,
subdivisionOptions subdivisionOptions
} = require('../../../src/lib/country-data'); } = require('../../../src/lib/country-data');
describe('unit test lib/country-data.js', () => { describe('unit test lib/country-data.js', () => {
test('countryOptions has the ballpark number of countries we expect', () => { test('countryInfo has the ballpark number of countries we expect', () => {
expect(typeof countryOptions).toBe('object'); expect(typeof countryInfo).toBe('object');
expect(countryOptions.length > 200).toEqual(true); expect(countryInfo.length > 200).toEqual(true);
expect(countryOptions.length < 300).toEqual(true); expect(countryInfo.length < 300).toEqual(true);
}); });
test('countryOptions is in alphabetical order', () => { test('countryOptions() maintains number of items', () => {
// test whether countryOptions is already sorted, by: expect(typeof countryOptions).toBe('function');
// 1) creating a sorted version of countryOptions const myCountryOptions = countryOptions(countryInfo, 'name');
const sortedCountryOptions = countryOptions.sort((a, b) => { const numCountries = countryInfo.length;
if (a.label < b.label) { expect(myCountryOptions.length).toEqual(numCountries);
return -1; });
}
return 1; test('countryOptions() called with value=name will use correct display strings and country name', () => {
}); expect(typeof countryOptions).toBe('function');
// 2) comparing sorted version of countryOptions to original const myCountryOptions = countryOptions(countryInfo, 'name');
expect(countryOptions.map(option => option.label))
.toEqual(sortedCountryOptions.map(option => option.label)); const eswatiniInfo = myCountryOptions.find(country => country.value === 'Swaziland');
expect(eswatiniInfo).toBeTruthy();
expect(eswatiniInfo.label).toEqual('Eswatini');
const swedenInfo = myCountryOptions.find(country => country.value === 'Sweden');
expect(swedenInfo).toBeTruthy();
expect(swedenInfo.label).toEqual('Sweden');
});
test('countryOptions() called with value==code will use correct display strings and country code', () => {
expect(typeof countryOptions).toBe('function');
const myCountryOptions = countryOptions(countryInfo, 'code');
const szInfo = myCountryOptions
.find(country => country.value === 'sz');
expect(szInfo).toBeTruthy();
expect(szInfo.label).toEqual('Eswatini');
});
test('lookupCountryInfo() will find country info', () => {
expect(typeof lookupCountryInfo).toBe('function');
const eswatiniInfo = lookupCountryInfo('sz');
expect(eswatiniInfo.name).toEqual('Swaziland');
expect(eswatiniInfo.display).toEqual('Eswatini');
expect(eswatiniInfo.code).toEqual('sz');
});
test('calling dupeCommonCountries() will duplicate the requested country info at start of array', () => {
expect(typeof dupeCommonCountries).toBe('function');
const countryInfoWithCommon = dupeCommonCountries(countryInfo, ['ca', 'gb']);
// test that the two entries have been added to the start of the array
const numCountries = countryInfo.length;
expect(countryInfoWithCommon.length).toEqual(numCountries + 2);
expect(countryInfoWithCommon[0]).toEqual({code: 'ca', name: 'Canada'});
expect(countryInfoWithCommon[1]).toEqual({code: 'gb', name: 'United Kingdom'});
// test that there are now two entries for Canada
const canadaItems = countryInfoWithCommon.reduce((acc, thisCountry) => (
thisCountry.code === 'ca' ? [...acc, thisCountry] : acc
), []);
expect(canadaItems.length).toEqual(2);
// test that there are now two entries for UK
const ukItems = countryInfoWithCommon.reduce((acc, thisCountry) => (
thisCountry.code === 'gb' ? [...acc, thisCountry] : acc
), []);
expect(ukItems.length).toEqual(2);
});
test('registrationCountryOptions object places USA and UK at start, with display name versions', () => {
expect(typeof registrationCountryOptions).toBe('object');
const numCountries = countryInfo.length;
// test that the two entries have been added to the start of the array, and that
// the name of the USA includes "America"
expect(registrationCountryOptions.length).toEqual(numCountries + 2);
expect(registrationCountryOptions[0]).toEqual({value: 'us', label: 'United States of America'});
expect(registrationCountryOptions[1]).toEqual({value: 'gb', label: 'United Kingdom'});
// test that there are now two entries for USA
const usaOptions = registrationCountryOptions.reduce((acc, thisCountry) => (
thisCountry.value === 'us' ? [...acc, thisCountry] : acc
), []);
expect(usaOptions.length).toEqual(2);
// test that there are now two entries for UK
const ukOptions = registrationCountryOptions.reduce((acc, thisCountry) => (
thisCountry.value === 'gb' ? [...acc, thisCountry] : acc
), []);
expect(ukOptions.length).toEqual(2);
}); });
test('subdivisionOptions object should include correct info for sample country', () => { test('subdivisionOptions object should include correct info for sample country', () => {

View file

@ -1,88 +0,0 @@
const {
countryInfo,
countryOptions,
dupeCommonCountries,
registrationCountryOptions
} = require('../../../src/lib/country-list');
describe('unit test lib/country-list.js', () => {
test('countryInfo has the ballpark number of countries we expect', () => {
expect(typeof countryInfo).toBe('object');
expect(countryInfo.length > 200).toEqual(true);
expect(countryInfo.length < 300).toEqual(true);
});
test('countryOptions() maintains number of items', () => {
expect(typeof countryOptions).toBe('function');
const myCountryOptions = countryOptions(countryInfo, 'name');
const numCountries = countryInfo.length;
expect(myCountryOptions.length).toEqual(numCountries);
});
test('countryOptions() called with value=name will use correct display strings and country name', () => {
expect(typeof countryOptions).toBe('function');
const myCountryOptions = countryOptions(countryInfo, 'name');
const eswatiniInfo = myCountryOptions.find(country => country.value === 'Swaziland');
expect(eswatiniInfo).toBeTruthy();
expect(eswatiniInfo.label).toEqual('Eswatini');
const swedenInfo = myCountryOptions.find(country => country.value === 'Sweden');
expect(swedenInfo).toBeTruthy();
expect(swedenInfo.label).toEqual('Sweden');
});
test('countryOptions() called with value==code will use correct display strings and country code', () => {
expect(typeof countryOptions).toBe('function');
const myCountryOptions = countryOptions(countryInfo, 'code');
const szInfo = myCountryOptions
.find(country => country.value === 'sz');
expect(szInfo).toBeTruthy();
expect(szInfo.label).toEqual('Eswatini');
});
test('calling dupeCommonCountries() will duplicate the requested country info at start of array', () => {
expect(typeof dupeCommonCountries).toBe('function');
const countryInfoWithCommon = dupeCommonCountries(countryInfo, ['ca', 'gb']);
// test that the two entries have been added to the start of the array
const numCountries = countryInfo.length;
expect(countryInfoWithCommon.length).toEqual(numCountries + 2);
expect(countryInfoWithCommon[0]).toEqual({code: 'ca', name: 'Canada'});
expect(countryInfoWithCommon[1]).toEqual({code: 'gb', name: 'United Kingdom'});
// test that there are now two entries for Canada
const canadaItems = countryInfoWithCommon.reduce((acc, thisCountry) => (
thisCountry.code === 'ca' ? [...acc, thisCountry] : acc
), []);
expect(canadaItems.length).toEqual(2);
// test that there are now two entries for UK
const ukItems = countryInfoWithCommon.reduce((acc, thisCountry) => (
thisCountry.code === 'gb' ? [...acc, thisCountry] : acc
), []);
expect(ukItems.length).toEqual(2);
});
test('registrationCountryOptions object places USA and UK at start, with display name versions', () => {
expect(typeof registrationCountryOptions).toBe('object');
const numCountries = countryInfo.length;
// test that the two entries have been added to the start of the array, and that
// the name of the USA includes "America"
expect(registrationCountryOptions.length).toEqual(numCountries + 2);
expect(registrationCountryOptions[0]).toEqual({value: 'us', label: 'United States of America'});
expect(registrationCountryOptions[1]).toEqual({value: 'gb', label: 'United Kingdom'});
// test that there are now two entries for USA
const usaOptions = registrationCountryOptions.reduce((acc, thisCountry) => (
thisCountry.value === 'us' ? [...acc, thisCountry] : acc
), []);
expect(usaOptions.length).toEqual(2);
// test that there are now two entries for UK
const ukOptions = registrationCountryOptions.reduce((acc, thisCountry) => (
thisCountry.value === 'gb' ? [...acc, thisCountry] : acc
), []);
expect(ukOptions.length).toEqual(2);
});
});