Skip to content

Commit ca883f9

Browse files
committed
chore: update unit tests to RTL
1 parent 318c7ef commit ca883f9

17 files changed

Lines changed: 480 additions & 354 deletions

__mocks__/domPolyfills.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* eslint-disable */
2+
3+
// Polyfill for Element.prototype.getRootNode (missing in older jsdom)
4+
if (!Element.prototype.getRootNode) {
5+
Element.prototype.getRootNode = function (options) {
6+
var node = this;
7+
while (node.parentNode) {
8+
node = node.parentNode;
9+
}
10+
return node;
11+
};
12+
}
13+
14+
// Polyfill for Element.prototype.closest (missing in older jsdom)
15+
if (!Element.prototype.closest) {
16+
Element.prototype.closest = function (selector) {
17+
var el = this;
18+
while (el) {
19+
if (el.matches && el.matches(selector)) {
20+
return el;
21+
}
22+
el = el.parentElement;
23+
}
24+
return null;
25+
};
26+
}

before-tests.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
11
/* eslint-env node */
22

3-
import { configure } from 'enzyme';
4-
import * as Adapter from 'enzyme-adapter-react-16';
5-
63
import 'url-search-params-polyfill';
7-
8-
// http://airbnb.io/enzyme/docs/installation/index.html#working-with-react-16
9-
configure({ adapter: new Adapter() });

jest-setup-framework.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
require('@testing-library/jest-dom');

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@
102102
"./__mocks__/serverFlags.js",
103103
"./__mocks__/mutationObserver.js",
104104
"./__mocks__/websocket.js",
105-
"./before-tests.js"
105+
"./before-tests.js",
106+
"./__mocks__/domPolyfills.js"
106107
],
107108
"coverageDirectory": "__coverage__",
108109
"coverageReporters": [
@@ -115,7 +116,8 @@
115116
"src/**/*.{js,jsx,ts,tsx}",
116117
"!**/node_modules/**"
117118
],
118-
"resolver": "./jest-resolver.js"
119+
"resolver": "./jest-resolver.js",
120+
"setupTestFrameworkScriptFile": "./jest-setup-framework.js"
119121
},
120122
"engines": {
121123
"node": ">=18.0.0"

packages/module/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"@rollup/plugin-commonjs": "^17.0.0",
6767
"@rollup/plugin-json": "^4.1.0",
6868
"@rollup/plugin-node-resolve": "^11.1.0",
69+
"@testing-library/jest-dom": "^6.9.1",
6970
"@testing-library/react": "^13.4.0",
7071
"@types/dompurify": "^3.0.5",
7172
"@types/enzyme": "^3.10.7",
Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,38 @@
1-
import { shallow } from 'enzyme';
2-
import MarkdownCopyClipboard, { CopyClipboard } from '../MarkdownCopyClipboard';
1+
import { render } from '@testing-library/react';
2+
import {
3+
QuickStartContext,
4+
QuickStartContextDefaults,
5+
} from '@quickstarts/utils/quick-start-context';
6+
import MarkdownCopyClipboard from '../MarkdownCopyClipboard';
7+
import { MARKDOWN_COPY_BUTTON_ID } from '../const';
38
import { htmlDocumentForCopyClipboard } from './test-data';
49

10+
const contextValues = {
11+
...QuickStartContextDefaults,
12+
getResource: (key: string) => key,
13+
};
14+
515
describe('MarkdownCopyClipboard', () => {
616
beforeAll(() => {
717
document.body.innerHTML = htmlDocumentForCopyClipboard;
818
});
19+
920
it('should render null if no element is found', () => {
10-
const wrapper = shallow(
11-
<MarkdownCopyClipboard docContext={document} rootSelector="#copy-markdown-3" />,
21+
const { container } = render(
22+
<QuickStartContext.Provider value={contextValues}>
23+
<MarkdownCopyClipboard docContext={document} rootSelector="#copy-markdown-3" />
24+
</QuickStartContext.Provider>,
1225
);
13-
expect(wrapper.isEmptyRender()).toBe(true);
14-
expect(wrapper.find(CopyClipboard).exists()).toBe(false);
26+
expect(container.firstChild).toBeNull();
1527
});
1628

17-
it('should render null if no element is found', () => {
18-
const wrapper = shallow(
19-
<MarkdownCopyClipboard docContext={document} rootSelector="#copy-markdown-1" />,
29+
it('should render copy targets when rootSelector matches buttons in the document', () => {
30+
render(
31+
<QuickStartContext.Provider value={contextValues}>
32+
<MarkdownCopyClipboard docContext={document} rootSelector="#copy-markdown-1" />
33+
</QuickStartContext.Provider>,
2034
);
21-
expect(wrapper.isEmptyRender()).toBe(false);
22-
expect(wrapper.find(CopyClipboard).exists()).toBe(true);
35+
const elements = document.querySelectorAll(`#copy-markdown-1 [${MARKDOWN_COPY_BUTTON_ID}]`);
36+
expect(elements).toHaveLength(2);
2337
});
2438
});
Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,40 @@
1-
import { Gallery, Card } from '@patternfly/react-core';
2-
import { shallow } from 'enzyme';
3-
import { EmptyBox } from '@console/internal/components/utils';
1+
import { render, screen } from '@testing-library/react';
42
import { getQuickStarts } from '../../data/test-utils';
5-
import { QuickStartCatalogPage } from '../../QuickStartCatalogPage';
3+
import {
4+
QuickStartContext,
5+
QuickStartContextDefaults,
6+
} from '../../utils/quick-start-context';
67
import QuickStartCatalog from '../QuickStartCatalog';
78

8-
jest.mock('@console/shared', () => {
9-
const ActualShared = require.requireActual('@console/shared');
10-
return {
11-
...ActualShared,
12-
useQueryParams: () => new Map(),
13-
};
14-
});
9+
const contextValues = {
10+
...QuickStartContextDefaults,
11+
activeQuickStartID: '',
12+
allQuickStartStates: {},
13+
getResource: (key: string) => key,
14+
};
15+
16+
const renderWithContext = (props: any) =>
17+
render(
18+
<QuickStartContext.Provider value={contextValues}>
19+
<QuickStartCatalog {...props} />
20+
</QuickStartContext.Provider>,
21+
);
1522

1623
describe('QuickStartCatalog', () => {
17-
it('should load an emptybox if no QS exist', () => {
18-
const QuickStartCatalogProps = { quickStarts: [], onClick: jest.fn() };
19-
const QuickStartCatalogWrapper = shallow(<QuickStartCatalogPage {...QuickStartCatalogProps} />);
20-
expect(QuickStartCatalogWrapper.find(EmptyBox).exists()).toBeTruthy();
24+
it('should render an empty state if no QS exist', () => {
25+
renderWithContext({ quickStarts: [] });
26+
// When no quickstarts, the catalog renders no cards
27+
expect(screen.queryByRole('article')).not.toBeInTheDocument();
2128
});
29+
2230
it('should load a gallery if QS exist', () => {
23-
const QuickStartCatalogProps = { quickStarts: getQuickStarts(), onClick: jest.fn() };
24-
const QuickStartCatalogWrapper = shallow(<QuickStartCatalog {...QuickStartCatalogProps} />);
25-
expect(QuickStartCatalogWrapper.find(Gallery).exists()).toBeTruthy();
26-
});
27-
xit('should load galleryItems equal to the number of QS', () => {
28-
const QuickStartCatalogProps = { quickStarts: getQuickStarts(), onClick: jest.fn() };
29-
const QuickStartCatalogWrapper = shallow(<QuickStartCatalog {...QuickStartCatalogProps} />);
30-
const galleryItems = QuickStartCatalogWrapper.find(Card);
31-
expect(galleryItems.exists()).toBeTruthy();
32-
expect(galleryItems.length).toEqual(getQuickStarts().length);
31+
const quickStarts = getQuickStarts();
32+
renderWithContext({ quickStarts });
33+
// Each tile exposes the quick start display name as the title control (link-styled button)
34+
quickStarts.forEach((qs) => {
35+
expect(
36+
screen.getByRole('button', { name: qs.spec.displayName }),
37+
).toBeInTheDocument();
38+
});
3339
});
3440
});
Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,55 @@
1-
import { Card } from '@patternfly/react-core';
2-
import { shallow } from 'enzyme';
1+
import { render, screen } from '@testing-library/react';
32
import { getQuickStarts } from '../../data/test-utils';
43
import { QuickStartStatus } from '../../utils/quick-start-types';
4+
import {
5+
QuickStartContext,
6+
QuickStartContextDefaults,
7+
} from '../../utils/quick-start-context';
58
import QuickStartTile from '../QuickStartTile';
69

7-
describe('QuickStartTile', () => {
8-
const quickstarts = getQuickStarts();
10+
const contextValues = {
11+
...QuickStartContextDefaults,
12+
activeQuickStartID: '',
13+
setActiveQuickStart: jest.fn(),
14+
getResource: (key: string) => key,
15+
};
16+
17+
const quickstarts = getQuickStarts();
918

19+
const renderWithContext = (props: any) =>
20+
render(
21+
<QuickStartContext.Provider value={contextValues}>
22+
<QuickStartTile {...props} />
23+
</QuickStartContext.Provider>,
24+
);
25+
26+
describe('QuickStartTile', () => {
1027
it('should load proper catalog tile without featured property', () => {
11-
const wrapper = shallow(
12-
<QuickStartTile
13-
quickStart={quickstarts[0]}
14-
status={QuickStartStatus.NOT_STARTED}
15-
onClick={jest.fn()}
16-
isActive={false}
17-
/>,
18-
);
19-
const catalogTile = wrapper.find(Card);
20-
expect(catalogTile.exists()).toBeTruthy();
21-
expect(catalogTile.hasClass('pf-m-current')).toBe(false);
28+
const quickStart = quickstarts[0];
29+
renderWithContext({
30+
quickStart,
31+
status: QuickStartStatus.NOT_STARTED,
32+
onClick: jest.fn(),
33+
isActive: false,
34+
});
35+
expect(
36+
screen.getByRole('button', { name: quickStart.spec.displayName }),
37+
).toBeInTheDocument();
38+
// Status label is omitted for not-started tiles
39+
expect(screen.queryByText('In progress')).not.toBeInTheDocument();
2240
});
2341

2442
it('should load proper catalog tile with featured property', () => {
25-
const wrapper = shallow(
26-
<QuickStartTile
27-
quickStart={quickstarts[1]}
28-
status={QuickStartStatus.IN_PROGRESS}
29-
onClick={jest.fn()}
30-
isActive
31-
/>,
32-
);
33-
const catalogTile = wrapper.find(Card);
34-
expect(catalogTile.exists()).toBeTruthy();
35-
expect(catalogTile.hasClass('pf-m-current')).toBe(true);
43+
const quickStart = quickstarts[1];
44+
renderWithContext({
45+
quickStart,
46+
status: QuickStartStatus.IN_PROGRESS,
47+
onClick: jest.fn(),
48+
isActive: true,
49+
});
50+
expect(
51+
screen.getByRole('button', { name: quickStart.spec.displayName }),
52+
).toBeInTheDocument();
53+
expect(screen.getByText('In progress')).toBeInTheDocument();
3654
});
3755
});
Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,41 @@
1-
import { Popover } from '@patternfly/react-core';
2-
import { shallow } from 'enzyme';
1+
import { render, screen } from '@testing-library/react';
32
import { getQuickStarts } from '../../data/test-utils';
3+
import {
4+
QuickStartContext,
5+
QuickStartContextDefaults,
6+
} from '../../utils/quick-start-context';
47
import QuickStartTileDescription from '../QuickStartTileDescription';
58

6-
jest.mock('react', () => {
7-
const ActualReact = require.requireActual('react');
8-
return {
9-
...ActualReact,
10-
useContext: () => jest.fn(),
11-
};
12-
});
9+
const contextValues = {
10+
...QuickStartContextDefaults,
11+
activeQuickStartID: '',
12+
startQuickStart: jest.fn(),
13+
restartQuickStart: jest.fn(),
14+
getResource: (key: string) => key,
15+
};
1316

14-
xdescribe('QuickStartCatalog', () => {
15-
beforeEach(() => {
16-
spyOn(React, 'useContext').and.returnValue({
17-
activeQuickStartID: '',
18-
startQuickStart: () => {},
19-
restartQuickStart: () => {},
20-
getResource: (key) => `quickstart~${key}`,
21-
});
22-
});
17+
const renderWithContext = (props: any) =>
18+
render(
19+
<QuickStartContext.Provider value={contextValues}>
20+
<QuickStartTileDescription {...props} />
21+
</QuickStartContext.Provider>,
22+
);
2323

24+
describe('QuickStartTileDescription', () => {
2425
it('should show prerequisites only if provided', () => {
25-
// this quick start does not have prereqs
2626
const quickStart = getQuickStarts()[0].spec;
27-
const QuickStartTileDescriptionWrapper = shallow(
28-
<QuickStartTileDescription description={quickStart.description} />,
29-
);
30-
expect(QuickStartTileDescriptionWrapper.find(Text)).toHaveLength(0);
27+
renderWithContext({ description: quickStart.description });
28+
expect(
29+
screen.queryByRole('button', { name: 'Show prerequisites' }),
30+
).not.toBeInTheDocument();
3131
});
3232

33-
it('shoould render prerequisites inside a popover', () => {
33+
it('should render prerequisites trigger when prerequisite list is non-empty', () => {
3434
const quickStart = getQuickStarts()[2].spec;
35-
const QuickStartTileDescriptionWrapper = shallow(
36-
<QuickStartTileDescription
37-
description={quickStart.description}
38-
prerequisites={quickStart.prerequisites}
39-
/>,
40-
);
41-
expect(QuickStartTileDescriptionWrapper.find(Popover)).toHaveLength(1);
35+
renderWithContext({
36+
description: quickStart.description,
37+
prerequisites: quickStart.prerequisites,
38+
});
39+
expect(screen.getByRole('button', { name: 'Show prerequisites' })).toBeInTheDocument();
4240
});
4341
});

0 commit comments

Comments
 (0)