Merge branch '21720-material-ui-upgrade'
[arvados.git] / services / workbench2 / src / components / subprocess-progress-bar / subprocess-progress-bar.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 { createServices } from "services/services";
7 import { configureStore } from "store/store";
8 import { createBrowserHistory } from "history";
9 import { mockConfig } from 'common/config';
10 import Axios from "axios";
11 import { ContainerState } from "models/container";
12 import { SubprocessProgressBar } from "./subprocess-progress-bar";
13 import { Provider } from "react-redux";
14 import { FilterBuilder } from 'services/api/filter-builder';
15 import { ProcessStatusFilter, buildProcessStatusFilters } from 'store/resource-type-filters/resource-type-filters';
16
17 describe("<SubprocessProgressBar />", () => {
18     const axiosInst = Axios.create({ headers: {} });
19
20     let store;
21     let services;
22     const config = {};
23     const actions = {
24         progressFn: (id, working) => { },
25         errorFn: (id, message) => { }
26     };
27     let statusResponse = {
28         [ProcessStatusFilter.COMPLETED]: 0,
29         [ProcessStatusFilter.RUNNING]: 0,
30         [ProcessStatusFilter.FAILED]: 0,
31         [ProcessStatusFilter.QUEUED]: 0,
32     };
33
34     const createMockListFunc = (uuid) => (async (args) => {
35         const baseFilter = new FilterBuilder().addEqual('requesting_container_uuid', uuid).getFilters();
36
37         const filterResponses = Object.keys(statusResponse)
38             .map(status => ({filters: buildProcessStatusFilters(new FilterBuilder(baseFilter), status).getFilters(), value: statusResponse[status]}));
39
40         const matchedFilter = filterResponses.find(response => response.filters === args.filters);
41         if (matchedFilter) {
42             return { itemsAvailable: matchedFilter.value };
43         } else {
44             return { itemsAvailable: 0 };
45         }
46     });
47
48     beforeEach(() => {
49         services = createServices(mockConfig({}), actions, axiosInst);
50         store = configureStore(createBrowserHistory(), services, config);
51     });
52
53     it("requests subprocess progress stats for stopped processes and displays progress", async () => {
54         // when
55         const containerRequest = {
56             uuid: 'zzzzz-xvhdp-000000000000000',
57             containerUuid: 'zzzzz-dz642-000000000000000',
58         };
59         const process = {
60             container: {
61                 state: ContainerState.COMPLETE,
62             },
63             containerRequest: {
64                 containerUuid: 'zzzzz-dz642-000000000000000',
65             },
66         };
67
68         statusResponse = {
69             [ProcessStatusFilter.COMPLETED]: 100,
70             [ProcessStatusFilter.RUNNING]: 200,
71
72             // Combined into failed segment
73             [ProcessStatusFilter.FAILED]: 200,
74             [ProcessStatusFilter.CANCELLED]: 100,
75
76             // Combined into queued segment
77             [ProcessStatusFilter.QUEUED]: 300,
78             [ProcessStatusFilter.ONHOLD]: 100,
79         };
80
81         services.containerRequestService.list = createMockListFunc(process.containerRequest.containerUuid);
82
83         cy.mount(
84             <Provider store={store}>
85                 <SubprocessProgressBar process={process} />
86             </Provider>);
87
88         // expects 6 subprocess status list requests
89         const expectedFilters = [
90             ProcessStatusFilter.COMPLETED,
91             ProcessStatusFilter.RUNNING,
92             ProcessStatusFilter.FAILED,
93             ProcessStatusFilter.CANCELLED,
94             ProcessStatusFilter.QUEUED,
95             ProcessStatusFilter.ONHOLD,
96         ].map((state) =>
97             buildProcessStatusFilters(
98                 new FilterBuilder().addEqual(
99                     "requesting_container_uuid",
100                     process.containerRequest.containerUuid
101                 ),
102                 state
103             ).getFilters()
104         );
105
106         cy.spy(services.containerRequestService, 'list').as('list');
107         
108         expectedFilters.forEach((filter) => {
109             cy.get('@list').should('have.been.calledWith', {limit: 0, offset: 0, filters: filter});
110         });
111
112         // Verify progress bar with correct degment widths
113         ['10%', '20%', '30%', '40%'].forEach((value, i) => {
114             cy.get('div[class=progress]').eq(i).should('have.attr', 'style').and('include', `width: ${value};`);
115
116         });
117     });
118
119     it("dislays correct progress bar widths with different values", async () => {
120         const containerRequest = {
121             uuid: 'zzzzz-xvhdp-000000000000001',
122             containerUuid: 'zzzzz-dz642-000000000000001',
123         };
124         const process = {
125             container: {
126                 state: ContainerState.COMPLETE,
127             },
128             containerRequest: {
129                 containerUuid: 'zzzzz-dz642-000000000000001',
130             },
131         };
132
133         statusResponse = {
134             [ProcessStatusFilter.COMPLETED]: 50,
135             [ProcessStatusFilter.RUNNING]: 55,
136
137             [ProcessStatusFilter.FAILED]: 30,
138             [ProcessStatusFilter.CANCELLED]: 30,
139
140             [ProcessStatusFilter.QUEUED]: 235,
141             [ProcessStatusFilter.ONHOLD]: 100,
142         };
143
144         services.containerRequestService.list = createMockListFunc(process.containerRequest.containerUuid);
145
146         cy.mount(
147             <Provider store={store}>
148                 <SubprocessProgressBar process={process} />
149             </Provider>);
150
151         // Verify progress bar with correct degment widths
152         ['10%', '11%', '12%', '67%'].forEach((value, i) => {
153             cy.get('div[class=progress]').eq(i).should('have.attr', 'style').and('include', `width: ${value};`);
154         });
155     });
156
157 });