Merge branch 'main' into 21720-material-ui-upgrade
[arvados.git] / services / workbench2 / src / components / data-table / data-table.cy.js
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 { Typography, Button } from "@mui/material";
7 import { DataTable } from "./data-table";
8 import { SortDirection, createDataColumn } from "./data-column";
9 import { ThemeProvider } from "@mui/material";
10 import { CustomTheme } from "common/custom-theme";
11
12 describe("<DataTable />", () => {
13     it("shows only selected columns", () => {
14         const columns = [
15             createDataColumn({
16                 name: "Column 1",
17                 render: () => <span />,
18                 selected: true,
19                 configurable: true,
20             }),
21             createDataColumn({
22                 name: "Column 2",
23                 render: () => <span />,
24                 selected: true,
25                 configurable: true,
26             }),
27             createDataColumn({
28                 name: "Column 3",
29                 render: () => <span />,
30                 selected: false,
31                 configurable: true,
32             }),
33         ];
34         cy.mount(
35             <ThemeProvider theme={CustomTheme}>
36                 <DataTable
37                     columns={columns}
38                     items={[{ key: "1", name: "item 1" }]}
39                     onFiltersChange={cy.stub()}
40                     onRowClick={cy.stub()}
41                     onRowDoubleClick={cy.stub()}
42                     onContextMenu={cy.stub()}
43                     onSortToggle={cy.stub()}
44                     setCheckedListOnStore={cy.stub()}
45                 />
46             </ThemeProvider>
47         );
48         cy.get('th').should('have.length', 3);
49     });
50
51     it("renders column name", () => {
52         const columns = [
53             createDataColumn({
54                 name: "Column 1",
55                 render: () => <span />,
56                 selected: true,
57                 configurable: true,
58             }),
59         ];
60         cy.mount(
61             <ThemeProvider theme={CustomTheme}>
62                 <DataTable
63                     columns={columns}
64                     items={["item 1"]}
65                     onFiltersChange={cy.stub()}
66                     onRowClick={cy.stub()}
67                     onRowDoubleClick={cy.stub()}
68                     onContextMenu={cy.stub()}
69                     onSortToggle={cy.stub()}
70                     setCheckedListOnStore={cy.stub()}
71                 />
72             </ThemeProvider>
73         );
74         cy.get('th').last().contains('Column 1').should('exist');
75     });
76
77     it("uses renderHeader instead of name prop", () => {
78         const columns = [
79             createDataColumn({
80                 name: "Column 1",
81                 renderHeader: () => <span>Column Header</span>,
82                 render: () => <span />,
83                 selected: true,
84                 configurable: true,
85             }),
86         ];
87         cy.mount(
88             <ThemeProvider theme={CustomTheme}>
89                 <DataTable
90                     columns={columns}
91                     items={[]}
92                     onFiltersChange={cy.stub()}
93                     onRowClick={cy.stub()}
94                     onRowDoubleClick={cy.stub()}
95                     onContextMenu={cy.stub()}
96                     onSortToggle={cy.stub()}
97                     setCheckedListOnStore={cy.stub()}
98                 />
99             </ThemeProvider>
100         );
101         cy.get('th').last().contains('Column Header').should('exist');
102     });
103
104     it("passes column key prop to corresponding cells", () => {
105         const columns = [
106             createDataColumn({
107                 name: "Column 1",
108                 key: "column-1-key",
109                 render: () => <span />,
110                 selected: true,
111                 configurable: true,
112             }),
113         ];
114         cy.mount(
115             <ThemeProvider theme={CustomTheme}>
116                 <DataTable
117                     columns={columns}
118                     working={false}
119                     items={["item 1"]}
120                     onFiltersChange={cy.stub()}
121                     onRowClick={cy.stub()}
122                     onRowDoubleClick={cy.stub()}
123                     onContextMenu={cy.stub()}
124                     onSortToggle={cy.stub()}
125                     setCheckedListOnStore={cy.stub()}
126                 />
127             </ThemeProvider>
128         );
129         setTimeout(() => {
130             // cannot access key prop directly, so data-cy is assigned to column.key value
131             cy.get('td').last().should('have.attr', 'data-cy', 'column-1-key');
132         }, 1000);
133     });
134
135     it("renders items", () => {
136         const columns = [
137             createDataColumn({
138                 name: "Column 1",
139                 render: item => <Typography>{item}</Typography>,
140                 selected: true,
141                 configurable: true,
142             }),
143             createDataColumn({
144                 name: "Column 2",
145                 render: item => <Button>{item}</Button>,
146                 selected: true,
147                 configurable: true,
148             }),
149         ];
150         cy.mount(
151             <ThemeProvider theme={CustomTheme}>
152                 <DataTable
153                     columns={columns}
154                     working={false}
155                     items={["item 1"]}
156                     onFiltersChange={cy.stub()}
157                     onRowClick={cy.stub()}
158                     onRowDoubleClick={cy.stub()}
159                     onContextMenu={cy.stub()}
160                     onSortToggle={cy.stub()}
161                     setCheckedListOnStore={cy.stub()}
162                 />
163             </ThemeProvider>
164         );
165         setTimeout(() => {
166             cy.get('p').last().contains('item 1').should('exist');
167             cy.get('button').last().contains('item 1').should('exist');
168         }, 1000);
169     });
170
171     it("passes sorting props to <TableSortLabel />", () => {
172         const columns = [
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 = cy.spy().as("onSortToggle");
182         cy.mount(
183             <ThemeProvider theme={CustomTheme}>
184                 <DataTable
185                     columns={columns}
186                     items={["item 1"]}
187                     onFiltersChange={cy.stub()}
188                     onRowClick={cy.stub()}
189                     onRowDoubleClick={cy.stub()}
190                     onContextMenu={cy.stub()}
191                     onSortToggle={onSortToggle}
192                     setCheckedListOnStore={cy.stub()}
193                 />
194             </ThemeProvider>
195         );
196         setTimeout(() => {
197             cy.get('th').last().contains('Column 1').should('exist');
198             cy.get('[data-cy="sort-button"]').should('exist').click();
199             cy.get('@onSortToggle').should('have.been.calledWith', columns[1]);
200         }, 1000);
201     });
202
203     it("does not display <DataTableFiltersPopover /> if there is no filters provided", () => {
204         const columns = [
205             {
206                 name: "Column 1",
207                 selected: true,
208                 configurable: true,
209                 filters: [],
210                 render: item => <Typography>{item}</Typography>,
211             },
212         ];
213         const onFiltersChange = cy.stub();
214         cy.mount(
215             <ThemeProvider theme={CustomTheme}>
216                 <DataTable
217                     columns={columns}
218                     items={[]}
219                     onFiltersChange={onFiltersChange}
220                     onRowClick={cy.stub()}
221                     onRowDoubleClick={cy.stub()}
222                     onSortToggle={cy.stub()}
223                     onContextMenu={cy.stub()}
224                     setCheckedListOnStore={cy.stub()}
225                 />
226             </ThemeProvider>
227         );
228         cy.get('[data-cy=data-table]').should('exist');
229         cy.get('[data-cy=popover]').should('not.exist');
230     });
231
232     it("passes filter props to <DataTableFiltersPopover />", () => {
233         const filters = { Filters : {
234             id: 'Filters id',
235             active: false,
236             children: ['Filter 1', 'Filter 2'],
237             expanded: false,
238             initialState: true,
239             parent: "",
240             selected: false,
241             status: "LOADED",
242             value: { name: 'Filter'}
243         } };
244         const columns = [
245             {
246                 name: "Column 1",
247                 selected: true,
248                 configurable: true,
249                 filters: filters,
250                 render: item => <Typography>{item}</Typography>,
251             },
252         ];
253         const onFiltersChange = cy.spy().as("onFiltersChange");
254         cy.mount(
255             <ThemeProvider theme={CustomTheme}>
256                 <DataTable
257                     columns={columns}
258                     items={[]}
259                     onFiltersChange={onFiltersChange}
260                     onRowClick={cy.stub()}
261                     onRowDoubleClick={cy.stub()}
262                     onSortToggle={cy.stub()}
263                     onContextMenu={cy.stub()}
264                     setCheckedListOnStore={cy.stub()}
265                 />  
266             </ThemeProvider>
267         );
268         setTimeout(() => {
269             cy.get('span[role="button"]').contains('Column 1').should('exist').click();
270             cy.get('[data-cy="tree-li"]').contains('Filter').should('exist').click();
271             cy.get('@onFiltersChange').should('have.been.calledWith', filters, columns[1]);
272         }, 1000);
273     });
274 });