fix: add location resitriction for popular and trending courses (#1010)

Description:
Filter courses on the basis of location

VAN-1573
This commit is contained in:
Blue
2023-07-31 14:47:22 +05:00
committed by GitHub
parent dff3903617
commit aeda262fb0
6 changed files with 63 additions and 14 deletions

View File

@@ -0,0 +1,20 @@
import { useEffect, useState } from 'react';
import { getConfig } from '@edx/frontend-platform';
import { filterLocationRestriction } from '../../data/utils';
export default function useProducts(countryCode) {
const [popularProducts, setPopularProducts] = useState([]);
const [trendingProducts, setTrendingProducts] = useState([]);
useEffect(() => {
const popular = filterLocationRestriction(JSON.parse(getConfig().POPULAR_PRODUCTS), countryCode);
const trending = filterLocationRestriction(JSON.parse(getConfig().TRENDING_PRODUCTS), countryCode);
setPopularProducts(popular);
setTrendingProducts(trending);
}, [countryCode]);
return { popularProducts, trendingProducts };
}

View File

@@ -1,4 +1,5 @@
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
@@ -10,22 +11,21 @@ import { Helmet } from 'react-helmet';
import { POPULAR, TRENDING } from './data/constants';
import messages from './messages';
import useProducts from './ProductCard/hooks/useProducts';
import RecommendationsList from './RecommendationsList';
import { trackRecommendationsViewed } from './track';
import { DEFAULT_REDIRECT_URL } from '../data/constants';
const RecommendationsPage = ({ location }) => {
const RecommendationsPage = ({ location, countryCode }) => {
const { formatMessage } = useIntl();
const registrationResponse = location.state?.registrationResult;
const userId = location.state?.userId;
const { popularProducts, trendingProducts } = useProducts(countryCode);
const DASHBOARD_URL = getConfig().LMS_BASE_URL.concat(DEFAULT_REDIRECT_URL);
const POPULAR_PRODUCTS = JSON.parse(getConfig().POPULAR_PRODUCTS);
const TRENDING_PRODUCTS = JSON.parse(getConfig().TRENDING_PRODUCTS);
useEffect(() => {
trackRecommendationsViewed(POPULAR_PRODUCTS, POPULAR, false, userId);
trackRecommendationsViewed(popularProducts, POPULAR, false, userId);
}, []); // eslint-disable-line react-hooks/exhaustive-deps
const handleRedirection = () => {
@@ -47,12 +47,12 @@ const RecommendationsPage = ({ location }) => {
return null;
}
if (!POPULAR_PRODUCTS.length || !TRENDING_PRODUCTS.length) {
if (!popularProducts.length || !trendingProducts.length) {
handleRedirection();
}
const handleOnSelect = (tabKey) => {
const recommendations = tabKey === POPULAR ? POPULAR_PRODUCTS : TRENDING_PRODUCTS;
const recommendations = tabKey === POPULAR ? popularProducts : trendingProducts;
trackRecommendationsViewed(recommendations, tabKey, false, userId);
};
@@ -83,13 +83,13 @@ const RecommendationsPage = ({ location }) => {
>
<Tab tabClassName="mb-3" eventKey={POPULAR} title={formatMessage(messages['recommendation.option.popular'])}>
<RecommendationsList
recommendations={POPULAR_PRODUCTS}
recommendations={popularProducts}
userId={userId}
/>
</Tab>
<Tab tabClassName="mb-3" eventKey={TRENDING} title={formatMessage(messages['recommendation.option.trending'])}>
<RecommendationsList
recommendations={TRENDING_PRODUCTS}
recommendations={trendingProducts}
userId={userId}
/>
</Tab>
@@ -121,11 +121,18 @@ RecommendationsPage.propTypes = {
userId: PropTypes.number,
}),
}),
countryCode: PropTypes.string.isRequired,
};
RecommendationsPage.defaultProps = {
location: { state: {} },
};
export default RecommendationsPage;
const mapStateToProps = state => ({
countryCode: state.register.backendCountryCode,
});
export default connect(
mapStateToProps,
null,
)(RecommendationsPage);

View File

@@ -1,10 +1,15 @@
import { convertCourseRunKeytoCourseKey, useProductType } from '../utils';
import mockedProductData from '../../tests/mockedData';
import { convertCourseRunKeytoCourseKey, filterLocationRestriction, useProductType } from '../utils';
describe('UtilsTests', () => {
it('should return the courseKey after parsing the activeCourseRun key', async () => {
const courseKey = convertCourseRunKeytoCourseKey('course-v1:Demox+Test101+2023');
expect(courseKey).toEqual('Demox+Test101');
});
it('should filter courses on the basis of country code', async () => {
const products = filterLocationRestriction(mockedProductData, 'PK');
expect(products.length).toEqual(1);
});
it('should return courseType and programType', async () => {
const programType = useProductType(undefined, 'Professional Certificate');
expect(programType).toEqual('Professional Certificate');

View File

@@ -49,4 +49,17 @@ export const createCodeFriendlyProduct = (type) => type?.replace(/\s+/g, '-').re
export const truncateText = (input) => (input?.length > 50 ? `${input.substring(0, 50)}...` : input);
export const filterLocationRestriction = (products, countryCode) => products.filter((product) => {
if (product.locationRestriction) {
if (product.locationRestriction.restrictionType === 'allowlist') {
return product.locationRestriction.countries.includes(countryCode);
}
if (product.locationRestriction.restrictionType === 'blocklist') {
return !product.locationRestriction.countries.includes(countryCode);
}
}
return true;
},
);
export default convertCourseRunKeytoCourseKey;

View File

@@ -44,7 +44,11 @@ describe('RecommendationsPageTests', () => {
);
beforeEach(() => {
store = mockStore({});
store = mockStore({
register: {
backendCountryCode: 'PK',
},
});
defaultProps = {
location: {
state: {

View File

@@ -71,9 +71,9 @@ const mockedProductData = [
status: 'active',
hidden: false,
degree: null,
locationRestriction: null,
cardType: 'program',
cardIndex: 1,
locationRestriction: { restrictionType: 'blocklist', countries: ['PK'] },
},
];