From 776cd125a2250737eec147cbf69824e3ee8fb4c2 Mon Sep 17 00:00:00 2001
From: Awais Ansari <79941147+awais-ansari@users.noreply.github.com>
Date: Tue, 17 Sep 2024 17:54:14 +0500
Subject: [PATCH] feat: added country disabling feature (#1084)
* feat: added country disabling feature
* fix: lint errors
* test: added test case for disabled countries
* refactor: combined test cases
---
src/profile/ProfilePage.test.jsx | 23 +
.../__mocks__/savingEditedBio.mockStore.js | 3 +-
.../__snapshots__/ProfilePage.test.jsx.snap | 4230 +++++++++++++++++
src/profile/data/reducers.js | 1 +
src/profile/data/selectors.js | 7 +-
src/profile/forms/Country.jsx | 37 +-
6 files changed, 4296 insertions(+), 5 deletions(-)
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`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ staff
+
+
+ Member since
+ 2017
+
+
+
+
+
+
+
+
+
+
+
+
+ staff
+
+
+ Member since
+ 2017
+
+
+
+
+
+
+
+
+
+ Lemon Seltzer
+
+
+ This is the name that appears in your account and on your certificates.
+
+
+
+
+
+
+
+
+
+ Elementary/primary school
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ staff
+
+
+ Member since
+ 2017
+
+
+
+
+
+
+
+
+
+
+
+
+ staff
+
+
+ Member since
+ 2017
+
+
+
+
+
+
+
+
+
+ Lemon Seltzer
+
+
+ This is the name that appears in your account and on your certificates.
+
+
+
+
+
+
+
+
+
+ Elementary/primary school
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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(