diff --git a/src/profile/ProfilePage.test.jsx b/src/profile/ProfilePage.test.jsx index 997a92e86..e347ba8c5 100644 --- a/src/profile/ProfilePage.test.jsx +++ b/src/profile/ProfilePage.test.jsx @@ -285,6 +285,29 @@ describe('', () => { expect(container.querySelector('.alert-danger')).toHaveClass('show'); }); + + it.each([ + ['test user with non-disabled country', 'PK'], + ['test user with disabled country', 'RU'], + ])('test user with %s', (_, accountCountry) => { + const storeData = JSON.parse(JSON.stringify(storeMocks.savingEditedBio)); + storeData.profilePage.errors.country = {}; + storeData.profilePage.currentlyEditingField = 'country'; + storeData.profilePage.disabledCountries = ['RU']; + storeData.profilePage.account.country = accountCountry; + const contextValue = { + authenticatedUser: { userId: 123, username: 'staff', administrator: true }, + config: getConfig(), + }; + const component = ( + + ); + const { container: tree } = render(component); + expect(tree).toMatchSnapshot(); + }); }); describe('handles analytics', () => { diff --git a/src/profile/__mocks__/savingEditedBio.mockStore.js b/src/profile/__mocks__/savingEditedBio.mockStore.js index 63551e823..a104762d6 100644 --- a/src/profile/__mocks__/savingEditedBio.mockStore.js +++ b/src/profile/__mocks__/savingEditedBio.mockStore.js @@ -125,7 +125,8 @@ module.exports = { } ], drafts: {}, - isLoadingProfile: false + isLoadingProfile: false, + disabledCountries: [], }, router: { location: { diff --git a/src/profile/__snapshots__/ProfilePage.test.jsx.snap b/src/profile/__snapshots__/ProfilePage.test.jsx.snap index bb9c11d0d..843a2c931 100644 --- a/src/profile/__snapshots__/ProfilePage.test.jsx.snap +++ b/src/profile/__snapshots__/ProfilePage.test.jsx.snap @@ -5107,6 +5107,4236 @@ exports[` Renders correctly in various states test preferreded la `; +exports[` Renders correctly in various states test user with test user with disabled country 1`] = ` +
+
+
+
+
+
+
+
+
+
+ +
+ profile avatar +
+
+ +
+
+
+
+
+
+ +

+ staff +

+

+ Member since + 2017 +

+
+
+
+
+
+
+
+
+
+ +

+ staff +

+

+ Member since + 2017 +

+
+
+
+
+
+
+
+

+ Full Name + +

+

+ + + + Just me + +

+
+

+ Lemon Seltzer +

+ + This is the name that appears in your account and on your certificates. + +
+
+
+
+
+
+
+ + +
+
+
+ + + + + + + +
+
+ + +
+
+
+
+
+
+
+
+
+

+ Primary Language Spoken + +

+

+ + + + Everyone on localhost + +

+
+

+ Yoruba +

+
+
+
+
+
+

+ Education + +

+

+ + + + Just me + +

+
+

+ Elementary/primary school +

+
+
+
+
+
+

+ Social Links + +

+

+ + + + Everyone on localhost + +

+
+ +
+
+
+
+
+
+
+

+ About Me + +

+

+ + + + Everyone on localhost + +

+
+

+ This is my bio +

+
+
+
+
+
+

+ My Certificates + +

+

+ + + + Everyone on localhost + +

+
+
+
+
+
+
+
+

+ Verified Certificate +

+

+ edX Demonstration Course +

+
+

+ From +

+

+ edX +

+
+

+ Completed on + 3/4/2019 +

+ +
+
+
+
+
+
+
+
+
+
+
+`; + +exports[` Renders correctly in various states test user with test user with non-disabled country 1`] = ` +
+
+
+
+
+
+
+
+
+
+ +
+ profile avatar +
+
+ +
+
+
+
+
+
+ +

+ staff +

+

+ Member since + 2017 +

+
+
+
+
+
+
+
+
+
+ +

+ staff +

+

+ Member since + 2017 +

+
+
+
+
+
+
+
+

+ Full Name + +

+

+ + + + Just me + +

+
+

+ Lemon Seltzer +

+ + This is the name that appears in your account and on your certificates. + +
+
+
+
+
+
+
+ + +
+
+
+ + + + + + + +
+
+ + +
+
+
+
+
+
+
+
+
+

+ Primary Language Spoken + +

+

+ + + + Everyone on localhost + +

+
+

+ Yoruba +

+
+
+
+
+
+

+ Education + +

+

+ + + + Just me + +

+
+

+ Elementary/primary school +

+
+
+
+
+
+

+ Social Links + +

+

+ + + + Everyone on localhost + +

+
+ +
+
+
+
+
+
+
+

+ About Me + +

+

+ + + + Everyone on localhost + +

+
+

+ This is my bio +

+
+
+
+
+
+

+ My Certificates + +

+

+ + + + Everyone on localhost + +

+
+
+
+
+
+
+
+

+ Verified Certificate +

+

+ edX Demonstration Course +

+
+

+ From +

+

+ edX +

+
+

+ Completed on + 3/4/2019 +

+ +
+
+
+
+
+
+
+
+
+
+
+`; + exports[` Renders correctly in various states viewing other profile with all fields 1`] = `
{ diff --git a/src/profile/data/selectors.js b/src/profile/data/selectors.js index b04493e6e..211cdf0d4 100644 --- a/src/profile/data/selectors.js +++ b/src/profile/data/selectors.js @@ -23,6 +23,7 @@ export const isLoadingProfileSelector = state => state.profilePage.isLoadingProf export const currentlyEditingFieldSelector = state => state.profilePage.currentlyEditingField; export const accountErrorsSelector = state => state.profilePage.errors; export const isAuthenticatedUserProfileSelector = state => state.profilePage.isAuthenticatedUserProfile; +export const disabledCountriesSelector = state => state.profilePage.disabledCountries; export const editableFormModeSelector = createSelector( profileAccountSelector, @@ -130,10 +131,14 @@ export const countrySelector = createSelector( editableFormSelector, sortedCountriesSelector, countryMessagesSelector, - (editableForm, sortedCountries, countryMessages) => ({ + disabledCountriesSelector, + profileAccountSelector, + (editableForm, sortedCountries, countryMessages, disabledCountries, account) => ({ ...editableForm, sortedCountries, countryMessages, + disabledCountries, + committedCountry: account.country, }), ); diff --git a/src/profile/forms/Country.jsx b/src/profile/forms/Country.jsx index 0048017e6..ffeaa24e5 100644 --- a/src/profile/forms/Country.jsx +++ b/src/profile/forms/Country.jsx @@ -35,7 +35,13 @@ class Country extends React.Component { handleSubmit(e) { e.preventDefault(); - this.props.submitHandler(this.props.formId); + const { + country, disabledCountries, formId, submitHandler, + } = this.props; + + if (!disabledCountries.includes(country)) { + submitHandler(formId); + } } handleClose() { @@ -46,6 +52,26 @@ class Country extends React.Component { this.props.openHandler(this.props.formId); } + isDisabledCountry = (country) => { + const { disabledCountries } = this.props; + return disabledCountries.includes(country); + }; + + filteredCountries = (countryList) => { + const { disabledCountries, committedCountry } = this.props; + + if (!disabledCountries.length) { + return countryList; + } + + return countryList.filter(({ code }) => { + const isDisabled = this.isDisabledCountry(code); + const isUserCountry = code === committedCountry; + + return !isDisabled || isUserCountry; + }); + }; + render() { const { formId, @@ -58,6 +84,7 @@ class Country extends React.Component { sortedCountries, countryMessages, } = this.props; + const filteredCountries = this.filteredCountries(sortedCountries); return ( - {sortedCountries.map(({ code, name }) => ( - + {filteredCountries.map(({ code, name }) => ( + ))} {error !== null && ( @@ -157,7 +184,9 @@ Country.propTypes = { code: PropTypes.string.isRequired, name: PropTypes.string.isRequired, })).isRequired, + disabledCountries: PropTypes.arrayOf(PropTypes.string), countryMessages: PropTypes.objectOf(PropTypes.string).isRequired, + committedCountry: PropTypes.string, // Actions changeHandler: PropTypes.func.isRequired, @@ -175,6 +204,8 @@ Country.defaultProps = { country: null, visibilityCountry: 'private', error: null, + disabledCountries: [], + committedCountry: '', }; export default connect(