Skip to content

Commit 96ce9e0

Browse files
andreilakatosMariaAga
authored andcommitted
Fixes #39507 - update editornavbar and radio buttons to pf5 and the tests to RTL
1 parent 6205d62 commit 96ce9e0

13 files changed

Lines changed: 525 additions & 825 deletions

File tree

webpack/assets/javascripts/react_app/components/Editor/Editor.js

Lines changed: 219 additions & 201 deletions
Large diffs are not rendered by default.
Lines changed: 156 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,172 @@
11
import React from 'react';
2-
import { act } from '@testing-library/react';
3-
import { mount } from 'enzyme';
4-
import { testComponentSnapshotsWithFixtures } from '../../../common/testHelpers';
2+
import { screen } from '@testing-library/react';
3+
import userEvent from '@testing-library/user-event';
4+
import '@testing-library/jest-dom';
5+
import { rtlHelpers } from '../../../common/rtlTestHelpers';
6+
57
import Editor from '../Editor';
68
import { editorOptions } from '../Editor.fixtures';
79

8-
const didMountStubs = () => ({
9-
changeState: jest.fn(),
10-
importFile: jest.fn(),
11-
revertChanges: jest.fn(),
12-
previewTemplate: jest.fn(),
13-
initializeEditor: jest.fn(),
14-
});
10+
const { renderWithI18n } = rtlHelpers;
11+
12+
const renderEditor = (props = {}) => {
13+
const initializeEditor = jest.fn();
1514

16-
const fixtures = {
17-
'renders editor': editorOptions,
15+
return {
16+
initializeEditor,
17+
...renderWithI18n(
18+
<Editor {...editorOptions} initializeEditor={initializeEditor} {...props} />
19+
),
20+
};
1821
};
1922

2023
describe('Editor', () => {
21-
jest.useFakeTimers();
22-
describe('rendering', () =>
23-
testComponentSnapshotsWithFixtures(Editor, fixtures));
24-
25-
describe('triggering', () => {
26-
it('should trigger input view', async () => {
27-
const props = { ...editorOptions, ...didMountStubs() };
28-
const component = mount(<Editor {...props} />);
29-
await act(async () => jest.advanceTimersByTime(1000));
30-
expect(
31-
component
32-
.find('li[role="presentation"]')
33-
.at(0)
34-
.hasClass('active')
35-
).toBe(true);
24+
it('renders editor tabs', async () => {
25+
renderEditor();
26+
27+
expect(await screen.findByRole('tab', { name: 'Editor' })).toBeInTheDocument();
28+
expect(screen.getByRole('tab', { name: 'Changes' })).toBeInTheDocument();
29+
expect(screen.getByRole('tab', { name: 'Preview' })).toBeInTheDocument();
30+
});
31+
32+
it('calls initializeEditor on mount', async () => {
33+
const { initializeEditor } = renderEditor();
34+
35+
await screen.findByRole('tab', { name: 'Editor' });
36+
37+
expect(initializeEditor).toHaveBeenCalledTimes(1);
38+
expect(initializeEditor).toHaveBeenCalledWith(
39+
expect.objectContaining({
40+
selectedView: editorOptions.selectedView,
41+
template: editorOptions.data.template,
42+
})
43+
);
44+
});
45+
46+
it('selects the input tab by default', async () => {
47+
renderEditor({ selectedView: 'input' });
48+
49+
expect(await screen.findByRole('tab', { name: 'Editor' })).toHaveAttribute(
50+
'aria-selected',
51+
'true'
52+
);
53+
});
54+
55+
it('selects the diff tab when diff view is active', async () => {
56+
renderEditor({ selectedView: 'diff' });
57+
58+
expect(await screen.findByRole('tab', { name: 'Changes' })).toHaveAttribute(
59+
'aria-selected',
60+
'true'
61+
);
62+
});
63+
64+
it('selects the preview tab when preview view is active', async () => {
65+
renderEditor({ selectedView: 'preview', isRendering: true });
66+
67+
expect(await screen.findByRole('tab', { name: 'Preview' })).toHaveAttribute(
68+
'aria-selected',
69+
'true'
70+
);
71+
});
72+
73+
it('shows the diff table when diff view is active', async () => {
74+
renderEditor({
75+
selectedView: 'diff',
76+
data: { ...editorOptions.data, template: 'old template' },
77+
value: 'new value',
3678
});
37-
it('should trigger input view with no template', async () => {
38-
const props = {
39-
...editorOptions,
40-
...didMountStubs(),
41-
data: { ...editorOptions.data, template: null },
42-
};
43-
const component = mount(<Editor {...props} />);
44-
await act(async () => jest.advanceTimersByTime(1000));
45-
expect(component.props().template).toBe('<? />');
79+
80+
expect(await screen.findByRole('tab', { name: 'Changes' })).toHaveAttribute(
81+
'aria-selected',
82+
'true'
83+
);
84+
expect(screen.getByText('old template')).toBeInTheDocument();
85+
expect(screen.getAllByText('new value').length).toBeGreaterThan(0);
86+
});
87+
88+
it('shows outdated preview warning', async () => {
89+
renderEditor({
90+
selectedView: 'preview',
91+
previewResult: 'rendered preview',
92+
renderedEditorValue: 'old rendered value',
93+
value: 'current value',
4694
});
47-
it('should trigger diff view', async () => {
48-
const props = {
49-
...editorOptions,
50-
...didMountStubs(),
51-
selectedView: 'diff',
52-
};
53-
const component = mount(<Editor {...props} />);
54-
await act(async () => jest.advanceTimersByTime(1000));
55-
expect(
56-
component
57-
.find('li[role="presentation"]')
58-
.at(1)
59-
.hasClass('active')
60-
).toBe(true);
95+
96+
expect(await screen.findByText('Preview is outdated.')).toBeInTheDocument();
97+
expect(
98+
screen.getByRole('button', { name: 'Preview' })
99+
).toBeInTheDocument();
100+
});
101+
102+
it('refreshes preview when outdated preview link is clicked', async () => {
103+
const previewTemplate = jest.fn();
104+
105+
renderEditor({
106+
previewTemplate,
107+
selectedView: 'preview',
108+
previewResult: 'rendered preview',
109+
renderedEditorValue: 'old rendered value',
110+
value: 'current value',
111+
selectedHost: { id: '1', name: 'host1' },
112+
data: {
113+
...editorOptions.data,
114+
safemodeRenderPath: '/safemode/path',
115+
},
61116
});
62-
it('should trigger preview view', async () => {
63-
const props = {
64-
...editorOptions,
65-
...didMountStubs(),
66-
selectedView: 'preview',
67-
isRendering: true,
68-
};
69-
const wrapper = mount(<Editor {...props} />);
70-
wrapper.find('button.close').simulate('click');
71-
await act(async () => jest.advanceTimersByTime(1000));
72-
const component = mount(<Editor {...props} />);
73-
await act(async () => jest.advanceTimersByTime(1000));
74-
75-
expect(
76-
component
77-
.find('li[role="presentation"]')
78-
.at(2)
79-
.hasClass('active')
80-
).toBe(true);
117+
118+
userEvent.click(
119+
await screen.findByRole('button', { name: 'Preview' })
120+
);
121+
122+
expect(previewTemplate).toHaveBeenCalledWith({
123+
host: { id: '1', name: 'host1' },
124+
renderPath: '/safemode/path',
125+
templateKindId: '',
81126
});
82127
});
83-
it('should trigger hidden value editor', async () => {
84-
const props = {
85-
...editorOptions,
86-
...didMountStubs(),
87-
selectedView: 'preview',
88-
isRendering: true,
89-
isMasked: true,
90-
};
91-
const wrapper = mount(<Editor {...props} />);
92-
await act(async () => jest.advanceTimersByTime(1000));
93-
expect(wrapper.find('.mask-editor').exists()).toBe(true);
128+
129+
it('dismisses the preview error toast', async () => {
130+
const dismissErrorToast = jest.fn();
131+
132+
renderEditor({ dismissErrorToast, showError: true, errorText: 'Preview failed' });
133+
134+
userEvent.click(await screen.findByRole('button', { name: /Close/i }));
135+
136+
expect(dismissErrorToast).toHaveBeenCalledTimes(1);
137+
});
138+
139+
it('renders the hidden value textarea when editable', async () => {
140+
renderEditor({ readOnly: false, value: 'editor value' });
141+
142+
await screen.findByRole('tab', { name: 'Editor' });
143+
144+
expect(screen.getByDisplayValue('editor value')).toBeInTheDocument();
94145
});
95-
it('textarea disappears if readOnly', async () => {
96-
const props = {
97-
...editorOptions,
98-
...didMountStubs(),
99-
selectedView: 'input',
100-
};
101-
const wrapper = mount(<Editor {...props} />);
102-
await act(async () => jest.advanceTimersByTime(1000));
103-
expect(wrapper.find('textarea.hidden').exists()).toBe(true);
104-
wrapper.setProps({ readOnly: true });
105-
expect(wrapper.find('textarea.hidden').exists()).toBe(false);
146+
147+
it('hides the value textarea when read only', async () => {
148+
const initializeEditor = jest.fn();
149+
const { rerender } = renderWithI18n(
150+
<Editor
151+
{...editorOptions}
152+
initializeEditor={initializeEditor}
153+
readOnly={false}
154+
value="editor value"
155+
/>
156+
);
157+
158+
await screen.findByRole('tab', { name: 'Editor' });
159+
expect(screen.getByDisplayValue('editor value')).toBeInTheDocument();
160+
161+
rerender(
162+
<Editor
163+
{...editorOptions}
164+
initializeEditor={initializeEditor}
165+
readOnly
166+
value="editor value"
167+
/>
168+
);
169+
170+
expect(screen.queryByDisplayValue('editor value')).not.toBeInTheDocument();
106171
});
107172
});

0 commit comments

Comments
 (0)