From fac5d6aba76f4d4b47498527e4f93bb245184a1c Mon Sep 17 00:00:00 2001 From: Ben Warzeski Date: Mon, 13 Jun 2022 22:17:06 -0400 Subject: [PATCH] feat: program card tests --- .../__snapshots__/index.test.jsx.snap | 4 +- .../EmailSettingsModal/index.test.jsx | 4 +- .../__snapshots__/index.test.jsx.snap | 167 ++++++++++++++++++ .../components/ProgramCard.jsx | 18 +- .../components/ProgramCard.test.jsx | 24 +++ .../__snapshots__/ProgramCard.test.jsx.snap | 70 ++++++++ .../components/messages.js | 24 +++ src/containers/RelatedProgramsModal/hooks.js | 15 +- .../RelatedProgramsModal/hooks.test.js | 67 +++++++ src/containers/RelatedProgramsModal/index.jsx | 4 +- .../RelatedProgramsModal/index.test.jsx | 49 +++++ src/setupTest.jsx | 6 +- 12 files changed, 425 insertions(+), 27 deletions(-) create mode 100644 src/containers/RelatedProgramsModal/__snapshots__/index.test.jsx.snap create mode 100644 src/containers/RelatedProgramsModal/components/ProgramCard.test.jsx create mode 100644 src/containers/RelatedProgramsModal/components/__snapshots__/ProgramCard.test.jsx.snap create mode 100644 src/containers/RelatedProgramsModal/components/messages.js create mode 100644 src/containers/RelatedProgramsModal/hooks.test.js create mode 100644 src/containers/RelatedProgramsModal/index.test.jsx diff --git a/src/containers/EmailSettingsModal/__snapshots__/index.test.jsx.snap b/src/containers/EmailSettingsModal/__snapshots__/index.test.jsx.snap index 17862eb..e9b5224 100644 --- a/src/containers/EmailSettingsModal/__snapshots__/index.test.jsx.snap +++ b/src/containers/EmailSettingsModal/__snapshots__/index.test.jsx.snap @@ -129,11 +129,11 @@ exports[`EmailSettingsModal render snapshot: emails enabled, show: true 1`] = ` />

diff --git a/src/containers/EmailSettingsModal/index.test.jsx b/src/containers/EmailSettingsModal/index.test.jsx index 60e08ac..6a82846 100644 --- a/src/containers/EmailSettingsModal/index.test.jsx +++ b/src/containers/EmailSettingsModal/index.test.jsx @@ -27,10 +27,10 @@ const dispatch = useDispatch(); describe('EmailSettingsModal', () => { beforeEach(() => { jest.clearAllMocks(); - hooks.mockReturnValueOnce(hookProps); }); describe('behavior', () => { beforeEach(() => { + hooks.mockReturnValueOnce(hookProps); shallow(); }); it('calls hook w/ dispatch from redux hook, and closeModal, courseNumber from props', () => { @@ -43,9 +43,11 @@ describe('EmailSettingsModal', () => { }); describe('render', () => { test('snapshot: emails disabled, show: false', () => { + hooks.mockReturnValueOnce(hookProps); expect(shallow()).toMatchSnapshot(); }); test('snapshot: emails disabled, show: true', () => { + hooks.mockReturnValueOnce(hookProps); expect(shallow()).toMatchSnapshot(); }); test('snapshot: emails enabled, show: true', () => { diff --git a/src/containers/RelatedProgramsModal/__snapshots__/index.test.jsx.snap b/src/containers/RelatedProgramsModal/__snapshots__/index.test.jsx.snap new file mode 100644 index 0000000..2217082 --- /dev/null +++ b/src/containers/RelatedProgramsModal/__snapshots__/index.test.jsx.snap @@ -0,0 +1,167 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`RelatedProgramsModal snapshot: closed 1`] = ` + + } +> + + + + + hookProps.courseTitle + + +

+ +

+ + + + + + + +`; + +exports[`RelatedProgramsModal snapshot: open 1`] = ` + + } +> + + + + + hookProps.courseTitle + + +

+ +

+ + + + + +
+
+`; diff --git a/src/containers/RelatedProgramsModal/components/ProgramCard.jsx b/src/containers/RelatedProgramsModal/components/ProgramCard.jsx index d60a538..d8f14f3 100644 --- a/src/containers/RelatedProgramsModal/components/ProgramCard.jsx +++ b/src/containers/RelatedProgramsModal/components/ProgramCard.jsx @@ -10,23 +10,11 @@ import { } from '@edx/paragon'; import { Program } from '@edx/paragon/icons'; +import messages from './messages'; import './index.scss'; export const whiteFontWrapper = (node) => ({node}); -export const messages = { - courses: { - id: 'learnerDashboard.programCard.courses', - defaultMessage: '{numCourses} Courses', - description: 'Number of courses in a program, displayed at the bottom of program card', - }, - duration: { - id: 'learnerDashboard.programCard.duration', - defaultMessage: '{numWeeks} Weeks', - description: 'Number of weeks in a program, displayed at the bottom of program card', - }, -}; - export const ProgramCard = ({ data }) => { const { formatMessage } = useIntl(); const numCoursesMessage = formatMessage( @@ -45,9 +33,9 @@ export const ProgramCard = ({ data }) => { { + test('snapshot', () => { + expect(shallow()).toMatchSnapshot(); + }); +}); diff --git a/src/containers/RelatedProgramsModal/components/__snapshots__/ProgramCard.test.jsx.snap b/src/containers/RelatedProgramsModal/components/__snapshots__/ProgramCard.test.jsx.snap new file mode 100644 index 0000000..e082c48 --- /dev/null +++ b/src/containers/RelatedProgramsModal/components/__snapshots__/ProgramCard.test.jsx.snap @@ -0,0 +1,70 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`RelatedProgramsModal ProgramCard snapshot 1`] = ` + + + } + logoSrc="props.data.logoUrl" + src="props.data.bannerUrl" + srcAlt={ + + } + /> + + props.data.provider + + } + title={ + + props.data.title + + } + /> +
+ + + + props.data.programType + +
+ + • + +
+
+
+`; diff --git a/src/containers/RelatedProgramsModal/components/messages.js b/src/containers/RelatedProgramsModal/components/messages.js new file mode 100644 index 0000000..ef96df6 --- /dev/null +++ b/src/containers/RelatedProgramsModal/components/messages.js @@ -0,0 +1,24 @@ +export const messages = { + courses: { + id: 'learnerDashboard.programCard.courses', + defaultMessage: '{numCourses} Courses', + description: 'Number of courses in a program, displayed at the bottom of program card', + }, + duration: { + id: 'learnerDashboard.programCard.duration', + defaultMessage: '{numWeeks} Weeks', + description: 'Number of weeks in a program, displayed at the bottom of program card', + }, + logoAlt: { + id: 'learnerDashboard.programCard.logoAlt', + defaultMessage: 'Provider logo', + description: 'Program provider logo alt-text', + }, + bannerAlt: { + id: 'learnerDashboard.programCard.bannerAlt', + defaultMessage: 'Programm banner', + description: 'Program banner logo alt-text', + }, +}; + +export default messages; diff --git a/src/containers/RelatedProgramsModal/hooks.js b/src/containers/RelatedProgramsModal/hooks.js index b5f716c..606386d 100644 --- a/src/containers/RelatedProgramsModal/hooks.js +++ b/src/containers/RelatedProgramsModal/hooks.js @@ -1,16 +1,19 @@ import { selectors } from 'data/redux'; -import { getCardValue } from 'hooks'; +import { getCardValues } from 'hooks'; const { cardData } = selectors; const { programs } = cardData; -export const programsModalData = ({ +export const modalData = ({ courseNumber, }) => { - const cardValue = getCardValue(courseNumber); + const data = getCardValues(courseNumber, { + courseTitle: cardData.courseTitle, + relatedPrograms: cardData.relatedPrograms, + }); return { - courseTitle: cardValue(cardData.courseTitle), - relatedPrograms: cardValue(cardData.relatedPrograms).map(program => ({ + courseTitle: data.courseTitle, + relatedPrograms: data.relatedPrograms.map(program => ({ estimatedNumberOfWeeks: programs.estimatedNumberOfWeeks(program), numberOfCourses: programs.numberOfCourses(program), programType: programs.programType(program), @@ -21,4 +24,4 @@ export const programsModalData = ({ }; }; -export default programsModalData; +export default modalData; diff --git a/src/containers/RelatedProgramsModal/hooks.test.js b/src/containers/RelatedProgramsModal/hooks.test.js new file mode 100644 index 0000000..936d938 --- /dev/null +++ b/src/containers/RelatedProgramsModal/hooks.test.js @@ -0,0 +1,67 @@ +import { testCardValues } from 'testUtils'; +import * as appHooks from 'hooks'; +import { selectors } from 'data/redux'; + +import * as hooks from './hooks'; + +jest.mock('data/redux/cardData/selectors', () => ({ + ...jest.requireActual('data/redux/cardData/selectors'), + programs: { + estimatedNumberOfWeeks: (p) => p.estimatedNumberOfWeeks, + numberOfCourses: (p) => p.numberOfCourses, + programType: (p) => p.programType, + programTypeUrl: (p) => p.programTypeUrl, + provider: (p) => p.provider, + title: (p) => p.title, + }, +})); + +const { fieldKeys } = selectors.cardData; + +const courseNumber = 'test-course-number'; + +const courseTitle = 'test-course-title'; +const relatedPrograms = [ + { + estimatedNumberOfWeeks: 1, + numberOfCourses: 2, + programType: 'test-program-type-1', + programTypeUrl: 'test-program-type-1-url', + provider: 'test-provider-1', + title: 'test-program-title-1', + }, + { + estimatedNumberOfWeeks: 2, + numberOfCourses: 3, + programType: 'test-program-type-2', + programTypeUrl: 'test-program-type-2-url', + provider: 'test-provider-2', + title: 'test-program-title-2', + }, + { + estimatedNumberOfWeeks: 3, + numberOfCourses: 5, + programType: 'test-program-type-3', + programTypeUrl: 'test-program-type-3-url', + provider: 'test-provider-3', + title: 'test-program-title-3', + }, +]; + +describe('RelatedProgramsModal hooks', () => { + let out; + beforeEach(() => { + appHooks.getCardValues.mockReturnValueOnce({ courseTitle, relatedPrograms }); + out = hooks.modalData({ courseNumber }); + }); + testCardValues(courseNumber, { + courseTitle: fieldKeys.courseTitle, + relatedPrograms: fieldKeys.relatedPrograms, + }); + test('courseTitle loads course title', () => { + expect(out.courseTitle).toEqual(courseTitle); + }); + test('relatedPrograms loads from course run related programs', () => { + expect(out.relatedPrograms).toEqual(relatedPrograms); + }); +}); diff --git a/src/containers/RelatedProgramsModal/index.jsx b/src/containers/RelatedProgramsModal/index.jsx index f896b28..fd94b50 100644 --- a/src/containers/RelatedProgramsModal/index.jsx +++ b/src/containers/RelatedProgramsModal/index.jsx @@ -7,7 +7,7 @@ import { CardGrid, ModalDialog } from '@edx/paragon'; import ProgramCard from './components/ProgramCard'; import messages from './messages'; -import programsData from './hooks'; +import { modalData } from './hooks'; import './index.scss'; export const RelatedProgramsModal = ({ @@ -16,7 +16,7 @@ export const RelatedProgramsModal = ({ courseNumber, }) => { const { formatMessage } = useIntl(); - const { courseTitle, relatedPrograms } = programsData({ courseNumber }); + const { courseTitle, relatedPrograms } = modalData({ courseNumber }); return ( 'ProgramCard'); +jest.mock('./hooks', () => ({ + modalData: jest.fn(), +})); + +const courseNumber = 'test-course-number'; +const hookProps = { + courseTitle: 'hookProps.courseTitle', + relatedPrograms: [ + { + programUrl: 'program-1-url', + programData: { dataFor: 'program1' }, + }, + { + programUrl: 'program-2-url', + programData: { dataFor: 'program2' }, + }, + { + programUrl: 'program-3-url', + programData: { dataFor: 'program3' }, + }, + ], +}; + +const props = { + isOpen: true, + closeModal: jest.fn().mockName('props.closeModal'), + courseNumber, +}; + +describe('RelatedProgramsModal', () => { + beforeEach(() => { + modalData.mockReturnValueOnce(hookProps); + }); + test('snapshot: open', () => { + expect(shallow()).toMatchSnapshot(); + }); + test('snapshot: closed', () => { + expect( + shallow(), + ).toMatchSnapshot(); + }); +}); diff --git a/src/setupTest.jsx b/src/setupTest.jsx index 28e2885..a460340 100755 --- a/src/setupTest.jsx +++ b/src/setupTest.jsx @@ -53,6 +53,7 @@ jest.mock('@edx/paragon', () => jest.requireActual('testUtils').mockNestedCompon ImageCap: 'Card.ImageCap', Section: 'Card.Section', }, + CardGrid: 'CardGrid', Col: 'Col', Collapsible: { Advanced: 'Collapsible.Advanced', @@ -88,7 +89,10 @@ jest.mock('@edx/paragon', () => jest.requireActual('testUtils').mockNestedCompon Hyperlink: 'Hyperlink', Icon: 'Icon', IconButton: 'IconButton', - ModalDialog: 'ModalDialog', + ModalDialog: { + Header: 'ModalDialog.Header', + Body: 'ModalDialog.Body', + }, MultiSelectDropdownFilter: 'MultiSelectDropdownFilter', OverlayTrigger: 'OverlayTrigger', Popover: {