Skip to content

Commit

Permalink
feat: refactoring catalog search to support exec ed content (#268)
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-sheehan-edx authored Dec 9, 2022
1 parent 58155c3 commit 96cef62
Show file tree
Hide file tree
Showing 16 changed files with 696 additions and 225 deletions.
3 changes: 2 additions & 1 deletion .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ MINIMAL_HEADER=true
EDX_FOR_BUSINESS_TITLE=''
EDX_FOR_ONLINE_EDU_TITLE=''
EDX_ENTERPRISE_ALACARTE_TITLE=''
FEATURE_LANGUAGE_FACET=True
FEATURE_LANGUAGE_FACET=true
HOTJAR_APP_ID=''
HOTJAR_VERSION=6
HOTJAR_DEBUG=true
HUBSPOT_MARKETING_URL='http://example.com'
EXEC_ED_INCLUSION=true
21 changes: 11 additions & 10 deletions src/components/catalogNoResultsDeck/CatalogNoResultsDeck.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import PropTypes from 'prop-types';
import {
CONTENT_TYPE_COURSE,
CONTENT_TYPE_PROGRAM,
EDX_COURSES_COURSE_TYPES,
EXECUTIVE_EDUCATION_2U_COURSE_TYPE,
NO_RESULTS_DECK_ITEM_COUNT,
NO_RESULTS_PAGE_SIZE,
NO_RESULTS_PAGE_ITEM_COUNT,
Expand All @@ -24,7 +24,6 @@ function CatalogNoResultsDeck({
columns,
renderCardComponent,
contentType,
courseType,
}) {
const [defaultData, setDefaultData] = useState([]);
const [apiError, setApiError] = useState(false);
Expand All @@ -42,12 +41,9 @@ function CatalogNoResultsDeck({
useEffect(() => {
const defaultCoursesRefinements = {
enterprise_catalog_query_titles: selectedCatalog,
content_type: contentType,
learning_type: contentType,
};
if (contentType === CONTENT_TYPE_COURSE) {
// if a course type is not specified, default to edx course content
defaultCoursesRefinements.course_type = courseType !== null ? [courseType] : EDX_COURSES_COURSE_TYPES;
}

EnterpriseCatalogApiService.fetchDefaultCoursesInCatalogWithFacets(
defaultCoursesRefinements,
)
Expand All @@ -59,7 +55,7 @@ function CatalogNoResultsDeck({
setApiError(true);
logError(err);
});
}, [selectedCatalog, contentType, courseType]);
}, [selectedCatalog, contentType]);

let defaultDeckTitle;
let alertText;
Expand All @@ -70,6 +66,13 @@ function CatalogNoResultsDeck({
defaultDeckTitle = intl.formatMessage(
messages['catalogSearchResults.DefaultCourseDeckTitle'],
);
} else if (contentType === EXECUTIVE_EDUCATION_2U_COURSE_TYPE) {
alertText = intl.formatMessage(
messages['catalogSearchResults.NoResultsExecEdCourseBannerText'],
);
defaultDeckTitle = intl.formatMessage(
messages['catalogSearchResults.DefaultExecEdCourseDeckTitle'],
);
} else if (contentType === CONTENT_TYPE_PROGRAM) {
alertText = intl.formatMessage(
messages['catalogSearchResults.NoResultsProgramBannerText'],
Expand Down Expand Up @@ -131,12 +134,10 @@ CatalogNoResultsDeck.defaultProps = {
renderCardComponent: () => {},
columns: [],
contentType: '',
courseType: null,
};

CatalogNoResultsDeck.propTypes = {
contentType: PropTypes.string,
courseType: PropTypes.string,
intl: intlShape.isRequired,
setCardView: PropTypes.func,
renderCardComponent: PropTypes.func,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ const messages = defineMessages({
defaultMessage: 'Popular Courses',
description: 'Popular Courses table header.',
},
'catalogSearchResults.DefaultExecEdCourseDeckTitle': {
id: 'catalogSearchResults.popularExecEdCourses',
defaultMessage: 'Popular Executive Education Courses',
description: 'Popular Executive Education Courses table header.',
},
'catalogSearchResults.DefaultProgramDeckTitle': {
id: 'catalogSearchResults.popularPrograms',
defaultMessage: 'Popular Programs',
Expand All @@ -21,6 +26,11 @@ const messages = defineMessages({
defaultMessage: 'No courses were found that match your search. Try ',
description: 'No results course alert modal text.',
},
'catalogSearchResults.NoResultsExecEdCourseBannerText': {
id: 'catalogSearchResults.NoResultsExecEdCourseBannerText',
defaultMessage: 'No Executive Education courses were found that match your search. Try ',
description: 'No results exec ed course alert modal text.',
},
'catalogSearchResults.NoResultsProgramBannerText': {
id: 'catalogSearchResults.NoResultsProgramBannerText',
defaultMessage: 'No programs were found that match your search. Try ',
Expand Down
26 changes: 26 additions & 0 deletions src/components/catalogNoResultsDeck/CatalogNoResultsDeck.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,23 @@ const defaultProps = {
},
};

const execEdProps = {
setCardView: jest.fn(),
columns: [],
renderCardComponent: jest.fn(),
contentType: 'executive-education-2u',
intl: {
formatMessage: (header) => header.defaultMessage,
formatDate: () => {},
formatTime: () => {},
formatRelative: () => {},
formatNumber: () => {},
formatPlural: () => {},
formatHTMLMessasge: () => {},
now: () => {},
},
};

describe('catalog no results deck works as expected', () => {
test('it displays no results alert text', () => {
mockCatalogApiService.mockResolvedValue(csvData);
Expand Down Expand Up @@ -107,4 +124,13 @@ describe('catalog no results deck works as expected', () => {
).not.toBeInTheDocument();
expect(logError).toBeCalled();
});
test('shows executive education alert text', async () => {
render(
<IntlProvider locale="en">
<CatalogNoResultsDeck {...execEdProps} />
</IntlProvider>,
);
expect(screen.getByText('No Executive Education courses were found that match your search. Try')).toBeInTheDocument();
expect(screen.getByText('Popular Executive Education Courses')).toBeInTheDocument();
});
});
51 changes: 44 additions & 7 deletions src/components/catalogPage/CatalogPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,27 @@ import Subheader from '../subheader/subheader';
import Hero from '../hero/Hero';
import messages from './CatalogPage.messages';
import CatalogSelectionDeck from '../catalogSelectionDeck/CatalogSelectionDeck';
import features from '../../config';
import {
AVAILABILITY_REFINEMENT,
AVAILABILITY_REFINEMENT_DEFAULTS,
CONTENT_TYPE_REFINEMENT,
EXECUTIVE_EDUCATION_2U_COURSE_TYPE,
QUERY_TITLE_REFINEMENT,
HIDE_CARDS_REFINEMENT,
TRACKING_APP_NAME,
} from '../../constants';

const contentType = {
attribute: 'content_type',
title: 'Type',
const LEARNING_TYPE_REFINEMENT = 'learning_type';
const learningType = {
attribute: 'learning_type',
title: 'Learning Type',
};
SEARCH_FACET_FILTERS.push(contentType);
// Add learning_type to the search facet filters if it doesn't exist in the list yet.
if (
!SEARCH_FACET_FILTERS.some((filter) => filter.attribute === 'learning_type')
) {
SEARCH_FACET_FILTERS.push(learningType);
}

function CatalogPage({ intl }) {
const config = getConfig();
Expand All @@ -48,9 +55,37 @@ function CatalogPage({ intl }) {
reloadPage = true;
}

// Remove the `learning_type = executive education` filter if the feature flag is disabled or if the selected
// catalog isn't `a la carte`
if (
(!features.EXEC_ED_INCLUSION
|| (config.EDX_ENTERPRISE_ALACARTE_TITLE
&& loadedSearchParams.get(LEARNING_TYPE_REFINEMENT)
&& !(
loadedSearchParams.get(QUERY_TITLE_REFINEMENT)
=== config.EDX_ENTERPRISE_ALACARTE_TITLE
)))
&& loadedSearchParams.get(LEARNING_TYPE_REFINEMENT)
=== EXECUTIVE_EDUCATION_2U_COURSE_TYPE
) {
const loadedLearningTypes = loadedSearchParams.getAll(LEARNING_TYPE_REFINEMENT);
if (loadedLearningTypes.length) {
loadedSearchParams.delete(LEARNING_TYPE_REFINEMENT);
loadedLearningTypes.forEach((type) => {
if (type !== EXECUTIVE_EDUCATION_2U_COURSE_TYPE) {
loadedSearchParams.append(LEARNING_TYPE_REFINEMENT, type);
}
});
}

reloadPage = true;
}

// If we don't have specified learning_type(s) and we don't have specified catalog(s) then automatically add
// the `a la carte` catalog
if (
config.EDX_ENTERPRISE_ALACARTE_TITLE
&& !loadedSearchParams.get(CONTENT_TYPE_REFINEMENT)
&& !loadedSearchParams.get(LEARNING_TYPE_REFINEMENT)
&& !loadedSearchParams.get(QUERY_TITLE_REFINEMENT)
) {
loadedSearchParams.set(
Expand All @@ -59,9 +94,11 @@ function CatalogPage({ intl }) {
);
reloadPage = true;
}

// Ensure we have availability refinement(s) set by default
if (
!loadedSearchParams.get(AVAILABILITY_REFINEMENT)
&& !loadedSearchParams.get(CONTENT_TYPE_REFINEMENT)
&& !loadedSearchParams.get(LEARNING_TYPE_REFINEMENT)
) {
AVAILABILITY_REFINEMENT_DEFAULTS.map((a) => loadedSearchParams.append(AVAILABILITY_REFINEMENT, a));
reloadPage = true;
Expand Down
42 changes: 42 additions & 0 deletions src/components/catalogPage/CatalogPage.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ jest.mock('@edx/frontend-platform', () => ({
mockWindowLocations();

describe('CatalogPage', () => {
const OLD_ENV = process.env;
beforeEach(() => {
jest.resetModules(); // Most important - it clears the cache
process.env = { ...OLD_ENV }; // Make a copy
});
afterAll(() => {
process.env = OLD_ENV; // Restore old environment
});
it('renders a catalog page component', () => {
const { container } = renderWithRouter(<CatalogPage />);
expect(container.querySelector('.hero')).toBeInTheDocument();
Expand Down Expand Up @@ -61,4 +69,38 @@ describe('CatalogPage', () => {
'enterprise_catalog_query_titles=baz&availability=Available+Now&availability=Starting+Soon&availability=Upcoming',
);
});
it('accounts for exec ed inclusion feature flag', () => {
process.env.EXEC_ED_INCLUSION = false;
const location = {
...window.location,
search: '?learning_type=executive-education-2u',
};
Object.defineProperty(window, 'location', {
writable: true,
value: location,
});
expect(window.location.search).toEqual('?learning_type=executive-education-2u');
renderWithRouter(<CatalogPage />);
// Assert we've removed the exec ed learning type because the feature flag was disabled
expect(window.location.search).toEqual(
'enterprise_catalog_query_titles=baz&availability=Available+Now&availability=Starting+Soon&availability=Upcoming',
);
});
it('accounts for exec ed disclusion when not a la carte is selected', () => {
process.env.EXEC_ED_INCLUSION = true;
const location = {
...window.location,
search: '?learning_type=executive-education-2u&learning_type=ayylmao&enterprise_catalog_query_titles=foobar',
};
Object.defineProperty(window, 'location', {
writable: true,
value: location,
});
expect(window.location.search).toEqual('?learning_type=executive-education-2u&learning_type=ayylmao&enterprise_catalog_query_titles=foobar');
renderWithRouter(<CatalogPage />);
// Assert learning type: exec ed has been removed but not learning type `ayylmao`
expect(window.location.search).toEqual(
'enterprise_catalog_query_titles=foobar&learning_type=ayylmao',
);
});
});
Loading

0 comments on commit 96cef62

Please sign in to comment.