20318: Merge branch 'main' into 20318-disk-cache
[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             />
51         );
52         expect(dataTable.find(TableHead).find(TableCell)).toHaveLength(3);
53     });
54
55     it("renders column name", () => {
56         const columns: DataColumns<string, string> = [
57             createDataColumn({
58                 name: "Column 1",
59                 render: () => <span />,
60                 selected: true,
61                 configurable: true,
62             }),
63         ];
64         const dataTable = mount(
65             <DataTable
66                 columns={columns}
67                 items={["item 1"]}
68                 onFiltersChange={jest.fn()}
69                 onRowClick={jest.fn()}
70                 onRowDoubleClick={jest.fn()}
71                 onContextMenu={jest.fn()}
72                 onSortToggle={jest.fn()}
73                 setCheckedListOnStore={jest.fn()}
74             />
75         );
76         expect(dataTable.find(TableHead).find(TableCell).last().text()).toBe("Column 1");
77     });
78
79     it("uses renderHeader instead of name prop", () => {
80         const columns: DataColumns<string, string> = [
81             createDataColumn({
82                 name: "Column 1",
83                 renderHeader: () => <span>Column Header</span>,
84                 render: () => <span />,
85                 selected: true,
86                 configurable: true,
87             }),
88         ];
89         const dataTable = mount(
90             <DataTable
91                 columns={columns}
92                 items={[]}
93                 onFiltersChange={jest.fn()}
94                 onRowClick={jest.fn()}
95                 onRowDoubleClick={jest.fn()}
96                 onContextMenu={jest.fn()}
97                 onSortToggle={jest.fn()}
98                 setCheckedListOnStore={jest.fn()}
99             />
100         );
101         expect(dataTable.find(TableHead).find(TableCell).last().text()).toBe("Column Header");
102     });
103
104     it("passes column key prop to corresponding cells", () => {
105         const columns: DataColumns<string, string> = [
106             createDataColumn({
107                 name: "Column 1",
108                 key: "column-1-key",
109                 render: () => <span />,
110                 selected: true,
111                 configurable: true,
112             }),
113         ];
114         const dataTable = mount(
115             <DataTable
116                 columns={columns}
117                 working={false}
118                 items={["item 1"]}
119                 onFiltersChange={jest.fn()}
120                 onRowClick={jest.fn()}
121                 onRowDoubleClick={jest.fn()}
122                 onContextMenu={jest.fn()}
123                 onSortToggle={jest.fn()}
124                 setCheckedListOnStore={jest.fn()}
125             />
126         );
127         expect(dataTable.find(TableBody).find(TableCell).last().key()).toBe("column-1-key");
128     });
129
130     it("renders items", () => {
131         const columns: DataColumns<string, string> = [
132             createDataColumn({
133                 name: "Column 1",
134                 render: item => <Typography>{item}</Typography>,
135                 selected: true,
136                 configurable: true,
137             }),
138             createDataColumn({
139                 name: "Column 2",
140                 render: item => <Button>{item}</Button>,
141                 selected: true,
142                 configurable: true,
143             }),
144         ];
145         const dataTable = mount(
146             <DataTable
147                 columns={columns}
148                 working={false}
149                 items={["item 1"]}
150                 onFiltersChange={jest.fn()}
151                 onRowClick={jest.fn()}
152                 onRowDoubleClick={jest.fn()}
153                 onContextMenu={jest.fn()}
154                 onSortToggle={jest.fn()}
155                 setCheckedListOnStore={jest.fn()}
156             />
157         );
158         expect(dataTable.find(TableBody).find(Typography).last().text()).toBe("item 1");
159         expect(dataTable.find(TableBody).find(Button).last().text()).toBe("item 1");
160     });
161
162     it("passes sorting props to <TableSortLabel />", () => {
163         const columns: DataColumns<string, string> = [
164             createDataColumn({
165                 name: "Column 1",
166                 sort: { direction: SortDirection.ASC, field: "length" },
167                 selected: true,
168                 configurable: true,
169                 render: item => <Typography>{item}</Typography>,
170             }),
171         ];
172         const onSortToggle = jest.fn();
173         const dataTable = mount(
174             <DataTable
175                 columns={columns}
176                 items={["item 1"]}
177                 onFiltersChange={jest.fn()}
178                 onRowClick={jest.fn()}
179                 onRowDoubleClick={jest.fn()}
180                 onContextMenu={jest.fn()}
181                 onSortToggle={onSortToggle}
182                 setCheckedListOnStore={jest.fn()}
183             />
184         );
185         expect(dataTable.find(TableSortLabel).prop("active")).toBeTruthy();
186         dataTable.find(TableSortLabel).at(0).simulate("click");
187         expect(onSortToggle).toHaveBeenCalledWith(columns[1]);
188     });
189
190     it("does not display <DataTableFiltersPopover /> if there is no filters provided", () => {
191         const columns: DataColumns<string, string> = [
192             {
193                 name: "Column 1",
194                 selected: true,
195                 configurable: true,
196                 filters: [],
197                 render: item => <Typography>{item}</Typography>,
198             },
199         ];
200         const onFiltersChange = jest.fn();
201         const dataTable = mount(
202             <DataTable
203                 columns={columns}
204                 items={[]}
205                 onFiltersChange={onFiltersChange}
206                 onRowClick={jest.fn()}
207                 onRowDoubleClick={jest.fn()}
208                 onSortToggle={jest.fn()}
209                 onContextMenu={jest.fn()}
210                 setCheckedListOnStore={jest.fn()}
211             />
212         );
213         expect(dataTable.find(DataTableFiltersPopover)).toHaveLength(0);
214     });
215
216     it("passes filter props to <DataTableFiltersPopover />", () => {
217         const filters = pipe(() => createTree<DataTableFilterItem>(), setNode(initTreeNode({ id: "filter", value: { name: "filter" } })));
218         const columns: DataColumns<string, string> = [
219             {
220                 name: "Column 1",
221                 selected: true,
222                 configurable: true,
223                 filters: filters(),
224                 render: item => <Typography>{item}</Typography>,
225             },
226         ];
227         const onFiltersChange = jest.fn();
228         const dataTable = mount(
229             <DataTable
230                 columns={columns}
231                 items={[]}
232                 onFiltersChange={onFiltersChange}
233                 onRowClick={jest.fn()}
234                 onRowDoubleClick={jest.fn()}
235                 onSortToggle={jest.fn()}
236                 onContextMenu={jest.fn()}
237                 setCheckedListOnStore={jest.fn()}
238             />
239         );
240         expect(dataTable.find(DataTableFiltersPopover).prop("filters")).toBe(columns[1].filters);
241         dataTable.find(DataTableFiltersPopover).prop("onChange")([]);
242         expect(onFiltersChange).toHaveBeenCalledWith([], columns[1]);
243     });
244 });