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