Skip to content

Commit 56c8215

Browse files
committed
Write tests for data_grid_cell
- Uses a non-inline snapshot, since this is a fairly complex component - NOTE: this is only ~80% coverage, as a lot of the class fns are extremely native DOM specific (focus, etc.) and is better tested in Cypress than Jest
1 parent c092407 commit 56c8215

2 files changed

Lines changed: 331 additions & 0 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`EuiDataGridCell renders 1`] = `
4+
<EuiDataGridCell
5+
colIndex={0}
6+
columnId="someColumn"
7+
interactiveCellId="someId"
8+
isExpandable={true}
9+
popoverContent={[Function]}
10+
renderCellValue={[Function]}
11+
rowIndex={0}
12+
visibleRowIndex={0}
13+
>
14+
<div
15+
className="euiDataGridRowCell"
16+
data-test-subj="dataGridRowCell"
17+
onBlur={[Function]}
18+
onFocus={[Function]}
19+
onKeyDown={[Function]}
20+
onMouseEnter={[Function]}
21+
role="gridcell"
22+
style={
23+
Object {
24+
"width": undefined,
25+
}
26+
}
27+
tabIndex={-1}
28+
>
29+
<div
30+
className="euiDataGridRowCell__expandFlex"
31+
>
32+
<div
33+
className="euiDataGridRowCell__expandContent"
34+
>
35+
<Memo()
36+
colIndex={0}
37+
columnId="someColumn"
38+
isDetails={false}
39+
isExpandable={true}
40+
isExpanded={false}
41+
renderCellValue={[Function]}
42+
rowIndex={0}
43+
setCellContentsRef={[Function]}
44+
setCellProps={[Function]}
45+
visibleRowIndex={0}
46+
>
47+
<div
48+
className="euiDataGridRowCell__truncate"
49+
style={Object {}}
50+
>
51+
<renderCellValue
52+
columnId="someColumn"
53+
data-test-subj="cell-content"
54+
isDetails={false}
55+
isExpandable={true}
56+
isExpanded={false}
57+
rowIndex={0}
58+
setCellProps={[Function]}
59+
visibleRowIndex={0}
60+
>
61+
<div>
62+
<button
63+
data-datagrid-interactable="true"
64+
>
65+
hello
66+
</button>
67+
<button
68+
data-datagrid-interactable="true"
69+
>
70+
world
71+
</button>
72+
</div>
73+
</renderCellValue>
74+
</div>
75+
<EuiScreenReaderOnly>
76+
<p
77+
className="euiScreenReaderOnly"
78+
>
79+
Row: 1; Column: 1
80+
</p>
81+
</EuiScreenReaderOnly>
82+
</Memo()>
83+
</div>
84+
</div>
85+
</div>
86+
</EuiDataGridCell>
87+
`;
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
import React from 'react';
10+
import { mount, ReactWrapper } from 'enzyme';
11+
import { keys } from '../../../services';
12+
13+
import { EuiDataGridCell } from './data_grid_cell';
14+
15+
describe('EuiDataGridCell', () => {
16+
const requiredProps = {
17+
rowIndex: 0,
18+
visibleRowIndex: 0,
19+
colIndex: 0,
20+
columnId: 'someColumn',
21+
interactiveCellId: 'someId',
22+
isExpandable: true,
23+
renderCellValue: () => (
24+
<div>
25+
<button data-datagrid-interactable="true">hello</button>
26+
<button data-datagrid-interactable="true">world</button>
27+
</div>
28+
),
29+
popoverContent: () => <div>popover</div>,
30+
};
31+
32+
const mountEuiDataGridCellWithContext = ({ ...props } = {}) => {
33+
const focusContext = {
34+
setFocusedCell: jest.fn(),
35+
onFocusUpdate: jest.fn(),
36+
};
37+
return mount(<EuiDataGridCell {...requiredProps} {...props} />, {
38+
context: focusContext,
39+
});
40+
};
41+
42+
it('renders', () => {
43+
const component = mountEuiDataGridCellWithContext();
44+
expect(component).toMatchSnapshot();
45+
});
46+
47+
it('renders cell buttons', () => {
48+
const component = mountEuiDataGridCellWithContext({
49+
isExpandable: false,
50+
column: {
51+
id: 'someColumn',
52+
cellActions: [() => <button />],
53+
},
54+
});
55+
component.setState({ popoverIsOpen: true });
56+
57+
const cellButtons = component.find('EuiDataGridCellButtons');
58+
expect(component.find('EuiDataGridCellButtons')).toHaveLength(1);
59+
60+
// Should handle re-closing the popover correctly
61+
62+
(cellButtons.prop('onExpandClick') as Function)();
63+
expect(component.state('popoverIsOpen')).toEqual(false);
64+
65+
component.setState({ popoverIsOpen: true });
66+
(cellButtons.prop('closePopover') as Function)();
67+
expect(component.state('popoverIsOpen')).toEqual(false);
68+
});
69+
70+
describe('shouldComponentUpdate', () => {
71+
let shouldComponentUpdate: jest.SpyInstance;
72+
let component: ReactWrapper;
73+
74+
beforeEach(() => {
75+
shouldComponentUpdate = jest.spyOn(
76+
EuiDataGridCell.prototype,
77+
'shouldComponentUpdate'
78+
);
79+
component = mountEuiDataGridCellWithContext();
80+
});
81+
afterEach(() => {
82+
shouldComponentUpdate.mockRestore();
83+
});
84+
85+
describe('should return true', () => {
86+
afterEach(() => {
87+
expect(shouldComponentUpdate).toHaveReturnedWith(true);
88+
});
89+
90+
describe('when props change:', () => {
91+
it('rowIndex', () => {
92+
component.setProps({ rowIndex: 1 });
93+
});
94+
it('visibleRowIndex', () => {
95+
component.setProps({ visibleRowIndex: 1 });
96+
});
97+
it('colIndex', () => {
98+
component.setProps({ colIndex: 1 });
99+
});
100+
it('columnId', () => {
101+
component.setProps({ columnId: 'test' });
102+
});
103+
it('columnType', () => {
104+
component.setProps({ columnType: 'string' });
105+
});
106+
it('width', () => {
107+
component.setProps({ width: 30 });
108+
});
109+
it('renderCellValue', () => {
110+
component.setProps({ renderCellValue: () => <div>test</div> });
111+
});
112+
it('interactiveCellId', () => {
113+
component.setProps({ interactiveCellId: 'test' });
114+
});
115+
it('popoverContent', () => {
116+
component.setProps({ popoverContent: () => <div>test</div> });
117+
});
118+
it('style', () => {
119+
component.setProps({ style: {} });
120+
component.setProps({ style: { top: 0 } });
121+
component.setProps({ style: { top: 0, left: 0 } });
122+
component.setProps({ style: { top: 0, left: 0, width: 50 } });
123+
component.setProps({
124+
style: { top: 0, left: 0, width: 50, height: 10 },
125+
});
126+
});
127+
});
128+
129+
describe('when state changes:', () => {
130+
it('cellProps', () => {
131+
component.setState({ cellProps: {} });
132+
});
133+
it('popoverIsOpen', () => {
134+
component.setState({ popoverIsOpen: true });
135+
});
136+
it('isEntered', () => {
137+
component.setState({ isEntered: true });
138+
});
139+
it('isFocused', () => {
140+
component.setState({ isFocused: true });
141+
});
142+
it('enableInteractions', () => {
143+
component.setState({ enableInteractions: true });
144+
});
145+
it('disableCellTabIndex', () => {
146+
component.setState({ disableCellTabIndex: true });
147+
});
148+
});
149+
150+
it('when cell height changes', () => {
151+
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', {
152+
configurable: true,
153+
value: 10,
154+
});
155+
const getRowHeight = jest.fn(() => 20);
156+
157+
component.setProps({ getRowHeight });
158+
});
159+
});
160+
161+
it('should not update for prop/state changes not specified above', () => {
162+
component.setProps({ className: 'test' });
163+
expect(shouldComponentUpdate).toHaveReturnedWith(false);
164+
});
165+
});
166+
167+
describe('componentDidUpdate', () => {
168+
it('resets cell props when the cell columnId changes', () => {
169+
const setState = jest.spyOn(EuiDataGridCell.prototype, 'setState');
170+
const component = mountEuiDataGridCellWithContext();
171+
172+
component.setProps({ columnId: 'newColumnId' });
173+
expect(setState).toHaveBeenCalledWith({ cellProps: {} });
174+
});
175+
});
176+
177+
// TODO: Test ResizeObserver logic in Cypress
178+
179+
// TODO: Test interacting/focus/tabbing in Cypress instead of Jest
180+
describe('interactions', () => {
181+
describe('keyboard events', () => {
182+
it('when cell is expandable', () => {
183+
const component = mountEuiDataGridCellWithContext();
184+
const preventDefault = jest.fn();
185+
186+
component.simulate('keyDown', { preventDefault, key: keys.ENTER });
187+
component.simulate('keyDown', { preventDefault, key: keys.F2 });
188+
189+
expect(component.state('popoverIsOpen')).toEqual(true);
190+
});
191+
192+
it('when cell is not expandable', () => {
193+
const component = mountEuiDataGridCellWithContext({
194+
isExpandable: false,
195+
});
196+
const preventDefault = jest.fn();
197+
198+
component.simulate('keyDown', { preventDefault, key: keys.ENTER });
199+
// TODO: Assert that tabbing should be enabled
200+
expect(component.state('isEntered')).toEqual(true);
201+
202+
component.simulate('keyDown', { preventDefault, key: keys.F2 });
203+
// TODO: Assert that tabbing should be prevented
204+
expect(component.state('isEntered')).toEqual(false);
205+
206+
component.simulate('keyDown', { preventDefault, key: keys.F2 });
207+
// TODO: Assert that tabbing should be enabled
208+
expect(component.state('isEntered')).toEqual(true);
209+
210+
component.simulate('keyDown', { preventDefault, key: keys.ENTER });
211+
component.simulate('keyDown', { preventDefault, key: keys.ESCAPE });
212+
// TODO: Assert that tabbing should be prevented
213+
expect(component.state('isEntered')).toEqual(false);
214+
});
215+
});
216+
217+
it('mouse event', () => {
218+
const component = mountEuiDataGridCellWithContext();
219+
component.simulate('mouseEnter');
220+
expect(component.state('enableInteractions')).toEqual(true);
221+
});
222+
223+
it('focus/blur events', () => {
224+
const component = mountEuiDataGridCellWithContext();
225+
component.simulate('focus');
226+
component.simulate('blur');
227+
expect(component.state('disableCellTabIndex')).toEqual(false);
228+
});
229+
});
230+
231+
it('renders certain classes/styles if rowHeightOptions is passed', () => {
232+
const component = mountEuiDataGridCellWithContext({
233+
rowHeightsOptions: {
234+
defaultHeight: 20,
235+
rowHeights: { 0: 10 },
236+
},
237+
});
238+
component.setState({ popoverIsOpen: true });
239+
240+
expect(
241+
component.find('.euiDataGridRowCell__contentByHeight').exists()
242+
).toBe(true);
243+
});
244+
});

0 commit comments

Comments
 (0)