test: Deprecate react-unit-test-utils 6/9 (#494)

* test: deprecate shallow

* test: remove debug
This commit is contained in:
Diana Villalvazo
2025-09-03 12:32:35 -06:00
committed by GitHub
parent 2456251790
commit a5aad38cff
12 changed files with 186 additions and 460 deletions

View File

@@ -1,11 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ReasonInput component render snapshot 1`] = `
<Form.Control
data-testid="reason-input-control"
name="reasonForChange"
onChange={[MockFunction hook.onChange]}
type="text"
value="test-value"
/>
`;

View File

@@ -1,37 +1,34 @@
import React from 'react'; import { render, screen } from '@testing-library/react';
import { shallow } from '@edx/react-unit-test-utils';
import { Form } from '@openedx/paragon';
import useReasonInputData from './hooks'; import useReasonInputData from './hooks';
import ReasonInput from '.'; import ReasonInput from '.';
jest.mock('./hooks', () => jest.fn()); jest.mock('./hooks', () => jest.fn());
jest.unmock('@openedx/paragon');
jest.unmock('react');
const hookProps = { const hookProps = {
ref: 'reason-input-ref', ref: jest.fn().mockName('hook.ref'),
onChange: jest.fn().mockName('hook.onChange'), onChange: jest.fn().mockName('hook.onChange'),
value: 'test-value', value: 'test-value',
}; };
useReasonInputData.mockReturnValue(hookProps); useReasonInputData.mockReturnValue(hookProps);
let el;
describe('ReasonInput component', () => { describe('ReasonInput component', () => {
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks(); jest.clearAllMocks();
el = shallow(<ReasonInput />); render(<ReasonInput />);
}); });
describe('behavior', () => { describe('behavior', () => {
it('initializes hook data', () => { it('initializes hook data', () => {
expect(useReasonInputData).toHaveBeenCalled(); expect(useReasonInputData).toHaveBeenCalled();
}); });
}); });
describe('render', () => { describe('renders', () => {
test('snapshot', () => { it('input correctly', () => {
expect(el.snapshot).toMatchSnapshot(); expect(screen.getByRole('textbox')).toBeInTheDocument();
const control = el.instance.findByType(Form.Control)[0]; expect(screen.getByRole('textbox')).toHaveValue(hookProps.value);
expect(control.props.value).toEqual(hookProps.value);
expect(control.props.onChange).toEqual(hookProps.onChange);
}); });
}); });
}); });

View File

@@ -1,25 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`OverrideTable component render snapshot 1`] = `
<DataTable
columns="test-columns"
data={
[
{
"test": "data",
},
{
"andOther": "test-data",
},
{
"adjustedGrade": <AdjustedGradeInput />,
"date": {
"formatted": 2000-01-01T00:00:00.000Z,
},
"reason": <ReasonInput />,
},
]
}
itemCount={3}
/>
`;

View File

@@ -1,65 +1,65 @@
import React from 'react'; 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 { DataTable } from '@openedx/paragon';
import { formatDateForDisplay } from 'utils';
import AdjustedGradeInput from './AdjustedGradeInput';
import ReasonInput from './ReasonInput';
import useOverrideTableData from './hooks'; import useOverrideTableData from './hooks';
import OverrideTable from '.'; import OverrideTable from '.';
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
jest.mock('utils', () => ({ jest.mock('utils', () => ({
...jest.requireActual('utils'),
formatDateForDisplay: (date) => ({ formatted: date }), formatDateForDisplay: (date) => ({ formatted: date }),
})); }));
jest.mock('./hooks', () => jest.fn()); jest.mock('./hooks', () => jest.fn());
jest.mock('./AdjustedGradeInput', () => 'AdjustedGradeInput');
jest.mock('./ReasonInput', () => 'ReasonInput');
const hookProps = { const hookProps = {
hide: false, hide: false,
data: [ data: [
{ test: 'data' }, { filename: 'data' },
{ andOther: 'test-data' }, { resultsSummary: 'test-data' },
], ],
columns: 'test-columns', columns: [{
Header: 'Gradebook',
accessor: 'filename',
},
{
Header: 'Download Summary',
accessor: 'resultsSummary',
}],
}; };
useOverrideTableData.mockReturnValue(hookProps);
let el;
describe('OverrideTable component', () => { describe('OverrideTable component', () => {
beforeEach(() => { beforeEach(() => {
jest jest
.clearAllMocks() .clearAllMocks()
.useFakeTimers('modern') .useFakeTimers('modern')
.setSystemTime(new Date('2000-01-01').getTime()); .setSystemTime(new Date('2000-01-01').getTime());
el = shallow(<OverrideTable />);
}); });
describe('behavior', () => { describe('hooks', () => {
it('initializes hook data', () => { it('initializes hook data', () => {
useOverrideTableData.mockReturnValue(hookProps);
render(<IntlProvider locale="en"><OverrideTable /></IntlProvider>);
expect(useOverrideTableData).toHaveBeenCalled(); expect(useOverrideTableData).toHaveBeenCalled();
}); });
}); });
describe('render', () => { describe('behavior', () => {
test('null render if hide', () => { it('null render if hide', () => {
useOverrideTableData.mockReturnValueOnce({ ...hookProps, hide: true }); useOverrideTableData.mockReturnValue({ ...hookProps, hide: true });
el = shallow(<OverrideTable />); render(<IntlProvider locale="en"><OverrideTable /></IntlProvider>);
expect(el.isEmptyRender()).toEqual(true); expect(screen.queryByRole('table')).toBeNull();
}); });
test('snapshot', () => { it('renders table with correct data', () => {
expect(el.snapshot).toMatchSnapshot(); useOverrideTableData.mockReturnValue(hookProps);
const table = el.instance.findByType(DataTable)[0]; render(<IntlProvider locale="en"><OverrideTable /></IntlProvider>);
expect(table.props.columns).toEqual(hookProps.columns); const table = screen.getByRole('table');
const data = [...table.props.data]; expect(table).toBeInTheDocument();
const inputRow = data.pop(); expect(screen.getByText(hookProps.columns[0].Header)).toBeInTheDocument();
const formattedDate = formatDateForDisplay(new Date()); expect(screen.getByText(hookProps.columns[1].Header)).toBeInTheDocument();
expect(data).toEqual(hookProps.data); expect(screen.getByText(hookProps.data[0].filename)).toBeInTheDocument();
expect(inputRow).toMatchObject({ expect(screen.getByText(hookProps.data[1].resultsSummary)).toBeInTheDocument();
adjustedGrade: <AdjustedGradeInput />,
date: formattedDate,
reason: <ReasonInput />,
});
}); });
}); });
}); });

View File

@@ -1,91 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`EditModal component render with error snapshot 1`] = `
<ModalDialog
hasCloseButton={true}
isFullscreenOnMobile={true}
isOpen="test-is-open"
onClose={[MockFunction hooks.onClose]}
size="xl"
title="Edit Grades"
>
<ModalDialog.Body>
<div>
<ModalHeaders />
<Alert
dismissible={false}
show={true}
variant="danger"
>
test-error
</Alert>
<OverrideTable />
<div>
Showing most recent actions (max 5). To see more, please contact support
</div>
<div>
Note: Once you save, your changes will be visible to students.
</div>
</div>
</ModalDialog.Body>
<ModalDialog.Footer>
<ActionRow>
<ModalDialog.CloseButton
variant="tertiary"
>
Cancel
</ModalDialog.CloseButton>
<Button
onClick={[MockFunction hooks.handleAdjustedGradeClick]}
variant="primary"
>
Save Grades
</Button>
</ActionRow>
</ModalDialog.Footer>
</ModalDialog>
`;
exports[`EditModal component render without error snapshot 1`] = `
<ModalDialog
hasCloseButton={true}
isFullscreenOnMobile={true}
isOpen="test-is-open"
onClose={[MockFunction hooks.onClose]}
size="xl"
title="Edit Grades"
>
<ModalDialog.Body>
<div>
<ModalHeaders />
<Alert
dismissible={false}
show={false}
variant="danger"
/>
<OverrideTable />
<div>
Showing most recent actions (max 5). To see more, please contact support
</div>
<div>
Note: Once you save, your changes will be visible to students.
</div>
</div>
</ModalDialog.Body>
<ModalDialog.Footer>
<ActionRow>
<ModalDialog.CloseButton
variant="tertiary"
>
Cancel
</ModalDialog.CloseButton>
<Button
onClick={[MockFunction hooks.handleAdjustedGradeClick]}
variant="primary"
>
Save Grades
</Button>
</ActionRow>
</ModalDialog.Footer>
</ModalDialog>
`;

View File

@@ -1,126 +1,106 @@
import React from 'react'; import { render, screen } from '@testing-library/react';
import { shallow } from '@edx/react-unit-test-utils'; import userEvent from '@testing-library/user-event';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import {
ActionRow,
ModalDialog,
} from '@openedx/paragon';
import { useIntl } from '@edx/frontend-platform/i18n';
import { formatMessage } from 'testUtils';
import ModalHeaders from './ModalHeaders';
import OverrideTable from './OverrideTable';
import useEditModalData from './hooks'; import useEditModalData from './hooks';
import EditModal from '.'; import EditModal from '.';
import messages from './messages'; import messages from './messages';
jest.mock('./hooks', () => jest.fn()); jest.mock('./hooks', () => jest.fn());
jest.mock('./ModalHeaders', () => 'ModalHeaders'); jest.mock('./ModalHeaders', () => jest.fn(() => <div>ModalHeaders</div>));
jest.mock('./OverrideTable', () => 'OverrideTable'); jest.mock('./OverrideTable', () => jest.fn(() => <div>OverrideTable</div>));
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
const hookProps = { const hookProps = {
onClose: jest.fn().mockName('hooks.onClose'), onClose: jest.fn().mockName('hooks.onClose'),
error: 'test-error', error: 'test-error',
handleAdjustedGradeClick: jest.fn().mockName('hooks.handleAdjustedGradeClick'), handleAdjustedGradeClick: jest.fn().mockName('hooks.handleAdjustedGradeClick'),
isOpen: 'test-is-open', isOpen: true,
}; };
useEditModalData.mockReturnValue(hookProps);
let el;
describe('EditModal component', () => { describe('EditModal component', () => {
beforeEach(() => { beforeEach(() => {
jest.clearAllMocks(); jest.clearAllMocks();
el = shallow(<EditModal />);
}); });
describe('behavior', () => { describe('behavior', () => {
it('initializes intl hook', () => {
expect(useIntl).toHaveBeenCalled();
});
it('initializes component hooks', () => { it('initializes component hooks', () => {
useEditModalData.mockReturnValue(hookProps);
render(<IntlProvider locale="en"><EditModal /></IntlProvider>);
expect(useEditModalData).toHaveBeenCalled(); expect(useEditModalData).toHaveBeenCalled();
}); });
}); });
describe('render', () => { describe('renders', () => {
test('modal props', () => { const testModal = () => {
const modalProps = el.instance.findByType(ModalDialog)[0].props; it('modal properly', () => {
expect(modalProps.title).toEqual(formatMessage(messages.title)); const modal = screen.getByRole('dialog', { title: messages.title.defaultMessage });
expect(modalProps.isOpen).toEqual(hookProps.isOpen); expect(modal).toBeInTheDocument();
expect(modalProps.onClose).toEqual(hookProps.onClose); });
}); it('triggers onClose when closed', async () => {
const loadBody = () => { const user = userEvent.setup();
const body = el.instance.findByType(ModalDialog)[0].children[0]; const closeButton = screen.getByRole('button', { name: messages.closeText.defaultMessage });
const { children } = body.children[0]; await user.click(closeButton);
return { body, children }; expect(hookProps.onClose).toHaveBeenCalled();
});
}; };
const testBody = () => { const testBody = () => {
test('type', () => { it('headers row', () => {
const { body } = loadBody(); const headers = screen.getByText('ModalHeaders');
expect(body.type).toEqual('ModalDialog.Body'); expect(headers).toBeInTheDocument();
}); });
test('headers row', () => { it('table row', () => {
const { children } = loadBody(); const table = screen.getByText('OverrideTable');
expect(children[0]).toMatchObject(shallow(<ModalHeaders />)); expect(table).toBeInTheDocument();
}); });
test('table row', () => { it('messages', () => {
const { children } = loadBody(); const visibilityMessage = screen.getByText(messages.visibility.defaultMessage);
expect(children[2]).toMatchObject(shallow(<OverrideTable />)); const saveVisibilityMessage = screen.getByText(messages.saveVisibility.defaultMessage);
}); expect(visibilityMessage).toBeInTheDocument();
test('messages', () => { expect(saveVisibilityMessage).toBeInTheDocument();
const { children } = loadBody();
expect(children[3].children[0].el).toEqual(formatMessage(messages.visibility));
expect(children[4].children[0].el).toEqual(formatMessage(messages.saveVisibility));
}); });
}; };
const testFooter = () => { const testFooter = () => {
let footer; it('adjusted grade button', async () => {
beforeEach(() => { const user = userEvent.setup();
footer = el.instance.findByType(ModalDialog)[0].children; const saveGradeButton = screen.getByRole('button', { name: messages.saveGrade.defaultMessage });
expect(saveGradeButton).toBeInTheDocument();
await user.click(saveGradeButton);
expect(hookProps.handleAdjustedGradeClick).toHaveBeenCalled();
}); });
test('type', () => { it('close button', async () => {
expect(footer[1].type).toEqual('ModalDialog.Footer'); const user = userEvent.setup();
}); const cancelButton = screen.getByRole('button', { name: messages.closeText.defaultMessage });
test('contains action row', () => { expect(cancelButton).toBeInTheDocument();
expect(footer[1].children[0].type).toEqual('ActionRow'); await user.click(cancelButton);
}); expect(hookProps.onClose).toHaveBeenCalled();
test('close button', () => {
const button = footer[1].findByType(ActionRow)[0].children[0];
expect(button.children[0].el).toEqual(formatMessage(messages.closeText));
expect(button.type).toEqual('ModalDialog.CloseButton');
});
test('adjusted grade button', () => {
const button = footer[1].findByType(ActionRow)[0].children[1];
expect(button.children[0].el).toEqual(formatMessage(messages.saveGrade));
expect(button.type).toEqual('Button');
expect(button.props.onClick).toEqual(hookProps.handleAdjustedGradeClick);
}); });
}; };
describe('without error', () => { describe('without error', () => {
beforeEach(() => { beforeEach(() => {
useEditModalData.mockReturnValueOnce({ ...hookProps, error: undefined }); useEditModalData.mockReturnValueOnce({ ...hookProps, error: undefined });
el = shallow(<EditModal />); render(<IntlProvider locale="en"><EditModal /></IntlProvider>);
});
test('snapshot', () => {
expect(el.snapshot).toMatchSnapshot();
}); });
testModal();
testBody(); testBody();
testFooter(); testFooter();
test('alert row', () => { test('alert row', () => {
const alert = loadBody().children[1]; const alert = screen.queryByRole('alert');
expect(alert.type).toEqual('Alert'); expect(alert).toBeNull();
expect(alert.props.show).toEqual(false);
}); });
}); });
describe('with error', () => { describe('with error', () => {
test('snapshot', () => { beforeEach(() => {
expect(el.snapshot).toMatchSnapshot(); useEditModalData.mockReturnValue(hookProps);
render(<IntlProvider locale="en"><EditModal /></IntlProvider>);
}); });
testModal();
testBody(); testBody();
test('alert row', () => { test('alert row', () => {
const alert = loadBody().children[1]; const alert = screen.getByRole('alert');
expect(alert.type).toEqual('Alert'); expect(alert).toBeInTheDocument();
expect(alert.props.show).toEqual(true); expect(alert).toHaveTextContent(hookProps.error);
expect(alert.children[0].el).toEqual(hookProps.error);
}); });
testFooter(); testFooter();
}); });

View File

@@ -1,10 +1,10 @@
import React from 'react'; import React from 'react';
import { shallow } from '@edx/react-unit-test-utils'; import { render, screen } from '@testing-library/react';
import { useIntl } from '@edx/frontend-platform/i18n'; import { useIntl } from '@edx/frontend-platform/i18n';
import { formatMessage } from 'testUtils'; import { formatMessage } from 'testUtils';
import { Button } from '@openedx/paragon';
import { selectors } from 'data/redux/hooks'; import { selectors } from 'data/redux/hooks';
import userEvent from '@testing-library/user-event';
import FilterBadge from './FilterBadge'; import FilterBadge from './FilterBadge';
jest.mock('@openedx/paragon', () => ({ jest.mock('@openedx/paragon', () => ({
@@ -18,7 +18,10 @@ jest.mock('data/redux/hooks', () => ({
}, },
})); }));
const handleClose = jest.fn(filters => ({ handleClose: filters })); jest.unmock('@openedx/paragon');
jest.unmock('react');
const handleClose = jest.fn();
const filterName = 'test-filter-name'; const filterName = 'test-filter-name';
const hookProps = { const hookProps = {
@@ -32,12 +35,11 @@ const hookProps = {
}; };
selectors.root.useFilterBadgeConfig.mockReturnValue(hookProps); selectors.root.useFilterBadgeConfig.mockReturnValue(hookProps);
let el;
describe('FilterBadge', () => { describe('FilterBadge', () => {
beforeEach(() => { describe('hooks', () => {
el = shallow(<FilterBadge {...{ handleClose, filterName }} />); beforeEach(() => {
}); render(<FilterBadge {...{ handleClose, filterName }} />);
describe('behavior', () => { });
it('initializes intl hook', () => { it('initializes intl hook', () => {
expect(useIntl).toHaveBeenCalled(); expect(useIntl).toHaveBeenCalled();
}); });
@@ -46,49 +48,42 @@ describe('FilterBadge', () => {
}); });
}); });
describe('render', () => { describe('render', () => {
const testDisplayName = () => { it('empty render if isDefault', () => {
test('formatted display name appears on badge', () => {
expect(el.instance.findByTestId('display-name')[0].children[0].el).toEqual(formatMessage(hookProps.displayName));
});
};
const testCloseButton = () => {
test('close button forwards close method', () => {
expect(el.instance.findByType(Button)[0].props.onClick).toEqual(handleClose(hookProps.connectedFilters));
});
};
test('empty render if isDefault', () => {
selectors.root.useFilterBadgeConfig.mockReturnValueOnce({ selectors.root.useFilterBadgeConfig.mockReturnValueOnce({
...hookProps, ...hookProps,
isDefault: true, isDefault: true,
}); });
el = shallow(<FilterBadge {...{ handleClose, filterName }} />); render(<FilterBadge {...{ handleClose, filterName }} />);
expect(el.isEmptyRender()).toEqual(true); expect(screen.queryByText(hookProps.displayName)).toBeNull();
}); });
describe('hide Value', () => { describe('hide Value', () => {
beforeEach(() => { it('renders display name, value is not shown and close button has correct behavior', async () => {
selectors.root.useFilterBadgeConfig.mockReturnValueOnce({ selectors.root.useFilterBadgeConfig.mockReturnValueOnce({
...hookProps, ...hookProps,
hideValue: true, hideValue: true,
}); });
el = shallow(<FilterBadge {...{ handleClose, filterName }} />); render(<FilterBadge {...{ handleClose, filterName }} />);
}); const user = userEvent.setup();
testDisplayName(); expect(screen.getByTestId('display-name')).toHaveTextContent(formatMessage(hookProps.displayName));
testCloseButton(); expect(screen.queryByTestId('filter-value')).toHaveTextContent('');
test('snapshot', () => { const button = screen.getByRole('button', { name: /close/i });
expect(el.snapshot).toMatchSnapshot(); await user.click(button);
}); expect(handleClose).toHaveBeenCalledWith(hookProps.connectedFilters);
test('value is note present in the badge', () => {
expect(el.instance.findByTestId('filter-value')[0].children).toHaveLength(0);
}); });
}); });
describe('do not hide value', () => { describe('do not hide value', () => {
testDisplayName(); it('renders display name and value, and close button has correct behavior', async () => {
testCloseButton(); selectors.root.useFilterBadgeConfig.mockReturnValueOnce({
test('snapshot', () => { ...hookProps,
expect(el.snapshot).toMatchSnapshot(); hideValue: false,
}); });
test('value is present in the badge', () => { render(<FilterBadge {...{ handleClose, filterName }} />);
expect(el.instance.findByTestId('filter-value')[0].children[0].el).toBe(`: ${hookProps.value}`); const user = userEvent.setup();
expect(screen.getByTestId('display-name')).toHaveTextContent(formatMessage(hookProps.displayName));
expect(screen.getByTestId('filter-value')).toHaveTextContent(`: ${hookProps.value}`);
const button = screen.getByRole('button', { name: /close/i });
await user.click(button);
expect(handleClose).toHaveBeenCalledWith(hookProps.connectedFilters);
}); });
}); });
}); });

View File

@@ -1,75 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`FilterBadge render do not hide value snapshot 1`] = `
<div>
<span
className="badge badge-info"
>
<span
data-testid="display-name"
>
a common name
</span>
<span
data-testid="filter-value"
>
: a common value
</span>
<Button
aria-label="close"
className="btn-info"
onClick={
{
"handleClose": [
"some",
"filters",
],
}
}
>
<span
aria-hidden="true"
>
×
</span>
</Button>
</span>
<br />
</div>
`;
exports[`FilterBadge render hide Value snapshot 1`] = `
<div>
<span
className="badge badge-info"
>
<span
data-testid="display-name"
>
a common name
</span>
<span
data-testid="filter-value"
/>
<Button
aria-label="close"
className="btn-info"
onClick={
{
"handleClose": [
"some",
"filters",
],
}
}
>
<span
aria-hidden="true"
>
×
</span>
</Button>
</span>
<br />
</div>
`;

View File

@@ -1,21 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`FilterBadges component snapshot - has a filterbadge with handleClose for each filter in badgeOrder 1`] = `
<div>
<FilterBadge
filterName="filter1"
handleClose={[MockFunction this.props.handleClose]}
key="filter1"
/>
<FilterBadge
filterName="filter2"
handleClose={[MockFunction this.props.handleClose]}
key="filter2"
/>
<FilterBadge
filterName="filter3"
handleClose={[MockFunction this.props.handleClose]}
key="filter3"
/>
</div>
`;

View File

@@ -1,11 +1,13 @@
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable import/no-named-as-default */ /* eslint-disable import/no-named-as-default */
import React from 'react'; 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 FilterBadges from '.'; import FilterBadges from '.';
import FilterBadge from './FilterBadge';
jest.mock('./FilterBadge', () => 'FilterBadge'); jest.unmock('@openedx/paragon');
jest.unmock('react');
const order = ['filter1', 'filter2', 'filter3']; const order = ['filter1', 'filter2', 'filter3'];
jest.mock('data/constants/filters', () => ({ jest.mock('data/constants/filters', () => ({
@@ -13,24 +15,24 @@ jest.mock('data/constants/filters', () => ({
badgeOrder: order, badgeOrder: order,
})); }));
// eslint-disable-next-line react/button-has-type
jest.mock('./FilterBadge', () => jest.fn(({ filterName, handleClose }) => <button onClick={handleClose}>{filterName}</button>));
const handleClose = jest.fn();
describe('FilterBadges', () => { describe('FilterBadges', () => {
describe('component', () => { describe('component', () => {
let el; it('has a filterbadge with handleClose for each filter in badgeOrder', async () => {
let handleClose; render(<FilterBadges handleClose={handleClose} />);
beforeEach(() => { const user = userEvent.setup();
handleClose = jest.fn().mockName('this.props.handleClose'); const badge1 = screen.getByText(order[0]);
el = shallow(<FilterBadges handleClose={handleClose} />); const badge2 = screen.getByText(order[1]);
}); const badge3 = screen.getByText(order[2]);
test('snapshot - has a filterbadge with handleClose for each filter in badgeOrder', () => { expect(badge1).toBeInTheDocument();
expect(el.snapshot).toMatchSnapshot(); expect(badge2).toBeInTheDocument();
}); expect(badge3).toBeInTheDocument();
test('has a filterbadge with handleClose for each filter in badgeOrder', () => { await user.click(badge1);
const badgeProps = el.instance.findByType(FilterBadge).map(badgeEl => badgeEl.props); expect(handleClose).toHaveBeenCalled();
// key prop is not rendered by react
expect(badgeProps[0]).toMatchObject({ filterName: order[0], handleClose });
expect(badgeProps[1]).toMatchObject({ filterName: order[1], handleClose });
expect(badgeProps[2]).toMatchObject({ filterName: order[2], handleClose });
expect(badgeProps.length).toEqual(3);
}); });
}); });
}); });

View File

@@ -1,32 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`GradebookTable snapshot 1`] = `
<div
className="gradebook-container"
>
<DataTable
RowStatusComponent={[MockFunction hooks.nullMethod]}
columns={
[
"some",
"columns",
]
}
data={
[
"some",
"data",
]
}
hasFixedColumnWidths={true}
itemCount={3}
rowHeaderColumnKey="username"
>
<DataTable.TableControlBar />
<DataTable.Table />
<DataTable.EmptyTable
content="empty-table-content"
/>
</DataTable>
</div>
`;

View File

@@ -1,39 +1,46 @@
import React from 'react'; import { render, screen } from '@testing-library/react';
import { shallow } from '@edx/react-unit-test-utils'; import { IntlProvider } from '@edx/frontend-platform/i18n';
import { DataTable } from '@openedx/paragon';
import useGradebookTableData from './hooks'; import useGradebookTableData from './hooks';
import GradebookTable from '.'; import GradebookTable from '.';
jest.mock('./hooks', () => jest.fn()); jest.mock('./hooks', () => jest.fn());
jest.unmock('@openedx/paragon');
jest.unmock('react');
jest.unmock('@edx/frontend-platform/i18n');
const hookProps = { const hookProps = {
columns: ['some', 'columns'], columns: [{ Header: 'Username', accessor: 'username' }, { Header: 'Email', accessor: 'email' }, { Header: 'Total Grade', accessor: 'totalGrade' }],
data: ['some', 'data'], data: [{ username: 'instructor', email: 'instructor@example.com', totalGrade: '100' }, { username: 'student', email: 'student@example.com', totalGrade: '90' }],
grades: ['a', 'few', 'grades'], grades: ['a', 'few', 'grades'],
nullMethod: jest.fn().mockName('hooks.nullMethod'), nullMethod: jest.fn().mockName('hooks.nullMethod'),
emptyContent: 'empty-table-content', emptyContent: 'empty-table-content',
}; };
useGradebookTableData.mockReturnValue(hookProps);
let el;
describe('GradebookTable', () => { describe('GradebookTable', () => {
beforeEach(() => { it('renders Datatable correctly', () => {
jest.clearAllMocks(); useGradebookTableData.mockReturnValue(hookProps);
el = shallow(<GradebookTable />); render(<IntlProvider locale="en"><GradebookTable /></IntlProvider>);
expect(useGradebookTableData).toHaveBeenCalled();
const headers = screen.getAllByRole('columnheader');
expect(headers).toHaveLength(3);
expect(headers[0]).toHaveTextContent(hookProps.columns[0].Header);
expect(headers[1]).toHaveTextContent(hookProps.columns[1].Header);
expect(headers[2]).toHaveTextContent(hookProps.columns[2].Header);
const rows = screen.getAllByRole('row');
expect(rows).toHaveLength(3);
expect(screen.getByText(hookProps.data[0].username)).toBeInTheDocument();
expect(screen.getByText(hookProps.data[0].email)).toBeInTheDocument();
expect(screen.getByText(hookProps.data[0].totalGrade)).toBeInTheDocument();
}); });
test('snapshot', () => { it('renders empty table content when no data is available', () => {
expect(el.snapshot).toMatchSnapshot(); useGradebookTableData.mockReturnValue({
}); ...hookProps,
test('Datatable props', () => { data: [],
const datatable = el.instance.findByType(DataTable)[0]; grades: [],
const { props } = datatable; });
expect(props.columns).toEqual(hookProps.columns); render(<IntlProvider locale="en"><GradebookTable /></IntlProvider>);
expect(props.data).toEqual(hookProps.data); expect(screen.getByText(hookProps.emptyContent)).toBeInTheDocument();
expect(props.itemCount).toEqual(hookProps.grades.length);
expect(props.RowStatusComponent).toEqual(hookProps.nullMethod);
expect(datatable.children[2].type).toEqual('DataTable.EmptyTable');
expect(datatable.children[2].props.content).toEqual(hookProps.emptyContent);
}); });
}); });