Skip to content

Commit

Permalink
chore: tests
Browse files Browse the repository at this point in the history
  • Loading branch information
brobro10000 committed Jun 18, 2024
1 parent 7e72f50 commit 3871d96
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 114 deletions.
7 changes: 0 additions & 7 deletions src/components/course/data/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ export const SUBSIDY_DISCOUNT_TYPE_MAP = {
ABSOLUTE: 'absolute',
};

// export const LICENSE_SUBSIDY_TYPE = 'license';
// export const COUPON_CODE_SUBSIDY_TYPE = 'couponCode';
// export const ENTERPRISE_OFFER_SUBSIDY_TYPE = 'enterpriseOffer';
// export const LEARNER_CREDIT_SUBSIDY_TYPE = 'learnerCredit';

export const PROMISE_FULFILLED = 'fulfilled';

export const CURRENCY_USD = 'USD';

export const COURSE_RUN_AVAILABILITY = {
Expand Down
2 changes: 1 addition & 1 deletion src/components/course/data/tests/hooks.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ jest.mock('../../../app/data', () => ({
useCouponCodes: jest.fn(),
useBrowseAndRequest: jest.fn(),
useCatalogsForSubsidyRequests: jest.fn(),
getSubsidyToApplyForCourse: jest.fn(),
}));

const oldGlobalLocation = global.location;
Expand All @@ -97,7 +98,6 @@ jest.mock('@tanstack/react-query', () => ({
jest.mock('../utils', () => ({
...jest.requireActual('../utils'),
getCourseRunPrice: jest.fn(),
getSubsidyToApplyForCourse: jest.fn(),
findCouponCodeForCourse: jest.fn(),
findEnterpriseOfferForCourse: jest.fn(),
getCourseTypeConfig: jest.fn(),
Expand Down
6 changes: 6 additions & 0 deletions src/components/course/data/utils.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ export function getProgramIcon(type) {

export const numberWithPrecision = (number, precision = 2) => number.toFixed(precision);

/**
*
* @param couponCodes
* @param catalogList
* @returns {*}
*/
export function findCouponCodeForCourse(couponCodes, catalogList = []) {
return couponCodes.find((couponCode) => catalogList?.includes(couponCode.catalog) && hasValidStartExpirationDates({
startDate: couponCode.couponStartDate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,6 @@ export const useCourseUpgradeData = ({
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
const courseService = new CourseService({
enterpriseUuid: enterpriseId,
courseKey: null,
courseRunKey,
});

// Don't do anything if the course is not part of the enterprise's catalog
if (!containsContentItems) {
setIsLoading(false);
Expand All @@ -162,19 +156,14 @@ export const useCourseUpgradeData = ({
setIsLoading(true);

try {
if (applicableSubscriptionLicense) {
setSubsidyForCourse(getSubsidyToApplyForCourse({ applicableSubscriptionLicense }));
setLicenseUpgradeUrl(createEnrollWithLicenseUrl({
courseRunKey,
enterpriseId,
licenseUUID: applicableSubscriptionLicense.uuid,
location,
}));
return;
}

if (applicableCouponCode) {
// TODO: Refactor to use react query
const courseService = new CourseService({
enterpriseUuid: enterpriseId,
courseKey: null,
courseRunKey,
});

const fetchCourseRunResponse = await courseService.fetchCourseRun(courseRunKey);
const courseRunDetails = camelCaseObject(fetchCourseRunResponse.data);
const sku = findHighestLevelSeatSku(courseRunDetails.seats);
Expand All @@ -195,13 +184,33 @@ export const useCourseUpgradeData = ({
}
};

fetchData();
if (!containsContentItems) {
setIsLoading(false);
return;

Check warning on line 189 in src/components/dashboard/main-content/course-enrollments/data/hooks.js

View check run for this annotation

Codecov / codecov/patch

src/components/dashboard/main-content/course-enrollments/data/hooks.js#L188-L189

Added lines #L188 - L189 were not covered by tests
}

if (applicableSubscriptionLicense) {
setSubsidyForCourse(getSubsidyToApplyForCourse({ applicableSubscriptionLicense }));
setLicenseUpgradeUrl(createEnrollWithLicenseUrl({
courseRunKey,
enterpriseId,
licenseUUID: applicableSubscriptionLicense.uuid,
location,
}));
setIsLoading(false);
return;
}

if (applicableCouponCode) {
fetchData();
}

// Learner credit audit -> upgrade URL generation
if (applicableSubsidyAccessPolicy?.canRedeem) {
setSubsidyForCourse(getSubsidyToApplyForCourse({ applicableSubsidyAccessPolicy }));
setCourseRunPrice(applicableSubsidyAccessPolicy.listPrice);
setLearnerCreditUpgradeUrl(applicableSubsidyAccessPolicy.redeemableSubsidyAccessPolicy.policyRedemptionUrl);
setIsLoading(false);

Check warning on line 213 in src/components/dashboard/main-content/course-enrollments/data/hooks.js

View check run for this annotation

Codecov / codecov/patch

src/components/dashboard/main-content/course-enrollments/data/hooks.js#L210-L213

Added lines #L210 - L213 were not covered by tests
}
}, [
courseRunKey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import camelCase from 'lodash.camelcase';
import dayjs from 'dayjs';
import { QueryClientProvider } from '@tanstack/react-query';
import { waitFor } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';

import { queryClient } from '../../../../../../utils/tests';
import {
Expand All @@ -23,9 +24,12 @@ import {
emptyRedeemableLearnerCreditPolicies,
transformCourseEnrollment,
transformLearnerContentAssignment,
useCanUpgradeWithLearnerCredit, useCouponCodes,
useEnterpriseCourseEnrollments,
useEnterpriseCustomer,
useEnterpriseCustomerContainsContent,
useRedeemablePolicies,
useSubscriptions,
} from '../../../../../app/data';
import { authenticatedUserFactory, enterpriseCustomerFactory } from '../../../../../app/data/services/data/__factories__';

Expand All @@ -40,6 +44,10 @@ jest.mock('../../../../../app/data', () => ({
useEnterpriseCustomer: jest.fn(),
useEnterpriseCourseEnrollments: jest.fn(),
useRedeemablePolicies: jest.fn(),
useSubscriptions: jest.fn(),
useCouponCodes: jest.fn(),
useCanUpgradeWithLearnerCredit: jest.fn(),
useEnterpriseCustomerContainsContent: jest.fn(),
}));

const mockCourseService = {
Expand All @@ -65,9 +73,11 @@ const mockAppContextValue = {

const wrapper = ({ children }) => (
<QueryClientProvider client={queryClient()}>
<AppContext.Provider value={mockAppContextValue}>
{children}
</AppContext.Provider>
<MemoryRouter>
<AppContext.Provider value={mockAppContextValue}>
{children}
</AppContext.Provider>
</MemoryRouter>
</QueryClientProvider>
);

Expand Down Expand Up @@ -170,91 +180,86 @@ describe('useCourseEnrollments', () => {

describe('useCourseUpgradeData', () => {
const courseRunKey = 'course-run-key';
const enterpriseId = 'uuid';
const enterpriseId = mockEnterpriseCustomer.uuid;
const subscriptionLicense = { uuid: 'license-uuid' };
const location = { search: '' };
const location = { pathname: '/', search: '' };
const basicArgs = {
courseRunKey,
enterpriseId,
subscriptionLicense,
couponCodes: [],
location,
};

beforeEach(() => {
jest.clearAllMocks();
useEnterpriseCustomer.mockReturnValue({ data: mockEnterpriseCustomer });
useSubscriptions.mockReturnValue({
data: { subscriptionLicense: null },
});
useCanUpgradeWithLearnerCredit.mockReturnValue({
data: { applicableSubsidyAccessPolicy: null },
});
useEnterpriseCustomerContainsContent.mockReturnValue({
data: {
containsContentItems: false,
catalogList: [],
},
});
useCouponCodes.mockReturnValue({
data: {
applicableCouponCode: null,
},
});
});
afterEach(() => jest.clearAllMocks());

it('should return undefined for upgrade urls if the course is not part of the enterprise catalog', async () => {
mockCourseService.fetchEnterpriseCustomerContainsContent.mockResolvedValueOnce(
{ data: { contains_content_items: false } },
);

const { result, waitForNextUpdate } = renderHook(() => useCourseUpgradeData(basicArgs));

expect(result.current.isLoading).toEqual(true);

await waitForNextUpdate();
it('should return undefined for upgrade urls if the course is not part of the enterprise catalog', () => {
useEnterpriseCustomerContainsContent.mockReturnValue({
data: {
containsContentItems: false,
catalogList: [],
},
});

expect(mockCourseService.fetchEnterpriseCustomerContainsContent).toHaveBeenCalledWith([courseRunKey]);
expect(mockCourseService.fetchUserLicenseSubsidy).not.toHaveBeenCalled();
const { result } = renderHook(() => useCourseUpgradeData(basicArgs), { wrapper });

expect(result.current.licenseUpgradeUrl).toBeUndefined();
expect(result.current.couponUpgradeUrl).toBeUndefined();
expect(result.current.courseRunPrice).toBeUndefined();
expect(result.current.learnerCreditUpgradeUrl).toBeUndefined();
expect(result.current.isLoading).toEqual(false);
});

describe('upgradeable via license', () => {
it('should return a license upgrade url', async () => {
mockCourseService.fetchEnterpriseCustomerContainsContent.mockResolvedValueOnce(
{ data: { contains_content_items: true } },
);
mockCourseService.fetchUserLicenseSubsidy.mockResolvedValueOnce({
it('should return a license upgrade url', () => {
useEnterpriseCustomerContainsContent.mockReturnValue({
data: {
subsidy_id: 'subsidy-id',
containsContentItems: true,
catalogList: [],
},
});

const { result, waitForNextUpdate } = renderHook(() => useCourseUpgradeData(basicArgs));

expect(result.current.isLoading).toEqual(true);

await waitForNextUpdate();
useSubscriptions.mockReturnValue({
data: {
subscriptionLicense: {
uuid: 'license-uuid',
subscriptionPlan: {
startDate: dayjs().subtract(10, 'days').toISOString(),
expirationDate: dayjs().add(10, 'days').toISOString(),
},
status: 'activated',
},
},
});

expect(mockCourseService.fetchEnterpriseCustomerContainsContent).toHaveBeenCalledWith([courseRunKey]);
expect(mockCourseService.fetchUserLicenseSubsidy).toHaveBeenCalledWith(courseRunKey);
const { result } = renderHook(() => useCourseUpgradeData(basicArgs), { wrapper });

expect(result.current.isLoading).toEqual(false);
expect(result.current.licenseUpgradeUrl).toEqual(createEnrollWithLicenseUrl({
courseRunKey,
enterpriseId,
licenseUUID: subscriptionLicense.uuid,
location,
}));
expect(result.current.learnerCreditUpgradeUrl).toBeUndefined();
expect(result.current.couponUpgradeUrl).toBeUndefined();
expect(result.current.courseRunPrice).toBeUndefined();
expect(result.current.isLoading).toEqual(false);
});

it('should return undefined for licenseUpgradeUrl upgrade url if fetchUserLicenseSubsidy returned undefined', async () => {
mockCourseService.fetchEnterpriseCustomerContainsContent.mockResolvedValueOnce(
{ data: { contains_content_items: true } },
);
mockCourseService.fetchUserLicenseSubsidy.mockResolvedValueOnce({
data: undefined,
});

const { result, waitForNextUpdate } = renderHook(() => useCourseUpgradeData(basicArgs));

expect(result.current.isLoading).toEqual(true);

await waitForNextUpdate();

expect(mockCourseService.fetchEnterpriseCustomerContainsContent).toHaveBeenCalledWith([courseRunKey]);
expect(mockCourseService.fetchUserLicenseSubsidy).toHaveBeenCalledWith(courseRunKey);

expect(result.current.upgradeUrl).toBeUndefined();
expect(result.current.couponUpgradeUrl).toBeUndefined();
expect(result.current.courseRunPrice).toBeUndefined();
expect(result.current.isLoading).toEqual(false);
});
});

Expand All @@ -267,9 +272,15 @@ describe('useCourseEnrollments', () => {
};

it('should return a coupon upgrade url', async () => {
mockCourseService.fetchEnterpriseCustomerContainsContent.mockResolvedValueOnce(
{ data: { contains_content_items: true, catalog_list: [mockCouponCode.catalog] } },
);
useEnterpriseCustomerContainsContent.mockReturnValue({
data: {
containsContentItems: true,
catalogList: [mockCouponCode.catalog],
},
});
useCouponCodes.mockReturnValue({
data: { applicableCouponCode: mockCouponCode },
});
const sku = 'ABCDEF';
const coursePrice = '149.00';

Expand All @@ -293,49 +304,47 @@ describe('useCourseEnrollments', () => {
},
);

const args = {
...basicArgs,
subscriptionLicense: undefined,
couponCodes: [mockCouponCode],
};

const { result, waitForNextUpdate } = renderHook(() => useCourseUpgradeData(args));
const { result } = renderHook(() => useCourseUpgradeData(basicArgs), { wrapper });

expect(result.current.isLoading).toEqual(true);

await waitForNextUpdate();

expect(mockCourseService.fetchEnterpriseCustomerContainsContent).toHaveBeenCalledWith([courseRunKey]);
expect(mockCourseService.fetchUserLicenseSubsidy).not.toHaveBeenCalled();
expect(mockCourseService.fetchCourseRun).toHaveBeenCalledWith(courseRunKey);
await waitFor(() => expect(mockCourseService.fetchCourseRun).toHaveBeenCalledWith(courseRunKey));
expect(result.current.licenseUpgradeUrl).toBeUndefined();
expect(result.current.couponUpgradeUrl).toEqual(createEnrollWithCouponCodeUrl({
courseRunKey,
sku,
code: mockCouponCode.code,
location,
}));
expect(result.current.learnerCreditUpgradeUrl).toBeUndefined();
expect(result.current.courseRunPrice).toEqual(coursePrice);
expect(result.current.isLoading).toEqual(false);
});
});

it('should handle errors', async () => {
const error = Error('Uh oh');
mockCourseService.fetchEnterpriseCustomerContainsContent.mockRejectedValueOnce(error);

const { result, waitForNextUpdate } = renderHook(() => useCourseUpgradeData(basicArgs));

expect(result.current.isLoading).toEqual(true);
it('should handle errors', async () => {
const error = Error('Uh oh');
mockCourseService.fetchCourseRun.mockRejectedValueOnce(error);
useEnterpriseCustomerContainsContent.mockReturnValue({
data: {
containsContentItems: true,
catalogList: [mockCouponCode.catalog],
},
});
useCouponCodes.mockReturnValue({
data: { applicableCouponCode: mockCouponCode },
});
const { result, waitForNextUpdate } = renderHook(() => useCourseUpgradeData(basicArgs), { wrapper });

await waitForNextUpdate();
expect(result.current.isLoading).toEqual(true);

expect(mockCourseService.fetchEnterpriseCustomerContainsContent).toHaveBeenCalledWith([courseRunKey]);
expect(mockCourseService.fetchUserLicenseSubsidy).not.toHaveBeenCalled();
await waitForNextUpdate();

expect(result.current.upgradeUrl).toBeUndefined();
expect(result.current.isLoading).toEqual(false);
expect(logger.logError).toHaveBeenCalledWith(error);
expect(result.current.licenseUpgradeUrl).toBeUndefined();
expect(result.current.couponUpgradeUrl).toBeUndefined();
expect(result.current.learnerCreditUpgradeUrl).toBeUndefined();
expect(result.current.isLoading).toEqual(false);
expect(logger.logError).toHaveBeenCalledWith(error);
});
});
});
});
Expand Down

0 comments on commit 3871d96

Please sign in to comment.