Skip to content

Commit f7673ba

Browse files
Luke Bowermangithub-actions[bot]lukelooker
authored
test(DataTableCell): Improved code coverage (#1856)
* test(DataTableCell): Improved code coverage * chore: image-snapshot updates (#1858) Co-authored-by: lukelooker <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: lukelooker <[email protected]>
1 parent 54c4ab0 commit f7673ba

File tree

10 files changed

+222
-9
lines changed

10 files changed

+222
-9
lines changed
159 Bytes
Loading
149 Bytes
Loading
-2 Bytes
Loading
14 Bytes
Loading
-3 Bytes
Loading
4 Bytes
Loading
0 Bytes
Loading
82 Bytes
Loading
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/*
2+
3+
MIT License
4+
5+
Copyright (c) 2020 Looker Data Sciences, Inc.
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.
24+
25+
*/
26+
27+
import React from 'react'
28+
import { renderWithTheme } from '@looker/components-test-utils'
29+
import { fireEvent, screen } from '@testing-library/react'
30+
import userEvent from '@testing-library/user-event'
31+
import { DataTableCell } from './DataTableCell'
32+
33+
describe('DataTableCell', () => {
34+
test('Basic content', () => {
35+
renderWithTheme(
36+
<table>
37+
<tbody>
38+
<tr>
39+
<DataTableCell>Cell content</DataTableCell>
40+
</tr>
41+
</tbody>
42+
</table>
43+
)
44+
45+
expect(screen.getByText('Cell content')).toBeInTheDocument()
46+
})
47+
48+
test('indicator', () => {
49+
renderWithTheme(
50+
<table>
51+
<tbody>
52+
<tr>
53+
<DataTableCell indicator="FauxIcon">Cell content</DataTableCell>
54+
</tr>
55+
</tbody>
56+
</table>
57+
)
58+
59+
expect(screen.getByText('FauxIcon')).toBeInTheDocument()
60+
})
61+
62+
test('description & indicator', () => {
63+
renderWithTheme(
64+
<table>
65+
<tbody>
66+
<tr>
67+
<DataTableCell indicator="FauxIcon" description="descriptive text">
68+
Cell content
69+
</DataTableCell>
70+
</tr>
71+
</tbody>
72+
</table>
73+
)
74+
75+
expect(screen.getByText('descriptive text')).toBeInTheDocument()
76+
expect(screen.getByText('FauxIcon')).toBeInTheDocument()
77+
})
78+
79+
test('onKeyUp callback', () => {
80+
const onKeyUp = jest.fn()
81+
82+
renderWithTheme(
83+
<table>
84+
<tbody>
85+
<tr>
86+
<DataTableCell onKeyUp={onKeyUp}>Cell content</DataTableCell>
87+
</tr>
88+
</tbody>
89+
</table>
90+
)
91+
92+
fireEvent.keyUp(screen.getByText('Cell content'), {
93+
charCode: 13,
94+
code: 13,
95+
key: 'Enter',
96+
})
97+
98+
expect(onKeyUp).toHaveBeenCalledTimes(1)
99+
})
100+
101+
test('keyup triggers :focus-visible blur removes', () => {
102+
renderWithTheme(
103+
<table>
104+
<tbody>
105+
<tr>
106+
<DataTableCell>Cell content</DataTableCell>
107+
</tr>
108+
</tbody>
109+
</table>
110+
)
111+
112+
const cell = screen.getByText('Cell content')
113+
const td = cell.closest('td')
114+
expect(td).toHaveStyleRule('outline', 'none', {
115+
modifier: ':focus',
116+
})
117+
118+
fireEvent.keyUp(cell, {
119+
charCode: 13,
120+
code: 13,
121+
key: 'Enter',
122+
})
123+
124+
expect(td).toHaveStyleRule('outline', '1px solid #6C43E0', {
125+
modifier: ':focus',
126+
})
127+
128+
fireEvent.blur(cell)
129+
130+
expect(td).toHaveStyleRule('outline', 'none', {
131+
modifier: ':focus',
132+
})
133+
})
134+
135+
test('onClick callback + unset :focus-visible', () => {
136+
const onClick = jest.fn()
137+
138+
renderWithTheme(
139+
<table>
140+
<tbody>
141+
<tr>
142+
<DataTableCell onClick={onClick}>Cell content</DataTableCell>
143+
</tr>
144+
</tbody>
145+
</table>
146+
)
147+
148+
const cell = screen.getByText('Cell content')
149+
const td = cell.closest('td')
150+
151+
// Apply focus to cell
152+
fireEvent.keyUp(cell, { key: 'Enter' })
153+
expect(td).toHaveStyleRule('outline', '1px solid #6C43E0', {
154+
modifier: ':focus',
155+
})
156+
157+
userEvent.click(cell)
158+
159+
/**
160+
* TODO: Missing coverage
161+
* Frustratingly, this doesn't work in test but appears to work properly in real-world
162+
*
163+
* expect(td).toHaveStyleRule('outline', 'none', {
164+
* modifier: ':focus',
165+
* })
166+
*/
167+
expect(onClick).toHaveBeenCalledTimes(1)
168+
})
169+
170+
test('tabIndex set properly on tabbable ', () => {
171+
renderWithTheme(
172+
<table>
173+
<tbody>
174+
<tr>
175+
<DataTableCell>
176+
<button>Click here</button>
177+
</DataTableCell>
178+
</tr>
179+
</tbody>
180+
</table>
181+
)
182+
183+
expect(screen.getByRole('button')).toHaveAttribute('tabIndex', '-1')
184+
})
185+
186+
test('onBlur callback', () => {
187+
const onBlur = jest.fn()
188+
189+
renderWithTheme(
190+
<table>
191+
<tbody>
192+
<tr>
193+
<DataTableCell onBlur={onBlur}>Cell content</DataTableCell>
194+
</tr>
195+
</tbody>
196+
</table>
197+
)
198+
199+
const cell = screen.getByText('Cell content')
200+
cell.focus()
201+
202+
userEvent.tab()
203+
expect(onBlur).toHaveBeenCalledTimes(1)
204+
})
205+
})

packages/components/src/DataTable/Column/DataTableCell.tsx

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ import React, {
3131
useEffect,
3232
useRef,
3333
useState,
34+
FocusEvent,
35+
KeyboardEvent,
36+
MouseEvent,
3437
} from 'react'
3538
import styled from 'styled-components'
3639
import { CompatibleHTMLProps } from '@looker/design-tokens'
@@ -51,26 +54,31 @@ export interface DataTableCellProps
5154

5255
const DataTableCellLayout = forwardRef(
5356
(props: DataTableCellProps, forwardedRef: Ref<HTMLElement>) => {
54-
const { children, description, indicator, onBlur, onKeyUp, size } = props
57+
const {
58+
children,
59+
description,
60+
indicator,
61+
onBlur,
62+
onClick,
63+
onKeyUp,
64+
size,
65+
} = props
5566

5667
const [isFocusVisible, setFocusVisible] = useState(false)
5768

58-
const handleOnKeyUp = (
59-
event: React.KeyboardEvent<HTMLTableDataCellElement>
60-
) => {
69+
const handleOnKeyUp = (event: KeyboardEvent<HTMLTableDataCellElement>) => {
6170
setFocusVisible(true)
6271
onKeyUp && onKeyUp(event)
6372
}
6473

65-
const handleOnBlur = (
66-
event: React.FocusEvent<HTMLTableDataCellElement>
67-
) => {
74+
const handleOnBlur = (event: FocusEvent<HTMLTableDataCellElement>) => {
6875
setFocusVisible(false)
6976
onBlur && onBlur(event)
7077
}
7178

72-
const onClick = () => {
79+
const handleOnClick = (event: MouseEvent<HTMLTableDataCellElement>) => {
7380
setFocusVisible(false)
81+
onClick && onClick(event)
7482
}
7583

7684
let content =
@@ -120,7 +128,7 @@ const DataTableCellLayout = forwardRef(
120128
<FocusableCell
121129
focusVisible={isFocusVisible}
122130
onBlur={handleOnBlur}
123-
onClick={onClick}
131+
onClick={handleOnClick}
124132
onKeyUp={handleOnKeyUp}
125133
ref={forkedRef}
126134
{...props}

0 commit comments

Comments
 (0)