1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
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 import { updateResources } from 'store/resources/resources-actions';
24 configure({ adapter: new Adapter() });
26 describe("<SubprocessProgressBar />", () => {
27 const axiosInst = Axios.create({ headers: {} });
28 const axiosMock = new MockAdapter(axiosInst);
31 let services: ServiceRepository;
32 const config: any = {};
33 const actions: ApiActions = {
34 progressFn: (id: string, working: boolean) => { },
35 errorFn: (id: string, message: string) => { }
37 let statusResponse = {
38 [ProcessStatusFilter.COMPLETED]: 0,
39 [ProcessStatusFilter.RUNNING]: 0,
40 [ProcessStatusFilter.FAILED]: 0,
41 [ProcessStatusFilter.QUEUED]: 0,
44 const createMockListFunc = (uuid: string) => jest.fn(async (args) => {
45 const baseFilter = new FilterBuilder().addEqual('requesting_container_uuid', uuid).getFilters();
47 const filterResponses = Object.keys(statusResponse)
48 .map(status => ({filters: buildProcessStatusFilters(new FilterBuilder(baseFilter), status).getFilters(), value: statusResponse[status]}));
50 const matchedFilter = filterResponses.find(response => response.filters === args.filters);
52 return { itemsAvailable: matchedFilter.value };
54 return { itemsAvailable: 0 };
59 services = createServices(mockConfig({}), actions, axiosInst);
60 store = configureStore(createBrowserHistory(), services, config);
63 it("requests subprocess progress stats for stopped processes and displays progress", async () => {
65 const containerRequest = {
66 uuid: 'zzzzz-xvhdp-000000000000000',
67 containerUuid: 'zzzzz-dz642-000000000000000',
71 state: ContainerState.COMPLETE,
73 containerRequest: containerRequest,
75 await store.dispatch(updateResources([containerRequest, process]));
78 [ProcessStatusFilter.COMPLETED]: 100,
79 [ProcessStatusFilter.RUNNING]: 200,
81 // Combined into failed segment
82 [ProcessStatusFilter.FAILED]: 200,
83 [ProcessStatusFilter.CANCELLED]: 100,
85 // Combined into queued segment
86 [ProcessStatusFilter.QUEUED]: 300,
87 [ProcessStatusFilter.ONHOLD]: 100,
90 services.containerRequestService.list = createMockListFunc(process.containerRequest.containerUuid);
93 await act(async () => {
95 <Provider store={store}>
96 <SubprocessProgressBar parentResource={process} />
99 await progressBar.update();
101 // expects 6 subprocess status list requests
102 const expectedFilters = [
103 ProcessStatusFilter.COMPLETED,
104 ProcessStatusFilter.RUNNING,
105 ProcessStatusFilter.FAILED,
106 ProcessStatusFilter.CANCELLED,
107 ProcessStatusFilter.QUEUED,
108 ProcessStatusFilter.ONHOLD,
110 buildProcessStatusFilters(
111 new FilterBuilder().addEqual(
112 "requesting_container_uuid",
113 process.containerRequest.containerUuid
119 expectedFilters.forEach((filter) => {
120 expect(services.containerRequestService.list).toHaveBeenCalledWith({limit: 0, offset: 0, filters: filter});
123 // Verify progress bar with correct degment widths
124 ['10%', '20%', '30%', '40%'].forEach((value, i) => {
125 const styles = progressBar.find('.progress').at(i).props().style;
126 expect(styles).toHaveProperty('width', value);
130 it("dislays correct progress bar widths with different values", async () => {
131 const containerRequest = {
132 uuid: 'zzzzz-xvhdp-000000000000001',
133 containerUuid: 'zzzzz-dz642-000000000000001',
137 state: ContainerState.COMPLETE,
139 containerRequest: containerRequest,
141 await store.dispatch(updateResources([containerRequest, process]));
144 [ProcessStatusFilter.COMPLETED]: 50,
145 [ProcessStatusFilter.RUNNING]: 55,
147 [ProcessStatusFilter.FAILED]: 30,
148 [ProcessStatusFilter.CANCELLED]: 30,
150 [ProcessStatusFilter.QUEUED]: 235,
151 [ProcessStatusFilter.ONHOLD]: 100,
154 services.containerRequestService.list = createMockListFunc(process.containerRequest.containerUuid);
157 await act(async () => {
159 <Provider store={store}>
160 <SubprocessProgressBar parentResource={process} />
163 await progressBar.update();
165 // Verify progress bar with correct degment widths
166 ['10%', '11%', '12%', '67%'].forEach((value, i) => {
167 const styles = progressBar.find('.progress').at(i).props().style;
168 expect(styles).toHaveProperty('width', value);