diff --git a/src/App.test.jsx b/src/App.test.jsx index 33969e308..9362c1aa9 100644 --- a/src/App.test.jsx +++ b/src/App.test.jsx @@ -1,23 +1,19 @@ -import React from 'react'; -import { Helmet } from 'react-helmet'; -import { shallow } from '@edx/react-unit-test-utils'; +import { render, screen, waitFor } from '@testing-library/react'; -import { useIntl } from '@edx/frontend-platform/i18n'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import { getConfig } from '@edx/frontend-platform'; import { RequestKeys } from 'data/constants/requests'; import { reduxHooks } from 'hooks'; -import Dashboard from 'containers/Dashboard'; -import LearnerDashboardHeader from 'containers/LearnerDashboardHeader'; -import AppWrapper from 'containers/WidgetContainers/AppWrapper'; import { App } from './App'; import messages from './messages'; -jest.mock('@edx/frontend-component-footer', () => ({ FooterSlot: 'FooterSlot' })); - -jest.mock('containers/Dashboard', () => 'Dashboard'); -jest.mock('containers/LearnerDashboardHeader', () => 'LearnerDashboardHeader'); -jest.mock('containers/WidgetContainers/AppWrapper', () => 'AppWrapper'); +jest.mock('@edx/frontend-component-footer', () => ({ + FooterSlot: jest.fn(() =>
FooterSlot
), +})); +jest.mock('containers/Dashboard', () => jest.fn(() =>
Dashboard
)); +jest.mock('containers/LearnerDashboardHeader', () => jest.fn(() =>
LearnerDashboardHeader
)); +jest.mock('containers/WidgetContainers/AppWrapper', () => jest.fn(({ children }) =>
{children}
)); jest.mock('data/redux', () => ({ selectors: 'redux.selectors', actions: 'redux.actions', @@ -36,113 +32,102 @@ jest.mock('@edx/frontend-platform', () => ({ getConfig: jest.fn(() => ({})), })); +jest.unmock('@openedx/paragon'); +jest.unmock('@edx/frontend-platform/i18n'); +jest.unmock('react'); + const loadData = jest.fn(); reduxHooks.useLoadData.mockReturnValue(loadData); -let el; - -const supportEmail = 'test-support-url'; +const supportEmail = 'test@support.com'; reduxHooks.usePlatformSettingsData.mockReturnValue({ supportEmail }); describe('App router component', () => { - const { formatMessage } = useIntl(); describe('component', () => { const runBasicTests = () => { - test('snapshot', () => { expect(el.snapshot).toMatchSnapshot(); }); - it('displays title in helmet component', () => { - const control = el.instance - .findByType(Helmet)[0] - .findByType('title')[0]; - expect(control.children[0].el).toEqual(formatMessage(messages.pageTitle)); + it('displays title in helmet component', async () => { + await waitFor(() => expect(document.title).toEqual(messages.pageTitle.defaultMessage)); }); it('displays learner dashboard header', () => { - expect(el.instance.findByType(LearnerDashboardHeader).length).toEqual(1); + const learnerDashboardHeader = screen.getByText('LearnerDashboardHeader'); + expect(learnerDashboardHeader).toBeInTheDocument(); }); it('wraps the header and main components in an AppWrapper widget container', () => { - const container = el.instance.findByType(AppWrapper)[0]; - expect(container.children[0].type).toEqual('LearnerDashboardHeader'); - expect(container.children[1].type).toEqual('main'); + const appWrapper = screen.getByText('LearnerDashboardHeader').parentElement; + expect(appWrapper).toHaveClass('AppWrapper'); + expect(appWrapper.children[1].id).toEqual('main'); + }); + it('displays footer slot', () => { + const footerSlot = screen.getByText('FooterSlot'); + expect(footerSlot).toBeInTheDocument(); }); }; describe('no network failure', () => { - beforeAll(() => { + beforeEach(() => { + jest.clearAllMocks(); reduxHooks.useRequestIsFailed.mockReturnValue(false); getConfig.mockReturnValue({}); - el = shallow(); + render(); }); runBasicTests(); it('loads dashboard', () => { - const main = el.instance.findByType('main')[0]; - expect(main.children.length).toEqual(1); - const dashboard = main.children[0].el; - expect(dashboard.type).toEqual('Dashboard'); - expect(dashboard).toEqual(shallow()); + const dashboard = screen.getByText('Dashboard'); + expect(dashboard).toBeInTheDocument(); }); }); describe('no network failure with optimizely url', () => { - beforeAll(() => { + beforeEach(() => { + jest.clearAllMocks(); reduxHooks.useRequestIsFailed.mockReturnValue(false); getConfig.mockReturnValue({ OPTIMIZELY_URL: 'fake.url' }); - el = shallow(); + render(); }); runBasicTests(); it('loads dashboard', () => { - const main = el.instance.findByType('main')[0]; - expect(main.children.length).toEqual(1); - const dashboard = main.children[0].el; - expect(dashboard.type).toEqual('Dashboard'); - expect(dashboard).toEqual(shallow()); + const dashboard = screen.getByText('Dashboard'); + expect(dashboard).toBeInTheDocument(); }); }); describe('no network failure with optimizely project id', () => { - beforeAll(() => { + beforeEach(() => { + jest.clearAllMocks(); reduxHooks.useRequestIsFailed.mockReturnValue(false); getConfig.mockReturnValue({ OPTIMIZELY_PROJECT_ID: 'fakeId' }); - el = shallow(); + render(); }); runBasicTests(); it('loads dashboard', () => { - const main = el.instance.findByType('main')[0]; - expect(main.children.length).toEqual(1); - const dashboard = main.children[0].el; - expect(dashboard.type).toEqual('Dashboard'); - expect(dashboard).toEqual(shallow()); + const dashboard = screen.getByText('Dashboard'); + expect(dashboard).toBeInTheDocument(); }); }); describe('initialize failure', () => { - beforeAll(() => { + beforeEach(() => { + jest.clearAllMocks(); reduxHooks.useRequestIsFailed.mockImplementation((key) => key === RequestKeys.initialize); getConfig.mockReturnValue({}); - el = shallow(); + render(); }); runBasicTests(); it('loads error page', () => { - const main = el.instance.findByType('main')[0]; - expect(main.children.length).toEqual(1); - const alert = main.children[0]; - expect(alert.type).toEqual('Alert'); - expect(alert.children.length).toEqual(1); - const errorPage = alert.children[0]; - expect(errorPage.type).toEqual('ErrorPage'); - expect(errorPage.props.message).toEqual(formatMessage(messages.errorMessage, { supportEmail })); + const alert = screen.getByRole('alert'); + expect(alert).toBeInTheDocument(); + const errorPage = screen.getByText('ErrorPage'); + expect(errorPage).toBeInTheDocument(); }); }); describe('refresh failure', () => { - beforeAll(() => { + beforeEach(() => { reduxHooks.useRequestIsFailed.mockImplementation((key) => key === RequestKeys.refreshList); getConfig.mockReturnValue({}); - el = shallow(); + render(); }); runBasicTests(); it('loads error page', () => { - const main = el.instance.findByType('main')[0]; - expect(main.children.length).toEqual(1); - const alert = main.children[0]; - expect(alert.type).toEqual('Alert'); - expect(alert.children.length).toEqual(1); - const errorPage = alert.children[0]; - expect(errorPage.type).toEqual('ErrorPage'); - expect(errorPage.props.message).toEqual(formatMessage(messages.errorMessage, { supportEmail })); + const alert = screen.getByRole('alert'); + expect(alert).toBeInTheDocument(); + const errorPage = screen.getByText('ErrorPage'); + expect(errorPage).toBeInTheDocument(); }); }); }); diff --git a/src/__snapshots__/App.test.jsx.snap b/src/__snapshots__/App.test.jsx.snap deleted file mode 100644 index cf067933e..000000000 --- a/src/__snapshots__/App.test.jsx.snap +++ /dev/null @@ -1,153 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`App router component component initialize failure snapshot 1`] = ` - - - - Learner Home - - - -
- - -
- - - -
-
- -
-
-`; - -exports[`App router component component no network failure snapshot 1`] = ` - - - - Learner Home - - - -
- - -
- -
-
- -
-
-`; - -exports[`App router component component no network failure with optimizely project id snapshot 1`] = ` - - - - Learner Home - - - -
- - -
- -
-
- -
-
-`; - -exports[`App router component component no network failure with optimizely url snapshot 1`] = ` - - - - Learner Home - - - -
- - -
- -
-
- -
-
-`; - -exports[`App router component component refresh failure snapshot 1`] = ` - - - - Learner Home - - - -
- - -
- - - -
-
- -
-
-`; diff --git a/src/containers/CourseCard/components/CourseCardActions/index.test.jsx b/src/containers/CourseCard/components/CourseCardActions/index.test.jsx index 329467238..201d452cb 100644 --- a/src/containers/CourseCard/components/CourseCardActions/index.test.jsx +++ b/src/containers/CourseCard/components/CourseCardActions/index.test.jsx @@ -1,13 +1,6 @@ -import { shallow } from '@edx/react-unit-test-utils'; - +import { render, screen } from '@testing-library/react'; import { reduxHooks } from 'hooks'; -import CourseCardActionSlot from 'plugin-slots/CourseCardActionSlot'; -import SelectSessionButton from './SelectSessionButton'; -import BeginCourseButton from './BeginCourseButton'; -import ResumeButton from './ResumeButton'; -import ViewCourseButton from './ViewCourseButton'; - import CourseCardActions from '.'; jest.mock('hooks', () => ({ @@ -19,16 +12,17 @@ jest.mock('hooks', () => ({ }, })); -jest.mock('plugin-slots/CourseCardActionSlot', () => 'CustomActionButton'); -jest.mock('./SelectSessionButton', () => 'SelectSessionButton'); -jest.mock('./ViewCourseButton', () => 'ViewCourseButton'); -jest.mock('./BeginCourseButton', () => 'BeginCourseButton'); -jest.mock('./ResumeButton', () => 'ResumeButton'); +jest.mock('plugin-slots/CourseCardActionSlot', () => jest.fn(() =>
CourseCardActionSlot
)); +jest.mock('./SelectSessionButton', () => jest.fn(() =>
SelectSessionButton
)); +jest.mock('./ViewCourseButton', () => jest.fn(() =>
ViewCourseButton
)); +jest.mock('./BeginCourseButton', () => jest.fn(() =>
BeginCourseButton
)); +jest.mock('./ResumeButton', () => jest.fn(() =>
ResumeButton
)); + +jest.unmock('@openedx/paragon'); const cardId = 'test-card-id'; const props = { cardId }; -let el; describe('CourseCardActions', () => { const mockHooks = ({ isEntitlement = false, @@ -44,13 +38,11 @@ describe('CourseCardActions', () => { reduxHooks.useCardEnrollmentData.mockReturnValueOnce({ isExecEd2UCourse, isVerified, hasStarted }); reduxHooks.useMasqueradeData.mockReturnValueOnce({ isMasquerading }); }; - const render = () => { - el = shallow(); - }; - describe('behavior', () => { + const renderComponent = () => render(); + describe('hooks', () => { it('initializes redux hooks', () => { mockHooks(); - render(); + renderComponent(); expect(reduxHooks.useCardEntitlementData).toHaveBeenCalledWith(cardId); expect(reduxHooks.useCardEnrollmentData).toHaveBeenCalledWith(cardId); expect(reduxHooks.useCardCourseRunData).toHaveBeenCalledWith(cardId); @@ -60,36 +52,44 @@ describe('CourseCardActions', () => { describe('entitlement course', () => { it('renders ViewCourseButton if fulfilled', () => { mockHooks({ isEntitlement: true, isFulfilled: true }); - render(); - expect(el.instance.findByType(ViewCourseButton)[0].props.cardId).toEqual(cardId); + renderComponent(); + const ViewCourseButton = screen.getByText('ViewCourseButton'); + expect(ViewCourseButton).toBeInTheDocument(); }); it('renders SelectSessionButton if not fulfilled', () => { mockHooks({ isEntitlement: true }); - render(); - expect(el.instance.findByType(SelectSessionButton)[0].props.cardId).toEqual(cardId); + renderComponent(); + const SelectSessionButton = screen.getByText('SelectSessionButton'); + expect(SelectSessionButton).toBeInTheDocument(); }); }); describe('not entitlement, verified, or exec ed', () => { it('renders CourseCardActionSlot and ViewCourseButton for archived courses', () => { mockHooks({ isArchived: true }); - render(); - expect(el.instance.findByType(CourseCardActionSlot)[0].props.cardId).toEqual(cardId); - expect(el.instance.findByType(ViewCourseButton)[0].props.cardId).toEqual(cardId); + renderComponent(); + const CourseCardActionSlot = screen.getByText('CourseCardActionSlot'); + expect(CourseCardActionSlot).toBeInTheDocument(); + const ViewCourseButton = screen.getByText('ViewCourseButton'); + expect(ViewCourseButton).toBeInTheDocument(); }); describe('unstarted courses', () => { it('renders CourseCardActionSlot and BeginCourseButton', () => { mockHooks(); - render(); - expect(el.instance.findByType(CourseCardActionSlot)[0].props.cardId).toEqual(cardId); - expect(el.instance.findByType(BeginCourseButton)[0].props.cardId).toEqual(cardId); + renderComponent(); + const CourseCardActionSlot = screen.getByText('CourseCardActionSlot'); + expect(CourseCardActionSlot).toBeInTheDocument(); + const BeginCourseButton = screen.getByText('BeginCourseButton'); + expect(BeginCourseButton).toBeInTheDocument(); }); }); describe('active courses (started, and not archived)', () => { it('renders CourseCardActionSlot and ResumeButton', () => { mockHooks({ hasStarted: true }); - render(); - expect(el.instance.findByType(CourseCardActionSlot)[0].props.cardId).toEqual(cardId); - expect(el.instance.findByType(ResumeButton)[0].props.cardId).toEqual(cardId); + renderComponent(); + const CourseCardActionSlot = screen.getByText('CourseCardActionSlot'); + expect(CourseCardActionSlot).toBeInTheDocument(); + const ResumeButton = screen.getByText('ResumeButton'); + expect(ResumeButton).toBeInTheDocument(); }); }); }); diff --git a/src/containers/CourseCard/components/CourseCardMenu/SocialShareMenu.test.jsx b/src/containers/CourseCard/components/CourseCardMenu/SocialShareMenu.test.jsx index fbcb8c21e..e05ddcc8e 100644 --- a/src/containers/CourseCard/components/CourseCardMenu/SocialShareMenu.test.jsx +++ b/src/containers/CourseCard/components/CourseCardMenu/SocialShareMenu.test.jsx @@ -1,32 +1,19 @@ import { when } from 'jest-when'; -import * as ReactShare from 'react-share'; -import { useIntl } from '@edx/frontend-platform/i18n'; -import { formatMessage, shallow } from '@edx/react-unit-test-utils'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; +import { render, screen } from '@testing-library/react'; import track from 'tracking'; import { reduxHooks } from 'hooks'; import { useEmailSettings } from './hooks'; -import SocialShareMenu, { testIds } from './SocialShareMenu'; +import SocialShareMenu from './SocialShareMenu'; import messages from './messages'; -jest.mock('react-share', () => ({ - FacebookShareButton: () => 'FacebookShareButton', - TwitterShareButton: () => 'TwitterShareButton', -})); - jest.mock('tracking', () => ({ socialShare: 'test-social-share-key', })); -jest.mock('@edx/frontend-platform/i18n', () => ({ - ...jest.requireActual('@edx/frontend-platform/i18n'), - useIntl: jest.fn().mockReturnValue({ - formatMessage: jest.requireActual('@edx/react-unit-test-utils').formatMessage, - }), -})); - jest.mock('hooks', () => ({ reduxHooks: { useMasqueradeData: jest.fn(), @@ -40,6 +27,10 @@ jest.mock('./hooks', () => ({ useEmailSettings: jest.fn(), })); +jest.unmock('@edx/frontend-platform/i18n'); +jest.unmock('@openedx/paragon'); +jest.unmock('react'); + const props = { cardId: 'test-card-id', emailSettings: { show: jest.fn() }, @@ -47,9 +38,9 @@ const props = { const mockHook = (fn, returnValue, options = {}) => { if (options.isCardHook) { - when(fn).calledWith(props.cardId).mockReturnValueOnce(returnValue); + when(fn).calledWith(props.cardId).mockReturnValue(returnValue); } else { - when(fn).calledWith().mockReturnValueOnce(returnValue); + when(fn).calledWith().mockReturnValue(returnValue); } }; @@ -89,19 +80,13 @@ const mockHooks = (returnVals = {}) => { ); }; -let el; -const render = () => { - el = shallow(); -}; +const renderComponent = () => render(); describe('SocialShareMenu', () => { describe('behavior', () => { beforeEach(() => { mockHooks(); - render(); - }); - it('initializes intl hook', () => { - expect(useIntl).toHaveBeenCalledWith(); + renderComponent(); }); it('initializes local hooks', () => { when(useEmailSettings).expectCalledWith(); @@ -118,53 +103,43 @@ describe('SocialShareMenu', () => { describe('render', () => { it('renders null if exec ed course', () => { mockHooks({ isExecEd2UCourse: true }); - render(); - expect(el.isEmptyRender()).toEqual(true); + renderComponent(); + const emailSettingsButton = screen.queryByRole('button', { name: messages.emailSettings.defaultMessage }); + expect(emailSettingsButton).toBeNull(); + const facebookShareButton = screen.queryByRole('button', { name: 'facebook' }); + expect(facebookShareButton).toBeNull(); + const twitterShareButton = screen.queryByRole('button', { name: 'twitter' }); + expect(twitterShareButton).toBeNull(); }); const testEmailSettingsDropdown = (isMasquerading = false) => { describe('email settings dropdown', () => { - const loadToggle = () => el.instance.findByTestId(testIds.emailSettingsModalToggle)[0]; it('renders', () => { - expect(el.instance.findByTestId(testIds.emailSettingsModalToggle).length).toEqual(1); + const emailSettingsButton = screen.getByRole('button', { name: messages.emailSettings.defaultMessage }); + expect(emailSettingsButton).toBeInTheDocument(); }); if (isMasquerading) { it('is disabled', () => { - expect(loadToggle().props.disabled).toEqual(true); + const emailSettingsButton = screen.getByRole('button', { name: messages.emailSettings.defaultMessage }); + expect(emailSettingsButton).toHaveAttribute('aria-disabled', 'true'); }); } else { it('is enabled', () => { - expect(loadToggle().props.disabled).toEqual(false); + const emailSettingsButton = screen.getByRole('button', { name: messages.emailSettings.defaultMessage }); + expect(emailSettingsButton).toBeEnabled(); }); } - test('show email settings modal on click', () => { - expect(loadToggle().props.onClick).toEqual(props.emailSettings.show); - }); }); }; const testFacebookShareButton = () => { - test('renders facebook share button with courseName and brand', () => { - const button = el.instance.findByType(ReactShare.FacebookShareButton)[0]; - expect(button.props.url).toEqual(socialShare.facebook.shareUrl); - expect(button.props.onClick).toEqual( - reduxHooks.useTrackCourseEvent(track.socialShare, props.cardId, 'facebook'), - ); - expect(button.props.title).toEqual(formatMessage(messages.shareQuote, { - courseName, - socialBrand: socialShare.facebook.socialBrand, - })); + it('renders facebook share button', () => { + const facebookShareButton = screen.getByRole('button', { name: 'facebook' }); + expect(facebookShareButton).toBeInTheDocument(); }); }; const testTwitterShareButton = () => { - test('renders twitter share button with courseName and brand', () => { - const button = el.instance.findByType(ReactShare.TwitterShareButton)[0]; - expect(button.props.url).toEqual(socialShare.twitter.shareUrl); - expect(button.props.onClick).toEqual( - reduxHooks.useTrackCourseEvent(track.socialShare, props.cardId, 'twitter'), - ); - expect(button.props.title).toEqual(formatMessage(messages.shareQuote, { - courseName, - socialBrand: socialShare.twitter.socialBrand, - })); + it('renders twitter share button', () => { + const twitterShareButton = screen.getByRole('button', { name: 'twitter' }); + expect(twitterShareButton).toBeInTheDocument(); }); }; describe('all enabled', () => { @@ -174,19 +149,7 @@ describe('SocialShareMenu', () => { twitter: { isEnabled: true }, isEmailEnabled: true, }); - render(); - }); - describe('email settings dropdown', () => { - const loadToggle = () => el.instance.findByTestId(testIds.emailSettingsModalToggle)[0]; - it('renders', () => { - expect(el.instance.findByTestId(testIds.emailSettingsModalToggle).length).toEqual(1); - }); - it('is enabled', () => { - expect(loadToggle().props.disabled).toEqual(false); - }); - test('show email settings modal on click', () => { - expect(loadToggle().props.onClick).toEqual(props.emailSettings.show); - }); + renderComponent(); }); testEmailSettingsDropdown(); testFacebookShareButton(); @@ -194,42 +157,49 @@ describe('SocialShareMenu', () => { }); describe('only email enabled', () => { beforeEach(() => { + jest.clearAllMocks(); mockHooks({ isEmailEnabled: true }); - render(); + renderComponent(); }); testEmailSettingsDropdown(); it('does not render facebook or twitter controls', () => { - expect(el.instance.findByType(ReactShare.FacebookShareButton).length).toEqual(0); - expect(el.instance.findByType(ReactShare.TwitterShareButton).length).toEqual(0); + const facebookShareButton = screen.queryByRole('button', { name: 'facebook' }); + expect(facebookShareButton).toBeNull(); + const twitterShareButton = screen.queryByRole('button', { name: 'twitter' }); + expect(twitterShareButton).toBeNull(); }); - describe('masquerading', () => { - beforeEach(() => { - mockHooks({ isEmailEnabled: true, isMasquerading: true }); - render(); - }); - testEmailSettingsDropdown(true); + }); + describe('masquerading', () => { + beforeEach(() => { + mockHooks({ isEmailEnabled: true, isMasquerading: true }); + renderComponent(); }); + testEmailSettingsDropdown(true); }); describe('only facebook enabled', () => { beforeEach(() => { mockHooks({ facebook: { isEnabled: true } }); - render(); + renderComponent(); }); testFacebookShareButton(); it('does not render email or twitter controls', () => { - expect(el.instance.findByTestId(testIds.emailSettingsModalToggle).length).toEqual(0); - expect(el.instance.findByType(ReactShare.TwitterShareButton).length).toEqual(0); + const emailSettingsButton = screen.queryByRole('button', { name: messages.emailSettings.defaultMessage }); + expect(emailSettingsButton).toBeNull(); + const twitterShareButton = screen.queryByRole('button', { name: 'twitter' }); + expect(twitterShareButton).toBeNull(); }); }); describe('only twitter enabled', () => { beforeEach(() => { mockHooks({ twitter: { isEnabled: true } }); - render(); + renderComponent(); }); testTwitterShareButton(); it('does not render email or facebook controls', () => { - expect(el.instance.findByTestId(testIds.emailSettingsModalToggle).length).toEqual(0); - expect(el.instance.findByType(ReactShare.FacebookShareButton).length).toEqual(0); + const emailSettingsButton = screen.queryByRole('button', { name: messages.emailSettings.defaultMessage }); + expect(emailSettingsButton).toBeNull(); + const facebookShareButton = screen.queryByRole('button', { name: 'facebook' }); + expect(facebookShareButton).toBeNull(); }); }); }); diff --git a/src/widgets/LookingForChallengeWidget/__snapshots__/index.test.jsx.snap b/src/widgets/LookingForChallengeWidget/__snapshots__/index.test.jsx.snap deleted file mode 100644 index 1400cc896..000000000 --- a/src/widgets/LookingForChallengeWidget/__snapshots__/index.test.jsx.snap +++ /dev/null @@ -1,45 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`LookingForChallengeWidget snapshots default 1`] = ` - - - -

- Looking for a new challenge? -

-
- - , - } - } - /> - -
-
-
-`; diff --git a/src/widgets/LookingForChallengeWidget/index.test.jsx b/src/widgets/LookingForChallengeWidget/index.test.jsx index db6c39786..45d412e7b 100644 --- a/src/widgets/LookingForChallengeWidget/index.test.jsx +++ b/src/widgets/LookingForChallengeWidget/index.test.jsx @@ -1,11 +1,14 @@ -import { shallow } from '@edx/react-unit-test-utils'; - +import { render, screen } from '@testing-library/react'; +import { IntlProvider } from '@edx/frontend-platform/i18n'; import LookingForChallengeWidget from '.'; +import messages from './messages'; + +const courseSearchUrl = 'http://localhost:18000/course-search-url'; jest.mock('hooks', () => ({ reduxHooks: { usePlatformSettingsData: () => ({ - courseSearchUrl: 'http://localhost:18000/course-search-url', + courseSearchUrl, }), }, })); @@ -14,11 +17,27 @@ jest.mock('./track', () => ({ findCoursesWidgetClicked: (href) => jest.fn().mockName(`track.findCoursesWidgetClicked('${href}')`), })); +jest.unmock('@openedx/paragon'); +jest.unmock('@openedx/paragon/icons'); +jest.unmock('@edx/frontend-platform/i18n'); +jest.unmock('react'); + describe('LookingForChallengeWidget', () => { - describe('snapshots', () => { - test('default', () => { - const wrapper = shallow(); - expect(wrapper.snapshot).toMatchSnapshot(); + describe('render', () => { + it('card image', () => { + render(); + const image = screen.getByRole('img', { alt: 'course side widget' }); + expect(image).toBeInTheDocument(); + }); + it('prompt', () => { + render(); + const prompt = screen.getByText(messages.lookingForChallengePrompt.defaultMessage); + expect(prompt).toBeInTheDocument(); + }); + it('hyperlink', () => { + render(); + const link = screen.getByRole('link', { href: courseSearchUrl }); + expect(link).toBeInTheDocument(); }); }); });