Skip to content

Commit 57368f5

Browse files
Convert 'kbn-unified-data-table' tests
1 parent a06e8f5 commit 57368f5

13 files changed

Lines changed: 882 additions & 933 deletions

src/platform/packages/shared/kbn-unified-data-table/src/components/build_copy_column_button.test.tsx

Lines changed: 57 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,113 +8,126 @@
88
*/
99

1010
import React from 'react';
11+
import userEvent from '@testing-library/user-event';
12+
import { buildCopyColumnNameButton, buildCopyColumnValuesButton } from './build_copy_column_button';
13+
import { dataTableContextMock } from '../../__mocks__/table_context';
1114
import { EuiButton } from '@elastic/eui';
12-
import { mountWithIntl } from '@kbn/test-jest-helpers';
15+
import { renderWithI18n } from '@kbn/test-jest-helpers';
16+
import { screen } from '@testing-library/react';
1317
import { servicesMock } from '../../__mocks__/services';
14-
import { dataTableContextMock } from '../../__mocks__/table_context';
15-
import { buildCopyColumnNameButton, buildCopyColumnValuesButton } from './build_copy_column_button';
1618

1719
const execCommandMock = (global.document.execCommand = jest.fn());
18-
const warn = jest.spyOn(console, 'warn').mockImplementation(() => {});
20+
const originalClipboard = global.window.navigator.clipboard;
21+
22+
const mockClipboard = () => {
23+
const writeText = jest.fn();
24+
25+
Object.assign(navigator, {
26+
clipboard: { writeText },
27+
});
28+
29+
return writeText;
30+
};
1931

2032
describe('Build a column button to copy to clipboard', () => {
21-
it('should copy a column name to clipboard on click', () => {
22-
const { label, iconType, onClick } = buildCopyColumnNameButton({
33+
beforeEach(() => {
34+
jest.clearAllMocks();
35+
});
36+
37+
afterEach(() => {
38+
jest.restoreAllMocks();
39+
Object.assign(navigator, {
40+
clipboard: originalClipboard,
41+
});
42+
});
43+
44+
it('should copy a column name to clipboard on click', async () => {
45+
const { iconType, label, onClick } = buildCopyColumnNameButton({
2346
columnDisplayName: 'test-field-name',
2447
toastNotifications: servicesMock.toastNotifications,
2548
});
2649
execCommandMock.mockImplementationOnce(() => true);
2750

28-
const wrapper = mountWithIntl(
51+
renderWithI18n(
2952
<EuiButton iconType={iconType} onClick={onClick}>
3053
{label}
3154
</EuiButton>
3255
);
3356

34-
wrapper.find('button').simulate('click');
57+
await userEvent.click(screen.getByRole('button', { name: 'Copy name' }));
3558

3659
expect(execCommandMock).toHaveBeenCalledWith('copy');
37-
expect(warn).not.toHaveBeenCalled();
60+
expect(servicesMock.toastNotifications.addWarning).not.toHaveBeenCalled();
3861
});
3962

40-
it('should copy column values to clipboard on click', async () => {
41-
const originalClipboard = global.window.navigator.clipboard;
42-
43-
Object.defineProperty(navigator, 'clipboard', {
44-
value: {
45-
writeText: jest.fn(),
46-
},
47-
writable: true,
48-
});
49-
50-
const { label, iconType, onClick } = buildCopyColumnValuesButton({
63+
it('should copy regular column values to clipboard on click', async () => {
64+
const writeText = mockClipboard();
65+
const { iconType, label, onClick } = buildCopyColumnValuesButton({
5166
columnId: 'extension',
5267
columnDisplayName: 'custom_extension',
53-
toastNotifications: servicesMock.toastNotifications,
5468
rowsCount: 3,
69+
toastNotifications: servicesMock.toastNotifications,
5570
valueToStringConverter: dataTableContextMock.valueToStringConverter,
5671
});
5772

58-
const wrapper = mountWithIntl(
73+
renderWithI18n(
5974
<EuiButton iconType={iconType} onClick={onClick}>
6075
{label}
6176
</EuiButton>
6277
);
6378

64-
await wrapper.find('button').simulate('click');
79+
await userEvent.click(screen.getByRole('button', { name: 'Copy column' }));
6580

6681
// first row out of 3 rows does not have a value
67-
expect(navigator.clipboard.writeText).toHaveBeenCalledWith('"custom_extension"\n\njpg\ngif');
82+
expect(writeText).toHaveBeenCalledWith('"custom_extension"\n\njpg\ngif');
83+
});
6884

69-
const {
70-
label: labelSource,
71-
iconType: iconTypeSource,
72-
onClick: onClickSource,
73-
} = buildCopyColumnValuesButton({
74-
columnId: '_source',
85+
it('should copy source column values to clipboard on click', async () => {
86+
const writeText = mockClipboard();
87+
const { iconType, label, onClick } = buildCopyColumnValuesButton({
7588
columnDisplayName: 'Document',
89+
columnId: '_source',
90+
rowsCount: 3,
7691
toastNotifications: servicesMock.toastNotifications,
7792
valueToStringConverter: dataTableContextMock.valueToStringConverter,
78-
rowsCount: 3,
7993
});
8094

81-
const wrapperSource = mountWithIntl(
82-
<EuiButton iconType={iconTypeSource} onClick={onClickSource}>
83-
{labelSource}
95+
renderWithI18n(
96+
<EuiButton iconType={iconType} onClick={onClick}>
97+
{label}
8498
</EuiButton>
8599
);
86100

87-
await wrapperSource.find('button').simulate('click');
101+
await userEvent.click(screen.getByRole('button', { name: 'Copy column' }));
88102

89103
// first row out of 3 rows does not have a value
90-
expect(navigator.clipboard.writeText).toHaveBeenNthCalledWith(
91-
2,
104+
expect(writeText).toHaveBeenCalledWith(
92105
'Document\n{"bytes":20,"date":"2020-20-01T12:12:12.123","message":"test1","_index":"i","_score":1}\n' +
93106
'{"date":"2020-20-01T12:12:12.124","extension":"jpg","name":"test2","_index":"i","_score":1}\n' +
94107
'{"bytes":50,"date":"2020-20-01T12:12:12.124","extension":"gif","name":"test3","_index":"i","_score":1}'
95108
);
96-
97-
Object.defineProperty(navigator, 'clipboard', {
98-
value: originalClipboard,
99-
});
100109
});
101110

102-
it('should not copy to clipboard on click', () => {
111+
it('should not copy to clipboard on click', async () => {
103112
const { label, iconType, onClick } = buildCopyColumnNameButton({
104113
columnDisplayName: 'test-field-name',
105114
toastNotifications: servicesMock.toastNotifications,
106115
});
107116
execCommandMock.mockImplementationOnce(() => false);
117+
const warn = jest.spyOn(console, 'warn').mockImplementation(() => {});
108118

109-
const wrapper = mountWithIntl(
119+
renderWithI18n(
110120
<EuiButton iconType={iconType} onClick={onClick}>
111121
{label}
112122
</EuiButton>
113123
);
114124

115-
wrapper.find('button').simulate('click');
125+
await userEvent.click(screen.getByRole('button', { name: 'Copy name' }));
116126

117127
expect(execCommandMock).toHaveBeenCalledWith('copy');
118128
expect(warn).toHaveBeenCalledWith('Unable to copy to clipboard.');
129+
expect(servicesMock.toastNotifications.addWarning).toHaveBeenCalledWith({
130+
title: 'Unable to copy to clipboard in this browser',
131+
});
119132
});
120133
});

src/platform/packages/shared/kbn-unified-data-table/src/components/build_edit_field_button.test.tsx

Lines changed: 63 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -7,120 +7,110 @@
77
* License v3.0 only", or the "Server Side Public License, v 1".
88
*/
99

10+
import type { DataViewField } from '@kbn/data-views-plugin/common';
1011
import type { EuiListGroupItemProps } from '@elastic/eui';
11-
import { EuiListGroupItem } from '@elastic/eui';
12-
import type { DataView, DataViewField } from '@kbn/data-views-plugin/common';
13-
import { mountWithIntl } from '@kbn/test-jest-helpers';
1412
import React from 'react';
15-
import { buildDataViewMock } from '@kbn/discover-utils/src/__mocks__';
16-
import { servicesMock } from '../../__mocks__/services';
13+
import userEvent from '@testing-library/user-event';
1714
import { buildEditFieldButton } from './build_edit_field_button';
15+
import { dataViewMock } from '@kbn/discover-utils/src/__mocks__';
16+
import { EuiListGroupItem } from '@elastic/eui';
17+
import { renderWithI18n } from '@kbn/test-jest-helpers';
18+
import { screen } from '@testing-library/react';
19+
import { servicesMock } from '../../__mocks__/services';
20+
21+
const getField = (name: string) => dataViewMock.getFieldByName(name) as DataViewField;
1822

19-
const dataView = buildDataViewMock({
20-
name: 'test-index-view',
21-
fields: [
22-
{
23-
name: '_source',
24-
type: '_source',
25-
},
26-
{
27-
name: 'unknown_field',
28-
type: 'unknown',
29-
},
30-
{
31-
name: 'unknown_selected_field',
32-
type: 'unknown',
33-
},
34-
{
35-
name: 'bytes',
36-
type: 'number',
37-
},
38-
{
39-
name: 'runtime_field',
40-
type: 'unknown',
41-
runtimeField: {
42-
type: 'unknown',
43-
script: {
44-
source: "emit('hello world')",
45-
},
46-
},
47-
},
48-
] as DataView['fields'],
23+
const unknownField = dataViewMock.fields.create({
24+
aggregatable: false,
25+
name: 'unknown_field',
26+
searchable: false,
27+
type: 'unknown',
4928
});
5029

5130
describe('buildEditFieldButton', () => {
31+
beforeEach(() => {
32+
jest.clearAllMocks();
33+
});
34+
35+
afterEach(() => {
36+
jest.restoreAllMocks();
37+
});
38+
5239
it('should return null if the field is not editable', () => {
53-
const field = dataView.getFieldByName('unknown_field') as DataViewField;
5440
const button = buildEditFieldButton({
55-
hasEditDataViewPermission: () => servicesMock.dataViewEditor.userPermissions.editDataView(),
56-
dataView,
57-
field,
41+
dataView: dataViewMock,
5842
editField: jest.fn(),
43+
field: unknownField,
44+
hasEditDataViewPermission: () => servicesMock.dataViewEditor.userPermissions.editDataView(),
5945
});
46+
6047
expect(button).toBeNull();
6148
});
6249

6350
it('should return null if the data view is not editable', () => {
6451
jest
6552
.spyOn(servicesMock.dataViewEditor.userPermissions, 'editDataView')
6653
.mockReturnValueOnce(false);
67-
const field = dataView.getFieldByName('bytes') as DataViewField;
54+
55+
const field = getField('bytes');
6856
const button = buildEditFieldButton({
69-
hasEditDataViewPermission: () => servicesMock.dataViewEditor.userPermissions.editDataView(),
70-
dataView,
71-
field,
57+
dataView: dataViewMock,
7258
editField: jest.fn(),
59+
field,
60+
hasEditDataViewPermission: () => servicesMock.dataViewEditor.userPermissions.editDataView(),
7361
});
62+
7463
expect(button).toBeNull();
7564
});
7665

7766
it('should return null if passed the _source field', () => {
78-
const field = dataView.getFieldByName('_source') as DataViewField;
67+
const field = getField('_source');
7968
const button = buildEditFieldButton({
80-
hasEditDataViewPermission: () => servicesMock.dataViewEditor.userPermissions.editDataView(),
81-
dataView,
82-
field,
69+
dataView: dataViewMock,
8370
editField: jest.fn(),
71+
field,
72+
hasEditDataViewPermission: () => servicesMock.dataViewEditor.userPermissions.editDataView(),
8473
});
74+
8575
expect(button).toBeNull();
8676
});
8777

8878
it('should return EuiListGroupItemProps if the field and data view are editable', () => {
89-
const field = dataView.getFieldByName('bytes') as DataViewField;
79+
const field = getField('bytes');
9080
const button = buildEditFieldButton({
91-
hasEditDataViewPermission: () => servicesMock.dataViewEditor.userPermissions.editDataView(),
92-
dataView,
93-
field,
81+
dataView: dataViewMock,
9482
editField: jest.fn(),
95-
});
83+
field,
84+
hasEditDataViewPermission: () => servicesMock.dataViewEditor.userPermissions.editDataView(),
85+
}) as EuiListGroupItemProps;
86+
9687
expect(button).not.toBeNull();
97-
expect(button).toMatchInlineSnapshot(`
98-
Object {
99-
"data-test-subj": "gridEditFieldButton",
100-
"iconProps": Object {
101-
"size": "m",
102-
},
103-
"iconType": "pencil",
104-
"label": <Memo(MemoizedFormattedMessage)
105-
defaultMessage="Edit data view field"
106-
id="unifiedDataTable.grid.editFieldButton"
107-
/>,
108-
"onClick": [Function],
109-
}
110-
`);
88+
expect(button).toMatchObject({
89+
'data-test-subj': 'gridEditFieldButton',
90+
iconProps: { size: 'm' },
91+
iconType: 'pencil',
92+
});
93+
expect(button.onClick).toEqual(expect.any(Function));
94+
95+
renderWithI18n(<EuiListGroupItem {...button} />);
96+
97+
expect(screen.getByText('Edit data view field')).toBeVisible();
11198
});
11299

113-
it('should call editField when onClick is triggered', () => {
114-
const field = dataView.getFieldByName('bytes') as DataViewField;
100+
it('should call editField when onClick is triggered', async () => {
115101
const editField = jest.fn();
102+
const field = getField('bytes');
116103
const buttonProps = buildEditFieldButton({
117-
hasEditDataViewPermission: () => servicesMock.dataViewEditor.userPermissions.editDataView(),
118-
dataView,
119-
field,
104+
dataView: dataViewMock,
120105
editField,
106+
field,
107+
hasEditDataViewPermission: () => servicesMock.dataViewEditor.userPermissions.editDataView(),
121108
}) as EuiListGroupItemProps;
122-
const listItem = mountWithIntl(<EuiListGroupItem {...buttonProps} />);
123-
listItem.find('button').simulate('click');
109+
110+
renderWithI18n(<EuiListGroupItem {...buttonProps} />);
111+
112+
await userEvent.click(screen.getByText('Edit data view field'));
113+
124114
expect(editField).toHaveBeenCalledTimes(1);
125115
expect(editField).toHaveBeenCalledWith('bytes');
126116
});

0 commit comments

Comments
 (0)