1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
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";
17 configure({ adapter: new Adapter() });
19 describe("<DataTable />", () => {
20 it("shows only selected columns", () => {
21 const columns: DataColumns<string> = [
24 render: () => <span />,
30 render: () => <span />,
36 render: () => <span />,
41 const dataTable = mount(<DataTable
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);
52 it("renders column name", () => {
53 const columns: DataColumns<string> = [
56 render: () => <span />,
61 const dataTable = mount(<DataTable
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");
72 it("uses renderHeader instead of name prop", () => {
73 const columns: DataColumns<string> = [
76 renderHeader: () => <span>Column Header</span>,
77 render: () => <span />,
82 const dataTable = mount(<DataTable
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");
93 it("passes column key prop to corresponding cells", () => {
94 const columns: DataColumns<string> = [
98 render: () => <span />,
103 const dataTable = mount(<DataTable
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");
115 it("renders items", () => {
116 const columns: DataColumns<string> = [
119 render: (item) => <Typography>{item}</Typography>,
125 render: (item) => <Button>{item}</Button>,
130 const dataTable = mount(<DataTable
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");
142 it("passes sorting props to <TableSortLabel />", () => {
143 const columns: DataColumns<string> = [
146 sortDirection: SortDirection.ASC,
149 render: (item) => <Typography>{item}</Typography>
151 const onSortToggle = jest.fn();
152 const dataTable = mount(<DataTable
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]);
165 it("does not display <DataTableFilter /> if there is no filters provided", () => {
166 const columns: DataColumns<string> = [{
168 sortDirection: SortDirection.ASC,
172 render: (item) => <Typography>{item}</Typography>
174 const onFiltersChange = jest.fn();
175 const dataTable = mount(<DataTable
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);
186 it("passes filter props to <DataTableFiltersPopover />", () => {
187 const filters = pipe(
188 () => createTree<DataTableFilterItem>(),
189 setNode(initTreeNode({ id: 'filter', value: { name: 'filter' } }))
191 const columns: DataColumns<string> = [{
193 sortDirection: SortDirection.ASC,
197 render: (item) => <Typography>{item}</Typography>
199 const onFiltersChange = jest.fn();
200 const dataTable = mount(<DataTable
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]);
213 // it("shows default view if there is no items", () => {
214 // const columns: DataColumns<string> = [
215 // createDataColumn({
217 // render: () => <span />,
219 // configurable: true
222 // const dataTable = mount(<DataTable
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);