Skip to content

Commit 97028f3

Browse files
Merge pull request #15694 from cajieh/missed-enzyme-rtl-migration-tests
CONSOLE-4860: Missed Enzyme to RTL migration tests
2 parents b15ef91 + 234a833 commit 97028f3

File tree

5 files changed

+225
-125
lines changed

5 files changed

+225
-125
lines changed

frontend/packages/console-app/src/components/detect-perspective/__tests__/DetectPerspective.spec.tsx

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
import { shallow } from 'enzyme';
1+
import { render, screen } from '@testing-library/react';
22
import { useLocation } from 'react-router-dom-v5-compat';
33
import { usePerspectives } from '@console/shared/src';
44
import DetectPerspective from '../DetectPerspective';
5-
import PerspectiveDetector from '../PerspectiveDetector';
65
import { useValuesForPerspectiveContext } from '../useValuesForPerspectiveContext';
76

87
const MockApp = () => <h1>App</h1>;
98

9+
jest.mock('../PerspectiveDetector', () => ({
10+
__esModule: true,
11+
default: () => 'PerspectiveDetector',
12+
}));
13+
1014
jest.mock('../useValuesForPerspectiveContext', () => ({
1115
useValuesForPerspectiveContext: jest.fn(),
1216
}));
@@ -28,29 +32,41 @@ describe('DetectPerspective', () => {
2832
useValuesForPerspectiveContextMock.mockClear();
2933
usePerspectivesMock.mockClear();
3034
useLocationMock.mockClear();
35+
useLocationMock.mockReturnValue({ pathname: '/test' });
3136
});
32-
it('should render children if there is an activePerspective', () => {
33-
useValuesForPerspectiveContextMock.mockReturnValue(['dev', () => {}, true]);
37+
38+
it('should render children when there is an active perspective', () => {
39+
useValuesForPerspectiveContextMock.mockReturnValue(['dev', jest.fn(), true]);
3440
usePerspectivesMock.mockReturnValue([
3541
{ properties: { id: 'admin' } },
3642
{ properties: { id: 'dev' } },
3743
{ properties: { id: 'dev-test' } },
3844
]);
39-
const wrapper = shallow(
45+
46+
render(
4047
<DetectPerspective>
4148
<MockApp />
4249
</DetectPerspective>,
4350
);
44-
expect(wrapper.find(MockApp).exists()).toBe(true);
51+
52+
expect(screen.getByRole('heading', { name: 'App' })).toBeVisible();
53+
expect(screen.queryByText('PerspectiveDetector')).not.toBeInTheDocument();
4554
});
4655

47-
it('should render PerspectiveDetector if there is no activePerspective', () => {
48-
useValuesForPerspectiveContextMock.mockReturnValue([undefined, () => {}, true]);
49-
const wrapper = shallow(
56+
it('should render PerspectiveDetector when there is no active perspective', () => {
57+
useValuesForPerspectiveContextMock.mockReturnValue([undefined, jest.fn(), true]);
58+
usePerspectivesMock.mockReturnValue([
59+
{ properties: { id: 'admin' } },
60+
{ properties: { id: 'dev' } },
61+
]);
62+
63+
render(
5064
<DetectPerspective>
5165
<MockApp />
5266
</DetectPerspective>,
5367
);
54-
expect(wrapper.find(PerspectiveDetector).exists()).toBe(true);
68+
69+
expect(screen.getByText('PerspectiveDetector')).toBeVisible();
70+
expect(screen.queryByRole('heading', { name: 'App' })).not.toBeInTheDocument();
5571
});
5672
});

frontend/packages/console-app/src/components/detect-perspective/__tests__/PerspectiveDetector.spec.tsx

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { mount } from 'enzyme';
2-
import { act } from 'react-dom/test-utils';
1+
import { render, waitFor } from '@testing-library/react';
32
import { Perspective } from '@console/dynamic-plugin-sdk';
43
import { LoadedExtension } from '@console/plugin-sdk';
54
import { usePerspectives } from '@console/shared/src';
@@ -13,12 +12,10 @@ jest.mock('@console/shared/src', () => ({
1312
usePerspectives: jest.fn(),
1413
}));
1514

16-
jest.mock('react-router', () => {
17-
return {
18-
...jest.requireActual('react-router'),
19-
useLocation: jest.fn(() => ({ pathname: '' })),
20-
};
21-
});
15+
jest.mock('react-router', () => ({
16+
...jest.requireActual('react-router'),
17+
useLocation: jest.fn(() => ({ pathname: '' })),
18+
}));
2219

2320
const mockPerspectives = [
2421
{
@@ -42,17 +39,21 @@ const mockPerspectives = [
4239
const setActivePerspective = jest.fn();
4340

4441
describe('PerspectiveDetector', () => {
45-
it('should set default perspective if there are no perspective detectors available', async () => {
42+
beforeEach(() => {
43+
setActivePerspective.mockClear();
44+
});
45+
46+
it('should set default perspective when there are no perspective detectors available', async () => {
4647
(usePerspectives as jest.Mock).mockImplementation(() => mockPerspectives);
4748

48-
const wrapper = mount(<PerspectiveDetector setActivePerspective={setActivePerspective} />);
49-
expect(wrapper.isEmptyRender()).toBe(true);
50-
expect(setActivePerspective).toHaveBeenCalledWith('admin', '');
49+
render(<PerspectiveDetector setActivePerspective={setActivePerspective} />);
50+
51+
await waitFor(() => {
52+
expect(setActivePerspective).toHaveBeenCalledWith('admin', '');
53+
});
5154
});
5255

53-
it('should set detected perspective if detection is successful', async () => {
54-
// create a promise and capture the resolver such that we can use act later on to ensure
55-
// the test waits for this promise to resolve before continuing
56+
it('should set detected perspective when detection is successful', async () => {
5657
let promiseResolver: (value: () => [boolean, boolean]) => void;
5758
const testPromise = new Promise<() => [boolean, boolean]>(
5859
(resolver) => (promiseResolver = resolver),
@@ -61,17 +62,16 @@ describe('PerspectiveDetector', () => {
6162

6263
(usePerspectives as jest.Mock).mockImplementation(() => mockPerspectives);
6364

64-
const wrapper = mount(<PerspectiveDetector setActivePerspective={setActivePerspective} />);
65-
await act(async () => {
66-
promiseResolver(() => [true, false]);
65+
render(<PerspectiveDetector setActivePerspective={setActivePerspective} />);
66+
67+
promiseResolver(() => [true, false]);
68+
69+
await waitFor(() => {
70+
expect(setActivePerspective).toHaveBeenCalledWith('dev', '');
6771
});
68-
expect(wrapper.isEmptyRender()).toBe(true);
69-
expect(setActivePerspective).toHaveBeenCalledWith('dev', '');
7072
});
7173

72-
it('should set default perspective if detection fails', async () => {
73-
// create a promise and capture the resolver such that we can use act later on to ensure
74-
// the test waits for this promise to resolve before continuing
74+
it('should set default perspective when detection fails', async () => {
7575
let promiseResolver: (value: () => [boolean, boolean]) => void;
7676
const testPromise = new Promise<() => [boolean, boolean]>(
7777
(resolver) => (promiseResolver = resolver),
@@ -80,15 +80,16 @@ describe('PerspectiveDetector', () => {
8080

8181
(usePerspectives as jest.Mock).mockImplementation(() => mockPerspectives);
8282

83-
const wrapper = mount(<PerspectiveDetector setActivePerspective={setActivePerspective} />);
84-
await act(async () => {
85-
promiseResolver(() => [false, false]);
83+
render(<PerspectiveDetector setActivePerspective={setActivePerspective} />);
84+
85+
promiseResolver(() => [false, false]);
86+
87+
await waitFor(() => {
88+
expect(setActivePerspective).toHaveBeenCalledWith('admin', '');
8689
});
87-
expect(wrapper.isEmptyRender()).toBe(true);
88-
expect(setActivePerspective).toHaveBeenCalledWith('admin', '');
8990
});
9091

91-
it('should set admin as default perspective if all perspectives are disabled', async () => {
92+
it('should set admin as default perspective when all perspectives are disabled', async () => {
9293
const perspectives: PerspectiveType[] = [
9394
{
9495
id: 'dev',
@@ -118,8 +119,7 @@ describe('PerspectiveDetector', () => {
118119
},
119120
];
120121
window.SERVER_FLAGS.perspectives = JSON.stringify(perspectives);
121-
// create a promise and capture the resolver such that we can use act later on to ensure
122-
// the test waits for this promise to resolve before continuing
122+
123123
let promiseResolver: (value: () => [boolean, boolean]) => void;
124124
const testPromise = new Promise<() => [boolean, boolean]>(
125125
(resolver) => (promiseResolver = resolver),
@@ -128,11 +128,12 @@ describe('PerspectiveDetector', () => {
128128

129129
(usePerspectives as jest.Mock).mockImplementation(() => mockPerspectives);
130130

131-
const wrapper = mount(<PerspectiveDetector setActivePerspective={setActivePerspective} />);
132-
await act(async () => {
133-
promiseResolver(() => [false, false]);
131+
render(<PerspectiveDetector setActivePerspective={setActivePerspective} />);
132+
133+
promiseResolver(() => [false, false]);
134+
135+
await waitFor(() => {
136+
expect(setActivePerspective).toHaveBeenCalledWith('admin', '');
134137
});
135-
expect(wrapper.isEmptyRender()).toBe(true);
136-
expect(setActivePerspective).toHaveBeenCalledWith('admin', '');
137138
});
138139
});
Lines changed: 72 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
2-
import { Alert } from '@patternfly/react-core';
3-
import { shallow, ShallowWrapper } from 'enzyme';
2+
import { ValidatedOptions } from '@patternfly/react-core';
3+
import { render, screen } from '@testing-library/react';
44
import * as formik from 'formik';
55
import { formikFormProps } from '@console/shared/src/test-utils/formik-props-utils';
66
import * as imgUtils from '../../../../utils/imagestream-utils';
@@ -10,49 +10,62 @@ import {
1010
internalImageValues,
1111
} from '../../../edit-application/__tests__/edit-application-data';
1212
import ImageStream from '../ImageStream';
13-
import ImageStreamDropdown from '../ImageStreamDropdown';
14-
import ImageStreamNsDropdown from '../ImageStreamNsDropdown';
15-
import ImageStreamTagDropdown from '../ImageStreamTagDropdown';
13+
14+
jest.mock('../ImageStreamNsDropdown', () => ({
15+
__esModule: true,
16+
default: () => 'Namespace Dropdown',
17+
}));
18+
19+
jest.mock('../ImageStreamDropdown', () => ({
20+
__esModule: true,
21+
default: () => 'ImageStream Dropdown',
22+
}));
23+
24+
jest.mock('../ImageStreamTagDropdown', () => ({
25+
__esModule: true,
26+
default: () => 'ImageStream Tag Dropdown',
27+
}));
1628

1729
const spyUseFormikContext = jest.spyOn(formik, 'useFormikContext');
1830
const spyUseReducer = jest.spyOn(React, 'useReducer');
19-
const spyUseField = jest.spyOn(formik, 'useField');
2031
const spyGetImageStreamTags = jest.spyOn(imgUtils, 'getImageStreamTags');
21-
const spyUseState = jest.spyOn(React, 'useState');
2232

2333
const mockReducerState = {
2434
loading: false,
2535
accessLoading: false,
2636
selectedImageStream: appResources.imageStream.data[0],
2737
};
28-
type ImagestreamProps = React.ComponentProps<typeof ImageStream>;
2938

30-
describe('Imagestream', () => {
31-
let wrapper: ShallowWrapper<ImagestreamProps>;
39+
describe('ImageStream', () => {
3240
beforeEach(() => {
3341
spyGetImageStreamTags.mockReturnValue({ 3.6: 3.6 });
3442
spyUseReducer.mockImplementation(() => [mockReducerState, jest.fn()]);
35-
spyUseField.mockImplementation(() => [{ value: '' }, {}]);
36-
spyUseState.mockReturnValue([true, jest.fn()]);
3743
spyUseFormikContext.mockReturnValue({
3844
...formikFormProps,
3945
values: internalImageValues,
4046
initialValues: internalImageValues,
4147
});
42-
wrapper = shallow(<ImageStream />);
4348
});
4449

45-
it('should render namespace, imagestream and imagestream-tag dropdowns ', () => {
46-
expect(wrapper.find(ImageStreamNsDropdown)).toHaveLength(1);
47-
expect(wrapper.find(ImageStreamDropdown)).toHaveLength(1);
48-
expect(wrapper.find(ImageStreamTagDropdown)).toHaveLength(1);
50+
afterEach(() => {
51+
jest.clearAllMocks();
4952
});
5053

51-
it('should not render any alerts if current project and imagestream project is the same', () => {
52-
expect(wrapper.find(Alert)).toHaveLength(0);
54+
it('should render namespace, imagestream and imagestream tag dropdowns', () => {
55+
render(<ImageStream />);
56+
57+
expect(screen.getByText('Namespace Dropdown')).toBeVisible();
58+
expect(screen.getByText('ImageStream Dropdown')).toBeVisible();
59+
expect(screen.getByText('ImageStream Tag Dropdown')).toBeVisible();
5360
});
5461

55-
it('should not render any alerts if the imagestream namespace is openshift', () => {
62+
it('should not render any alerts when current project and imagestream project are the same', () => {
63+
render(<ImageStream />);
64+
65+
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
66+
});
67+
68+
it('should not render any alerts when imagestream namespace is openshift', () => {
5669
spyUseFormikContext.mockReturnValue({
5770
...formikFormProps,
5871
values: {
@@ -65,34 +78,53 @@ describe('Imagestream', () => {
6578
},
6679
initialValues: internalImageValues,
6780
});
68-
wrapper = shallow(<ImageStream />);
69-
expect(wrapper.find(Alert)).toHaveLength(0);
81+
82+
render(<ImageStream />);
83+
84+
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
7085
});
7186

72-
it('should render oc command alert if current namespace and imagestream namespace are not equal', () => {
87+
it('should render oc command alert when current namespace and imagestream namespace are not equal', () => {
88+
const spyUseState = jest.spyOn(React, 'useState');
89+
spyUseState.mockReturnValueOnce([ValidatedOptions.default, jest.fn()]); // validated state
90+
spyUseState.mockReturnValueOnce([true, jest.fn()]); // hasImageStreams state
91+
7392
spyUseFormikContext.mockReturnValue({
7493
...formikFormProps,
75-
values: { ...internalImageValues, project: { name: 'project-a' } },
94+
values: {
95+
...internalImageValues,
96+
project: { name: 'project-a' },
97+
imageStream: { image: 'python', tag: '3.6', namespace: 'div' },
98+
},
7699
initialValues: internalImageValues,
77100
});
78-
wrapper = shallow(<ImageStream />);
79-
const alert = wrapper.find(Alert);
80-
expect(alert).toHaveLength(1);
81-
expect(alert.props().title).toEqual(
82-
'Service account default will need pull authority to deploy Images from div',
83-
);
101+
102+
render(<ImageStream />);
103+
104+
expect(
105+
screen.getByText(
106+
'Service account default will need pull authority to deploy Images from div',
107+
),
108+
).toBeInTheDocument();
109+
expect(screen.getByText(/You can grant authority with the command/)).toBeInTheDocument();
110+
111+
spyUseState.mockRestore();
84112
});
85113

86-
it('should render imagestream not found alert if there are no imagestreams', () => {
114+
it('should render imagestream not found alert when there are no imagestreams', () => {
115+
spyUseReducer.mockImplementation(() => [{ ...mockReducerState, loading: false }, jest.fn()]);
87116
spyUseFormikContext.mockReturnValue({
88117
...formikFormProps,
89-
values: { ...internalImageValues, imageStream: { image: '' } },
118+
values: { ...internalImageValues, imageStream: { image: '', namespace: 'div' } },
90119
});
91-
wrapper = shallow(<ImageStream />);
92-
expect(wrapper.find(Alert)).toHaveLength(1);
120+
121+
render(<ImageStream />);
122+
123+
expect(screen.getByText('No Image streams found')).toBeInTheDocument();
124+
expect(screen.getByText('No Image streams are available in Project div')).toBeInTheDocument();
93125
});
94126

95-
it('should render imagestream tag not found alert if there are no imagestreams tags', () => {
127+
it('should render imagestream tag not found alert when there are no imagestream tags', () => {
96128
spyGetImageStreamTags.mockReturnValue({});
97129
spyUseFormikContext.mockReturnValue({
98130
...formikFormProps,
@@ -102,7 +134,10 @@ describe('Imagestream', () => {
102134
},
103135
initialValues: internalImageValues,
104136
});
105-
wrapper = shallow(<ImageStream />);
106-
expect(wrapper.find(Alert)).toHaveLength(1);
137+
138+
render(<ImageStream />);
139+
140+
expect(screen.getByText('No Image streams tags found')).toBeInTheDocument();
141+
expect(screen.getByText('No tags are available in Image Stream python')).toBeInTheDocument();
107142
});
108143
});

0 commit comments

Comments
 (0)