21720:
[arvados.git] / services / workbench2 / src / views-components / data-explorer / renderers.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 { GroupMembersCount, ProcessStatus, ResourceFileSize } from './renderers';
7 import { Provider } from 'react-redux';
8 import configureMockStore from 'redux-mock-store'
9 import { ResourceKind } from '../../models/resource';
10 import { ContainerRequestState as CR } from '../../models/container-request';
11 import { ContainerState as C } from '../../models/container';
12 import { ProcessStatus as PS } from '../../store/processes/process';
13 import { ThemeProvider, Theme, StyledEngineProvider } from '@mui/material';
14 import { CustomTheme } from 'common/custom-theme';
15
16 const middlewares = [];
17 const mockStore = configureMockStore(middlewares);
18
19 describe('renderers', () => {
20     let props = null;
21
22     describe('ProcessStatus', () => {
23         props = {
24             uuid: 'zzzzz-xvhdp-zzzzzzzzzzzzzzz',
25             theme: {
26                 customs: {
27                     colors: {
28                         // Color values are arbitrary, but they should be
29                         // representative of the colors used in the UI.
30                         green800: 'rgb(0, 255, 0)',
31                         red900: 'rgb(255, 0, 0)',
32                         orange: 'rgb(240, 173, 78)',
33                         grey600: 'rgb(128, 128, 128)',
34                     }
35                 },
36                 spacing: (value) => value * 8,
37                 palette: {
38                     common: {
39                         white: 'rgb(255, 255, 255)',
40                     },
41                 },
42             },
43         };
44
45         [
46             // CR Status ; Priority ; C Status ; Exit Code ; C RuntimeStatus ; Expected label ; Expected bg color ; Expected fg color
47             [CR.COMMITTED, 1, C.RUNNING, null, {}, PS.RUNNING, props.theme.palette.common.white, props.theme.customs.colors.green800],
48             [CR.COMMITTED, 1, C.RUNNING, null, { error: 'whoops' }, PS.FAILING, props.theme.palette.common.white, props.theme.customs.colors.red900],
49             [CR.COMMITTED, 1, C.RUNNING, null, { warning: 'watch out!' }, PS.WARNING, props.theme.palette.common.white, props.theme.customs.colors.green800],
50             [CR.FINAL, 1, C.CANCELLED, null, {}, PS.CANCELLED, props.theme.customs.colors.red900, props.theme.palette.common.white],
51             [CR.FINAL, 1, C.COMPLETE, 137, {}, PS.FAILED, props.theme.customs.colors.red900, props.theme.palette.common.white],
52             [CR.FINAL, 1, C.COMPLETE, 0, {}, PS.COMPLETED, props.theme.customs.colors.green800, props.theme.palette.common.white],
53             [CR.COMMITTED, 0, C.LOCKED, null, {}, PS.ONHOLD, props.theme.customs.colors.grey600, props.theme.palette.common.white],
54             [CR.COMMITTED, 0, C.QUEUED, null, {}, PS.ONHOLD, props.theme.customs.colors.grey600, props.theme.palette.common.white],
55             [CR.COMMITTED, 1, C.LOCKED, null, {}, PS.QUEUED, props.theme.palette.common.white, props.theme.customs.colors.grey600],
56             [CR.COMMITTED, 1, C.QUEUED, null, {}, PS.QUEUED, props.theme.palette.common.white, props.theme.customs.colors.grey600],
57         ].forEach(([crState, crPrio, cState, exitCode, rs, eLabel, eColor, tColor]) => {
58             it(`should render the state label '${eLabel}' and color '${eColor}' for CR state=${crState}, priority=${crPrio}, C state=${cState}, exitCode=${exitCode} and RuntimeStatus=${JSON.stringify(rs)}`, () => {
59                 const containerUuid = 'zzzzz-dz642-zzzzzzzzzzzzzzz';
60                 const store = mockStore({
61                     resources: {
62                         [props.uuid]: {
63                             kind: ResourceKind.CONTAINER_REQUEST,
64                             state: crState,
65                             containerUuid: containerUuid,
66                             priority: crPrio,
67                         },
68                         [containerUuid]: {
69                             kind: ResourceKind.CONTAINER,
70                             state: cState,
71                             runtimeStatus: rs,
72                             exitCode: exitCode,
73                         },
74                     }
75                 });
76
77                 cy.mount(
78                     <Provider store={store}>
79                         <ThemeProvider theme={CustomTheme}>
80                             <ProcessStatus {...props} />
81                         </ThemeProvider>
82                     </Provider>);
83
84                 cy.get('span').should('have.text', eLabel);
85                 cy.get('span').should('have.css', 'color', tColor);
86                 cy.get('[data-cy=process-status-chip]').should('have.css', 'background-color', eColor);
87             });
88         })
89     });
90
91     describe('ResourceFileSize', () => {
92         beforeEach(() => {
93             props = {
94                 uuid: 'UUID',
95             };
96         });
97
98         it('should render collection fileSizeTotal', () => {
99             // given
100             const store = mockStore({
101                 resources: {
102                     [props.uuid]: {
103                         kind: ResourceKind.COLLECTION,
104                         fileSizeTotal: 100,
105                     }
106                 }
107             });
108
109             // when
110             cy.mount(<Provider store={store}>
111                 <ResourceFileSize {...props}></ResourceFileSize>
112             </Provider>);
113
114             // then
115             cy.get('p').should('have.text', '100 B');
116         });
117
118         it('should render 0 B as file size', () => {
119             // given
120             const store = mockStore({ resources: {} });
121
122             // when
123             cy.mount(<Provider store={store}>
124                 <ResourceFileSize {...props}></ResourceFileSize>
125             </Provider>);
126
127             // then
128             cy.get('p').should('have.text', '0 B');
129         });
130
131         it('should render empty string for non collection resource', () => {
132             // given
133             const store1 = mockStore({
134                 resources: {
135                     [props.uuid]: {
136                         kind: ResourceKind.PROJECT,
137                         fileSizeTotal: 100,
138                     }
139                 }
140             });
141             const store2 = mockStore({
142                 resources: {
143                     [props.uuid]: {
144                         kind: ResourceKind.PROCESS,
145                         fileSizeTotal: 200,
146                     }
147                 }
148             });
149
150             // when
151             cy.mount(<Provider store={store1}>
152                 <ResourceFileSize {...props}></ResourceFileSize>
153             </Provider>);
154
155             // then
156             cy.get('p').should('have.text', '-');
157             
158             // when
159             cy.mount(<Provider store={store2}>
160                 <ResourceFileSize {...props}></ResourceFileSize>
161             </Provider>);
162
163             // then
164             cy.get('p').should('have.text', '-');
165         });
166     });
167
168     describe('GroupMembersCount', () => {
169         let fakeGroup;
170         beforeEach(() => {
171             props = {
172                 uuid: 'zzzzz-j7d0g-000000000000000',
173             };
174             fakeGroup = {
175                 "canManage": true,
176                 "canWrite": true,
177                 "createdAt": "2020-09-24T22:52:57.546521000Z",
178                 "deleteAt": null,
179                 "description": "Test Group",
180                 "etag": "0000000000000000000000000",
181                 "frozenByUuid": null,
182                 "groupClass": "role",
183                 "href": `/groups/${props.uuid}`,
184                 "isTrashed": false,
185                 "kind": ResourceKind.GROUP,
186                 "modifiedAt": "2020-09-24T22:52:57.545669000Z",
187                 "modifiedByClientUuid": null,
188                 "modifiedByUserUuid": "zzzzz-tpzed-000000000000000",
189                 "name": "System group",
190                 "ownerUuid": "zzzzz-tpzed-000000000000000",
191                 "properties": {},
192                 "trashAt": null,
193                 "uuid": props.uuid,
194                 "writableBy": [
195                     "zzzzz-tpzed-000000000000000",
196                 ]
197             };
198         });
199
200         it('shows loading group count when no memberCount', () => {
201             // Given
202             const store = mockStore({resources: {
203                 [props.uuid]: fakeGroup,
204             }});
205
206             const wrapper = cy.mount(<Provider store={store}>
207                 <StyledEngineProvider injectFirst>
208                     <ThemeProvider theme={CustomTheme}>
209                         <GroupMembersCount {...props} />
210                     </ThemeProvider>
211                 </StyledEngineProvider>
212             </Provider>);
213
214             cy.get('[data-testid=three-dots-svg]').should('exist');
215         });
216
217         it('shows group count when memberCount present', () => {
218             // Given
219             const store = mockStore({resources: {
220                 [props.uuid]: {
221                     ...fakeGroup,
222                     "memberCount": 765,
223                 }
224             }});
225
226             cy.mount(<Provider store={store}>
227                 <StyledEngineProvider injectFirst>
228                     <ThemeProvider theme={CustomTheme}>
229                         <GroupMembersCount {...props} />
230                     </ThemeProvider>
231                 </StyledEngineProvider>
232             </Provider>);
233
234             cy.get('p').should('have.text', '765');
235         });
236
237         it('shows group count error icon when memberCount is null', () => {
238             // Given
239             const store = mockStore({resources: {
240                 [props.uuid]: {
241                     ...fakeGroup,
242                     "memberCount": null,
243                 }
244             }});
245
246             cy.mount(<Provider store={store}>
247                 <StyledEngineProvider injectFirst>
248                     <ThemeProvider theme={CustomTheme}>
249                         <GroupMembersCount {...props} />
250                     </ThemeProvider>
251                 </StyledEngineProvider>
252             </Provider>);
253
254             cy.get('[data-testid=ErrorRoundedIcon]').should('exist');
255         });
256
257     });
258
259 });