Skip to content

Commit cba4e68

Browse files
test: replacing snapshot tests with RTL tests part 5 (#2143)
* test: replacing snapshot tests with rtl tests part 5 * test: removig extra tests * test: snaps update * test: adding import shorthand and turning tests into ts * docs: clarify which line the comment is about --------- Co-authored-by: Braden MacDonald <[email protected]>
1 parent 96df339 commit cba4e68

File tree

25 files changed

+400
-934
lines changed

25 files changed

+400
-934
lines changed

jest.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ module.exports = createConfig('jest', {
1111
],
1212
moduleNameMapper: {
1313
'^lodash-es$': 'lodash',
14+
// This alias is for any code in the src directory that wants to avoid '../../' style relative imports:
15+
'^@src/(.*)$': '<rootDir>/src/$1',
16+
// This alias is used for plugins in the plugins/ folder only.
1417
'^CourseAuthoring/(.*)$': '<rootDir>/src/$1',
1518
},
1619
modulePathIgnorePatterns: [

src/editors/EditorContainer.test.jsx

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/editors/EditorContainer.test.tsx

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import React from 'react';
2+
import { getConfig } from '@edx/frontend-platform';
3+
import {
4+
render, screen, initializeMocks, fireEvent, act,
5+
} from '@src/testUtils';
6+
import EditorContainer from './EditorContainer';
7+
import { mockWaffleFlags } from '../data/apiHooks.mock';
8+
import editorCmsApi from './data/services/cms/api';
9+
10+
mockWaffleFlags();
11+
12+
const mockPathname = '/editor/';
13+
jest.mock('react-router-dom', () => ({
14+
...jest.requireActual('react-router-dom'),
15+
useParams: () => ({
16+
blockId: 'block-v1:Org+TS100+24+type@fake+block@123456fake',
17+
blockType: 'fake',
18+
}),
19+
useLocation: () => ({
20+
pathname: mockPathname,
21+
}),
22+
useSearchParams: () => [{
23+
get: () => 'lb:Axim:TEST:html:571fe018-f3ce-45c9-8f53-5dafcb422fdd',
24+
}],
25+
}));
26+
27+
jest.mock('react-redux', () => ({
28+
...jest.requireActual('react-redux'),
29+
useSelector: () => ({
30+
useReactMarkdownEditor: true, // or false depending on the test
31+
}),
32+
}));
33+
34+
// Mock this plugins component:
35+
jest.mock('frontend-components-tinymce-advanced-plugins', () => ({ a11ycheckerCss: '' }));
36+
// Always mock out the "fetch course images" endpoint:
37+
jest.spyOn(editorCmsApi, 'fetchCourseImages').mockImplementation(async () => ( // eslint-disable-next-line
38+
{ data: { assets: [], start: 0, end: 0, page: 0, pageSize: 50, totalCount: 0 } }
39+
));
40+
// Mock out the 'get ancestors' API:
41+
jest.spyOn(editorCmsApi, 'fetchByUnitId').mockImplementation(async () => ({
42+
status: 200,
43+
data: {
44+
ancestors: [{
45+
id: 'block-v1:Org+TS100+24+type@vertical+block@parent',
46+
display_name: 'You-Knit? The Test Unit',
47+
category: 'vertical',
48+
has_children: true,
49+
}],
50+
},
51+
}));
52+
jest.mock('../library-authoring/LibraryBlock', () => ({
53+
LibraryBlock: jest.fn(() => (<div>Advanced Editor Iframe</div>)),
54+
}));
55+
56+
const props = { learningContextId: 'cOuRsEId' };
57+
58+
describe('EditorContainer', () => {
59+
beforeEach(() => {
60+
initializeMocks();
61+
jest.spyOn(editorCmsApi, 'fetchBlockById').mockImplementationOnce(async () => (
62+
{
63+
status: 200,
64+
data: {
65+
display_name: 'Fake Un-editable Block', category: 'fake', metadata: {}, data: '',
66+
},
67+
}
68+
));
69+
});
70+
71+
test('render component', () => {
72+
render(<EditorContainer {...props} />);
73+
expect(screen.getByText('View in Library')).toBeInTheDocument();
74+
expect(screen.getByText('Advanced Editor Iframe')).toBeInTheDocument();
75+
});
76+
77+
test('should call onClose param when receiving "cancel-clicked" message', () => {
78+
const onCloseMock = jest.fn();
79+
render(<EditorContainer {...props} onClose={onCloseMock} />);
80+
const messageEvent = new MessageEvent('message', {
81+
data: {
82+
type: 'xblock-event',
83+
eventName: 'cancel',
84+
},
85+
origin: getConfig().STUDIO_BASE_URL,
86+
});
87+
88+
act(() => {
89+
window.dispatchEvent(messageEvent);
90+
});
91+
fireEvent.click(screen.getByRole('button', { name: 'Discard Changes and Exit' }));
92+
expect(onCloseMock).toHaveBeenCalled();
93+
});
94+
});

src/editors/__snapshots__/EditorContainer.test.jsx.snap

Lines changed: 0 additions & 69 deletions
This file was deleted.
Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33

4-
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
4+
import { useIntl } from '@edx/frontend-platform/i18n';
55
import { Collapsible, Icon, IconButton } from '@openedx/paragon';
66
import { ExpandLess, ExpandMore, InfoOutline } from '@openedx/paragon/icons';
77

@@ -20,40 +20,41 @@ const CollapsibleFormWidget = ({
2020
subtitle,
2121
title,
2222
fontSize,
23-
// injected
24-
intl,
25-
}) => (
26-
<Collapsible.Advanced
27-
className="collapsible-card rounded mx-4 my-3 px-4 text-primary-500"
28-
defaultOpen
29-
open={isError || undefined}
30-
>
31-
<Collapsible.Trigger
32-
className="collapsible-trigger d-flex border-0 align-items-center pt-4 p-0"
33-
style={{ justifyContent: 'unset' }}
23+
}) => {
24+
const intl = useIntl();
25+
return (
26+
<Collapsible.Advanced
27+
className="collapsible-card rounded mx-4 my-3 px-4 text-primary-500"
28+
defaultOpen
29+
open={isError || undefined}
3430
>
35-
<Collapsible.Visible whenClosed className="p-0 pb-3">
36-
<div className="d-flex flex-column flex-grow-1">
31+
<Collapsible.Trigger
32+
className="collapsible-trigger d-flex border-0 align-items-center pt-4 p-0"
33+
style={{ justifyContent: 'unset' }}
34+
>
35+
<Collapsible.Visible whenClosed className="p-0 pb-3">
36+
<div className="d-flex flex-column flex-grow-1">
37+
<div className="d-flex flex-grow-1 w-75 x-small">{title}</div>
38+
{subtitle ? <div className={`${fontSize} mb-4 mt-3`}>{subtitle}</div> : <div className="mb-4" />}
39+
</div>
40+
<div className="d-flex flex-row align-self-start">
41+
{isError && <Icon className="alert-icon" src={InfoOutline} />}
42+
<IconButton alt={intl.formatMessage(messages.expandAltText)} src={ExpandMore} iconAs={Icon} variant="dark" />
43+
</div>
44+
</Collapsible.Visible>
45+
<Collapsible.Visible whenOpen>
3746
<div className="d-flex flex-grow-1 w-75 x-small">{title}</div>
38-
{subtitle ? <div className={`${fontSize} mb-4 mt-3`}>{subtitle}</div> : <div className="mb-4" />}
39-
</div>
40-
<div className="d-flex flex-row align-self-start">
41-
{isError && <Icon className="alert-icon" src={InfoOutline} />}
42-
<IconButton alt={intl.formatMessage(messages.expandAltText)} src={ExpandMore} iconAs={Icon} variant="dark" />
43-
</div>
44-
</Collapsible.Visible>
45-
<Collapsible.Visible whenOpen>
46-
<div className="d-flex flex-grow-1 w-75 x-small">{title}</div>
47-
<div className="align-self-start">
48-
<IconButton alt={intl.formatMessage(messages.collapseAltText)} src={ExpandLess} iconAs={Icon} variant="dark" />
49-
</div>
50-
</Collapsible.Visible>
51-
</Collapsible.Trigger>
52-
<Collapsible.Body className={`collapsible-body rounded px-0 ${fontSize} pb-4`}>
53-
{children}
54-
</Collapsible.Body>
55-
</Collapsible.Advanced>
56-
);
47+
<div className="align-self-start">
48+
<IconButton alt={intl.formatMessage(messages.collapseAltText)} src={ExpandLess} iconAs={Icon} variant="dark" />
49+
</div>
50+
</Collapsible.Visible>
51+
</Collapsible.Trigger>
52+
<Collapsible.Body className={`collapsible-body rounded px-0 ${fontSize} pb-4`}>
53+
{children}
54+
</Collapsible.Body>
55+
</Collapsible.Advanced>
56+
);
57+
};
5758

5859
CollapsibleFormWidget.defaultProps = {
5960
subtitle: null,
@@ -66,9 +67,6 @@ CollapsibleFormWidget.propTypes = {
6667
subtitle: PropTypes.node,
6768
title: PropTypes.node.isRequired,
6869
fontSize: PropTypes.string,
69-
// injected
70-
intl: intlShape.isRequired,
7170
};
7271

73-
export const CollapsibleFormWidgetInternal = CollapsibleFormWidget; // For testing only
74-
export default injectIntl(CollapsibleFormWidget);
72+
export default CollapsibleFormWidget;

src/editors/containers/VideoEditor/components/VideoSettingsModal/components/CollapsibleFormWidget.test.jsx

Lines changed: 0 additions & 29 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react';
2+
import {
3+
render, screen, initializeMocks,
4+
} from '@src/testUtils';
5+
import CollapsibleFormWidget from './CollapsibleFormWidget';
6+
7+
describe('CollapsibleFormWidget', () => {
8+
const props = {
9+
isError: false,
10+
subtitle: 'Sample subtitle',
11+
title: 'Sample title',
12+
fontSize: 'x-small',
13+
};
14+
const testContent = (<p>Some test string</p>);
15+
16+
beforeEach(() => {
17+
initializeMocks();
18+
});
19+
20+
test('renders component', () => {
21+
render(<CollapsibleFormWidget {...props}>{testContent}</CollapsibleFormWidget>);
22+
expect(screen.getByText('Sample title')).toBeInTheDocument();
23+
expect(screen.getByText('Some test string')).toBeInTheDocument();
24+
});
25+
});

src/editors/containers/VideoEditor/components/VideoSettingsModal/components/DurationWidget/__snapshots__/index.test.jsx.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

33
exports[`DurationWidget render snapshots: renders as expected with default props 1`] = `
4-
<injectIntl(ShimmedIntlComponent)
4+
<CollapsibleFormWidget
55
fontSize="x-small"
66
subtitle="Custom: 00:00:00"
77
title="Duration"
@@ -60,5 +60,5 @@ exports[`DurationWidget render snapshots: renders as expected with default props
6060
Total: 00:00:00
6161
</span>
6262
</div>
63-
</injectIntl(ShimmedIntlComponent)>
63+
</CollapsibleFormWidget>
6464
`;

0 commit comments

Comments
 (0)