diff --git a/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/EligibleContent.test.jsx b/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/EligibleContent.test.jsx
index bbdfd16..fb75912 100644
--- a/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/EligibleContent.test.jsx
+++ b/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/EligibleContent.test.jsx
@@ -1,8 +1,8 @@
-import React from 'react';
-import { shallow } from '@edx/react-unit-test-utils';
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import { IntlProvider } from '@edx/frontend-platform/i18n';
import { reduxHooks } from 'hooks';
-import { formatMessage } from 'testUtils';
import track from 'tracking';
import messages from './messages';
@@ -14,15 +14,16 @@ jest.mock('hooks', () => ({
useCardCourseRunData: jest.fn(),
},
}));
-jest.mock('./components/CreditContent', () => 'CreditContent');
+
jest.mock('tracking', () => ({
credit: {
- purchase: (...args) => ({ trackCredit: args }),
+ purchase: jest.fn(),
},
}));
-let el;
-let component;
+jest.unmock('@edx/frontend-platform/i18n');
+jest.unmock('@openedx/paragon');
+jest.unmock('react');
const cardId = 'test-card-id';
const courseId = 'test-course-id';
@@ -32,50 +33,45 @@ const credit = {
reduxHooks.useCardCreditData.mockReturnValue(credit);
reduxHooks.useCardCourseRunData.mockReturnValue({ courseId });
-const render = () => {
- el = shallow();
-};
-const loadComponent = () => {
- component = el.instance.findByType('CreditContent');
-};
+const renderEligibleContent = () => render();
+
describe('EligibleContent component', () => {
- beforeEach(() => {
- render();
- });
- describe('behavior', () => {
+ describe('hooks', () => {
it('initializes credit data with cardId', () => {
+ renderEligibleContent();
expect(reduxHooks.useCardCreditData).toHaveBeenCalledWith(cardId);
});
it('initializes course run data with cardId', () => {
+ renderEligibleContent();
expect(reduxHooks.useCardCourseRunData).toHaveBeenCalledWith(cardId);
});
});
- describe('render', () => {
+ describe('behavior', () => {
describe('rendered CreditContent component', () => {
- beforeEach(() => {
- loadComponent();
+ it('action message is formatted getCredit message', () => {
+ renderEligibleContent();
+ const button = screen.getByRole('button', { name: messages.getCredit.defaultMessage });
+ expect(button).toBeInTheDocument();
});
- test('action.onClick sends credit purchase track event', () => {
- expect(component[0].props.action.onClick).toEqual(
- track.credit.purchase(courseId),
- );
+ it('onClick sends credit purchase track event', async () => {
+ const user = userEvent.setup();
+ renderEligibleContent();
+ const button = screen.getByRole('button', { name: messages.getCredit.defaultMessage });
+ await user.click(button);
+ expect(track.credit.purchase).toHaveBeenCalledWith(courseId);
});
- test('action.message is formatted getCredit message', () => {
- expect(component[0].props.action.message).toEqual(formatMessage(messages.getCredit));
+ it('message is formatted eligible message if provider', () => {
+ renderEligibleContent();
+ const eligibleMessage = screen.getByTestId('credit-msg');
+ expect(eligibleMessage).toBeInTheDocument();
+ expect(eligibleMessage).toHaveTextContent(credit.providerName);
});
- test('message is formatted eligible message if no provider', () => {
- reduxHooks.useCardCreditData.mockReturnValueOnce({});
- render();
- loadComponent();
- expect(component[0].props.message).toEqual(formatMessage(
- messages.eligible,
- { getCredit: ({formatMessage(messages.getCredit)}) },
- ));
- });
- test('message is formatted eligible message if provider', () => {
- expect(component[0].props.message).toEqual(
- formatMessage(messages.eligibleFromProvider, { providerName: credit.providerName }),
- );
+ it('message is formatted eligible message if no provider', () => {
+ reduxHooks.useCardCreditData.mockReturnValue({});
+ renderEligibleContent();
+ const eligibleMessage = screen.getByTestId('credit-msg');
+ expect(eligibleMessage).toBeInTheDocument();
+ expect(eligibleMessage).toHaveTextContent(messages.getCredit.defaultMessage);
});
});
});
diff --git a/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/MustRequestContent.test.jsx b/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/MustRequestContent.test.jsx
index 9eb4200..7509316 100644
--- a/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/MustRequestContent.test.jsx
+++ b/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/MustRequestContent.test.jsx
@@ -1,73 +1,107 @@
-import React from 'react';
-import { shallow } from '@edx/react-unit-test-utils';
-
-import { formatMessage } from 'testUtils';
+import { render, screen } from '@testing-library/react';
+import { IntlProvider } from '@edx/frontend-platform/i18n';
+import userEvent from '@testing-library/user-event';
import { reduxHooks } from 'hooks';
import messages from './messages';
import hooks from './hooks';
-import ProviderLink from './components/ProviderLink';
import MustRequestContent from './MustRequestContent';
jest.mock('./hooks', () => ({
useCreditRequestData: jest.fn(),
}));
-jest.mock('hooks', () => ({
- reduxHooks: { useMasqueradeData: jest.fn() },
-}));
-jest.mock('./components/CreditContent', () => 'CreditContent');
-jest.mock('./components/ProviderLink', () => 'ProviderLink');
-let el;
-let component;
+jest.mock('hooks', () => ({
+ reduxHooks: {
+ useMasqueradeData: jest.fn(),
+ useCardCreditData: jest.fn(),
+ },
+}));
+
+jest.unmock('@openedx/paragon');
+jest.unmock('@edx/frontend-platform/i18n');
+jest.unmock('react');
const cardId = 'test-card-id';
-const requestData = { test: 'requestData' };
-const createCreditRequest = jest.fn().mockName('createCreditRequest');
-hooks.useCreditRequestData.mockReturnValue({
- requestData,
- createCreditRequest,
-});
-reduxHooks.useMasqueradeData.mockReturnValue({ isMasquerading: false });
-
-const render = () => {
- el = shallow();
+const requestData = {
+ url: 'test-request-data-url',
+ parameters: {
+ key1: 'val1',
+ key2: 'val2',
+ key3: 'val3',
+ },
};
+const providerName = 'test-credit-provider-name';
+const providerStatusUrl = 'test-credit-provider-status-url';
+const createCreditRequest = jest.fn().mockName('createCreditRequest');
+
+const renderMustRequestContent = () => render(
+
+
+ ,
+);
+
describe('MustRequestContent component', () => {
beforeEach(() => {
- render();
+ jest.clearAllMocks();
+ hooks.useCreditRequestData.mockReturnValue({
+ requestData,
+ createCreditRequest,
+ });
+ reduxHooks.useMasqueradeData.mockReturnValue({ isMasquerading: false });
+ reduxHooks.useCardCreditData.mockReturnValue({
+ providerName,
+ providerStatusUrl,
+ });
});
- describe('behavior', () => {
+
+ describe('hooks', () => {
it('initializes credit request data with cardId', () => {
+ renderMustRequestContent();
expect(hooks.useCreditRequestData).toHaveBeenCalledWith(cardId);
});
});
- describe('render', () => {
- describe('rendered CreditContent component', () => {
+
+ describe('behavior', () => {
+ describe('rendered content', () => {
beforeEach(() => {
- component = el.instance.findByType('CreditContent');
+ renderMustRequestContent();
});
- test('action.onClick calls createCreditRequest from useCreditRequestData hook', () => {
- expect(component[0].props.action.onClick).toEqual(createCreditRequest);
+
+ it('calls createCreditRequest when request credit button is clicked', async () => {
+ const user = userEvent.setup();
+ const button = screen.getByRole('button', { name: /request credit/i });
+ await user.click(button);
+ expect(createCreditRequest).toHaveBeenCalled();
});
- test('action.message is formatted requestCredit message', () => {
- expect(component[0].props.action.message).toEqual(
- formatMessage(messages.requestCredit),
- );
+
+ it('shows request credit button that is enabled', () => {
+ const button = screen.getByRole('button', { name: /request credit/i });
+ expect(button).toBeEnabled();
});
- test('action.disabled is false', () => {
- expect(component[0].props.action.disabled).toEqual(false);
+
+ it('displays must request message with provider link', () => {
+ expect(screen.getByTestId('credit-msg')).toHaveTextContent(/request credit/i);
});
- test('message is formatted mustRequest message', () => {
- expect(component[0].props.message).toEqual(
- formatMessage(messages.mustRequest, {
- linkToProviderSite: ,
- requestCredit: {formatMessage(messages.requestCredit)},
- }),
- );
+
+ it('renders credit request form with correct data', () => {
+ const { container } = renderMustRequestContent();
+ const form = container.querySelector('form');
+ expect(form).toBeInTheDocument();
+ expect(form).toHaveAttribute('action', requestData.url);
});
- test('requestData drawn from useCreditRequestData hook', () => {
- expect(component[0].props.requestData).toEqual(requestData);
+ });
+
+ describe('when masquerading', () => {
+ beforeEach(() => {
+ reduxHooks.useMasqueradeData.mockReturnValue({ isMasquerading: true });
+ renderMustRequestContent();
+ });
+
+ it('disables the request credit button', () => {
+ const button = screen.getByRole('button', { name: /request credit/i });
+ expect(button).toHaveClass('disabled');
+ expect(button).toHaveAttribute('aria-disabled', 'true');
});
});
});
diff --git a/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/PendingContent.test.jsx b/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/PendingContent.test.jsx
index 0711412..4edefa2 100644
--- a/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/PendingContent.test.jsx
+++ b/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/PendingContent.test.jsx
@@ -1,7 +1,6 @@
-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 messages from './messages';
@@ -10,11 +9,10 @@ import PendingContent from './PendingContent';
jest.mock('hooks', () => ({
reduxHooks: { useCardCreditData: jest.fn(), useMasqueradeData: jest.fn() },
}));
-jest.mock('./components/CreditContent', () => 'CreditContent');
-jest.mock('./components/ProviderLink', () => 'ProviderLink');
-let el;
-let component;
+jest.unmock('@edx/frontend-platform/i18n');
+jest.unmock('@openedx/paragon');
+jest.unmock('react');
const cardId = 'test-card-id';
const providerName = 'test-credit-provider-name';
@@ -25,38 +23,48 @@ reduxHooks.useCardCreditData.mockReturnValue({
});
reduxHooks.useMasqueradeData.mockReturnValue({ isMasquerading: false });
-const render = () => {
- el = shallow();
-};
+const renderPendingContent = () => render(
+
+
+ ,
+);
describe('PendingContent component', () => {
- beforeEach(() => {
- render();
- });
- describe('behavior', () => {
+ describe('hooks', () => {
it('initializes card credit data with cardId', () => {
+ renderPendingContent();
expect(reduxHooks.useCardCreditData).toHaveBeenCalledWith(cardId);
});
});
- describe('render', () => {
+ describe('behavior', () => {
describe('rendered CreditContent component', () => {
- beforeEach(() => {
- component = el.instance.findByType('CreditContent');
+ it('action message is formatted requestCredit message', () => {
+ renderPendingContent();
+ const button = screen.getByRole('link', { name: messages.viewDetails.defaultMessage });
+ expect(button).toBeInTheDocument();
});
- test('action.href will go to provider status site', () => {
- expect(component[0].props.action.href).toEqual(providerStatusUrl);
+ it('action href will go to provider status site', () => {
+ renderPendingContent();
+ const button = screen.getByRole('link', { name: messages.viewDetails.defaultMessage });
+ expect(button).toHaveAttribute('href', providerStatusUrl);
});
- test('action.message is formatted requestCredit message', () => {
- expect(component[0].props.action.message).toEqual(
- formatMessage(messages.viewDetails),
- );
+ it('action.disabled is false', () => {
+ renderPendingContent();
+ const button = screen.getByRole('link', { name: messages.viewDetails.defaultMessage });
+ expect(button).not.toHaveClass('disabled');
});
- test('action.disabled is false', () => {
- expect(component[0].props.action.disabled).toEqual(false);
+ it('message is formatted pending message with provider name', () => {
+ renderPendingContent();
+ const component = screen.getByTestId('credit-msg');
+ expect(component).toBeInTheDocument();
+ expect(component).toHaveTextContent(`${providerName} has received`);
});
- test('message is formatted pending message', () => {
- expect(component[0].props.message).toEqual(
- formatMessage(messages.received, { providerName }),
- );
+ describe('when masqueradeData is true', () => {
+ it('disables the view details button', () => {
+ reduxHooks.useMasqueradeData.mockReturnValue({ isMasquerading: true });
+ renderPendingContent();
+ const button = screen.getByRole('link', { name: messages.viewDetails.defaultMessage });
+ expect(button).toHaveClass('disabled');
+ });
});
});
});
diff --git a/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/RejectedContent.test.jsx b/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/RejectedContent.test.jsx
index b9aea8f..b61a6e4 100644
--- a/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/RejectedContent.test.jsx
+++ b/src/containers/CourseCard/components/CourseCardBanners/CreditBanner/views/RejectedContent.test.jsx
@@ -1,10 +1,7 @@
-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 messages from './messages';
-import ProviderLink from './components/ProviderLink';
import RejectedContent from './RejectedContent';
jest.mock('hooks', () => ({
@@ -12,8 +9,10 @@ jest.mock('hooks', () => ({
useCardCreditData: jest.fn(),
},
}));
-jest.mock('./components/CreditContent', () => 'CreditContent');
-jest.mock('./components/ProviderLink', () => 'ProviderLink');
+
+jest.unmock('@openedx/paragon');
+jest.unmock('@edx/frontend-platform/i18n');
+jest.unmock('react');
const cardId = 'test-card-id';
const credit = {
@@ -22,32 +21,27 @@ const credit = {
};
reduxHooks.useCardCreditData.mockReturnValue(credit);
-let el;
-let component;
-const render = () => { el = shallow(); };
-const loadComponent = () => { component = el.instance.findByType('CreditContent'); };
+const renderRejectedContent = () => render();
describe('RejectedContent component', () => {
- beforeEach(render);
- describe('behavior', () => {
+ describe('hooks', () => {
it('initializes credit data with cardId', () => {
+ renderRejectedContent();
expect(reduxHooks.useCardCreditData).toHaveBeenCalledWith(cardId);
});
});
describe('render', () => {
describe('rendered CreditContent component', () => {
- beforeAll(loadComponent);
- test('no action is passed', () => {
- expect(component[0].props.action).toEqual(undefined);
+ it('no action is passed', () => {
+ renderRejectedContent();
+ const action = screen.queryByTestId('action-row-btn');
+ expect(action).not.toBeInTheDocument();
});
- test('message is formatted rejected message', () => {
- expect(component[0].props.message).toEqual(formatMessage(
- messages.rejected,
- {
- linkToProviderSite: ,
- providerName: credit.providerName,
- },
- ));
+ it('message is formatted rejected message', () => {
+ renderRejectedContent();
+ const message = screen.getByTestId('credit-msg');
+ expect(message).toBeInTheDocument();
+ expect(message).toHaveTextContent(`${credit.providerName} did not approve your request for course credit.`);
});
});
});
diff --git a/src/plugin-slots/WidgetSidebarSlot/__snapshots__/index.test.jsx.snap b/src/plugin-slots/WidgetSidebarSlot/__snapshots__/index.test.jsx.snap
deleted file mode 100644
index 38ac325..0000000
--- a/src/plugin-slots/WidgetSidebarSlot/__snapshots__/index.test.jsx.snap
+++ /dev/null
@@ -1,14 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`WidgetSidebar snapshots 1`] = `
-
-`;
diff --git a/src/plugin-slots/WidgetSidebarSlot/index.test.jsx b/src/plugin-slots/WidgetSidebarSlot/index.test.jsx
index 591ddcc..e000426 100644
--- a/src/plugin-slots/WidgetSidebarSlot/index.test.jsx
+++ b/src/plugin-slots/WidgetSidebarSlot/index.test.jsx
@@ -1,18 +1,26 @@
-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 WidgetSidebarSlot from '.';
-jest.mock('widgets/LookingForChallengeWidget', () => 'LookingForChallengeWidget');
+jest.unmock('react');
+jest.unmock('@edx/frontend-platform/i18n');
+jest.unmock('@openedx/paragon');
-jest.mock('@openedx/frontend-plugin-framework', () => ({
- PluginSlot: 'PluginSlot',
+jest.mock('hooks', () => ({
+ reduxHooks: {
+ usePlatformSettingsData: jest.fn(),
+ },
}));
-describe('WidgetSidebar', () => {
- beforeEach(() => jest.resetAllMocks());
+const courseSearchUrl = 'mock-url';
- test('snapshots', () => {
- const wrapper = shallow();
- expect(wrapper.snapshot).toMatchSnapshot();
+describe('WidgetSidebar', () => {
+ it('renders PluginSlot with correct children', () => {
+ reduxHooks.usePlatformSettingsData.mockReturnValueOnce({ courseSearchUrl });
+ render();
+ const pluginSlot = screen.getByText('Looking for a new challenge?');
+ expect(pluginSlot).toBeDefined();
});
});