foreman_rh_cloud 13.0.12 → 13.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/package.json +1 -1
- data/webpack/ForemanColumnExtensions/index.js +5 -3
- data/webpack/ForemanRhCloudFills.js +7 -0
- data/webpack/HostsIndexExtensions/VulnerabilityAnalysisActions.js +138 -0
- data/webpack/HostsIndexExtensions/__tests__/VulnerabilityAnalysisActions.test.js +567 -0
- data/webpack/HostsIndexExtensions/hostVulnerabilityStoreUtils.js +41 -0
- data/webpack/InsightsVulnerabilityActionsBar/InsightsVulnerabilityActionsBar.scss +14 -0
- data/webpack/InsightsVulnerabilityActionsBar/InsightsVulnerabilityActionsBarActions.js +169 -0
- data/webpack/InsightsVulnerabilityActionsBar/__tests__/InsightsVulnerabilityActionsBar.test.js +91 -0
- data/webpack/InsightsVulnerabilityActionsBar/__tests__/InsightsVulnerabilityActionsBarActions.test.js +299 -0
- data/webpack/InsightsVulnerabilityActionsBar/index.js +93 -0
- data/webpack/InsightsVulnerabilityHostIndexExtensions/CVECountCell.js +25 -13
- data/webpack/InsightsVulnerabilityHostIndexExtensions/__tests__/CVECountCell.test.js +156 -87
- data/webpack/__mocks__/foremanReact/Root/Context/ForemanContext.js +6 -2
- data/webpack/__mocks__/foremanReact/common/I18n.js +2 -1
- data/webpack/__mocks__/foremanReact/common/helpers.js +11 -0
- data/webpack/__mocks__/foremanReact/components/HostsIndex/index.js +8 -0
- data/webpack/__mocks__/foremanReact/redux.js +10 -0
- data/webpack/common/Hooks/ConfigHooks.js +1 -1
- data/webpack/global_index.js +7 -0
- metadata +11 -1
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import {
|
|
3
|
+
import { useDispatch } from 'react-redux';
|
|
4
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
|
4
5
|
import { Link } from 'react-router-dom';
|
|
5
6
|
import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
|
|
7
|
+
import { propsToCamelCase } from 'foremanReact/common/helpers';
|
|
6
8
|
import { insightsCloudUrl } from '../InsightsCloudSync/InsightsCloudSyncHelpers';
|
|
7
9
|
import { useIopConfig } from '../common/Hooks/ConfigHooks';
|
|
10
|
+
import { updateHostVulnerabilityOptOut } from '../HostsIndexExtensions/hostVulnerabilityStoreUtils';
|
|
8
11
|
|
|
9
12
|
const vulnerabilityApiPath = path =>
|
|
10
13
|
insightsCloudUrl(`api/vulnerability/v1/${path}`);
|
|
11
14
|
|
|
12
15
|
export const CVECountCell = ({ hostDetails }) => {
|
|
13
16
|
const isIopEnabled = useIopConfig();
|
|
17
|
+
const dispatch = useDispatch();
|
|
14
18
|
|
|
15
19
|
// eslint-disable-next-line camelcase
|
|
16
20
|
const uuid = hostDetails?.subscription_facet_attributes?.uuid;
|
|
21
|
+
const hostId = hostDetails?.id;
|
|
17
22
|
|
|
18
23
|
const key = `HOST_CVE_COUNT_${uuid}`;
|
|
19
24
|
const response = useAPI(
|
|
@@ -24,24 +29,31 @@ export const CVECountCell = ({ hostDetails }) => {
|
|
|
24
29
|
}
|
|
25
30
|
);
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
const { cveCount, optOut } = propsToCamelCase(
|
|
33
|
+
(response.response?.data || [])[0]?.attributes || {}
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// Update HOSTS Redux data when CVE data loads
|
|
37
|
+
// This triggers table re-render so kebab actions recompute with correct opt_out value
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (optOut !== undefined && hostId) {
|
|
40
|
+
updateHostVulnerabilityOptOut(hostId, optOut, dispatch);
|
|
41
|
+
}
|
|
42
|
+
}, [optOut, hostId, dispatch]);
|
|
30
43
|
|
|
31
|
-
if (uuid === undefined) {
|
|
32
|
-
return
|
|
44
|
+
if (!isIopEnabled || uuid === undefined) {
|
|
45
|
+
return '—';
|
|
33
46
|
}
|
|
34
47
|
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
if (optOut === true) {
|
|
49
|
+
return __('Analysis disabled');
|
|
50
|
+
}
|
|
37
51
|
|
|
38
52
|
const cveLink = (
|
|
39
|
-
|
|
40
|
-
<Link to={`hosts/${hostDetails.name}#/Vulnerabilities`}>{cve_count}</Link>
|
|
53
|
+
<Link to={`hosts/${hostDetails.name}#/Vulnerabilities`}>{cveCount}</Link>
|
|
41
54
|
);
|
|
42
55
|
|
|
43
|
-
|
|
44
|
-
return cve_count === undefined ? <UnknownIcon /> : cveLink;
|
|
56
|
+
return cveCount == null ? '—' : cveLink;
|
|
45
57
|
};
|
|
46
58
|
|
|
47
59
|
CVECountCell.propTypes = {
|
|
@@ -1,129 +1,198 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { screen } from '@testing-library/react';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
4
|
+
import { Provider } from 'react-redux';
|
|
5
|
+
import { ConnectedRouter } from 'connected-react-router';
|
|
6
|
+
import { createMemoryHistory } from 'history';
|
|
7
|
+
import configureMockStore from 'redux-mock-store';
|
|
8
|
+
import { STATUS } from 'foremanReact/constants';
|
|
9
|
+
import * as APIHooks from 'foremanReact/common/hooks/API/APIHooks';
|
|
10
|
+
import * as ConfigHooks from '../../common/Hooks/ConfigHooks';
|
|
5
11
|
import { CVECountCell } from '../CVECountCell';
|
|
6
12
|
|
|
7
|
-
jest.mock('foremanReact/
|
|
13
|
+
jest.mock('foremanReact/common/hooks/API/APIHooks');
|
|
8
14
|
jest.mock('../../common/Hooks/ConfigHooks');
|
|
9
15
|
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
{
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const mockStore = configureMockStore();
|
|
17
|
+
const history = createMemoryHistory();
|
|
18
|
+
const store = mockStore({
|
|
19
|
+
router: {
|
|
20
|
+
location: {
|
|
21
|
+
pathname: '/',
|
|
22
|
+
search: '',
|
|
23
|
+
hash: '',
|
|
24
|
+
state: null,
|
|
18
25
|
},
|
|
19
|
-
|
|
20
|
-
}
|
|
26
|
+
action: 'POP',
|
|
27
|
+
},
|
|
28
|
+
});
|
|
21
29
|
|
|
22
30
|
const hostDetailsMock = {
|
|
31
|
+
id: 1,
|
|
23
32
|
name: 'test-host.example.com',
|
|
24
33
|
subscription_facet_attributes: {
|
|
25
34
|
uuid: 'test-uuid-123',
|
|
26
35
|
},
|
|
27
36
|
};
|
|
28
37
|
|
|
38
|
+
const renderComponent = (props = {}) => {
|
|
39
|
+
const allProps = {
|
|
40
|
+
hostDetails: hostDetailsMock,
|
|
41
|
+
...props,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
return render(
|
|
45
|
+
<Provider store={store}>
|
|
46
|
+
<ConnectedRouter history={history}>
|
|
47
|
+
<CVECountCell {...allProps} />
|
|
48
|
+
</ConnectedRouter>
|
|
49
|
+
</Provider>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
29
53
|
describe('CVECountCell', () => {
|
|
30
|
-
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
store.clearActions();
|
|
31
56
|
jest.clearAllMocks();
|
|
32
57
|
});
|
|
33
58
|
|
|
34
59
|
it('renders an empty cves count column when no subscription UUID', () => {
|
|
35
|
-
|
|
60
|
+
ConfigHooks.useIopConfig.mockReturnValue(true);
|
|
61
|
+
APIHooks.useAPI.mockReturnValue({
|
|
62
|
+
status: STATUS.RESOLVED,
|
|
63
|
+
response: null,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const hostDetailsMockNoUuid = {
|
|
36
67
|
name: 'test-host.example.com',
|
|
37
68
|
subscription_facet_attributes: {
|
|
38
69
|
uuid: null, // no subscription
|
|
39
70
|
},
|
|
40
71
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
ADVISOR_ENGINE_CONFIG: {
|
|
52
|
-
response: { use_iop_mode: true },
|
|
53
|
-
status: 'RESOLVED',
|
|
54
|
-
},
|
|
55
|
-
},
|
|
72
|
+
|
|
73
|
+
renderComponent({ hostDetails: hostDetailsMockNoUuid });
|
|
74
|
+
expect(screen.getByText('—')).toBeInTheDocument();
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('renders — when IoP is not enabled', () => {
|
|
78
|
+
ConfigHooks.useIopConfig.mockReturnValue(false);
|
|
79
|
+
APIHooks.useAPI.mockReturnValue({
|
|
80
|
+
status: STATUS.RESOLVED,
|
|
81
|
+
response: null,
|
|
56
82
|
});
|
|
57
|
-
|
|
83
|
+
|
|
84
|
+
renderComponent();
|
|
85
|
+
expect(screen.getByText('—')).toBeInTheDocument();
|
|
58
86
|
});
|
|
59
87
|
|
|
60
|
-
it('renders
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
search: '',
|
|
66
|
-
hash: '',
|
|
67
|
-
query: {},
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
API: {
|
|
71
|
-
ADVISOR_ENGINE_CONFIG: {
|
|
72
|
-
response: { use_iop_mode: false },
|
|
73
|
-
status: 'RESOLVED',
|
|
74
|
-
},
|
|
75
|
-
},
|
|
88
|
+
it('renders — when IoP is enabled but CVE API call fails', () => {
|
|
89
|
+
ConfigHooks.useIopConfig.mockReturnValue(true);
|
|
90
|
+
APIHooks.useAPI.mockReturnValue({
|
|
91
|
+
status: STATUS.ERROR,
|
|
92
|
+
response: null,
|
|
76
93
|
});
|
|
77
|
-
|
|
94
|
+
|
|
95
|
+
renderComponent();
|
|
96
|
+
expect(screen.getByText('—')).toBeInTheDocument();
|
|
78
97
|
});
|
|
79
98
|
|
|
80
|
-
it('renders
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
99
|
+
it('renders — when IoP is undefined (API call pending)', () => {
|
|
100
|
+
ConfigHooks.useIopConfig.mockReturnValue(undefined);
|
|
101
|
+
APIHooks.useAPI.mockReturnValue({
|
|
102
|
+
status: STATUS.PENDING,
|
|
103
|
+
response: null,
|
|
84
104
|
});
|
|
85
105
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
106
|
+
renderComponent();
|
|
107
|
+
expect(screen.getByText('—')).toBeInTheDocument();
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('renders "Analysis disabled" when opt_out is true', () => {
|
|
111
|
+
ConfigHooks.useIopConfig.mockReturnValue(true);
|
|
112
|
+
APIHooks.useAPI.mockReturnValue({
|
|
113
|
+
status: STATUS.RESOLVED,
|
|
114
|
+
response: {
|
|
115
|
+
data: [
|
|
116
|
+
{
|
|
117
|
+
attributes: {
|
|
118
|
+
opt_out: true,
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
],
|
|
94
122
|
},
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
renderComponent();
|
|
126
|
+
expect(screen.getByText('Analysis disabled')).toBeInTheDocument();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('renders CVE count link when valid count is returned', () => {
|
|
130
|
+
ConfigHooks.useIopConfig.mockReturnValue(true);
|
|
131
|
+
APIHooks.useAPI.mockReturnValue({
|
|
132
|
+
status: STATUS.RESOLVED,
|
|
133
|
+
response: {
|
|
134
|
+
data: [
|
|
135
|
+
{
|
|
136
|
+
attributes: {
|
|
137
|
+
cve_count: 1,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
],
|
|
105
141
|
},
|
|
106
142
|
});
|
|
107
|
-
|
|
108
|
-
|
|
143
|
+
|
|
144
|
+
renderComponent();
|
|
145
|
+
|
|
146
|
+
// Should render a link with the CVE count
|
|
147
|
+
const link = screen.getByRole('link');
|
|
148
|
+
expect(link).toBeInTheDocument();
|
|
149
|
+
expect(link).toHaveTextContent('1');
|
|
150
|
+
expect(link).toHaveAttribute(
|
|
151
|
+
'href',
|
|
152
|
+
`/hosts/${hostDetailsMock.name}#/Vulnerabilities`
|
|
153
|
+
);
|
|
109
154
|
});
|
|
110
155
|
|
|
111
|
-
it('renders
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
156
|
+
it('renders — when cve_count is null (analysis enabled but not scanned yet)', () => {
|
|
157
|
+
ConfigHooks.useIopConfig.mockReturnValue(true);
|
|
158
|
+
APIHooks.useAPI.mockReturnValue({
|
|
159
|
+
status: STATUS.RESOLVED,
|
|
160
|
+
response: {
|
|
161
|
+
data: [
|
|
162
|
+
{
|
|
163
|
+
attributes: {
|
|
164
|
+
cve_count: null, // null when enabled but not scanned
|
|
165
|
+
opt_out: false,
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
],
|
|
120
169
|
},
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
renderComponent();
|
|
173
|
+
expect(screen.getByText('—')).toBeInTheDocument();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('renders 0 CVE count link when count is 0', () => {
|
|
177
|
+
ConfigHooks.useIopConfig.mockReturnValue(true);
|
|
178
|
+
APIHooks.useAPI.mockReturnValue({
|
|
179
|
+
status: STATUS.RESOLVED,
|
|
180
|
+
response: {
|
|
181
|
+
data: [
|
|
182
|
+
{
|
|
183
|
+
attributes: {
|
|
184
|
+
cve_count: 0,
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
],
|
|
125
188
|
},
|
|
126
189
|
});
|
|
127
|
-
|
|
190
|
+
|
|
191
|
+
renderComponent();
|
|
192
|
+
|
|
193
|
+
// Should render a link with 0
|
|
194
|
+
const link = screen.getByRole('link');
|
|
195
|
+
expect(link).toBeInTheDocument();
|
|
196
|
+
expect(link).toHaveTextContent('0');
|
|
128
197
|
});
|
|
129
198
|
});
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
export const useForemanSettings = () => ({ perPage: 20 });
|
|
2
|
-
export const useForemanOrganization = () => ({
|
|
1
|
+
export const useForemanSettings = jest.fn(() => ({ perPage: 20 }));
|
|
2
|
+
export const useForemanOrganization = jest.fn(() => ({
|
|
3
|
+
id: 1,
|
|
4
|
+
title: 'some-org',
|
|
5
|
+
}));
|
|
6
|
+
export const useForemanContext = jest.fn(() => ({ metadata: {} }));
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
import camelCase from 'lodash/camelCase';
|
|
2
|
+
|
|
1
3
|
export const getURIQuery = jest.fn(() => ({}));
|
|
2
4
|
|
|
3
5
|
export const noop = Function.prototype;
|
|
6
|
+
|
|
7
|
+
export const propsToCamelCase = ob => {
|
|
8
|
+
if (typeof ob !== 'object' || ob === null) return ob;
|
|
9
|
+
|
|
10
|
+
return Object.keys(ob).reduce((memo, key) => {
|
|
11
|
+
memo[camelCase(key)] = ob[key];
|
|
12
|
+
return memo;
|
|
13
|
+
}, {});
|
|
14
|
+
};
|
|
@@ -2,4 +2,4 @@ import { useForemanContext } from 'foremanReact/Root/Context/ForemanContext';
|
|
|
2
2
|
|
|
3
3
|
export const useIopConfig = () =>
|
|
4
4
|
// eslint-disable-next-line camelcase
|
|
5
|
-
useForemanContext().metadata?.foreman_rh_cloud?.iop;
|
|
5
|
+
useForemanContext().metadata?.foreman_rh_cloud?.iop === true;
|
data/webpack/global_index.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { registerColumns } from 'foremanReact/components/HostsIndex/Columns/core';
|
|
2
|
+
import { registerGetActions } from 'foremanReact/components/HostsIndex/TableRowActions/core';
|
|
2
3
|
import { registerReducers } from './ForemanRhCloudReducers';
|
|
3
4
|
import { registerFills } from './ForemanRhCloudFills';
|
|
4
5
|
import { registerRoutes } from './ForemanRhCloudPages';
|
|
5
6
|
import hostsIndexColumnExtensions from './ForemanColumnExtensions/index';
|
|
7
|
+
import getVulnerabilityAnalysisActions from './HostsIndexExtensions/VulnerabilityAnalysisActions';
|
|
6
8
|
|
|
7
9
|
registerReducers();
|
|
8
10
|
registerFills();
|
|
9
11
|
registerRoutes();
|
|
10
12
|
registerColumns(hostsIndexColumnExtensions);
|
|
13
|
+
registerGetActions({
|
|
14
|
+
pluginName: 'foreman_rh_cloud',
|
|
15
|
+
getActionsFunc: getVulnerabilityAnalysisActions,
|
|
16
|
+
tableName: 'hosts',
|
|
17
|
+
});
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foreman_rh_cloud
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 13.0
|
|
4
|
+
version: 13.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Foreman Red Hat Cloud team
|
|
@@ -513,6 +513,9 @@ files:
|
|
|
513
513
|
- webpack/ForemanRhCloudReducers.js
|
|
514
514
|
- webpack/ForemanRhCloudSelectors.js
|
|
515
515
|
- webpack/ForemanRhCloudTestHelpers.js
|
|
516
|
+
- webpack/HostsIndexExtensions/VulnerabilityAnalysisActions.js
|
|
517
|
+
- webpack/HostsIndexExtensions/__tests__/VulnerabilityAnalysisActions.test.js
|
|
518
|
+
- webpack/HostsIndexExtensions/hostVulnerabilityStoreUtils.js
|
|
516
519
|
- webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettings.js
|
|
517
520
|
- webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettingsActions.js
|
|
518
521
|
- webpack/InsightsCloudSync/Components/InsightsSettings/InsightsSettingsConstants.js
|
|
@@ -592,6 +595,11 @@ files:
|
|
|
592
595
|
- webpack/InsightsHostDetailsTab/index.js
|
|
593
596
|
- webpack/InsightsVulnerability/InsightsVulnerabilityListPage.js
|
|
594
597
|
- webpack/InsightsVulnerability/InsightsVulnerabilityListPage.test.js
|
|
598
|
+
- webpack/InsightsVulnerabilityActionsBar/InsightsVulnerabilityActionsBar.scss
|
|
599
|
+
- webpack/InsightsVulnerabilityActionsBar/InsightsVulnerabilityActionsBarActions.js
|
|
600
|
+
- webpack/InsightsVulnerabilityActionsBar/__tests__/InsightsVulnerabilityActionsBar.test.js
|
|
601
|
+
- webpack/InsightsVulnerabilityActionsBar/__tests__/InsightsVulnerabilityActionsBarActions.test.js
|
|
602
|
+
- webpack/InsightsVulnerabilityActionsBar/index.js
|
|
595
603
|
- webpack/InsightsVulnerabilityHostIndexExtensions/CVECountCell.js
|
|
596
604
|
- webpack/InsightsVulnerabilityHostIndexExtensions/__tests__/CVECountCell.test.js
|
|
597
605
|
- webpack/IopRecommendationDetails/IopRecommendationDetails.js
|
|
@@ -601,10 +609,12 @@ files:
|
|
|
601
609
|
- webpack/__mocks__/foremanReact/common/helpers.js
|
|
602
610
|
- webpack/__mocks__/foremanReact/components/ConfirmModal/index.js
|
|
603
611
|
- webpack/__mocks__/foremanReact/components/Head.js
|
|
612
|
+
- webpack/__mocks__/foremanReact/components/HostsIndex/index.js
|
|
604
613
|
- webpack/__mocks__/foremanReact/components/Layout/LayoutConstants.js
|
|
605
614
|
- webpack/__mocks__/foremanReact/components/ToastsList/index.js
|
|
606
615
|
- webpack/__mocks__/foremanReact/components/common/dates/RelativeDateTime.js
|
|
607
616
|
- webpack/__mocks__/foremanReact/constants.js
|
|
617
|
+
- webpack/__mocks__/foremanReact/redux.js
|
|
608
618
|
- webpack/__mocks__/foremanReact/redux/API/APISelectors.js
|
|
609
619
|
- webpack/__mocks__/foremanReact/redux/API/index.js
|
|
610
620
|
- webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware.js
|