Merge branch 'master' into 14258-collection-filtering
[arvados.git] / 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 * as 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 * as Adapter from "enzyme-adapter-react-16";
10 import { DataTable, DataColumns } from "./data-table";
11 import { DataTableFilters } from "~/components/data-table-filters/data-table-filters";
12 import { SortDirection, createDataColumn } from "./data-column";
13 import { DataTableFiltersPopover } from '~/components/data-table-filters/data-table-filters-popover';
14 import { createTree, setNode, initTreeNode } from '~/models/tree';
15 import { DataTableFilterItem } from "~/components/data-table-filters/data-table-filters-tree";
16
17 configure({ adapter: new Adapter() });
18
19 describe("<DataTable />", () => {
20     it("shows only selected columns", () => {
21         const columns: DataColumns<string> = [
22             createDataColumn({
23                 name: "Column 1",
24                 render: () => <span />,
25                 selected: true,
26                 configurable: true
27             }),
28             createDataColumn({
29                 name: "Column 2",
30                 render: () => <span />,
31                 selected: true,
32                 configurable: true
33             }),
34             createDataColumn({
35                 name: "Column 3",
36                 render: () => <span />,
37                 selected: false,
38                 configurable: true
39             }),
40         ];
41         const dataTable = mount(<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         expect(dataTable.find(TableHead).find(TableCell)).toHaveLength(2);
50     });
51
52     it("renders column name", () => {
53         const columns: DataColumns<string> = [
54             createDataColumn({
55                 name: "Column 1",
56                 render: () => <span />,
57                 selected: true,
58                 configurable: true
59             }),
60         ];
61         const dataTable = mount(<DataTable
62             columns={columns}
63             items={["item 1"]}
64             onFiltersChange={jest.fn()}
65             onRowClick={jest.fn()}
66             onRowDoubleClick={jest.fn()}
67             onContextMenu={jest.fn()}
68             onSortToggle={jest.fn()} />);
69         expect(dataTable.find(TableHead).find(TableCell).text()).toBe("Column 1");
70     });
71
72     it("uses renderHeader instead of name prop", () => {
73         const columns: DataColumns<string> = [
74             createDataColumn({
75                 name: "Column 1",
76                 renderHeader: () => <span>Column Header</span>,
77                 render: () => <span />,
78                 selected: true,
79                 configurable: true
80             }),
81         ];
82         const dataTable = mount(<DataTable
83             columns={columns}
84             items={[]}
85             onFiltersChange={jest.fn()}
86             onRowClick={jest.fn()}
87             onRowDoubleClick={jest.fn()}
88             onContextMenu={jest.fn()}
89             onSortToggle={jest.fn()} />);
90         expect(dataTable.find(TableHead).find(TableCell).text()).toBe("Column Header");
91     });
92
93     it("passes column key prop to corresponding cells", () => {
94         const columns: DataColumns<string> = [
95             createDataColumn({
96                 name: "Column 1",
97                 key: "column-1-key",
98                 render: () => <span />,
99                 selected: true,
100                 configurable: true
101             })
102         ];
103         const dataTable = mount(<DataTable
104             columns={columns}
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> = [
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             items={["item 1"]}
133             onFiltersChange={jest.fn()}
134             onRowClick={jest.fn()}
135             onRowDoubleClick={jest.fn()}
136             onContextMenu={jest.fn()}
137             onSortToggle={jest.fn()} />);
138         expect(dataTable.find(TableBody).find(Typography).text()).toBe("item 1");
139         expect(dataTable.find(TableBody).find(Button).text()).toBe("item 1");
140     });
141
142     it("passes sorting props to <TableSortLabel />", () => {
143         const columns: DataColumns<string> = [
144             createDataColumn({
145                 name: "Column 1",
146                 sortDirection: SortDirection.ASC,
147                 selected: true,
148                 configurable: true,
149                 render: (item) => <Typography>{item}</Typography>
150             })];
151         const onSortToggle = jest.fn();
152         const dataTable = mount(<DataTable
153             columns={columns}
154             items={["item 1"]}
155             onFiltersChange={jest.fn()}
156             onRowClick={jest.fn()}
157             onRowDoubleClick={jest.fn()}
158             onContextMenu={jest.fn()}
159             onSortToggle={onSortToggle} />);
160         expect(dataTable.find(TableSortLabel).prop("active")).toBeTruthy();
161         dataTable.find(TableSortLabel).at(0).simulate("click");
162         expect(onSortToggle).toHaveBeenCalledWith(columns[0]);
163     });
164
165     it("does not display <DataTableFilter /> if there is no filters provided", () => {
166         const columns: DataColumns<string> = [{
167             name: "Column 1",
168             sortDirection: SortDirection.ASC,
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(DataTableFilters)).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> = [{
192             name: "Column 1",
193             sortDirection: SortDirection.ASC,
194             selected: true,
195             configurable: true,
196             filters: filters(),
197             render: (item) => <Typography>{item}</Typography>
198         }];
199         const onFiltersChange = jest.fn();
200         const dataTable = mount(<DataTable
201             columns={columns}
202             items={[]}
203             onFiltersChange={onFiltersChange}
204             onRowClick={jest.fn()}
205             onRowDoubleClick={jest.fn()}
206             onSortToggle={jest.fn()}
207             onContextMenu={jest.fn()} />);
208         expect(dataTable.find(DataTableFiltersPopover).prop("filters")).toBe(columns[0].filters);
209         dataTable.find(DataTableFiltersPopover).prop("onChange")([]);
210         expect(onFiltersChange).toHaveBeenCalledWith([], columns[0]);
211     });
212
213     // it("shows default view if there is no items", () => {
214     //     const columns: DataColumns<string> = [
215     //         createDataColumn({
216     //             name: "Column 1",
217     //             render: () => <span />,
218     //             selected: true,
219     //             configurable: true
220     //         }),
221     //     ];
222     //     const dataTable = mount(<DataTable
223     //         columns={columns}
224     //         items={[]}
225     //         onFiltersChange={jest.fn()}
226     //         onRowClick={jest.fn()}
227     //         onRowDoubleClick={jest.fn()}
228     //         onContextMenu={jest.fn()}
229     //         onSortToggle={jest.fn()} />);
230     //     expect(dataTable.find(DataTableDefaultView)).toHaveLength(1);
231     // });
232 });