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