diff --git a/src/containers/CourseCard/components/CourseCardBanners/EntitlementBanner.test.jsx b/src/containers/CourseCard/components/CourseCardBanners/EntitlementBanner.test.jsx index af213ab..3d1bcc7 100644 --- a/src/containers/CourseCard/components/CourseCardBanners/EntitlementBanner.test.jsx +++ b/src/containers/CourseCard/components/CourseCardBanners/EntitlementBanner.test.jsx @@ -1,10 +1,11 @@ -import React from 'react'; -import { shallow } from '@edx/react-unit-test-utils'; +import { render, screen } from '@testing-library/react'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; +import { formatMessage } from 'testUtils'; import { reduxHooks } from 'hooks'; import EntitlementBanner from './EntitlementBanner'; +import messages from './messages'; -jest.mock('components/Banner', () => 'Banner'); jest.mock('hooks', () => ({ utilHooks: { useFormatDate: () => date => date, @@ -18,9 +19,11 @@ jest.mock('hooks', () => ({ }, })); -const cardId = 'my-test-course-number'; +jest.unmock('@edx/frontend-platform/i18n'); +jest.unmock('@openedx/paragon'); +jest.unmock('react'); -let el; +const cardId = 'test-card-id'; const entitlementData = { isEntitlement: true, @@ -31,33 +34,43 @@ const entitlementData = { }; const platformData = { supportEmail: 'test-support-email' }; -const render = (overrides = {}) => { +const renderComponent = (overrides = {}) => { const { entitlement = {} } = overrides; reduxHooks.useCardEntitlementData.mockReturnValueOnce({ ...entitlementData, ...entitlement }); reduxHooks.usePlatformSettingsData.mockReturnValueOnce(platformData); - el = shallow(); + return render(); }; describe('EntitlementBanner', () => { - test('initializes data with course number from entitlement', () => { - render(); + it('initializes data with course number from entitlement', () => { + renderComponent(); expect(reduxHooks.useCardEntitlementData).toHaveBeenCalledWith(cardId); expect(reduxHooks.useUpdateSelectSessionModalCallback).toHaveBeenCalledWith(cardId); }); - test('no display if not an entitlement', () => { - render({ entitlement: { isEntitlement: false } }); - expect(el.isEmptyRender()).toEqual(true); + it('no display if not an entitlement', () => { + renderComponent({ entitlement: { isEntitlement: false } }); + const banner = screen.queryByRole('alert'); + expect(banner).toBeNull(); }); - test('snapshot: no sessions available', () => { - render({ entitlement: { isFulfilled: false, hasSessions: false } }); - expect(el.snapshot).toMatchSnapshot(); + it('renders when no sessions available', () => { + renderComponent({ entitlement: { isFulfilled: false, hasSessions: false } }); + const banner = screen.getByRole('alert'); + expect(banner).toBeInTheDocument(); + expect(banner).toHaveClass('alert-warning'); + expect(banner.innerHTML).toContain(platformData.supportEmail); }); - test('snapshot: expiration warning', () => { - render({ entitlement: { showExpirationWarning: true } }); - expect(el.snapshot).toMatchSnapshot(); + it('renders when expiration warning', () => { + renderComponent({ entitlement: { showExpirationWarning: true } }); + const banner = screen.getByRole('alert'); + expect(banner).toBeInTheDocument(); + expect(banner).toHaveClass('alert-info'); + const button = screen.getByRole('button', { name: formatMessage(messages.selectSession) }); + expect(button).toBeInTheDocument(); }); - test('no display if sessions available and not displaying warning', () => { - render(); - expect(el.isEmptyRender()).toEqual(true); + it('renders expired banner', () => { + renderComponent({ entitlement: { isExpired: true } }); + const banner = screen.getByRole('alert'); + expect(banner).toBeInTheDocument(); + expect(banner.innerHTML).toContain(formatMessage(messages.entitlementExpired)); }); }); diff --git a/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/EntitlementBanner.test.jsx.snap b/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/EntitlementBanner.test.jsx.snap deleted file mode 100644 index 4b3a668..0000000 --- a/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/EntitlementBanner.test.jsx.snap +++ /dev/null @@ -1,53 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`EntitlementBanner snapshot: expiration warning 1`] = ` - - - select a session - , - } - } - /> - -`; - -exports[`EntitlementBanner snapshot: no sessions available 1`] = ` - - - test-support-email - , - } - } - /> - -`; diff --git a/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/index.test.jsx.snap b/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/index.test.jsx.snap deleted file mode 100644 index dd66404..0000000 --- a/src/containers/CourseCard/components/CourseCardBanners/__snapshots__/index.test.jsx.snap +++ /dev/null @@ -1,41 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CourseCardBanners render with isEnrolled false 1`] = ` -
- - - -
-`; - -exports[`CourseCardBanners renders default CourseCardBanners 1`] = ` -
- - - - - -
-`; diff --git a/src/containers/CourseCard/components/CourseCardBanners/index.test.jsx b/src/containers/CourseCard/components/CourseCardBanners/index.test.jsx index 18a6720..90f273b 100644 --- a/src/containers/CourseCard/components/CourseCardBanners/index.test.jsx +++ b/src/containers/CourseCard/components/CourseCardBanners/index.test.jsx @@ -1,14 +1,23 @@ -import { shallow } from '@edx/react-unit-test-utils'; +import { render, screen } from '@testing-library/react'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import { reduxHooks } from 'hooks'; import CourseCardBanners from '.'; -jest.mock('./CourseBanner', () => 'CourseBanner'); -jest.mock('./CertificateBanner', () => 'CertificateBanner'); -jest.mock('./CreditBanner', () => 'CreditBanner'); -jest.mock('./EntitlementBanner', () => 'EntitlementBanner'); -jest.mock('./RelatedProgramsBanner', () => 'RelatedProgramsBanner'); +jest.mock('./CourseBanner', () => jest.fn(() =>
CourseBanner
)); +jest.mock('./CertificateBanner', () => jest.fn(() =>
CertificateBanner
)); +jest.mock('./CreditBanner', () => jest.fn(() =>
CreditBanner
)); +jest.mock('./EntitlementBanner', () => jest.fn(() =>
EntitlementBanner
)); +jest.mock('./RelatedProgramsBanner', () => jest.fn(() =>
RelatedProgramsBanner
)); + +const mockedComponents = [ + 'CourseBanner', + 'CertificateBanner', + 'CreditBanner', + 'EntitlementBanner', + 'RelatedProgramsBanner', +]; jest.mock('hooks', () => ({ reduxHooks: { @@ -20,13 +29,20 @@ describe('CourseCardBanners', () => { const props = { cardId: 'test-card-id', }; - test('renders default CourseCardBanners', () => { - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); + it('renders default CourseCardBanners', () => { + render(); + mockedComponents.map((componentName) => { + const mockedComponent = screen.getByText(componentName); + return expect(mockedComponent).toBeInTheDocument(); + }); }); - test('render with isEnrolled false', () => { + it('render with isEnrolled false', () => { reduxHooks.useCardEnrollmentData.mockReturnValueOnce({ isEnrolled: false }); - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); + render(); + const mockedComponentsIfNotEnrolled = mockedComponents.slice(-2); + mockedComponentsIfNotEnrolled.map((componentName) => { + const mockedComponent = screen.getByText(componentName); + return expect(mockedComponent).toBeInTheDocument(); + }); }); }); diff --git a/src/containers/CourseCard/components/CourseCardMenu/SocialShareMenu.jsx b/src/containers/CourseCard/components/CourseCardMenu/SocialShareMenu.jsx index 90cb858..a1ea214 100644 --- a/src/containers/CourseCard/components/CourseCardMenu/SocialShareMenu.jsx +++ b/src/containers/CourseCard/components/CourseCardMenu/SocialShareMenu.jsx @@ -2,7 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import * as ReactShare from 'react-share'; -import { StrictDict } from '@edx/react-unit-test-utils'; import { useIntl } from '@edx/frontend-platform/i18n'; import { Dropdown } from '@openedx/paragon'; @@ -11,9 +10,9 @@ import { reduxHooks } from 'hooks'; import messages from './messages'; -export const testIds = StrictDict({ +export const testIds = { emailSettingsModalToggle: 'emailSettingsModalToggle', -}); +}; export const SocialShareMenu = ({ cardId, emailSettings }) => { const { formatMessage } = useIntl(); diff --git a/src/containers/CourseCard/components/CourseCardMenu/hooks.js b/src/containers/CourseCard/components/CourseCardMenu/hooks.js index 2fce036..0918436 100644 --- a/src/containers/CourseCard/components/CourseCardMenu/hooks.js +++ b/src/containers/CourseCard/components/CourseCardMenu/hooks.js @@ -1,12 +1,12 @@ -import { useKeyedState, StrictDict } from '@edx/react-unit-test-utils'; +import { useKeyedState } from '@edx/react-unit-test-utils'; import track from 'tracking'; import { reduxHooks } from 'hooks'; -export const stateKeys = StrictDict({ +export const stateKeys = { isUnenrollConfirmVisible: 'isUnenrollConfirmVisible', isEmailSettingsVisible: 'isEmailSettingsVisible', -}); +}; export const useUnenrollData = () => { const [isVisible, setIsVisible] = useKeyedState(stateKeys.isUnenrollConfirmVisible, false); diff --git a/src/containers/CourseCard/components/CourseCardMenu/index.jsx b/src/containers/CourseCard/components/CourseCardMenu/index.jsx index b8687a5..918ef37 100644 --- a/src/containers/CourseCard/components/CourseCardMenu/index.jsx +++ b/src/containers/CourseCard/components/CourseCardMenu/index.jsx @@ -1,10 +1,8 @@ -import React from 'react'; import PropTypes from 'prop-types'; import { useIntl } from '@edx/frontend-platform/i18n'; import { Dropdown, Icon, IconButton } from '@openedx/paragon'; import { MoreVert } from '@openedx/paragon/icons'; -import { StrictDict } from '@edx/react-unit-test-utils'; import EmailSettingsModal from 'containers/EmailSettingsModal'; import UnenrollConfirmModal from 'containers/UnenrollConfirmModal'; @@ -19,9 +17,9 @@ import { import messages from './messages'; -export const testIds = StrictDict({ +export const testIds = { unenrollModalToggle: 'unenrollModalToggle', -}); +}; export const CourseCardMenu = ({ cardId }) => { const { formatMessage } = useIntl(); diff --git a/src/containers/CourseCard/components/RelatedProgramsBadge/__snapshots__/index.test.jsx.snap b/src/containers/CourseCard/components/RelatedProgramsBadge/__snapshots__/index.test.jsx.snap deleted file mode 100644 index 3b56629..0000000 --- a/src/containers/CourseCard/components/RelatedProgramsBadge/__snapshots__/index.test.jsx.snap +++ /dev/null @@ -1,25 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`RelatedProgramsBadge component snapshot: 3 programs 1`] = ` - - - - -`; diff --git a/src/containers/CourseCard/components/RelatedProgramsBadge/index.test.jsx b/src/containers/CourseCard/components/RelatedProgramsBadge/index.test.jsx index 09e3b9f..81bae60 100644 --- a/src/containers/CourseCard/components/RelatedProgramsBadge/index.test.jsx +++ b/src/containers/CourseCard/components/RelatedProgramsBadge/index.test.jsx @@ -1,5 +1,5 @@ -import React from 'react'; -import { shallow } from '@edx/react-unit-test-utils'; +import { render, screen } from '@testing-library/react'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import useRelatedProgramsBadge from './hooks'; import RelatedProgramsBadge from '.'; @@ -7,6 +7,10 @@ import RelatedProgramsBadge from '.'; jest.mock('containers/RelatedProgramsModal', () => 'RelatedProgramsModal'); jest.mock('./hooks', () => jest.fn()); +jest.unmock('@edx/frontend-platform/i18n'); +jest.unmock('@openedx/paragon'); +jest.unmock('react'); + const hookProps = { isOpen: true, openModal: jest.fn().mockName('useRelatedProgramsBadge.openModal'), @@ -15,16 +19,21 @@ const hookProps = { programsMessage: 'useRelatedProgramsBadge.programsMessage', }; -const cardId = 'test-course-number'; +const cardId = 'test-card-id'; describe('RelatedProgramsBadge component', () => { - test('empty render: no programs', () => { + it('should not render if no programs', () => { useRelatedProgramsBadge.mockReturnValueOnce({ ...hookProps, numPrograms: 0 }); - const el = shallow(); - expect(el.isEmptyRender()).toEqual(true); + render(); + const button = screen.queryByRole('button', { name: hookProps.programsMessage }); + expect(button).toBeNull(); + const dialog = screen.queryByRole('dialog'); + expect(dialog).toBeNull(); }); - test('snapshot: 3 programs', () => { - useRelatedProgramsBadge.mockReturnValueOnce(hookProps); - expect(shallow().snapshot).toMatchSnapshot(); + it('3 programs closed', () => { + useRelatedProgramsBadge.mockReturnValue({ ...hookProps, isOpen: false }); + render(); + const button = screen.getByRole('button', { name: hookProps.programsMessage }); + expect(button).toBeInTheDocument(); }); });