Skip to content

Commit

Permalink
feat: migrates license activation and auto-apply to route loaders, pl…
Browse files Browse the repository at this point in the history
…us general cleanup (#990)
  • Loading branch information
adamstankiewicz authored Mar 7, 2024
1 parent dd6e06e commit 68eb524
Show file tree
Hide file tree
Showing 93 changed files with 2,698 additions and 2,185 deletions.
3 changes: 1 addition & 2 deletions src/components/app/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import {
} from '../../utils/common';
// import extractNamedExport from '../../utils/extract-named-export';

import createAppRouter from './data/createAppRouter';
import { RouterFallback } from './routes';
import { RouterFallback, createAppRouter } from './routes';

/* eslint-disable max-len */
// const EnterpriseAppPageRoutes = lazy(() => import(/* webpackChunkName: "enterprise-app-routes" */ './EnterpriseAppPageRoutes'));
Expand Down
2 changes: 0 additions & 2 deletions src/components/app/AuthenticatedUserSubsidyPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ import React from 'react';
import PropTypes from 'prop-types';

import AuthenticatedPage from './AuthenticatedPage';
import { AutoActivateLicense } from '../enterprise-user-subsidy';

const AuthenticatedUserSubsidyPage = ({ children }) => (
<AuthenticatedPage>
<AutoActivateLicense />
{children}
</AuthenticatedPage>
);
Expand Down
5 changes: 1 addition & 4 deletions src/components/app/AuthenticatedUserSubsidyPage.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import '@testing-library/jest-dom/extend-expect';

import AuthenticatedUserSubsidyPage from './AuthenticatedUserSubsidyPage';
import AuthenticatedPage from './AuthenticatedPage';
import { AutoActivateLicense, UserSubsidy } from '../enterprise-user-subsidy';
import { UserSubsidy } from '../enterprise-user-subsidy';

describe('<AuthenticatedUserSubsidyPage />', () => {
let wrapper;
Expand All @@ -21,9 +21,6 @@ describe('<AuthenticatedUserSubsidyPage />', () => {
it('renders <UserSubsidy>', () => {
expect(wrapper.find(UserSubsidy)).toBeTruthy();
});
it('renders <AutoActivateLicense>', () => {
expect(wrapper.find(AutoActivateLicense)).toBeTruthy();
});
it('renders children', () => {
expect(wrapper.find('div.did-i-render')).toBeTruthy();
});
Expand Down
2 changes: 0 additions & 2 deletions src/components/app/EnterpriseAppPageRoutes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const ProgramPage = lazy(() => extractNamedExport(import(/* webpackChunkName: "p
const ProgramProgressRedirect = lazy(() => extractNamedExport(import(/* webpackChunkName: "program-progress-redirect" */ '../program-progress'), 'ProgramProgressRedirect'));
const ProgramProgressPage = lazy(() => extractNamedExport(import(/* webpackChunkName: "program-progress" */ '../program-progress'), 'ProgramProgressPage'));
const SkillsQuizPage = lazy(() => extractNamedExport(import(/* webpackChunkName: "skills-quiz" */ '../skills-quiz'), 'SkillsQuizPage'));
const LicenseActivationPage = lazy(() => extractNamedExport(import(/* webpackChunkName: "license-activation" */ '../license-activation'), 'LicenseActivationPage'));
const PathwayProgressPage = lazy(() => extractNamedExport(import(/* webpackChunkName: "pathway-progress" */ '../pathway-progress'), 'PathwayProgressPage'));
const AcademyDetailPage = lazy(() => extractNamedExport(import(/* webpackChunkName: "academy" */ '../academies'), 'AcademyDetailPage'));

Expand Down Expand Up @@ -46,7 +45,6 @@ const EnterpriseAppPageRoutes = () => (
<Route path="program-progress/:programUUID" element={<PageWrap><ProgramProgressRedirect /></PageWrap>} />
<Route path="program/:programUUID/progress" element={<PageWrap><ProgramProgressPage /></PageWrap>} />
<Route path="skills-quiz" element={<PageWrap><SkillsQuizPage /></PageWrap>} />
<Route path="licenses/:activationKey/activate" element={<PageWrap><LicenseActivationPage /></PageWrap>} />
{features.FEATURE_ENABLE_PATHWAY_PROGRESS && (
<Route exact path="pathway/:pathwayUUID/progress" element={<PageWrap><PathwayProgressPage /></PageWrap>} />
)}
Expand Down
18 changes: 2 additions & 16 deletions src/components/app/Layout.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { AppContext } from '@edx/frontend-platform/react';
import { useContext } from 'react';
import { Helmet } from 'react-helmet';
import { Outlet } from 'react-router-dom';
import SiteFooter from '@edx/frontend-component-footer';
import { getConfig } from '@edx/frontend-platform/config';

import { useEnterpriseLearner, isSystemMaintenanceAlertOpen } from './data';
import { useStylesForCustomBrandColors } from '../layout/data/hooks';
import NotFoundPage from '../NotFoundPage';
import DelayedFallbackContainer from '../DelayedFallback/DelayedFallbackContainer';
import { SiteHeader } from '../site-header';
import { EnterpriseBanner } from '../enterprise-banner';
import { SystemWideWarningBanner } from '../system-wide-banner';
Expand All @@ -16,7 +14,7 @@ export const TITLE_TEMPLATE = '%s - edX';
export const DEFAULT_TITLE = 'edX';

const Layout = () => {
const { authenticatedUser, config } = useContext(AppContext);
const config = getConfig();
const { data: enterpriseLearnerData } = useEnterpriseLearner();

const brandStyles = useStylesForCustomBrandColors(enterpriseLearnerData.enterpriseCustomer);
Expand All @@ -27,18 +25,6 @@ const Layout = () => {
return <NotFoundPage />;
}

// User is authenticated with an active enterprise customer, but
// the user account API data is still hydrating. If it is still
// hydrating, render a loading state.
if (!authenticatedUser.profileImage) {
return (
<DelayedFallbackContainer
className="py-5 text-center"
screenReaderText="Loading your account details. Please wait."
/>
);
}

return (
<>
<Helmet titleTemplate={TITLE_TEMPLATE} defaultTitle={DEFAULT_TITLE}>
Expand Down
147 changes: 147 additions & 0 deletions src/components/app/Layout.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import { screen } from '@testing-library/react';
import { QueryClientProvider } from '@tanstack/react-query';
import { AppContext } from '@edx/frontend-platform/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { mergeConfig } from '@edx/frontend-platform';
import dayjs from 'dayjs';
import '@testing-library/jest-dom/extend-expect';

import Layout from './Layout';
import { queryClient, renderWithRouterProvider } from '../../utils/tests';
import { useEnterpriseLearner } from './data';

const mockDefaultAppContextValue = {
authenticatedUser: {
userId: 3,
},
config: {
LMS_BASE_URL: 'https://test-lms.url',
},
};

const mockEnterpriseCustomer = {
uuid: 'test-enterprise-uuid',
brandingConfiguration: {
logo: 'https://test-logo.url',
primaryColor: '#000000',
secondaryColor: '#FF0000',
tertiaryColor: '#0000FF',
},
};

jest.mock('@edx/frontend-component-footer', () => jest.fn(() => <div data-testid="site-footer" />));
jest.mock('../site-header', () => ({
...jest.requireActual('../site-header'),
SiteHeader: jest.fn(() => <div data-testid="site-header" />),
}));
jest.mock('../enterprise-banner', () => ({
...jest.requireActual('../enterprise-banner'),
EnterpriseBanner: jest.fn(() => <div data-testid="enterprise-banner" />),
}));
jest.mock('../../utils/common', () => ({
...jest.requireActual('../../utils/common'),
getBrandColorsFromCSSVariables: jest.fn().mockReturnValue({
white: '#FFFFFF',
dark: '#000000',
}),
}));

jest.mock('./data', () => ({
...jest.requireActual('./data'),
useEnterpriseLearner: jest.fn().mockReturnValue({
data: {
enterpriseCustomer: null,
},
}),
}));

const LayoutWrapper = ({
appContextValue = mockDefaultAppContextValue,
}) => (
<QueryClientProvider client={queryClient()}>
<IntlProvider locale="en">
<AppContext.Provider value={appContextValue}>
<Layout />
</AppContext.Provider>
</IntlProvider>
</QueryClientProvider>
);

describe('Layout', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('renders the not found page when the user is not linked to an enterprise customer', () => {
renderWithRouterProvider(<LayoutWrapper />);
expect(screen.getByText('404', { selector: 'h1' })).toBeInTheDocument();
});

it.each([
{
isSystemMaintenanceAlertOpen: false,
maintenanceMessage: undefined,
maintenanceStartTimestamp: undefined,
},
{
isSystemMaintenanceAlertOpen: true,
maintenanceMessage: 'Hello World!',
maintenanceStartTimestamp: undefined,
},
{
isSystemMaintenanceAlertOpen: true,
maintenanceMessage: 'Hello World!',
maintenanceStartTimestamp: dayjs().subtract(1, 'm').toISOString(),
},
{
isSystemMaintenanceAlertOpen: false,
maintenanceMessage: 'Hello World!',
maintenanceStartTimestamp: dayjs().add(1, 'm').toISOString(),
},
])('renders with enterprise customer (%s)', ({
isSystemMaintenanceAlertOpen,
maintenanceMessage,
maintenanceStartTimestamp,
}) => {
useEnterpriseLearner.mockReturnValue({
data: {
enterpriseCustomer: mockEnterpriseCustomer,
},
});

if (maintenanceMessage) {
mergeConfig({
IS_MAINTENANCE_ALERT_ENABLED: isSystemMaintenanceAlertOpen,
MAINTENANCE_ALERT_MESSAGE: maintenanceMessage,
});
}
if (maintenanceStartTimestamp) {
mergeConfig({
MAINTENANCE_ALERT_START_TIMESTAMP: maintenanceStartTimestamp ?? '',
});
}

renderWithRouterProvider({
path: '/:enterpriseSlug',
element: <LayoutWrapper />,
children: [
{
path: '',
element: <div data-testid="child-route" />,
},
],
}, {
initialEntries: ['/test-enterprise'],
});
expect(screen.getByTestId('site-header')).toBeInTheDocument();
expect(screen.getByTestId('enterprise-banner')).toBeInTheDocument();
expect(screen.getByTestId('child-route')).toBeInTheDocument();
expect(screen.getByTestId('site-footer')).toBeInTheDocument();

if (isSystemMaintenanceAlertOpen) {
expect(screen.getByText(maintenanceMessage)).toBeInTheDocument();
} else if (maintenanceMessage) {
expect(screen.queryByText(maintenanceMessage)).not.toBeInTheDocument();
}
});
});
80 changes: 0 additions & 80 deletions src/components/app/data/createAppRouter.jsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useQuery } from '@tanstack/react-query';

import useEnterpriseLearner from './useEnterpriseLearner';
import { queryBrowseAndRequestConfiguration } from '../../routes/data';
import { queryBrowseAndRequestConfiguration } from '../queries';

/**
* Retrieves the course metadata for the given enterprise customer and course key.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useQuery } from '@tanstack/react-query';

import useEnterpriseLearner from './useEnterpriseLearner';
import { queryContentHighlightsConfiguration } from '../../routes/data/queries';
import { queryContentHighlightsConfiguration } from '../queries';

/**
* Retrieves the content highlights configuration for the active enterprise customer user.
Expand Down
2 changes: 1 addition & 1 deletion src/components/app/data/hooks/useCourseMetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useQuery } from '@tanstack/react-query';
import { useParams } from 'react-router-dom';

import useEnterpriseLearner from './useEnterpriseLearner';
import { queryCourseMetadata } from '../../routes/data/queries';
import { queryCourseMetadata } from '../queries';

/**
* Retrieves the course metadata for the given enterprise customer and course key.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useQuery } from '@tanstack/react-query';

import useCourseMetadata from './useCourseMetadata';
import useEnterpriseLearner from './useEnterpriseLearner';
import { queryCanRedeem } from '../../routes/data/queries';
import { queryCanRedeem } from '../queries';

/**
* Retrieves the course redemption eligibility for the given enterprise customer and course key.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useQuery } from '@tanstack/react-query';

import useEnterpriseLearner from './useEnterpriseLearner';
import { queryEnterpriseCourseEnrollments } from '../../routes/data/queries';
import { queryEnterpriseCourseEnrollments } from '../queries';

/**
* Retrieves the enterprise course enrollments for the active enterprise customer user.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
queryBrowseAndRequestConfiguration,
queryLicenseRequests,
queryCouponCodeRequests,
} from '../../routes/data/queries';
} from '../queries';
/**
* Retrieves the subsidies present for the active enterprise customer user.
* @returns {Types.UseQueryResult}} The query results for the enterprise customer user subsidies.
Expand Down
2 changes: 1 addition & 1 deletion src/components/app/data/hooks/useEnterpriseLearner.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { AppContext } from '@edx/frontend-platform/react';
import { useQuery } from '@tanstack/react-query';
import { useContext } from 'react';
import { useParams } from 'react-router-dom';
import { queryEnterpriseLearner } from '../../routes/data/queries';
import { queryEnterpriseLearner } from '../queries';

/**
* Retrieves the enterprise learner data for the authenticated user.
Expand Down
Loading

0 comments on commit 68eb524

Please sign in to comment.