Merge branch '21225-project-panel-tabs' into main. Closes #21225
[arvados.git] / services / workbench2 / src / components / data-table / data-table.test.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React from "react";
6 import { mount, configure } from "enzyme";
7 import { pipe } from "lodash/fp";
8 import { TableHead, TableCell, Typography, TableBody, Button, TableSortLabel } from "@material-ui/core";
9 import Adapter from "enzyme-adapter-react-16";
10 import { DataTable, DataColumns } from "./data-table";
11 import { SortDirection, createDataColumn } from "./data-column";
12 import { DataTableFiltersPopover } from "components/data-table-filters/data-table-filters-popover";
13 import { createTree, setNode, initTreeNode } from "models/tree";
14 import { DataTableFilterItem } from "components/data-table-filters/data-table-filters-tree";
15
16 configure({ adapter: new Adapter() });
17
18 describe("<DataTable />", () => {
19     it("shows only selected columns", () => {
20         const columns: DataColumns<string, string> = [
21             createDataColumn({
22                 name: "Column 1",
23                 render: () => <span />,
24                 selected: true,
25                 configurable: true,
26             }),
27             createDataColumn({
28                 name: "Column 2",
29                 render: () => <span />,
30                 selected: true,
31                 configurable: true,
32             }),
33             createDataColumn({
34                 name: "Column 3",
35                 render: () => <span />,
36                 selected: false,
37                 configurable: true,
38             }),
39         ];
40         const dataTable = mount(
41             <DataTable
42                 columns={columns}
43                 items={[{ key: "1", name: "item 1" }]}
44                 onFiltersChange={jest.fn()}
45                 onRowClick={jest.fn()}
46                 onRowDoubleClick={jest.fn()}
47                 onContextMenu={jest.fn()}
48                 onSortToggle={jest.fn()}
49                 setCheckedListOnStore={jest.fn()}
50                 checkedList={{}}
51             />
52         );
53         expect(dataTable.find(TableHead).find(TableCell)).toHaveLength(3);
54     });
55
56     it("renders column name", () => {
57         const columns: DataColumns<string, string> = [
58             createDataColumn({
59                 name: "Column 1",
60                 render: () => <span />,
61                 selected: true,
62                 configurable: true,
63             }),
64         ];
65         const dataTable = mount(
66             <DataTable
67                 columns={columns}
68                 items={["item 1"]}
69                 onFiltersChange={jest.fn()}
70                 onRowClick={jest.fn()}
71                 onRowDoubleClick={jest.fn()}
72                 onContextMenu={jest.fn()}
73                 onSortToggle={jest.fn()}
74                 setCheckedListOnStore={jest.fn()}
75                 checkedList={{}}
76             />
77         );
78         expect(dataTable.find(TableHead).find(TableCell).last().text()).toBe("Column 1");
79     });
80
81     it("uses renderHeader instead of name prop", () => {
82         const columns: DataColumns<string, string> = [
83             createDataColumn({
84                 name: "Column 1",
85                 renderHeader: () => <span>Column Header</span>,
86                 render: () => <span />,
87                 selected: true,
88                 configurable: true,
89             }),
90         ];
91         const dataTable = mount(
92             <DataTable
93                 columns={columns}
94                 items={[]}
95                 onFiltersChange={jest.fn()}
96                 onRowClick={jest.fn()}
97                 onRowDoubleClick={jest.fn()}
98                 onContextMenu={jest.fn()}
99                 onSortToggle={jest.fn()}
100                 setCheckedListOnStore={jest.fn()}
101                 checkedList={{}}
102             />
103         );
104         expect(dataTable.find(TableHead).find(TableCell).last().text()).toBe("Column Header");
105     });
106
107     it("passes column key prop to corresponding cells", () => {
108         const columns: DataColumns<string, string> = [
109             createDataColumn({
110                 name: "Column 1",
111                 key: "column-1-key",
112                 render: () => <span />,
113                 selected: true,
114                 configurable: true,
115             }),
116         ];
117         const dataTable = mount(
118             <DataTable
119                 columns={columns}
120                 working={false}
121                 items={["item 1"]}
122                 onFiltersChange={jest.fn()}
123                 onRowClick={jest.fn()}
124                 onRowDoubleClick={jest.fn()}
125                 onContextMenu={jest.fn()}
126                 onSortToggle={jest.fn()}
127                 setCheckedListOnStore={jest.fn()}
128                 checkedList={{}}
129             />
130         );
131         setTimeout(() => {
132             expect(dataTable.find(TableBody).find(TableCell).last().key()).toBe("column-1-key");
133         }, 1000);
134     });
135
136     it("renders items", () => {
137         const columns: DataColumns<string, string> = [
138             createDataColumn({
139                 name: "Column 1",
140                 render: item => <Typography>{item}</Typography>,
141                 selected: true,
142                 configurable: true,
143             }),
144             createDataColumn({
145                 name: "Column 2",
146                 render: item => <Button>{item}</Button>,
147                 selected: true,
148                 configurable: true,
149             }),
150         ];
151         const dataTable = mount(
152             <DataTable
153                 columns={columns}
154                 working={false}
155                 items={["item 1"]}
156                 onFiltersChange={jest.fn()}
157                 onRowClick={jest.fn()}
158                 onRowDoubleClick={jest.fn()}
159                 onContextMenu={jest.fn()}
160                 onSortToggle={jest.fn()}
161                 setCheckedListOnStore={jest.fn()}
162                 checkedList={{}}
163             />
164         );
165         setTimeout(() => {
166             expect(dataTable.find(TableBody).find(Typography).last().text()).toBe("item 1");
167             expect(dataTable.find(TableBody).find(Button).last().text()).toBe("item 1");
168         }, 1000);
169     });
170
171     it("passes sorting props to <TableSortLabel />", () => {
172         const columns: DataColumns<string, string> = [
173             createDataColumn({
174                 name: "Column 1",
175                 sort: { direction: SortDirection.ASC, field: "length" },
176                 selected: true,
177                 configurable: true,
178                 render: item => <Typography>{item}</Typography>,
179             }),
180         ];
181         const onSortToggle = jest.fn();
182         const dataTable = mount(
183             <DataTable
184                 columns={columns}
185                 items={["item 1"]}
186                 onFiltersChange={jest.fn()}
187                 onRowClick={jest.fn()}
188                 onRowDoubleClick={jest.fn()}
189                 onContextMenu={jest.fn()}
190                 onSortToggle={onSortToggle}
191                 setCheckedListOnStore={jest.fn()}
192                 checkedList={{}}
193             />
194         );
195         expect(dataTable.find(TableSortLabel).prop("active")).toBeTruthy();
196         dataTable.find(TableSortLabel).at(0).simulate("click");
197         expect(onSortToggle).toHaveBeenCalledWith(columns[1]);
198     });
199
200     it("does not display <DataTableFiltersPopover /> if there is no filters provided", () => {
201         const columns: DataColumns<string, string> = [
202             {
203                 name: "Column 1",
204                 selected: true,
205                 configurable: true,
206                 filters: [],
207                 render: item => <Typography>{item}</Typography>,
208             },
209         ];
210         const onFiltersChange = jest.fn();
211         const dataTable = mount(
212             <DataTable
213                 columns={columns}
214                 items={[]}
215                 onFiltersChange={onFiltersChange}
216                 onRowClick={jest.fn()}
217                 onRowDoubleClick={jest.fn()}
218                 onSortToggle={jest.fn()}
219                 onContextMenu={jest.fn()}
220                 setCheckedListOnStore={jest.fn()}
221                 checkedList={{}}
222             />
223         );
224         expect(dataTable.find(DataTableFiltersPopover)).toHaveLength(0);
225     });
226
227     it("passes filter props to <DataTableFiltersPopover />", () => {
228         const filters = pipe(() => createTree<DataTableFilterItem>(), setNode(initTreeNode({ id: "filter", value: { name: "filter" } })));
229         const columns: DataColumns<string, string> = [
230             {
231                 name: "Column 1",
232                 selected: true,
233                 configurable: true,
234                 filters: filters(),
235                 render: item => <Typography>{item}</Typography>,
236             },
237         ];
238         const onFiltersChange = jest.fn();
239         const dataTable = mount(
240             <DataTable
241                 columns={columns}
242                 items={[]}
243                 onFiltersChange={onFiltersChange}
244                 onRowClick={jest.fn()}
245                 onRowDoubleClick={jest.fn()}
246                 onSortToggle={jest.fn()}
247                 onContextMenu={jest.fn()}
248                 setCheckedListOnStore={jest.fn()}
249                 checkedList={{}}
250             />
251         );
252         expect(dataTable.find(DataTableFiltersPopover).prop("filters")).toBe(columns[1].filters);
253         dataTable.find(DataTableFiltersPopover).prop("onChange")([]);
254         expect(onFiltersChange).toHaveBeenCalledWith([], columns[1]);
255     });
256 });