test: deprecate react-unit-test-utils part-9 (#446)
* test: deprecate react-unit-test-utils part-9 * test: check metadata on test * test: remove debug --------- Co-authored-by: diana-villalvazo-wgu <diana.villalvazo@wgu.edu>
This commit is contained in:
133
src/App.test.jsx
133
src/App.test.jsx
@@ -1,63 +1,102 @@
|
||||
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 { selectors } from 'data/redux';
|
||||
import { App, mapStateToProps } from './App';
|
||||
|
||||
import { App } from './App';
|
||||
jest.unmock('react');
|
||||
jest.unmock('@openedx/paragon');
|
||||
jest.unmock('@edx/frontend-platform/i18n');
|
||||
|
||||
// we want to scope these tests to the App component, so we mock some child components to reduce complexity
|
||||
|
||||
jest.mock('@edx/frontend-platform/auth', () => ({
|
||||
getAuthenticatedHttpClient: jest.fn(),
|
||||
getLoginRedirectUrl: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@edx/frontend-component-footer', () => ({
|
||||
FooterSlot: () => <div data-testid="footer">Footer</div>,
|
||||
}));
|
||||
|
||||
jest.mock('containers/ListView', () => function ListView() {
|
||||
return <div data-testid="list-view">List View</div>;
|
||||
});
|
||||
|
||||
jest.mock('containers/DemoWarning', () => function DemoWarning() {
|
||||
return <div role="alert" data-testid="demo-warning">Demo Warning</div>;
|
||||
});
|
||||
|
||||
jest.mock('data/redux', () => ({
|
||||
app: {
|
||||
selectors: {
|
||||
courseMetadata: (state) => ({ courseMetadata: state }),
|
||||
isEnabled: (state) => ({ isEnabled: state }),
|
||||
selectors: {
|
||||
app: {
|
||||
courseMetadata: jest.fn((state) => state.courseMetadata || {
|
||||
org: 'test-org',
|
||||
number: 'test-101',
|
||||
title: 'Test Course',
|
||||
}),
|
||||
isEnabled: jest.fn((state) => (state.isEnabled !== undefined ? state.isEnabled : true)),
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('@edx/frontend-component-header', () => ({
|
||||
LearningHeader: 'Header',
|
||||
}));
|
||||
jest.mock('@edx/frontend-component-footer', () => ({ FooterSlot: 'FooterSlot' }));
|
||||
const renderWithIntl = (component) => render(
|
||||
<IntlProvider locale="en" messages={{}}>
|
||||
{component}
|
||||
</IntlProvider>,
|
||||
);
|
||||
|
||||
jest.mock('containers/DemoWarning', () => 'DemoWarning');
|
||||
jest.mock('containers/ListView', () => 'ListView');
|
||||
jest.mock('components/Head', () => 'Head');
|
||||
|
||||
let el;
|
||||
|
||||
describe('App router component', () => {
|
||||
const props = {
|
||||
describe('App component', () => {
|
||||
const defaultProps = {
|
||||
courseMetadata: {
|
||||
org: 'course-org',
|
||||
number: 'course-number',
|
||||
title: 'course-title',
|
||||
org: 'test-org',
|
||||
number: 'test-101',
|
||||
title: 'Test Course',
|
||||
},
|
||||
isEnabled: true,
|
||||
};
|
||||
test('snapshot: enabled', () => {
|
||||
expect(shallow(<App {...props} />).snapshot).toMatchSnapshot();
|
||||
});
|
||||
test('snapshot: disabled (show demo warning)', () => {
|
||||
expect(shallow(<App {...props} isEnabled={false} />).snapshot).toMatchSnapshot();
|
||||
});
|
||||
describe('component', () => {
|
||||
beforeEach(() => {
|
||||
el = shallow(<App {...props} />);
|
||||
});
|
||||
describe('Router', () => {
|
||||
test('Routing - ListView is only route', () => {
|
||||
expect(el.instance.findByTestId('main')[0].children).toHaveLength(1);
|
||||
expect(el.instance.findByTestId('main')[0].children[0].type).toBe('ListView');
|
||||
});
|
||||
});
|
||||
|
||||
test('Header to use courseMetadata props', () => {
|
||||
const {
|
||||
courseTitle,
|
||||
courseNumber,
|
||||
courseOrg,
|
||||
} = el.instance.findByTestId('header')[0].props;
|
||||
expect(courseTitle).toEqual(props.courseMetadata.title);
|
||||
expect(courseNumber).toEqual(props.courseMetadata.number);
|
||||
expect(courseOrg).toEqual(props.courseMetadata.org);
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders header with course metadata', () => {
|
||||
renderWithIntl(<App {...defaultProps} />);
|
||||
const org = screen.getByText((text) => text.includes('test-org'));
|
||||
expect(org).toBeInTheDocument();
|
||||
const title = screen.getByText('Test Course');
|
||||
expect(title).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders main content', () => {
|
||||
renderWithIntl(<App {...defaultProps} />);
|
||||
|
||||
const main = screen.getByTestId('main');
|
||||
expect(main).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not render demo warning when enabled', () => {
|
||||
renderWithIntl(<App {...defaultProps} />);
|
||||
|
||||
const demoWarning = screen.queryByRole('alert');
|
||||
expect(demoWarning).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders demo warning when disabled', () => {
|
||||
renderWithIntl(<App {...defaultProps} isEnabled={false} />);
|
||||
|
||||
const demoWarning = screen.getByRole('alert');
|
||||
expect(demoWarning).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('mapStateToProps', () => {
|
||||
it('maps state properties correctly', () => {
|
||||
const testState = { arbitraryState: 'some data' };
|
||||
const mapped = mapStateToProps(testState);
|
||||
|
||||
expect(selectors.app.courseMetadata).toHaveBeenCalledWith(testState);
|
||||
expect(selectors.app.isEnabled).toHaveBeenCalledWith(testState);
|
||||
expect(mapped.courseMetadata).toEqual(selectors.app.courseMetadata(testState));
|
||||
expect(mapped.isEnabled).toEqual(selectors.app.isEnabled(testState));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`App router component snapshot: disabled (show demo warning) 1`] = `
|
||||
<BrowserRouter>
|
||||
<div>
|
||||
<Head />
|
||||
<Header
|
||||
courseNumber="course-number"
|
||||
courseOrg="course-org"
|
||||
courseTitle="course-title"
|
||||
data-testid="header"
|
||||
/>
|
||||
<DemoWarning />
|
||||
<main
|
||||
data-testid="main"
|
||||
>
|
||||
<ListView />
|
||||
</main>
|
||||
<FooterSlot />
|
||||
</div>
|
||||
</BrowserRouter>
|
||||
`;
|
||||
|
||||
exports[`App router component snapshot: enabled 1`] = `
|
||||
<BrowserRouter>
|
||||
<div>
|
||||
<Head />
|
||||
<Header
|
||||
courseNumber="course-number"
|
||||
courseOrg="course-org"
|
||||
courseTitle="course-title"
|
||||
data-testid="header"
|
||||
/>
|
||||
<main
|
||||
data-testid="main"
|
||||
>
|
||||
<ListView />
|
||||
</main>
|
||||
<FooterSlot />
|
||||
</div>
|
||||
</BrowserRouter>
|
||||
`;
|
||||
@@ -1,4 +1,6 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { selectors, thunkActions } from 'data/redux';
|
||||
import { RequestKeys } from 'data/constants/requests';
|
||||
@@ -9,6 +11,10 @@ import {
|
||||
mapDispatchToProps,
|
||||
} from './FetchErrors';
|
||||
|
||||
jest.unmock('@openedx/paragon');
|
||||
jest.unmock('react');
|
||||
jest.unmock('@edx/frontend-platform/i18n');
|
||||
|
||||
jest.mock('data/redux', () => ({
|
||||
selectors: {
|
||||
requests: {
|
||||
@@ -22,39 +28,51 @@ jest.mock('data/redux', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('./ReviewError', () => 'ReviewError');
|
||||
|
||||
const requestKey = RequestKeys.fetchSubmission;
|
||||
|
||||
const renderWithIntl = (component) => render(
|
||||
<IntlProvider locale="en" messages={{}}>
|
||||
{component}
|
||||
</IntlProvider>,
|
||||
);
|
||||
|
||||
describe('FetchErrors component', () => {
|
||||
const props = {
|
||||
isFailed: false,
|
||||
reload: jest.fn(),
|
||||
};
|
||||
describe('component', () => {
|
||||
beforeEach(() => {
|
||||
props.reload = jest.fn();
|
||||
});
|
||||
describe('snapshots', () => {
|
||||
test('snapshot: no failure', () => {
|
||||
expect(<FetchErrors {...props} />).toMatchSnapshot();
|
||||
});
|
||||
test('snapshot: with failure', () => {
|
||||
expect(<FetchErrors {...props} isFailed={false} />).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('does not render when isFailed is false', () => {
|
||||
const { container } = renderWithIntl(<FetchErrors {...props} />);
|
||||
expect(container.firstChild).toBeNull();
|
||||
});
|
||||
|
||||
it('renders error message when isFailed is true', () => {
|
||||
renderWithIntl(<FetchErrors {...props} isFailed />);
|
||||
expect(screen.getByText('Error loading submissions')).toBeInTheDocument();
|
||||
expect(screen.getByText('An error occurred while loading this submission. Try reloading this submission.')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders reload button when error occurs', () => {
|
||||
renderWithIntl(<FetchErrors {...props} isFailed />);
|
||||
expect(screen.getByText('Reload submission')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('mapStateToProps', () => {
|
||||
let mapped;
|
||||
const testState = { some: 'test-state' };
|
||||
beforeEach(() => {
|
||||
mapped = mapStateToProps(testState);
|
||||
});
|
||||
test('isFailed loads from requests.isFailed(fetchSubmission)', () => {
|
||||
|
||||
it('maps isFailed from requests selector', () => {
|
||||
const mapped = mapStateToProps(testState);
|
||||
expect(mapped.isFailed).toEqual(selectors.requests.isFailed(testState, { requestKey }));
|
||||
});
|
||||
});
|
||||
|
||||
describe('mapDispatchToProps', () => {
|
||||
it('loads reload from thunkActions.grading.loadSubmission', () => {
|
||||
it('maps reload from thunkActions.grading.loadSubmission', () => {
|
||||
expect(mapDispatchToProps.reload).toEqual(thunkActions.grading.loadSubmission);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`SubmitErrors component snapshots snapshot: no failure 1`] = `null`;
|
||||
|
||||
exports[`SubmitErrors component snapshots snapshot: with valid error, loads from hook 1`] = `
|
||||
<ReviewError
|
||||
actions={
|
||||
{
|
||||
"cancel": "hooks.reviewActions.cancel",
|
||||
"confirm": "hooks.reviewActions.confirm",
|
||||
}
|
||||
}
|
||||
headingMessage="hooks.headingMessage"
|
||||
>
|
||||
hooks.content
|
||||
</ReviewError>
|
||||
`;
|
||||
@@ -1,34 +1,100 @@
|
||||
import React from 'react';
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
|
||||
import { keyStore } from 'utils';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import * as hooks from './hooks';
|
||||
import { SubmitErrors } from '.';
|
||||
|
||||
jest.mock('../ReviewError', () => 'ReviewError');
|
||||
jest.unmock('@openedx/paragon');
|
||||
jest.unmock('react');
|
||||
jest.unmock('@edx/frontend-platform/i18n');
|
||||
|
||||
jest.mock('react-redux', () => ({
|
||||
useDispatch: jest.fn(() => jest.fn()),
|
||||
}));
|
||||
|
||||
jest.mock('./hooks', () => ({
|
||||
rendererHooks: jest.fn(() => ({ show: false })),
|
||||
}));
|
||||
|
||||
const renderWithIntl = (component) => render(
|
||||
<IntlProvider locale="en" messages={{}}>
|
||||
{component}
|
||||
</IntlProvider>,
|
||||
);
|
||||
|
||||
const hookKeys = keyStore(hooks);
|
||||
describe('SubmitErrors component', () => {
|
||||
describe('snapshots', () => {
|
||||
test('snapshot: no failure', () => {
|
||||
jest.spyOn(hooks, hookKeys.rendererHooks).mockReturnValueOnce({ show: false });
|
||||
const el = shallow(<SubmitErrors />);
|
||||
expect(el.snapshot).toMatchSnapshot();
|
||||
expect(el.isEmptyRender()).toEqual(true);
|
||||
});
|
||||
test('snapshot: with valid error, loads from hook', () => {
|
||||
const mockHook = {
|
||||
show: true,
|
||||
reviewActions: {
|
||||
confirm: 'hooks.reviewActions.confirm',
|
||||
cancel: 'hooks.reviewActions.cancel',
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('does not render when show is false', () => {
|
||||
hooks.rendererHooks.mockReturnValueOnce({ show: false });
|
||||
const { container } = renderWithIntl(<SubmitErrors />);
|
||||
expect(container.firstChild).toBeNull();
|
||||
});
|
||||
|
||||
it('renders ReviewError when show is true', () => {
|
||||
const mockHook = {
|
||||
show: true,
|
||||
reviewActions: {
|
||||
confirm: {
|
||||
onClick: jest.fn(),
|
||||
message: {
|
||||
id: 'ora-grading.ReviewModal.resubmitGrade',
|
||||
defaultMessage: 'Resubmit grate',
|
||||
},
|
||||
},
|
||||
headingMessage: 'hooks.headingMessage',
|
||||
content: 'hooks.content',
|
||||
};
|
||||
jest.spyOn(hooks, hookKeys.rendererHooks).mockReturnValueOnce(mockHook);
|
||||
expect(shallow(<SubmitErrors />).snapshot).toMatchSnapshot();
|
||||
});
|
||||
cancel: {
|
||||
onClick: jest.fn(),
|
||||
message: {
|
||||
id: 'ora-grading.ReviewModal.dismiss',
|
||||
defaultMessage: 'Dismiss',
|
||||
},
|
||||
},
|
||||
},
|
||||
headingMessage: {
|
||||
id: 'ora-grading.ReviewModal.gradeNotSubmitted.heading',
|
||||
defaultMessage: 'Grade not submitted',
|
||||
},
|
||||
content: "We're sorry, something went wrong when we tried to submit this grade. Please try again.",
|
||||
};
|
||||
hooks.rendererHooks.mockReturnValueOnce(mockHook);
|
||||
|
||||
renderWithIntl(<SubmitErrors />);
|
||||
expect(screen.getByText('Grade not submitted')).toBeInTheDocument();
|
||||
expect(screen.getByText("We're sorry, something went wrong when we tried to submit this grade. Please try again.")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders action buttons when provided', () => {
|
||||
const mockHook = {
|
||||
show: true,
|
||||
reviewActions: {
|
||||
confirm: {
|
||||
onClick: jest.fn(),
|
||||
message: {
|
||||
id: 'ora-grading.ReviewModal.resubmitGrade',
|
||||
defaultMessage: 'Resubmit grate',
|
||||
},
|
||||
},
|
||||
cancel: {
|
||||
onClick: jest.fn(),
|
||||
message: {
|
||||
id: 'ora-grading.ReviewModal.dismiss',
|
||||
defaultMessage: 'Dismiss',
|
||||
},
|
||||
},
|
||||
},
|
||||
headingMessage: {
|
||||
id: 'ora-grading.ReviewModal.gradeNotSubmitted.heading',
|
||||
defaultMessage: 'Grade not submitted',
|
||||
},
|
||||
content: "We're sorry, something went wrong when we tried to submit this grade. Please try again.",
|
||||
};
|
||||
hooks.rendererHooks.mockReturnValueOnce(mockHook);
|
||||
|
||||
renderWithIntl(<SubmitErrors />);
|
||||
expect(screen.getByText('Resubmit grate')).toBeInTheDocument();
|
||||
expect(screen.getByText('Dismiss')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`FetchErrors component component snapshots snapshot: no failure 1`] = `
|
||||
<FetchErrors
|
||||
isFailed={false}
|
||||
reload={[MockFunction]}
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`FetchErrors component component snapshots snapshot: with failure 1`] = `
|
||||
<FetchErrors
|
||||
isFailed={false}
|
||||
reload={[MockFunction]}
|
||||
/>
|
||||
`;
|
||||
@@ -1,10 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ReviewErrors component component snapshot: no failure 1`] = `
|
||||
<Fragment>
|
||||
<FetchErrors />
|
||||
<SubmitErrors />
|
||||
<LockErrors />
|
||||
<DownloadErrors />
|
||||
</Fragment>
|
||||
`;
|
||||
@@ -1,17 +1,77 @@
|
||||
import React from 'react';
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
|
||||
import { render } from '@testing-library/react';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { ReviewErrors } from '.';
|
||||
|
||||
jest.mock('./FetchErrors', () => 'FetchErrors');
|
||||
jest.mock('./SubmitErrors', () => 'SubmitErrors');
|
||||
jest.mock('./LockErrors', () => 'LockErrors');
|
||||
jest.mock('./DownloadErrors', () => 'DownloadErrors');
|
||||
jest.unmock('@openedx/paragon');
|
||||
jest.unmock('react');
|
||||
jest.unmock('@edx/frontend-platform/i18n');
|
||||
|
||||
jest.mock('react-redux', () => ({
|
||||
useDispatch: jest.fn(() => jest.fn()),
|
||||
useSelector: jest.fn((selector) => selector({
|
||||
requests: { isFailed: false, error: null, errorStatus: null },
|
||||
grading: { isLocked: false },
|
||||
})),
|
||||
connect: (mapStateToProps, mapDispatchToProps) => (Component) => {
|
||||
const MockedComponent = (props) => {
|
||||
const mockState = {};
|
||||
const mockDispatch = jest.fn();
|
||||
const stateProps = mapStateToProps ? mapStateToProps(mockState) : {};
|
||||
let dispatchProps = {};
|
||||
if (mapDispatchToProps) {
|
||||
if (typeof mapDispatchToProps === 'function') {
|
||||
dispatchProps = mapDispatchToProps(mockDispatch);
|
||||
} else {
|
||||
dispatchProps = mapDispatchToProps;
|
||||
}
|
||||
}
|
||||
return <Component {...props} {...stateProps} {...dispatchProps} />;
|
||||
};
|
||||
return MockedComponent;
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('data/redux', () => ({
|
||||
selectors: {
|
||||
requests: {
|
||||
isFailed: jest.fn(() => false),
|
||||
error: jest.fn(() => null),
|
||||
errorStatus: jest.fn(() => null),
|
||||
},
|
||||
grading: {
|
||||
selected: {
|
||||
isLocked: jest.fn(() => false),
|
||||
},
|
||||
},
|
||||
},
|
||||
thunkActions: {
|
||||
app: {
|
||||
initialize: jest.fn(),
|
||||
},
|
||||
grading: {
|
||||
loadSubmission: jest.fn(),
|
||||
submitResponse: jest.fn(),
|
||||
},
|
||||
download: {
|
||||
downloadFiles: jest.fn(),
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
requests: {
|
||||
clearRequest: jest.fn(),
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
const renderWithIntl = (component) => render(
|
||||
<IntlProvider locale="en" messages={{}}>
|
||||
{component}
|
||||
</IntlProvider>,
|
||||
);
|
||||
|
||||
describe('ReviewErrors component', () => {
|
||||
describe('component', () => {
|
||||
test('snapshot: no failure', () => {
|
||||
expect(shallow(<ReviewErrors />).snapshot).toMatchSnapshot();
|
||||
});
|
||||
it('renders without errors', () => {
|
||||
const { container } = renderWithIntl(<ReviewErrors />);
|
||||
expect(container).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Rubric Container shapshot: hide footer 1`] = `
|
||||
<Fragment>
|
||||
<Card
|
||||
className="grading-rubric-card"
|
||||
>
|
||||
<Card.Section
|
||||
className="grading-rubric-body"
|
||||
>
|
||||
<h3>
|
||||
Rubric
|
||||
</h3>
|
||||
<hr
|
||||
className="m-2.5"
|
||||
/>
|
||||
<CriterionContainer
|
||||
key="1"
|
||||
prop="hook-criteria-props-1"
|
||||
/>
|
||||
<CriterionContainer
|
||||
key="2"
|
||||
prop="hook-criteria-props-2"
|
||||
/>
|
||||
<CriterionContainer
|
||||
key="3"
|
||||
prop="hook-criteria-props-3"
|
||||
/>
|
||||
<hr />
|
||||
<RubricFeedback />
|
||||
</Card.Section>
|
||||
</Card>
|
||||
<DemoAlert
|
||||
prop="demo-alert-props"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`Rubric Container snapshot: show footer 1`] = `
|
||||
<Fragment>
|
||||
<Card
|
||||
className="grading-rubric-card"
|
||||
>
|
||||
<Card.Section
|
||||
className="grading-rubric-body"
|
||||
>
|
||||
<h3>
|
||||
Rubric
|
||||
</h3>
|
||||
<hr
|
||||
className="m-2.5"
|
||||
/>
|
||||
<CriterionContainer
|
||||
key="1"
|
||||
prop="hook-criteria-props-1"
|
||||
/>
|
||||
<CriterionContainer
|
||||
key="2"
|
||||
prop="hook-criteria-props-2"
|
||||
/>
|
||||
<CriterionContainer
|
||||
key="3"
|
||||
prop="hook-criteria-props-3"
|
||||
/>
|
||||
<hr />
|
||||
<RubricFeedback />
|
||||
</Card.Section>
|
||||
<div
|
||||
className="grading-rubric-footer"
|
||||
>
|
||||
<StatefulButton
|
||||
labels={
|
||||
{
|
||||
"complete": "Grade Submitted",
|
||||
"default": "Submit grade",
|
||||
"pending": "Submitting grade",
|
||||
}
|
||||
}
|
||||
prop="hook-button-props"
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
<DemoAlert
|
||||
prop="demo-alert-props"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
@@ -1,34 +1,134 @@
|
||||
import React from 'react';
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
|
||||
import * as hooks from './hooks';
|
||||
import { render } from '@testing-library/react';
|
||||
import { IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { Rubric } from '.';
|
||||
import * as hooks from './hooks';
|
||||
|
||||
jest.unmock('@openedx/paragon');
|
||||
jest.unmock('react');
|
||||
jest.unmock('@edx/frontend-platform/i18n');
|
||||
|
||||
jest.mock('react-redux', () => ({
|
||||
useDispatch: jest.fn(() => jest.fn()),
|
||||
connect: jest.fn((mapStateToProps, mapDispatchToProps) => (Component) => {
|
||||
const ConnectedComponent = (props) => {
|
||||
const mockState = {};
|
||||
const stateProps = mapStateToProps ? mapStateToProps(mockState, props) : {};
|
||||
const dispatchProps = mapDispatchToProps || {};
|
||||
return <Component {...props} {...stateProps} {...dispatchProps} />;
|
||||
};
|
||||
return ConnectedComponent;
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock('data/redux', () => ({
|
||||
actions: {
|
||||
grading: {
|
||||
setCriterionOption: jest.fn(),
|
||||
setRubricFeedback: jest.fn(),
|
||||
},
|
||||
},
|
||||
selectors: {
|
||||
app: {
|
||||
courseId: jest.fn(() => 'test-course-id'),
|
||||
isEnabled: jest.fn(() => false),
|
||||
rubric: {
|
||||
criteriaIndices: jest.fn(() => [0, 1]),
|
||||
criterionConfig: jest.fn((state, { orderNum }) => ({
|
||||
name: `test-criterion-${orderNum}`,
|
||||
prompt: `Test criterion prompt ${orderNum}`,
|
||||
options: [
|
||||
{
|
||||
name: 'option1',
|
||||
label: 'Option 1',
|
||||
points: 1,
|
||||
explanation: 'First option',
|
||||
},
|
||||
{
|
||||
name: 'option2',
|
||||
label: 'Option 2',
|
||||
points: 2,
|
||||
explanation: 'Second option',
|
||||
},
|
||||
],
|
||||
})),
|
||||
criterionFeedbackConfig: jest.fn((state, { orderNum }) => ({
|
||||
feedbackEnabled: true,
|
||||
defaultValue: `Default feedback for criterion ${orderNum}`,
|
||||
})),
|
||||
feedbackConfig: jest.fn(() => ({
|
||||
enabled: true,
|
||||
defaultValue: 'Overall feedback default',
|
||||
})),
|
||||
feedbackPrompt: jest.fn(() => 'Please provide overall feedback'),
|
||||
},
|
||||
},
|
||||
grading: {
|
||||
selected: {
|
||||
gradeStatus: jest.fn(() => 'ungraded'),
|
||||
isGrading: jest.fn(() => true),
|
||||
criterionSelectedOption: jest.fn(() => 'option1'),
|
||||
criterionFeedback: jest.fn(() => 'Test feedback'),
|
||||
overallFeedback: jest.fn(() => 'Test overall feedback'),
|
||||
},
|
||||
validation: {
|
||||
criterionSelectedOptionIsInvalid: jest.fn(() => false),
|
||||
criterionFeedbackIsInvalid: jest.fn(() => false),
|
||||
overallFeedbackIsInvalid: jest.fn(() => false),
|
||||
},
|
||||
},
|
||||
requests: {
|
||||
isPending: jest.fn(() => false),
|
||||
isCompleted: jest.fn(() => false),
|
||||
},
|
||||
},
|
||||
thunkActions: {
|
||||
grading: {
|
||||
submitGrade: jest.fn(() => jest.fn()),
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('containers/CriterionContainer', () => 'CriterionContainer');
|
||||
jest.mock('./RubricFeedback', () => 'RubricFeedback');
|
||||
jest.mock('components/DemoAlert', () => 'DemoAlert');
|
||||
jest.mock('./hooks', () => ({
|
||||
rendererHooks: jest.fn(),
|
||||
ButtonStates: jest.requireActual('./hooks').ButtonStates,
|
||||
}));
|
||||
|
||||
const renderWithIntl = (component) => render(
|
||||
<IntlProvider locale="en" messages={{}}>
|
||||
{component}
|
||||
</IntlProvider>,
|
||||
);
|
||||
|
||||
describe('Rubric Container', () => {
|
||||
const hookProps = {
|
||||
criteria: [
|
||||
{ prop: 'hook-criteria-props-1', key: 1 },
|
||||
{ prop: 'hook-criteria-props-2', key: 2 },
|
||||
{ prop: 'hook-criteria-props-3', key: 3 },
|
||||
{ orderNum: 1, key: 1, isGrading: true },
|
||||
{ orderNum: 2, key: 2, isGrading: true },
|
||||
],
|
||||
showFooter: false,
|
||||
buttonProps: { prop: 'hook-button-props' },
|
||||
demoAlertProps: { prop: 'demo-alert-props' },
|
||||
buttonProps: { variant: 'primary' },
|
||||
demoAlertProps: { show: false },
|
||||
};
|
||||
test('snapshot: show footer', () => {
|
||||
hooks.rendererHooks.mockReturnValueOnce({ ...hookProps, showFooter: true });
|
||||
expect(shallow(<Rubric />).snapshot).toMatchSnapshot();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
hooks.rendererHooks.mockReturnValue(hookProps);
|
||||
});
|
||||
test('shapshot: hide footer', () => {
|
||||
hooks.rendererHooks.mockReturnValueOnce(hookProps);
|
||||
expect(shallow(<Rubric />).snapshot).toMatchSnapshot();
|
||||
|
||||
it('renders rubric with footer when showFooter is true', () => {
|
||||
hooks.rendererHooks.mockReturnValueOnce({ ...hookProps, showFooter: true });
|
||||
const { container } = renderWithIntl(<Rubric />);
|
||||
const rubricCard = container.querySelector('.grading-rubric-card');
|
||||
const footer = container.querySelector('.grading-rubric-footer');
|
||||
expect(rubricCard).toBeInTheDocument();
|
||||
expect(footer).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders rubric without footer when showFooter is false', () => {
|
||||
const { container } = renderWithIntl(<Rubric />);
|
||||
const rubricCard = container.querySelector('.grading-rubric-card');
|
||||
const footer = container.querySelector('.grading-rubric-footer');
|
||||
expect(rubricCard).toBeInTheDocument();
|
||||
expect(footer).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -43,7 +43,6 @@ jest.mock('@edx/frontend-platform/auth', () => ({
|
||||
jest.mock('@edx/frontend-component-header', () => ({
|
||||
LearningHeader: () => 'Header',
|
||||
}));
|
||||
// jest.mock('@edx/frontend-component-footer', () => () => 'Footer');
|
||||
|
||||
jest.mock('react-pdf', () => ({
|
||||
Document: () => <div>Document</div>,
|
||||
@@ -55,11 +54,7 @@ jest.mock('react-pdf', () => ({
|
||||
View: () => <div>View</div>,
|
||||
pdfjs: { GlobalWorkerOptions: {} },
|
||||
}));
|
||||
/*
|
||||
jest.mock('react-pdf/node_modules/pdfjs-dist/build/pdf.worker.entry', () => (
|
||||
jest.requireActual('react-pdf/dist/umd/entry.jest')
|
||||
));
|
||||
*/
|
||||
|
||||
const configureStore = () => redux.createStore(
|
||||
reducers,
|
||||
redux.compose(redux.applyMiddleware(thunk)),
|
||||
|
||||
Reference in New Issue
Block a user