diff --git a/.env.test b/.env.test index 705a9889b..1a3381eff 100644 --- a/.env.test +++ b/.env.test @@ -20,7 +20,6 @@ LMS_CLIENT_ID='login-service-client-id' SEGMENT_KEY='' FEATURE_FLAGS={} MARKETING_SITE_BASE_URL='http://localhost:18000' -SUPPORT_URL='http://localhost:18000/support' CONTACT_URL='http://localhost:18000/contact' OPEN_SOURCE_URL='http://localhost:18000/openedx' TERMS_OF_SERVICE_URL='http://localhost:18000/terms-of-service' diff --git a/src/containers/LearnerDashboardHeader/LearnerDashboardMenu.jsx b/src/containers/LearnerDashboardHeader/LearnerDashboardMenu.jsx index 9dcecc3a1..a6be308c9 100644 --- a/src/containers/LearnerDashboardHeader/LearnerDashboardMenu.jsx +++ b/src/containers/LearnerDashboardHeader/LearnerDashboardMenu.jsx @@ -9,6 +9,7 @@ const getLearnerHeaderMenu = ( courseSearchUrl, authenticatedUser, exploreCoursesClick, + programsEnabled = false, ) => ({ mainMenu: [ { @@ -17,11 +18,11 @@ const getLearnerHeaderMenu = ( content: formatMessage(messages.course), isActive: true, }, - { + ...(programsEnabled ? [{ type: 'item', href: `${urls.programsUrl()}`, content: formatMessage(messages.program), - }, + }] : []), { type: 'item', href: `${urls.baseAppUrl(courseSearchUrl)}`, @@ -32,11 +33,11 @@ const getLearnerHeaderMenu = ( }, ], secondaryMenu: [ - { + ...(getConfig().SUPPORT_URL ? [{ type: 'item', - href: `${getConfig().SUPPORT_URL}`, + href: getConfig().SUPPORT_URL, content: formatMessage(messages.help), - }, + }] : []), ], userMenu: [ { @@ -70,6 +71,7 @@ const getLearnerHeaderMenu = ( ], }, ], -}); +} +); export default getLearnerHeaderMenu; diff --git a/src/containers/LearnerDashboardHeader/__snapshots__/index.test.jsx.snap b/src/containers/LearnerDashboardHeader/__snapshots__/index.test.jsx.snap index a1f0a9e71..80d090019 100644 --- a/src/containers/LearnerDashboardHeader/__snapshots__/index.test.jsx.snap +++ b/src/containers/LearnerDashboardHeader/__snapshots__/index.test.jsx.snap @@ -25,15 +25,7 @@ exports[`LearnerDashboardHeader render 1`] = ` }, ] } - secondaryMenuItems={ - [ - { - "content": "Help", - "href": "http://localhost:18000/support", - "type": "item", - }, - ] - } + secondaryMenuItems={[]} userMenuItems={ [ { diff --git a/src/containers/LearnerDashboardHeader/hooks.js b/src/containers/LearnerDashboardHeader/hooks.js index 115322c1d..e3eecf8aa 100644 --- a/src/containers/LearnerDashboardHeader/hooks.js +++ b/src/containers/LearnerDashboardHeader/hooks.js @@ -5,6 +5,7 @@ import track from 'tracking'; import { StrictDict } from 'utils'; import { linkNames } from 'tracking/constants'; +import { apiHooks } from 'hooks'; import getLearnerHeaderMenu from './LearnerDashboardMenu'; import * as module from './hooks'; @@ -30,8 +31,9 @@ export const findCoursesNavDropdownClicked = (href) => track.findCourses.findCou export const useLearnerDashboardHeaderMenu = ({ courseSearchUrl, authenticatedUser, exploreCoursesClick, }) => { + const { enabled: programsEnabled } = apiHooks.useProgramsConfig(); const { formatMessage } = useIntl(); - return getLearnerHeaderMenu(formatMessage, courseSearchUrl, authenticatedUser, exploreCoursesClick); + return getLearnerHeaderMenu(formatMessage, courseSearchUrl, authenticatedUser, exploreCoursesClick, programsEnabled); }; export const useLearnerDashboardHeaderData = () => { diff --git a/src/containers/LearnerDashboardHeader/hooks.test.js b/src/containers/LearnerDashboardHeader/hooks.test.js index c9bac080a..0e7eb24b0 100644 --- a/src/containers/LearnerDashboardHeader/hooks.test.js +++ b/src/containers/LearnerDashboardHeader/hooks.test.js @@ -4,6 +4,8 @@ import { linkNames } from 'tracking/constants'; import { MockUseState } from 'testUtils'; +import { apiHooks } from 'hooks'; +import { mergeConfig } from '@edx/frontend-platform'; import * as hooks from './hooks'; const state = new MockUseState(hooks); @@ -22,6 +24,12 @@ jest.mock('tracking', () => ({ }, })); +jest.mock('hooks', () => ({ + apiHooks: { + useProgramsConfig: jest.fn(() => ({})), + }, +})); + const url = 'http://example.com'; describe('LearnerDashboardHeader hooks', () => { @@ -50,13 +58,21 @@ describe('LearnerDashboardHeader hooks', () => { }); describe('getLearnerDashboardHeaderMenu', () => { + const courseSearchUrl = '/courses'; + const authenticatedUser = { + username: 'test', + }; test('calls header menu data hook', () => { - const courseSearchUrl = '/courses'; - const authenticatedUser = { - username: 'test', - }; + const learnerHomeHeaderMenu = useLearnerDashboardHeaderMenu({ courseSearchUrl, authenticatedUser }); + expect(learnerHomeHeaderMenu.mainMenu.length).toBe(2); + expect(learnerHomeHeaderMenu.secondaryMenu.length).toBe(0); + }); + test('should add programs and/or support link to menu if the service are configured', () => { + mergeConfig({ SUPPORT_URL: 'http://localhost:18000/support' }); + apiHooks.useProgramsConfig.mockReturnValue({ enabled: true }); const learnerHomeHeaderMenu = useLearnerDashboardHeaderMenu({ courseSearchUrl, authenticatedUser }); expect(learnerHomeHeaderMenu.mainMenu.length).toBe(3); + expect(learnerHomeHeaderMenu.secondaryMenu.length).toBe(1); }); }); diff --git a/src/containers/LearnerDashboardHeader/index.test.jsx b/src/containers/LearnerDashboardHeader/index.test.jsx index e07fbda42..9064dce77 100644 --- a/src/containers/LearnerDashboardHeader/index.test.jsx +++ b/src/containers/LearnerDashboardHeader/index.test.jsx @@ -12,6 +12,9 @@ jest.mock('hooks', () => ({ courseSearchUrl: '/course-search-url', })), }, + apiHooks: { + useProgramsConfig: jest.fn(() => ({ enabled: true })), + }, })); jest.mock('./hooks', () => ({ ...jest.requireActual('./hooks'), diff --git a/src/data/services/lms/api.js b/src/data/services/lms/api.js index 6f9acd560..915b52a9b 100644 --- a/src/data/services/lms/api.js +++ b/src/data/services/lms/api.js @@ -20,6 +20,8 @@ export const initializeList = ({ user } = {}) => get( stringifyUrl(urls.getInitApiUrl(), { [apiKeys.user]: user }), ); +export const getProgramsConfig = () => get(urls.programsConfigUrl()); + export const updateEntitlementEnrollment = ({ uuid, courseId }) => post( urls.entitlementEnrollment(uuid), { [apiKeys.courseRunId]: courseId }, @@ -73,6 +75,7 @@ export const createCreditRequest = ({ providerId, courseId, username }) => post( export default { initializeList, + getProgramsConfig, unenrollFromCourse, updateEmailSettings, updateEntitlementEnrollment, diff --git a/src/data/services/lms/urls.js b/src/data/services/lms/urls.js index 30c2bbf1b..789d614c3 100644 --- a/src/data/services/lms/urls.js +++ b/src/data/services/lms/urls.js @@ -22,6 +22,7 @@ export const baseAppUrl = (url) => updateUrl(getBaseUrl(), url); export const learningMfeUrl = (url) => updateUrl(getConfig().LEARNING_BASE_URL, url); // static view url +const programsConfigUrl = () => baseAppUrl('/config/programs'); const programsUrl = () => baseAppUrl('/dashboard/programs'); export const creditPurchaseUrl = (courseId) => `${getEcommerceUrl()}/credit/checkout/${courseId}/`; @@ -37,6 +38,7 @@ export default StrictDict({ event, getInitApiUrl, learningMfeUrl, + programsConfigUrl, programsUrl, updateEmailSettings, }); diff --git a/src/hooks/api.js b/src/hooks/api.js index d64a11850..70a448090 100644 --- a/src/hooks/api.js +++ b/src/hooks/api.js @@ -31,6 +31,25 @@ export const useInitializeApp = () => { }); }; +export const useProgramsConfig = () => { + const [config, setConfig] = React.useState({}); + + React.useEffect(() => { + const fetchProgramsConfig = async () => { + try { + const { data } = await api.getProgramsConfig(); + setConfig(data); + } catch (error) { + console.error('Error accessing programs configuration', error); + } + }; + + fetchProgramsConfig(); + }, []); + + return config; +}; + export const useNewEntitlementEnrollment = (cardId) => { const { uuid } = reduxHooks.useCardEntitlementData(cardId); const onSuccess = module.useInitializeApp();