Files
frontend-app-learner-dashboard/src/data/redux/app/selectors/courseCard.test.js
2022-10-26 15:22:06 -04:00

345 lines
15 KiB
JavaScript

import { keyStore } from 'utils';
import { baseAppUrl } from 'data/services/lms/urls';
import simpleSelectors from './simpleSelectors';
import * as module from './courseCard';
jest.mock('data/services/lms/urls', () => ({
baseAppUrl: url => ({ baseAppUrl: url }),
}));
jest.mock('./simpleSelectors', () => ({
mkCardSelector: (simpleSelector, selector) => ({
mkCardSelector: { selector, simpleSelector },
}),
cardSimpleSelectors: jest.requireActual('./simpleSelectors').cardSimpleSelectors,
}));
const { courseCard } = module;
const { cardSimpleSelectors } = simpleSelectors;
const moduleKeys = keyStore(module);
let testData;
let selector;
let simpleSelector;
let selected;
const dates = {
today: new Date(),
tomorrow: new Date(),
nextYear: new Date(),
yesterday: new Date(),
};
dates.tomorrow.setDate(dates.tomorrow.getDate() + 1);
dates.nextYear.setDate(dates.nextYear.getDate() + 365);
dates.yesterday.setDate(dates.yesterday.getDate() - 1);
/*
* Takes a selector as input and fetches the referenced selector and simpleSelector for
* the selector to be tested, to be stored in global variables.
* Also sets `selected` global variable is loaded with the passed data, which is stored
* as `testData`.
*/
const loadSelector = (sel, data) => {
({ simpleSelector, selector } = sel.mkCardSelector);
testData = data;
selected = selector(data);
};
describe('courseCard selectors module', () => {
describe('loadDateVal helper function', () => {
it('returns passed date value converted to Date', () => {
const testDate = '2000-10-10';
expect(module.loadDateVal(testDate)).toEqual(new Date(testDate));
});
it('returns null if no value is passed', () => {
expect(module.loadDateVal()).toEqual(null);
});
});
describe('courseCard selectors', () => {
let dateSpy;
beforeEach(() => {
dateSpy = jest.spyOn(module, moduleKeys.loadDateVal);
dateSpy.mockImplementation(v => new Date(v));
});
afterEach(() => {
dateSpy.mockRestore();
});
describe('certificate selector', () => {
beforeEach(() => {
loadSelector(courseCard.certificate, {
certPreviewUrl: 'test-cert-preview-url',
isDownloadable: 'test-is-downloadable',
isRestricted: 'test-is-restricted',
isEarned: false,
availableDate: '2020-10-10',
});
});
it('returns a card selector based on certificate cardSimpleSelector', () => {
expect(simpleSelector).toEqual(cardSimpleSelectors.certificate);
});
it('passes availableDate, converted to a date', () => {
expect(selected.availableDate).toMatchObject(new Date(testData.availableDate));
});
it('passes [isDownloadable, isRestricted]', () => {
expect(selected.isDownloadable).toEqual(testData.isDownloadable);
expect(selected.isRestricted).toEqual(testData.isRestricted);
});
it('passes certPreviewUrl as app url', () => {
expect(selected.certPreviewUrl).toEqual(baseAppUrl(testData.certPreviewUrl));
});
describe('isEarnedButUnavailable', () => {
it('passes true iff certificate is earned but availableDate is in the future', () => {
const testSelector = (data, expected) => {
expect(selector({ ...testData, ...data }).isEarnedButUnavailable).toEqual(expected);
};
testSelector({ isEarned: true, availableDate: dates.today }, false);
testSelector({ isEarned: true, availableDate: dates.yesterday }, false);
testSelector({ isEarned: true, availableDate: dates.tomorrow }, true);
testSelector({ isEarned: false, availableDate: dates.tomorrow }, false);
});
});
});
describe('course selector', () => {
beforeEach(() => {
loadSelector(courseCard.course, {
bannerImgSrc: 'test-banner-img-src',
courseNumber: 'test-course-number',
courseName: 'test-course-name',
socialShareUrl: 'test-social-share-url',
});
});
it('returns a card selector based on course cardSimpleSelector', () => {
expect(simpleSelector).toEqual(cardSimpleSelectors.course);
});
it('passes bannerImgSrc, converted to a baseAppUrl', () => {
expect(selected.bannerImgSrc).toEqual(baseAppUrl(testData.bannerImgSrc));
});
it('passes [courseNumber, courseName, socialShareUrl]', () => {
expect(selected.courseNumber).toEqual(testData.courseNumber);
expect(selected.courseName).toEqual(testData.courseName);
expect(selected.socialShareUrl).toEqual(testData.socialShareUrl);
});
});
describe('courseProvider selector', () => {
beforeEach(() => {
loadSelector(courseCard.courseProvider, { name: 'test-provider-name' });
});
it('returns a card selector based on courseProvider cardSimpleSelector', () => {
expect(simpleSelector).toEqual(cardSimpleSelectors.courseProvider);
});
describe('name', () => {
it('passes the provider name if provider is known', () => {
expect(selected.name).toEqual(testData.name);
});
it('passes undefined if provider is not known', () => {
expect(selector().name).toEqual(undefined);
});
});
});
describe('courseRun selector', () => {
beforeEach(() => {
loadSelector(courseCard.courseRun, {
endDate: '3000-10-20',
startDate: '2000-10-20',
courseId: 'test-course-id',
isArchived: 'test-is-archived',
isStarted: 'test-is-started',
minPassingGrade: 0.9354,
homeUrl: 'test-home-url',
marketingUrl: 'test-marketing-url',
upgradeUrl: 'test-upgrade-url',
progressUrl: 'test-progress-url',
resumeUrl: 'test-resume-url',
unenrollUrl: 'test-unenroll-url',
});
});
it('returns a card selector based on courseRun cardSimpleSelector', () => {
expect(simpleSelector).toEqual(cardSimpleSelectors.courseRun);
});
it('passes [endDate, startDate], converted to dates', () => {
expect(selected.endDate).toEqual(new Date(testData.endDate));
expect(selected.startDate).toEqual(new Date(testData.startDate));
});
it('passes [courseId, isArchived, isStarted]', () => {
expect(selected.courseId).toEqual(testData.courseId);
expect(selected.isArchived).toEqual(testData.isArchived);
expect(selected.isStarted).toEqual(testData.isStarted);
});
it('passes minPassingGrade floored from float to a percentage value', () => {
expect(selected.minPassingGrade).toEqual(93);
});
it('passes [homeUrl, marketingUrl, upgradeUrl]', () => {
expect(selected.homeUrl).toEqual(testData.homeUrl);
expect(selected.marketingUrl).toEqual(testData.marketingUrl);
expect(selected.upgradeUrl).toEqual(testData.upgradeUrl);
});
it('passes [progressUrl, unenrollUrl, resumeUrl], converted to baseAppUrl', () => {
expect(selected.progressUrl).toEqual(baseAppUrl(testData.progressUrl));
expect(selected.resumeUrl).toEqual(baseAppUrl(testData.resumeUrl));
expect(selected.unenrollUrl).toEqual(baseAppUrl(testData.unenrollUrl));
});
});
describe('enrollment selector', () => {
beforeEach(() => {
loadSelector(courseCard.enrollment, {
coursewareAccess: {
isStaff: false,
hasUnmetPrereqs: false,
isTooEarly: false,
},
isEnrolled: 'test-is-enrolled',
lastEnrolled: 'test-last-enrolled',
hasStarted: 'test-has-started',
accessExpirationDate: '3000-10-20',
canUpgrade: 'test-can-upgrade',
isAudit: 'test-is-audit',
isAuditAccessExpired: 'test-is-audit-access-expired',
isVerified: 'test-is-verified',
isEmailEnabled: 'test-is-email-enabled',
});
});
it('returns a card selector based on enrollment cardSimpleSelector', () => {
expect(simpleSelector).toEqual(cardSimpleSelectors.enrollment);
});
it('returns { isEnrolled: false } object if null enrollment received', () => {
expect(selector(null)).toEqual({ isEnrolled: false });
});
it('passes [coursewareAccess, hasStarted, isEnrolled, lastEnrolled]', () => {
expect(selected.coursewareAccess).toEqual(testData.coursewareAccess);
expect(selected.hasStarted).toEqual(testData.hasStarted);
expect(selected.isEnrolled).toEqual(testData.isEnrolled);
expect(selected.lastEnrolled).toEqual(testData.lastEnrolled);
});
it('passes hasAccess if staff or neither has umet prereqs nor is too early', () => {
const testAccess = (access, expected) => {
expect(selector({ ...testData, coursewareAccess: access }).hasAccess).toEqual(expected);
};
testAccess({ isStaff: false, hasUnmetPrereqs: false, isTooEarly: false }, true);
testAccess({ isStaff: false, hasUnmetPrereqs: false, isTooEarly: true }, false);
testAccess({ isStaff: false, hasUnmetPrereqs: true, isTooEarly: false }, false);
testAccess({ isStaff: false, hasUnmetPrereqs: true, isTooEarly: true }, false);
testAccess({ isStaff: true, hasUnmetPrereqs: true, isTooEarly: true }, true);
});
it('passes accessExpirationDate, converted to date', () => {
expect(selected.accessExpirationDate).toEqual(new Date(testData.accessExpirationDate));
});
it('passes [canUpgrade, isAudit, isAuditAccessExpired, isVerified]', () => {
expect(selected.canUpgrade).toEqual(testData.canUpgrade);
expect(selected.isAudit).toEqual(testData.isAudit);
expect(selected.isAuditAccessExpired).toEqual(testData.isAuditAccessExpired);
expect(selected.isVerified).toEqual(testData.isVerified);
});
it('passes isEmailEnabled', () => {
expect(selected.isEmailEnabled).toEqual(testData.isEmailEnabled);
});
});
describe('entitlement selector', () => {
beforeEach(() => {
loadSelector(courseCard.entitlement, {
availableSessions: ['test', 'sessions'],
changeDeadline: '2000-10-20',
isExpired: 'test-is-expired',
isFulfilled: 'test-is-fulfilled',
uuid: 'test-uuid',
});
});
it('returns a card selector based on entilement cardSimpleSelector', () => {
expect(simpleSelector).toEqual(cardSimpleSelectors.entitlement);
});
it('returns { isEntilement: false } if entitlement object is missing or empty', () => {
expect(selector({})).toEqual({ isEntitlement: false });
expect(selector()).toEqual({ isEntitlement: false });
});
it('passes isEntitlement: true for entilement data', () => {
expect(selected.isEntitlement).toEqual(true);
});
it('passes [availableSessions, isExpired, isFulfilled, uuid]', () => {
expect(selected.availableSessions).toEqual(testData.availableSessions);
expect(selected.isExpired).toEqual(testData.isExpired);
expect(selected.isFulfilled).toEqual(testData.isFulfilled);
expect(selected.uuid).toEqual(testData.uuid);
});
it('passess changeDeadline as changeDeadline, converted to a date', () => {
expect(selected.changeDeadline).toEqual(new Date(testData.changeDeadline));
});
it('passes hasSessions if availableSessions is provided and has a length > 0', () => {
expect(selected.hasSessions).toEqual(true);
expect(selector({ ...testData, availableSessions: [] }).hasSessions).toEqual(false);
});
it('passes canChange if the deadline is not before current date', () => {
expect(selector({ ...testData, changeDeadline: dates.yesterday }).canChange).toEqual(false);
expect(selector({ ...testData, changeDeadline: dates.tomorrow }).canChange).toEqual(true);
});
it('passes showExpirationWarning if the deadline is 0-6 months in the future and not fulfilled', () => {
const testSelector = ({ isFulfilled, changeDeadline }, expected) => {
expect(
selector({ ...testData, isFulfilled, changeDeadline }).showExpirationWarning,
).toEqual(expected);
};
testSelector({ isFulfilled: false, changeDeadline: dates.yesterday }, false);
testSelector({ isFulfilled: false, changeDeadline: dates.tomorrow }, true);
testSelector({ isFulfilled: false, changeDeadline: dates.nextYear }, false);
testSelector({ isFulfilled: true, changeDeadline: dates.nextYear }, false);
});
});
describe('gradeData selector', () => {
beforeEach(() => {
loadSelector(courseCard.gradeData, { isPassing: 'test-is-passing' });
});
it('returns a card selector based on gradeData cardSimpleSelector', () => {
expect(simpleSelector).toEqual(cardSimpleSelectors.gradeData);
});
it('passes isPassing', () => {
expect(selected.isPassing).toEqual(testData.isPassing);
});
});
describe('relatedPrograms selector', () => {
beforeEach(() => {
const programData = (index) => ({
bannerImgSrc: `test-banner-img-src-${index}`,
logoImgSrc: `test-logo-img-src-${index}`,
numberOfCourses: `test-number-of-courses-${index}`,
programType: `test-program-type-${index}`,
programUrl: `test-program-url-${index}`,
provider: `test-provider-${index}`,
title: `test-title-${index}`,
});
loadSelector(courseCard.relatedPrograms, [
programData(0),
programData(1),
programData(2),
programData(3),
programData(4),
]);
});
it('returns a card selector based on relatedPrograms cardSimpleSelector', () => {
expect(simpleSelector).toEqual(cardSimpleSelectors.relatedPrograms);
});
it('passes [bannerImgSrc, logoImgSrc] for each program', () => {
selected.list.forEach((row, i) => {
expect(row.bannerImgSrc).toEqual(testData[i].bannerImgSrc);
expect(row.logoImgSrc).toEqual(testData[i].logoImgSrc);
});
});
it('passes [numberOfCourses, programType, programUrl, provider, title] for each', () => {
selected.list.forEach((row, i) => {
expect(row.numberOfCourses).toEqual(testData[i].numberOfCourses);
expect(row.programType).toEqual(testData[i].programType);
expect(row.programUrl).toEqual(testData[i].programUrl);
expect(row.provider).toEqual(testData[i].provider);
expect(row.title).toEqual(testData[i].title);
});
});
it('passes number of programs a length', () => {
expect(selected.length).toEqual(testData.length);
});
});
});
});