Skip to content

Commit d64d345

Browse files
test: deprecate react-unit-test-utils 6/14 (#342)
* test: deprecate react-unit-test-utils 6/14 * fix: improve accessible queries * test: fixes test to cover required TextEditor attribute, and checks badge-variant class on StatusBadge * test: remove unwanted test-id --------- Co-authored-by: Tony Busa <[email protected]>
1 parent 4530e8b commit d64d345

File tree

11 files changed

+230
-271
lines changed

11 files changed

+230
-271
lines changed
Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,66 @@
11
import React from 'react';
2-
import { shallow } from '@edx/react-unit-test-utils';
2+
import { render } from '@testing-library/react';
3+
import '@testing-library/jest-dom';
34
import { renderMathJax } from 'utils/index';
45

56
import LatexPreview from './LaTexPreview';
67

8+
jest.unmock('@openedx/paragon');
9+
jest.unmock('react');
10+
jest.unmock('@edx/frontend-platform/i18n');
11+
712
jest.mock('utils/index', () => ({
813
renderMathJax: jest.fn(),
914
}));
1015

1116
describe('<LatexPreview />', () => {
12-
it('renders', () => {
13-
const wrapper = shallow(<LatexPreview latexValue="some latext value" />);
14-
expect(wrapper.snapshot).toMatchSnapshot();
17+
const mockRenderMathJax = renderMathJax;
18+
19+
beforeEach(() => {
20+
jest.clearAllMocks();
21+
});
22+
23+
it('renders with latex value', () => {
24+
const latexValue = 'some latex value';
25+
const { container } = render(<LatexPreview latexValue={latexValue} />);
26+
27+
const previewDiv = container.querySelector('.mt-2');
28+
expect(previewDiv).toBeInTheDocument();
29+
30+
const contentDiv = previewDiv.querySelector('div');
31+
expect(contentDiv).toBeInTheDocument();
32+
});
33+
34+
it('calls renderMathJax on mount', () => {
35+
render(<LatexPreview latexValue="test latex" />);
36+
37+
expect(mockRenderMathJax).toHaveBeenCalledTimes(1);
38+
});
39+
40+
it('calls renderMathJax when latexValue changes', () => {
41+
const { rerender } = render(<LatexPreview latexValue="initial value" />);
42+
43+
expect(mockRenderMathJax).toHaveBeenCalledTimes(1);
44+
45+
rerender(<LatexPreview latexValue="new value" />);
46+
47+
expect(mockRenderMathJax).toHaveBeenCalledTimes(2);
48+
});
49+
50+
it('renders with correct HTML content', () => {
51+
const latexValue = '<math>x^2</math>';
52+
const { container } = render(<LatexPreview latexValue={latexValue} />);
53+
54+
const previewDiv = container.querySelector('.mt-2');
55+
const contentDiv = previewDiv.querySelector('div');
56+
expect(contentDiv.innerHTML).toBe(latexValue);
57+
});
58+
59+
it('has correct CSS structure', () => {
60+
const { container } = render(<LatexPreview latexValue="test" />);
1561

16-
React.useEffect.mock.calls[0][0]();
17-
expect(renderMathJax).toHaveBeenCalled();
62+
const outerDiv = container.querySelector('.mt-2');
63+
expect(outerDiv).toBeInTheDocument();
64+
expect(outerDiv.children).toHaveLength(1);
1865
});
1966
});

src/views/SubmissionView/TextResponseEditor/TextEditor.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const TextEditor = ({
2727
{formatMessage(messages.yourResponse)} ({formatMessage(optional ? messages.optional : messages.required)})
2828
</h3>
2929
)}
30+
required={!optional}
3031
value={value}
3132
onChange={onChange}
3233
placeholder={formatMessage(messages.textResponsePlaceholder)}
Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,53 @@
1-
import { shallow } from '@edx/react-unit-test-utils';
1+
import { render, screen } from '@testing-library/react';
2+
import '@testing-library/jest-dom';
3+
import { IntlProvider } from '@edx/frontend-platform/i18n';
4+
25
import TextEditor from './TextEditor';
36

7+
jest.unmock('@openedx/paragon');
8+
jest.unmock('react');
9+
jest.unmock('@edx/frontend-platform/i18n');
10+
411
describe('<TextEditor />', () => {
5-
const props = {
12+
const renderWithIntl = (component) => render(<IntlProvider locale="en">{component}</IntlProvider>);
13+
14+
const defaultProps = {
615
optional: true,
716
disabled: false,
817
value: 'value',
9-
onChange: jest.fn().mockName('onChange'),
18+
onChange: jest.fn(),
19+
};
20+
21+
const defaultPropsOptionalFalseDisabledTrue = {
22+
optional: false,
23+
disabled: true,
24+
value: 'value',
25+
onChange: jest.fn(),
1026
};
1127

12-
it('render optional', () => {
13-
const wrapper = shallow(<TextEditor {...props} />);
14-
expect(wrapper.snapshot).toMatchSnapshot();
28+
it('has correct CSS classes and accessibility attributes', () => {
29+
renderWithIntl(<TextEditor {...defaultProps} />);
30+
const textarea = screen.getByRole('textbox');
31+
expect(textarea).toBeInTheDocument();
32+
expect(textarea).toHaveAttribute('name', 'text-response');
33+
expect(textarea).toHaveAttribute(
34+
'placeholder',
35+
'Enter your response to the prompt above',
36+
);
37+
expect(textarea).toHaveValue('value');
38+
expect(textarea).not.toHaveAttribute('required');
1539
});
1640

17-
it('render required', () => {
18-
const wrapper = shallow(<TextEditor {...props} optional={false} isInValid />);
19-
expect(wrapper.snapshot).toMatchSnapshot();
41+
it('has correct CSS classes and accessibility attributes with optional false and disabled true', () => {
42+
renderWithIntl(<TextEditor {...defaultPropsOptionalFalseDisabledTrue} />);
43+
const textarea = screen.getByRole('textbox');
44+
expect(textarea).toBeInTheDocument();
45+
expect(textarea).toHaveAttribute('name', 'text-response');
46+
expect(textarea).toHaveAttribute(
47+
'placeholder',
48+
'Enter your response to the prompt above',
49+
);
50+
expect(textarea).toHaveValue('value');
51+
expect(textarea).toHaveAttribute('required');
2052
});
2153
});

src/views/SubmissionView/TextResponseEditor/__snapshots__/LaTexPreview.test.jsx.snap

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

src/views/SubmissionView/TextResponseEditor/__snapshots__/TextEditor.test.jsx.snap

Lines changed: 0 additions & 54 deletions
This file was deleted.
Lines changed: 94 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,126 @@
1-
import { shallow } from '@edx/react-unit-test-utils';
1+
import { render, screen } from '@testing-library/react';
2+
import '@testing-library/jest-dom';
3+
import { IntlProvider } from '@edx/frontend-platform/i18n';
24

35
import { useRubricConfig } from 'hooks/app';
46

57
import StudioViewRubric from './StudioViewRubric';
68

9+
jest.unmock('@openedx/paragon');
10+
jest.unmock('react');
11+
jest.unmock('@edx/frontend-platform/i18n');
12+
713
jest.mock('hooks/app', () => ({
814
useRubricConfig: jest.fn(),
915
}));
1016
jest.mock('./XBlockStudioViewProvider', () => ({
1117
useXBlockStudioViewContext: () => ({
1218
rubricIsOpen: true,
13-
toggleRubric: jest.fn().mockName('toggleRubric'),
19+
toggleRubric: jest.fn(),
1420
}),
1521
}));
1622

1723
describe('<StudioViewRubric />', () => {
18-
it('render with criteria and options', () => {
19-
useRubricConfig.mockReturnValue({
20-
criteria: [
24+
const renderWithIntl = (component) => render(<IntlProvider locale="en">{component}</IntlProvider>);
25+
26+
const sampleCriteria = [
27+
{
28+
name: 'criterion1',
29+
description: 'description1',
30+
options: [
2131
{
22-
name: 'criterion1',
32+
name: 'option1',
33+
label: 'label1',
34+
points: 1,
2335
description: 'description1',
24-
options: [
25-
{
26-
name: 'option1',
27-
label: 'label1',
28-
points: 1,
29-
description: 'description1',
30-
},
31-
{
32-
name: 'option2',
33-
label: 'label2',
34-
points: 2,
35-
description: 'description2',
36-
},
37-
],
3836
},
3937
{
40-
name: 'criterion2',
38+
name: 'option2',
39+
label: 'label2',
40+
points: 2,
4141
description: 'description2',
42-
options: [
43-
{
44-
name: 'option2',
45-
label: 'label2',
46-
points: 2,
47-
description: 'description2',
48-
},
49-
],
5042
},
5143
],
44+
},
45+
{
46+
name: 'criterion2',
47+
description: 'description2',
48+
options: [
49+
{
50+
name: 'option3',
51+
label: 'label3',
52+
points: 3,
53+
description: 'description3',
54+
},
55+
],
56+
},
57+
];
58+
59+
beforeEach(() => {
60+
jest.clearAllMocks();
61+
});
62+
63+
it('renders rubric with criteria and options', () => {
64+
useRubricConfig.mockReturnValue({
65+
criteria: sampleCriteria,
66+
});
67+
68+
renderWithIntl(<StudioViewRubric />);
69+
70+
expect(screen.getByText('Rubric')).toBeInTheDocument();
71+
expect(screen.getAllByTestId('criteria-test-id')).toHaveLength(2);
72+
73+
expect(screen.getByText('criterion1')).toBeInTheDocument();
74+
expect(screen.getAllByText('description1')).toHaveLength(2);
75+
expect(screen.getByText('criterion2')).toBeInTheDocument();
76+
expect(screen.getAllByText('description2')).toHaveLength(2);
77+
});
78+
79+
it('renders criterion options with points', () => {
80+
useRubricConfig.mockReturnValue({
81+
criteria: sampleCriteria,
5282
});
5383

54-
const wrapper = shallow(<StudioViewRubric />);
55-
expect(wrapper.snapshot).toMatchSnapshot();
84+
renderWithIntl(<StudioViewRubric />);
5685

57-
expect(wrapper.instance.findByTestId('criteria-test-id').length).toBe(2);
86+
expect(screen.getByText(/label1: 1/)).toBeInTheDocument();
87+
expect(screen.getByText(/label2: 2/)).toBeInTheDocument();
88+
expect(screen.getByText(/label3: 3/)).toBeInTheDocument();
89+
expect(screen.getAllByText(/point/)).toHaveLength(3);
5890
});
5991

60-
it('render without criteria', () => {
92+
it('renders without criteria when empty', () => {
6193
useRubricConfig.mockReturnValue({ criteria: [] });
6294

63-
const wrapper = shallow(<StudioViewRubric />);
64-
expect(wrapper.snapshot).toMatchSnapshot();
95+
renderWithIntl(<StudioViewRubric />);
96+
97+
expect(screen.getByText('Rubric')).toBeInTheDocument();
98+
expect(screen.queryAllByTestId('criteria-test-id')).toHaveLength(0);
99+
});
100+
101+
it('renders criterion labels correctly', () => {
102+
useRubricConfig.mockReturnValue({
103+
criteria: sampleCriteria,
104+
});
105+
106+
renderWithIntl(<StudioViewRubric />);
107+
108+
expect(screen.getAllByText('Criteria name:')).toHaveLength(2);
109+
expect(screen.getAllByText('Criteria description:')).toHaveLength(2);
110+
expect(screen.getAllByText('Criteria options:')).toHaveLength(2);
111+
});
112+
113+
it('renders multiple criteria with different option counts', () => {
114+
useRubricConfig.mockReturnValue({
115+
criteria: sampleCriteria,
116+
});
117+
118+
renderWithIntl(<StudioViewRubric />);
119+
120+
const criteria = screen.getAllByTestId('criteria-test-id');
121+
expect(criteria).toHaveLength(2);
65122

66-
expect(wrapper.instance.findByTestId('criteria-test-id').length).toBe(0);
123+
const lists = screen.getAllByRole('list');
124+
expect(lists).toHaveLength(2);
67125
});
68126
});

0 commit comments

Comments
 (0)