fix: course list styling for hidden panel and new endpoint integration (#165)
Co-authored-by: Ben Warzeski <bwarzesk@gmail.com>
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
import { get, stringifyUrl } from 'data/services/lms/utils';
|
||||
import urls from 'data/services/lms/urls';
|
||||
|
||||
export const productRecommendationsUrl = (courseId) => `${urls.api}/learner_recommendations/product_recommendations/${courseId}/`;
|
||||
export const crossProductAndAmplitudeRecommendationsUrl = (courseId) => `${urls.getApiUrl()}/learner_recommendations/product_recommendations/${courseId}/`;
|
||||
export const amplitudeRecommendationsUrl = () => `${urls.getApiUrl()}/learner_recommendations/product_recommendations/`;
|
||||
|
||||
const fetchProductRecommendations = (courseId) => get(stringifyUrl(productRecommendationsUrl(courseId)));
|
||||
const fetchCrossProductRecommendations = (courseId) => (
|
||||
get(stringifyUrl(crossProductAndAmplitudeRecommendationsUrl(courseId)))
|
||||
);
|
||||
const fetchAmplitudeRecommendations = () => get(stringifyUrl(amplitudeRecommendationsUrl()));
|
||||
|
||||
export default {
|
||||
fetchProductRecommendations,
|
||||
fetchCrossProductRecommendations,
|
||||
fetchAmplitudeRecommendations,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { get, stringifyUrl } from 'data/services/lms/utils';
|
||||
import api, { productRecommendationsUrl } from './api';
|
||||
|
||||
import api, { crossProductAndAmplitudeRecommendationsUrl, amplitudeRecommendationsUrl } from './api';
|
||||
|
||||
jest.mock('data/services/lms/utils', () => ({
|
||||
stringifyUrl: (...args) => ({ stringifyUrl: args }),
|
||||
@@ -7,10 +8,18 @@ jest.mock('data/services/lms/utils', () => ({
|
||||
}));
|
||||
|
||||
describe('productRecommendationCourses api', () => {
|
||||
describe('fetchProductRecommendations', () => {
|
||||
describe('fetchCrossProductRecommendations', () => {
|
||||
it('calls get with the correct recommendation courses URL', () => {
|
||||
expect(api.fetchProductRecommendations('CourseRunKey')).toEqual(
|
||||
get(stringifyUrl(productRecommendationsUrl('CourseRunKey'))),
|
||||
expect(api.fetchCrossProductRecommendations('CourseRunKey')).toEqual(
|
||||
get(stringifyUrl(crossProductAndAmplitudeRecommendationsUrl('CourseRunKey'))),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchAmplitudeRecommendations', () => {
|
||||
it('calls get with the correct recommendation courses URL', () => {
|
||||
expect(api.fetchAmplitudeRecommendations()).toEqual(
|
||||
get(stringifyUrl(amplitudeRecommendationsUrl())),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,42 +13,56 @@ export const state = StrictDict({
|
||||
});
|
||||
|
||||
export const useShowRecommendationsFooter = () => {
|
||||
const hasCourses = reduxHooks.useHasCourses();
|
||||
const hasAvailableDashboards = reduxHooks.useHasAvailableDashboards();
|
||||
const initIsPending = reduxHooks.useRequestIsPending(RequestKeys.initialize);
|
||||
const hasRequestCompleted = reduxHooks.useRequestIsCompleted(RequestKeys.initialize);
|
||||
|
||||
// Hardcoded to not show until experiment related code is implemented
|
||||
return !initIsPending && hasCourses && !hasAvailableDashboards && false;
|
||||
return {
|
||||
shouldShowFooter: false,
|
||||
shouldLoadFooter: hasRequestCompleted && !hasAvailableDashboards,
|
||||
};
|
||||
};
|
||||
|
||||
export const useMostRecentCourseRunKey = () => {
|
||||
const mostRecentCourse = reduxHooks.useCurrentCourseList({
|
||||
const mostRecentCourseRunKey = reduxHooks.useCurrentCourseList({
|
||||
sortBy: SortKeys.enrolled,
|
||||
filters: [],
|
||||
pageSize: 0,
|
||||
}).visible[0].courseRun.courseId;
|
||||
}).visible[0]?.courseRun?.courseId;
|
||||
|
||||
return mostRecentCourse;
|
||||
return mostRecentCourseRunKey;
|
||||
};
|
||||
|
||||
export const useFetchProductRecommendations = (setRequestState, setData) => {
|
||||
export const useFetchRecommendations = (setRequestState, setData) => {
|
||||
const courseRunKey = module.useMostRecentCourseRunKey();
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
api
|
||||
.fetchProductRecommendations(courseRunKey)
|
||||
.then((response) => {
|
||||
if (isMounted) {
|
||||
setData(response.data);
|
||||
setRequestState(RequestStates.completed);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
if (isMounted) {
|
||||
setRequestState(RequestStates.failed);
|
||||
}
|
||||
});
|
||||
|
||||
const handleSuccess = (response) => {
|
||||
if (isMounted) {
|
||||
setData(response.data);
|
||||
setRequestState(RequestStates.completed);
|
||||
}
|
||||
};
|
||||
|
||||
const handleError = () => {
|
||||
if (isMounted) {
|
||||
setRequestState(RequestStates.failed);
|
||||
}
|
||||
};
|
||||
|
||||
if (courseRunKey) {
|
||||
api
|
||||
.fetchCrossProductRecommendations(courseRunKey)
|
||||
.then(handleSuccess)
|
||||
.catch(handleError);
|
||||
} else {
|
||||
api
|
||||
.fetchAmplitudeRecommendations()
|
||||
.then(handleSuccess)
|
||||
.catch(handleError);
|
||||
}
|
||||
return () => {
|
||||
isMounted = false;
|
||||
};
|
||||
@@ -59,7 +73,7 @@ export const useFetchProductRecommendations = (setRequestState, setData) => {
|
||||
export const useProductRecommendationsData = () => {
|
||||
const [requestState, setRequestState] = module.state.requestState(RequestStates.pending);
|
||||
const [data, setData] = module.state.data({});
|
||||
module.useFetchProductRecommendations(setRequestState, setData);
|
||||
module.useFetchRecommendations(setRequestState, setData);
|
||||
|
||||
return {
|
||||
productRecommendations: data,
|
||||
|
||||
@@ -10,15 +10,15 @@ import api from './api';
|
||||
import * as hooks from './hooks';
|
||||
|
||||
jest.mock('./api', () => ({
|
||||
fetchProductRecommendations: jest.fn(),
|
||||
fetchCrossProductRecommendations: jest.fn(),
|
||||
fetchAmplitudeRecommendations: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('hooks', () => ({
|
||||
reduxHooks: {
|
||||
useCurrentCourseList: jest.fn(),
|
||||
useHasCourses: jest.fn(),
|
||||
useHasAvailableDashboards: jest.fn(),
|
||||
useRequestIsPending: jest.fn(),
|
||||
useRequestIsCompleted: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -38,11 +38,16 @@ const courses = [
|
||||
},
|
||||
];
|
||||
|
||||
const courseListData = {
|
||||
const populatedCourseListData = {
|
||||
visible: courses,
|
||||
numPages: 0,
|
||||
};
|
||||
|
||||
const emptyCourseListData = {
|
||||
visible: [],
|
||||
numPages: 0,
|
||||
};
|
||||
|
||||
let output;
|
||||
describe('ProductRecommendations hooks', () => {
|
||||
beforeEach(() => {
|
||||
@@ -56,7 +61,7 @@ describe('ProductRecommendations hooks', () => {
|
||||
|
||||
describe('useMostRecentCourseRunKey', () => {
|
||||
it('returns the courseId of the first course in the sorted visible array', () => {
|
||||
reduxHooks.useCurrentCourseList.mockReturnValueOnce(courseListData);
|
||||
reduxHooks.useCurrentCourseList.mockReturnValueOnce(populatedCourseListData);
|
||||
|
||||
expect(hooks.useMostRecentCourseRunKey()).toBe(mostRecentCourseRunKey);
|
||||
});
|
||||
@@ -64,16 +69,17 @@ describe('ProductRecommendations hooks', () => {
|
||||
|
||||
describe('useShowRecommendationsFooter', () => {
|
||||
// TODO: Update when hardcoded value is removed
|
||||
it('returns whether the footer widget should show', () => {
|
||||
reduxHooks.useHasCourses.mockReturnValueOnce(true);
|
||||
it('returns whether the footer widget should show and should load', () => {
|
||||
reduxHooks.useHasAvailableDashboards.mockReturnValueOnce(false);
|
||||
reduxHooks.useRequestIsPending.mockReturnValueOnce(false);
|
||||
reduxHooks.useRequestIsCompleted.mockReturnValueOnce(true);
|
||||
const { shouldShowFooter, shouldLoadFooter } = hooks.useShowRecommendationsFooter();
|
||||
|
||||
expect(hooks.useShowRecommendationsFooter()).toBeFalsy();
|
||||
expect(shouldShowFooter).toBeFalsy();
|
||||
expect(shouldLoadFooter).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('useFetchProductRecommendations', () => {
|
||||
describe('useFetchRecommendations', () => {
|
||||
describe('behavior', () => {
|
||||
describe('useEffect call', () => {
|
||||
let calls;
|
||||
@@ -81,86 +87,176 @@ describe('ProductRecommendations hooks', () => {
|
||||
const response = { data: 'response data' };
|
||||
const setRequestState = jest.fn();
|
||||
const setData = jest.fn();
|
||||
beforeEach(() => {
|
||||
reduxHooks.useCurrentCourseList.mockReturnValue(courseListData);
|
||||
hooks.useFetchProductRecommendations(setRequestState, setData);
|
||||
|
||||
const setUp = (mockCourseListData) => {
|
||||
reduxHooks.useCurrentCourseList.mockReturnValue(mockCourseListData);
|
||||
hooks.useFetchRecommendations(setRequestState, setData);
|
||||
({ calls } = React.useEffect.mock);
|
||||
([[cb]] = calls);
|
||||
});
|
||||
};
|
||||
|
||||
it('calls useEffect once', () => {
|
||||
setUp(populatedCourseListData);
|
||||
expect(calls.length).toEqual(1);
|
||||
});
|
||||
it('calls fetchProductRecommendations with the most recently enrolled courseId', () => {
|
||||
api.fetchProductRecommendations.mockReturnValueOnce(Promise.resolve(response));
|
||||
cb();
|
||||
expect(api.fetchProductRecommendations).toHaveBeenCalledWith(mostRecentCourseRunKey);
|
||||
});
|
||||
describe('successful fetch on mounted component', () => {
|
||||
it('sets the request state to completed and loads response', async () => {
|
||||
let resolveFn;
|
||||
api.fetchProductRecommendations.mockReturnValueOnce(new Promise(resolve => {
|
||||
resolveFn = resolve;
|
||||
}));
|
||||
describe('without no courseId due to no enrolled courses', () => {
|
||||
it('calls fetchAmplitudeRecommendations', () => {
|
||||
setUp(emptyCourseListData);
|
||||
api.fetchAmplitudeRecommendations.mockReturnValueOnce(Promise.resolve(response));
|
||||
cb();
|
||||
expect(api.fetchProductRecommendations).toHaveBeenCalledWith(mostRecentCourseRunKey);
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
resolveFn(response);
|
||||
await waitFor(() => {
|
||||
expect(setRequestState).toHaveBeenCalledWith(RequestStates.completed);
|
||||
expect(setData).toHaveBeenCalledWith(response.data);
|
||||
expect(api.fetchAmplitudeRecommendations).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
describe('with most recently enrolled courseId', () => {
|
||||
it('calls fetchCrossProductRecommendations with the most recently enrolled courseId', () => {
|
||||
setUp(populatedCourseListData);
|
||||
api.fetchCrossProductRecommendations.mockReturnValueOnce(Promise.resolve(response));
|
||||
cb();
|
||||
expect(api.fetchCrossProductRecommendations).toHaveBeenCalledWith(mostRecentCourseRunKey);
|
||||
});
|
||||
});
|
||||
describe('fetching cross product recommendations', () => {
|
||||
beforeEach(() => setUp(populatedCourseListData));
|
||||
|
||||
describe('successful fetch on mounted component', () => {
|
||||
it('sets the request state to completed and loads response', async () => {
|
||||
let resolveFn;
|
||||
api.fetchCrossProductRecommendations.mockReturnValueOnce(new Promise(resolve => {
|
||||
resolveFn = resolve;
|
||||
}));
|
||||
cb();
|
||||
expect(api.fetchCrossProductRecommendations).toHaveBeenCalledWith(mostRecentCourseRunKey);
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
resolveFn(response);
|
||||
await waitFor(() => {
|
||||
expect(setRequestState).toHaveBeenCalledWith(RequestStates.completed);
|
||||
expect(setData).toHaveBeenCalledWith(response.data);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('successful fetch on unmounted component', () => {
|
||||
it('does not set the state', async () => {
|
||||
let resolveFn;
|
||||
api.fetchProductRecommendations.mockReturnValueOnce(new Promise(resolve => {
|
||||
resolveFn = resolve;
|
||||
}));
|
||||
const unMount = cb();
|
||||
expect(api.fetchProductRecommendations).toHaveBeenCalledWith(mostRecentCourseRunKey);
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
unMount();
|
||||
resolveFn(response);
|
||||
await wait(10);
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
describe('successful fetch on unmounted component', () => {
|
||||
it('does not set the state', async () => {
|
||||
let resolveFn;
|
||||
api.fetchCrossProductRecommendations.mockReturnValueOnce(new Promise(resolve => {
|
||||
resolveFn = resolve;
|
||||
}));
|
||||
const unMount = cb();
|
||||
expect(api.fetchCrossProductRecommendations).toHaveBeenCalledWith(mostRecentCourseRunKey);
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
unMount();
|
||||
resolveFn(response);
|
||||
await wait(10);
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('unsuccessful fetch on mounted component', () => {
|
||||
it('sets the request state to failed and does not set the data state', async () => {
|
||||
let rejectFn;
|
||||
api.fetchProductRecommendations.mockReturnValueOnce(new Promise((resolve, reject) => {
|
||||
rejectFn = reject;
|
||||
}));
|
||||
cb();
|
||||
expect(api.fetchProductRecommendations).toHaveBeenCalledWith(mostRecentCourseRunKey);
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
rejectFn();
|
||||
await waitFor(() => {
|
||||
expect(setRequestState).toHaveBeenCalledWith(RequestStates.failed);
|
||||
describe('unsuccessful fetch on mounted component', () => {
|
||||
it('sets the request state to failed and does not set the data state', async () => {
|
||||
let rejectFn;
|
||||
api.fetchCrossProductRecommendations.mockReturnValueOnce(new Promise((resolve, reject) => {
|
||||
rejectFn = reject;
|
||||
}));
|
||||
cb();
|
||||
expect(api.fetchCrossProductRecommendations).toHaveBeenCalledWith(mostRecentCourseRunKey);
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
rejectFn();
|
||||
await waitFor(() => {
|
||||
expect(setRequestState).toHaveBeenCalledWith(RequestStates.failed);
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('unsuccessful fetch on unmounted component', () => {
|
||||
it('does not set the state', async () => {
|
||||
let rejectFn;
|
||||
api.fetchCrossProductRecommendations.mockReturnValueOnce(new Promise((resolve, reject) => {
|
||||
rejectFn = reject;
|
||||
}));
|
||||
const unMount = cb();
|
||||
expect(api.fetchCrossProductRecommendations).toHaveBeenCalledWith(mostRecentCourseRunKey);
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
unMount();
|
||||
rejectFn();
|
||||
await wait(10);
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('unsuccessful fetch on unmounted component', () => {
|
||||
it('does not set the state', async () => {
|
||||
let rejectFn;
|
||||
api.fetchProductRecommendations.mockReturnValueOnce(new Promise((resolve, reject) => {
|
||||
rejectFn = reject;
|
||||
}));
|
||||
const unMount = cb();
|
||||
expect(api.fetchProductRecommendations).toHaveBeenCalledWith(mostRecentCourseRunKey);
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
unMount();
|
||||
rejectFn();
|
||||
await wait(10);
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
describe('fetching Amplitude recommendations', () => {
|
||||
beforeEach(() => setUp(emptyCourseListData));
|
||||
|
||||
describe('successful fetch on mounted component', () => {
|
||||
it('sets the request state to completed and loads response', async () => {
|
||||
let resolveFn;
|
||||
api.fetchAmplitudeRecommendations.mockReturnValueOnce(new Promise(resolve => {
|
||||
resolveFn = resolve;
|
||||
}));
|
||||
cb();
|
||||
expect(api.fetchAmplitudeRecommendations).toHaveBeenCalled();
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
resolveFn(response);
|
||||
await waitFor(() => {
|
||||
expect(setRequestState).toHaveBeenCalledWith(RequestStates.completed);
|
||||
expect(setData).toHaveBeenCalledWith(response.data);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('successful fetch on unmounted component', () => {
|
||||
it('does not set the state', async () => {
|
||||
let resolveFn;
|
||||
api.fetchAmplitudeRecommendations.mockReturnValueOnce(new Promise(resolve => {
|
||||
resolveFn = resolve;
|
||||
}));
|
||||
const unMount = cb();
|
||||
expect(api.fetchAmplitudeRecommendations).toHaveBeenCalled();
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
unMount();
|
||||
resolveFn(response);
|
||||
await wait(10);
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
describe('unsuccessful fetch on mounted component', () => {
|
||||
it('sets the request state to failed and does not set the data state', async () => {
|
||||
let rejectFn;
|
||||
api.fetchAmplitudeRecommendations.mockReturnValueOnce(new Promise((resolve, reject) => {
|
||||
rejectFn = reject;
|
||||
}));
|
||||
cb();
|
||||
expect(api.fetchAmplitudeRecommendations).toHaveBeenCalled();
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
rejectFn();
|
||||
await waitFor(() => {
|
||||
expect(setRequestState).toHaveBeenCalledWith(RequestStates.failed);
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('unsuccessful fetch on unmounted component', () => {
|
||||
it('does not set the state', async () => {
|
||||
let rejectFn;
|
||||
api.fetchAmplitudeRecommendations.mockReturnValueOnce(new Promise((resolve, reject) => {
|
||||
rejectFn = reject;
|
||||
}));
|
||||
const unMount = cb();
|
||||
expect(api.fetchAmplitudeRecommendations).toHaveBeenCalled();
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
unMount();
|
||||
rejectFn();
|
||||
await wait(10);
|
||||
expect(setRequestState).not.toHaveBeenCalled();
|
||||
expect(setData).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -170,10 +266,10 @@ describe('ProductRecommendations hooks', () => {
|
||||
let fetchSpy;
|
||||
beforeEach(() => {
|
||||
state.mock();
|
||||
fetchSpy = jest.spyOn(hooks, 'useFetchProductRecommendations').mockImplementationOnce(() => {});
|
||||
fetchSpy = jest.spyOn(hooks, 'useFetchRecommendations').mockImplementationOnce(() => {});
|
||||
output = hooks.useProductRecommendationsData();
|
||||
});
|
||||
it('calls useFetchProductRecommendations with setRequestState and setData', () => {
|
||||
it('calls useFetchRecommendations with setRequestState and setData', () => {
|
||||
expect(fetchSpy).toHaveBeenCalledWith(state.setState.requestState, state.setState.data);
|
||||
});
|
||||
it('initializes requestState as RequestStates.pending', () => {
|
||||
|
||||
@@ -18,7 +18,7 @@ const ProductRecommendations = () => {
|
||||
return (
|
||||
<LoadedView
|
||||
openCourses={productRecommendations.amplitudeCourses}
|
||||
crossProductCourses={productRecommendations.crossProductCourses}
|
||||
crossProductCourses={productRecommendations.crossProductCourses || []}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import hooks from './hooks';
|
||||
import ProductRecommendations from './index';
|
||||
import LoadingView from './components/LoadingView';
|
||||
import LoadedView from './components/LoadedView';
|
||||
import { mockResponse } from './testData';
|
||||
import { mockCrossProductResponse, mockAmplitudeResponse } from './testData';
|
||||
|
||||
jest.mock('./hooks', () => ({
|
||||
useProductRecommendationsData: jest.fn(),
|
||||
@@ -25,7 +25,7 @@ describe('ProductRecommendations', () => {
|
||||
const successfullLoadValues = {
|
||||
...defaultValues,
|
||||
isLoaded: true,
|
||||
productRecommendations: mockResponse,
|
||||
productRecommendations: mockCrossProductResponse,
|
||||
};
|
||||
|
||||
const desktopWindowSize = {
|
||||
@@ -41,7 +41,7 @@ describe('ProductRecommendations', () => {
|
||||
|
||||
expect(shallow(<ProductRecommendations />)).toMatchSnapshot();
|
||||
});
|
||||
it('renders the LoadedView with course data if the request completed', () => {
|
||||
it('renders the LoadedView with cross product data if the request completed', () => {
|
||||
useWindowSize.mockReturnValueOnce(desktopWindowSize);
|
||||
hooks.useProductRecommendationsData.mockReturnValueOnce({
|
||||
...successfullLoadValues,
|
||||
@@ -50,8 +50,24 @@ describe('ProductRecommendations', () => {
|
||||
expect(shallow(<ProductRecommendations />)).toMatchObject(
|
||||
shallow(
|
||||
<LoadedView
|
||||
openCourses={mockResponse.amplitudeCourses}
|
||||
crossProductCourses={mockResponse.crossProductCourses}
|
||||
openCourses={mockCrossProductResponse.amplitudeCourses}
|
||||
crossProductCourses={mockCrossProductResponse.crossProductCourses}
|
||||
/>,
|
||||
),
|
||||
);
|
||||
});
|
||||
it('renders the LoadedView with Amplitude course data if the request completed', () => {
|
||||
useWindowSize.mockReturnValueOnce(desktopWindowSize);
|
||||
hooks.useProductRecommendationsData.mockReturnValueOnce({
|
||||
...successfullLoadValues,
|
||||
productRecommendations: mockAmplitudeResponse,
|
||||
});
|
||||
|
||||
expect(shallow(<ProductRecommendations />)).toMatchObject(
|
||||
shallow(
|
||||
<LoadedView
|
||||
openCourses={mockCrossProductResponse.amplitudeCourses}
|
||||
crossProductCourses={[]}
|
||||
/>,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -22,10 +22,21 @@ export const getCoursesWithType = (courseTypes) => {
|
||||
return courses;
|
||||
};
|
||||
|
||||
export const mockFooterRecommendationsHook = {
|
||||
showAndLoad: { shouldShowFooter: true, shouldLoadFooter: true },
|
||||
showDontLoad: { shouldShowFooter: true, shouldLoadFooter: false },
|
||||
loadDontShow: { shouldShowFooter: false, shouldLoadFooter: true },
|
||||
dontShowOrLoad: { shouldShowFooter: false, shouldLoadFooter: false },
|
||||
};
|
||||
|
||||
export const mockCrossProductCourses = getCoursesWithType(['executive-education-2u', 'bootcamp-2u']);
|
||||
export const mockOpenCourses = getCoursesWithType(['verified-audit', 'audit', 'verified', 'course']);
|
||||
|
||||
export const mockResponse = {
|
||||
export const mockCrossProductResponse = {
|
||||
crossProductCourses: mockCrossProductCourses,
|
||||
amplitudeCourses: mockOpenCourses,
|
||||
};
|
||||
|
||||
export const mockAmplitudeResponse = {
|
||||
amplitudeCourses: mockOpenCourses,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user