foreman-tasks 12.2.3 → 12.2.4
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_tasks/version.rb +1 -1
- data/webpack/ForemanTasks/Components/TaskActions/TaskAction.test.js +212 -42
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Errors.js +224 -55
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Errors.scss +41 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Errors.test.js +159 -11
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboard.test.js +94 -7
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardActions.test.js +97 -16
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardReducer.test.js +112 -46
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardSelectors.test.js +103 -15
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +1 -1
- metadata +2 -6
- data/webpack/ForemanTasks/Components/TaskActions/__snapshots__/TaskAction.test.js.snap +0 -233
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboard.test.js.snap +0 -51
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboardActions.test.js.snap +0 -151
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboardReducer.test.js.snap +0 -275
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboardSelectors.test.js.snap +0 -119
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
3
3
|
import '@testing-library/jest-dom';
|
|
4
4
|
|
|
5
5
|
import Errors from '../Errors';
|
|
@@ -20,6 +20,8 @@ const failedStepFixture = {
|
|
|
20
20
|
output: '{}\n',
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
+
const executionPlan = { state: 'paused', cancellable: false };
|
|
24
|
+
|
|
23
25
|
describe('Errors', () => {
|
|
24
26
|
it('renders warning when execution plan is missing', () => {
|
|
25
27
|
render(<Errors failedSteps={[]} executionPlan={null} />);
|
|
@@ -30,30 +32,176 @@ describe('Errors', () => {
|
|
|
30
32
|
|
|
31
33
|
it('renders success state when there are no failed steps', () => {
|
|
32
34
|
render(<Errors failedSteps={[]} executionPlan={{ state: 'paused' }} />);
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
expect(
|
|
36
|
+
screen.getByRole('heading', { level: 2, name: /no errors found/i })
|
|
37
|
+
).toBeInTheDocument();
|
|
38
|
+
expect(
|
|
39
|
+
screen.getByText(/the task finished with no errors or warnings/i)
|
|
40
|
+
).toBeInTheDocument();
|
|
35
41
|
});
|
|
36
42
|
|
|
37
43
|
it('renders failed step details when failedSteps is non-empty', () => {
|
|
38
44
|
const { container } = render(
|
|
39
45
|
<Errors
|
|
40
|
-
executionPlan={
|
|
46
|
+
executionPlan={executionPlan}
|
|
41
47
|
failedSteps={[failedStepFixture]}
|
|
42
48
|
/>
|
|
43
49
|
);
|
|
44
|
-
const
|
|
50
|
+
const errorTab = container.querySelector(
|
|
45
51
|
'[data-ouia-component-id="task-error-0"]'
|
|
46
52
|
);
|
|
47
|
-
expect(
|
|
48
|
-
expect(
|
|
53
|
+
expect(errorTab).toBeInTheDocument();
|
|
54
|
+
expect(
|
|
55
|
+
screen.getByRole('tab', {
|
|
56
|
+
name: /action actions::katello::eventqueue::monitor is already active/i,
|
|
57
|
+
})
|
|
58
|
+
).toBeInTheDocument();
|
|
49
59
|
expect(
|
|
50
|
-
screen.
|
|
60
|
+
screen.getByLabelText(/failed task errors/i)
|
|
51
61
|
).toBeInTheDocument();
|
|
62
|
+
expect(screen.getByText('Input')).toBeInTheDocument();
|
|
63
|
+
expect(screen.getByText('Output')).toBeInTheDocument();
|
|
64
|
+
expect(screen.getByText('Exception:')).toBeInTheDocument();
|
|
65
|
+
expect(screen.getByText('Backtrace')).toBeInTheDocument();
|
|
52
66
|
expect(screen.getByText(/runtimeerror/i)).toBeInTheDocument();
|
|
67
|
+
expect(screen.getByText(/singleton_lock/i)).toBeInTheDocument();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('switches detail pane when a different error tab is clicked', () => {
|
|
71
|
+
const firstStep = {
|
|
72
|
+
...failedStepFixture,
|
|
73
|
+
action_class: 'Action::First',
|
|
74
|
+
input: 'INPUT_FROM_FIRST_STEP',
|
|
75
|
+
output: '{}',
|
|
76
|
+
};
|
|
77
|
+
const secondStep = {
|
|
78
|
+
...failedStepFixture,
|
|
79
|
+
action_class: 'Action::Second',
|
|
80
|
+
error: {
|
|
81
|
+
exception_class: 'StandardError',
|
|
82
|
+
message: 'second step failure',
|
|
83
|
+
backtrace: [],
|
|
84
|
+
},
|
|
85
|
+
input: 'INPUT_FROM_SECOND_STEP',
|
|
86
|
+
output: 'OUTPUT_SECOND',
|
|
87
|
+
state: 'error',
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
render(
|
|
91
|
+
<Errors
|
|
92
|
+
executionPlan={executionPlan}
|
|
93
|
+
failedSteps={[firstStep, secondStep]}
|
|
94
|
+
/>
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
expect(screen.getByText('INPUT_FROM_FIRST_STEP')).toBeInTheDocument();
|
|
98
|
+
expect(screen.queryByText('INPUT_FROM_SECOND_STEP')).not.toBeInTheDocument();
|
|
99
|
+
|
|
100
|
+
const tabs = screen.getAllByRole('tab');
|
|
101
|
+
expect(tabs[0]).toHaveAttribute('aria-selected', 'true');
|
|
102
|
+
expect(tabs[1]).toHaveAttribute('aria-selected', 'false');
|
|
103
|
+
|
|
104
|
+
fireEvent.click(tabs[1]);
|
|
105
|
+
|
|
106
|
+
expect(screen.getByText('INPUT_FROM_SECOND_STEP')).toBeInTheDocument();
|
|
107
|
+
expect(screen.queryByText('INPUT_FROM_FIRST_STEP')).not.toBeInTheDocument();
|
|
108
|
+
expect(tabs[0]).toHaveAttribute('aria-selected', 'false');
|
|
109
|
+
expect(tabs[1]).toHaveAttribute('aria-selected', 'true');
|
|
110
|
+
expect(screen.getByText('OUTPUT_SECOND')).toBeInTheDocument();
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('clamps selection when failedSteps shrinks', () => {
|
|
114
|
+
const firstStep = {
|
|
115
|
+
...failedStepFixture,
|
|
116
|
+
action_class: 'Action::First',
|
|
117
|
+
input: 'AFTER_CLAMP',
|
|
118
|
+
output: '{}',
|
|
119
|
+
};
|
|
120
|
+
const secondStep = {
|
|
121
|
+
...failedStepFixture,
|
|
122
|
+
action_class: 'Action::Second',
|
|
123
|
+
input: 'REMOVED',
|
|
124
|
+
output: '{}',
|
|
125
|
+
state: 'error',
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const { rerender } = render(
|
|
129
|
+
<Errors
|
|
130
|
+
executionPlan={executionPlan}
|
|
131
|
+
failedSteps={[firstStep, secondStep]}
|
|
132
|
+
/>
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
fireEvent.click(screen.getAllByRole('tab')[1]);
|
|
136
|
+
expect(screen.getByText('REMOVED')).toBeInTheDocument();
|
|
137
|
+
|
|
138
|
+
rerender(
|
|
139
|
+
<Errors executionPlan={executionPlan} failedSteps={[firstStep]} />
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
expect(screen.getAllByRole('tab')).toHaveLength(1);
|
|
143
|
+
expect(screen.getByText('AFTER_CLAMP')).toBeInTheDocument();
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('truncates long tab titles to 120 characters with ellipsis', () => {
|
|
147
|
+
const longMessage = 'x'.repeat(150);
|
|
148
|
+
const longStep = {
|
|
149
|
+
...failedStepFixture,
|
|
150
|
+
error: {
|
|
151
|
+
...failedStepFixture.error,
|
|
152
|
+
message: longMessage,
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const { container } = render(
|
|
157
|
+
<Errors executionPlan={executionPlan} failedSteps={[longStep]} />
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
const tabTitle = container.querySelector('.task-errors-tab-title');
|
|
161
|
+
expect(tabTitle.textContent).toHaveLength(120);
|
|
162
|
+
expect(tabTitle.textContent.endsWith('...')).toBe(true);
|
|
163
|
+
expect(
|
|
164
|
+
screen.getByRole('tab', { name: longMessage })
|
|
165
|
+
).toBeInTheDocument();
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('uses warning styling for skipped steps', () => {
|
|
169
|
+
const skippedStep = {
|
|
170
|
+
action_class: 'Actions::Example',
|
|
171
|
+
state: 'skipped',
|
|
172
|
+
input: '{}',
|
|
173
|
+
output: '{}',
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const { container } = render(
|
|
177
|
+
<Errors executionPlan={executionPlan} failedSteps={[skippedStep]} />
|
|
178
|
+
);
|
|
179
|
+
|
|
53
180
|
expect(
|
|
54
|
-
screen.
|
|
55
|
-
/action actions::katello::eventqueue::monitor is already active/i
|
|
56
|
-
)
|
|
181
|
+
screen.getByRole('tab', { name: /actions::example/i })
|
|
57
182
|
).toBeInTheDocument();
|
|
183
|
+
|
|
184
|
+
const errorTab = container.querySelector(
|
|
185
|
+
'[data-ouia-component-id="task-error-0"]'
|
|
186
|
+
);
|
|
187
|
+
expect(errorTab.querySelector('.pf-m-warning')).toBeInTheDocument();
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('omits exception and backtrace when step has no error object', () => {
|
|
191
|
+
const stepWithoutError = {
|
|
192
|
+
action_class: 'Actions::NoError',
|
|
193
|
+
state: 'error',
|
|
194
|
+
input: 'plain-input',
|
|
195
|
+
output: 'plain-output',
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
render(
|
|
199
|
+
<Errors executionPlan={executionPlan} failedSteps={[stepWithoutError]} />
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
expect(screen.getByText('plain-input')).toBeInTheDocument();
|
|
203
|
+
expect(screen.getByText('plain-output')).toBeInTheDocument();
|
|
204
|
+
expect(screen.queryByText('Exception:')).not.toBeInTheDocument();
|
|
205
|
+
expect(screen.queryByText('Backtrace')).not.toBeInTheDocument();
|
|
58
206
|
});
|
|
59
207
|
});
|
|
@@ -1,13 +1,100 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
2
4
|
|
|
5
|
+
import { TASKS_DASHBOARD_AVAILABLE_TIMES } from '../TasksDashboardConstants';
|
|
6
|
+
import { getQueryFromUrl } from '../TasksDashboardHelper';
|
|
3
7
|
import TasksDashboard from '../TasksDashboard';
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
'
|
|
7
|
-
|
|
8
|
-
};
|
|
9
|
+
jest.mock('../TasksDashboardHelper', () => ({
|
|
10
|
+
...jest.requireActual('../TasksDashboardHelper'),
|
|
11
|
+
getQueryFromUrl: jest.fn(() => ({})),
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
jest.mock(
|
|
15
|
+
'../Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChart',
|
|
16
|
+
() => {
|
|
17
|
+
const React = require('react');
|
|
18
|
+
const Stub = () => <div data-testid="tasks-donut-chart-stub" />;
|
|
19
|
+
Stub.displayName = 'TasksDonutChart';
|
|
20
|
+
|
|
21
|
+
return Stub;
|
|
22
|
+
}
|
|
23
|
+
);
|
|
9
24
|
|
|
10
25
|
describe('TasksDashboard', () => {
|
|
11
|
-
|
|
12
|
-
|
|
26
|
+
const cardIds = [
|
|
27
|
+
'running-tasks-card',
|
|
28
|
+
'paused-tasks-card',
|
|
29
|
+
'stopped-tasks-card',
|
|
30
|
+
'scheduled-tasks-card',
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
jest.clearAllMocks();
|
|
35
|
+
getQueryFromUrl.mockReturnValue({});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('renders the dashboard grid with time picker and task cards', () => {
|
|
39
|
+
const { container } = render(<TasksDashboard history={{}} />);
|
|
40
|
+
|
|
41
|
+
expect(container.querySelector('.tasks-dashboard-grid')).toBeInTheDocument();
|
|
42
|
+
expect(screen.getByText('With focus on last')).toBeInTheDocument();
|
|
43
|
+
expect(
|
|
44
|
+
screen.getByRole('button', { name: /24h/i })
|
|
45
|
+
).toBeInTheDocument();
|
|
46
|
+
|
|
47
|
+
cardIds.forEach(id => {
|
|
48
|
+
expect(container.querySelector(`#${id}`)).toBeInTheDocument();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('initializes the dashboard and fetches the summary on mount', () => {
|
|
53
|
+
const initializeDashboard = jest.fn();
|
|
54
|
+
const fetchTasksSummary = jest.fn();
|
|
55
|
+
|
|
56
|
+
render(
|
|
57
|
+
<TasksDashboard
|
|
58
|
+
history={{}}
|
|
59
|
+
initializeDashboard={initializeDashboard}
|
|
60
|
+
fetchTasksSummary={fetchTasksSummary}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
expect(initializeDashboard).toHaveBeenCalledWith({
|
|
65
|
+
time: undefined,
|
|
66
|
+
query: {},
|
|
67
|
+
});
|
|
68
|
+
expect(fetchTasksSummary).toHaveBeenCalledWith(
|
|
69
|
+
TASKS_DASHBOARD_AVAILABLE_TIMES.H24,
|
|
70
|
+
''
|
|
71
|
+
);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('fetches the summary again when time changes', () => {
|
|
75
|
+
const fetchTasksSummary = jest.fn();
|
|
76
|
+
|
|
77
|
+
const { rerender } = render(
|
|
78
|
+
<TasksDashboard
|
|
79
|
+
history={{}}
|
|
80
|
+
fetchTasksSummary={fetchTasksSummary}
|
|
81
|
+
time={TASKS_DASHBOARD_AVAILABLE_TIMES.H24}
|
|
82
|
+
/>
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
fetchTasksSummary.mockClear();
|
|
86
|
+
|
|
87
|
+
rerender(
|
|
88
|
+
<TasksDashboard
|
|
89
|
+
history={{}}
|
|
90
|
+
fetchTasksSummary={fetchTasksSummary}
|
|
91
|
+
time={TASKS_DASHBOARD_AVAILABLE_TIMES.H12}
|
|
92
|
+
/>
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
expect(fetchTasksSummary).toHaveBeenCalledWith(
|
|
96
|
+
TASKS_DASHBOARD_AVAILABLE_TIMES.H12,
|
|
97
|
+
''
|
|
98
|
+
);
|
|
99
|
+
});
|
|
13
100
|
});
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
import { testActionSnapshotWithFixtures } from '@theforeman/test';
|
|
2
1
|
import { API } from 'foremanReact/redux/API';
|
|
3
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
FOREMAN_TASKS_DASHBOARD_INIT,
|
|
4
|
+
FOREMAN_TASKS_DASHBOARD_UPDATE_TIME,
|
|
5
|
+
FOREMAN_TASKS_DASHBOARD_UPDATE_QUERY,
|
|
6
|
+
FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST,
|
|
7
|
+
FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_SUCCESS,
|
|
8
|
+
FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_FAILURE,
|
|
9
|
+
} from '../TasksDashboardConstants';
|
|
10
|
+
import { timeToHoursNumber, resolveQuery } from '../TasksDashboardHelper';
|
|
4
11
|
import {
|
|
5
12
|
initializeDashboard,
|
|
6
13
|
updateTime,
|
|
@@ -12,25 +19,99 @@ import {
|
|
|
12
19
|
wrongTime,
|
|
13
20
|
parentTaskID,
|
|
14
21
|
apiGetMock,
|
|
22
|
+
taskSummary,
|
|
23
|
+
subtaskSummary,
|
|
15
24
|
} from './TaskDashboard.fixtures';
|
|
16
25
|
|
|
17
26
|
jest.mock('foremanReact/redux/API');
|
|
18
27
|
jest.mock('../TasksDashboardHelper');
|
|
19
28
|
|
|
20
29
|
timeToHoursNumber.mockImplementation(arg => arg);
|
|
30
|
+
resolveQuery.mockImplementation(() => {});
|
|
21
31
|
API.get.mockImplementation(apiGetMock);
|
|
22
32
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
describe('TasksDashboard - Actions', () => {
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
jest.clearAllMocks();
|
|
36
|
+
timeToHoursNumber.mockImplementation(arg => arg);
|
|
37
|
+
resolveQuery.mockImplementation(() => {});
|
|
38
|
+
API.get.mockImplementation(apiGetMock);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should initialize-dashboard', () => {
|
|
42
|
+
expect(
|
|
43
|
+
initializeDashboard({ time: 'some-time', query: 'some-query' })
|
|
44
|
+
).toEqual({
|
|
45
|
+
type: FOREMAN_TASKS_DASHBOARD_INIT,
|
|
46
|
+
payload: { time: 'some-time', query: 'some-query' },
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should update-time', () => {
|
|
51
|
+
expect(updateTime('some-time')).toEqual({
|
|
52
|
+
type: FOREMAN_TASKS_DASHBOARD_UPDATE_TIME,
|
|
53
|
+
payload: 'some-time',
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should update-query', () => {
|
|
58
|
+
const dispatch = jest.fn();
|
|
59
|
+
const getState = jest.fn();
|
|
60
|
+
const history = { push: jest.fn(), replace: jest.fn() };
|
|
61
|
+
const query = { state: 'running' };
|
|
62
|
+
|
|
63
|
+
updateQuery(query, history)(dispatch, getState);
|
|
64
|
+
|
|
65
|
+
expect(resolveQuery).toHaveBeenCalledWith(query, history);
|
|
66
|
+
expect(dispatch).toHaveBeenCalledWith({
|
|
67
|
+
type: FOREMAN_TASKS_DASHBOARD_UPDATE_QUERY,
|
|
68
|
+
payload: query,
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should fetch-tasks-summary and success', async () => {
|
|
73
|
+
const dispatch = jest.fn();
|
|
74
|
+
|
|
75
|
+
await fetchTasksSummary(correctTime)(dispatch);
|
|
76
|
+
|
|
77
|
+
expect(dispatch).toHaveBeenCalledTimes(2);
|
|
78
|
+
expect(dispatch.mock.calls[0][0]).toEqual({
|
|
79
|
+
type: FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST,
|
|
80
|
+
});
|
|
81
|
+
expect(dispatch.mock.calls[1][0]).toEqual({
|
|
82
|
+
type: FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_SUCCESS,
|
|
83
|
+
payload: taskSummary,
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('should fetch-tasks-summary for subtasks and success', async () => {
|
|
88
|
+
const dispatch = jest.fn();
|
|
89
|
+
|
|
90
|
+
await fetchTasksSummary(correctTime, parentTaskID)(dispatch);
|
|
91
|
+
|
|
92
|
+
expect(dispatch).toHaveBeenCalledTimes(2);
|
|
93
|
+
expect(dispatch.mock.calls[0][0]).toEqual({
|
|
94
|
+
type: FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST,
|
|
95
|
+
});
|
|
96
|
+
expect(dispatch.mock.calls[1][0]).toEqual({
|
|
97
|
+
type: FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_SUCCESS,
|
|
98
|
+
payload: subtaskSummary,
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should fetch-tasks-summary and fail', async () => {
|
|
103
|
+
const dispatch = jest.fn();
|
|
104
|
+
|
|
105
|
+
await fetchTasksSummary(wrongTime)(dispatch);
|
|
106
|
+
|
|
107
|
+
expect(dispatch).toHaveBeenCalledTimes(2);
|
|
108
|
+
expect(dispatch.mock.calls[0][0]).toEqual({
|
|
109
|
+
type: FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST,
|
|
110
|
+
});
|
|
111
|
+
expect(dispatch.mock.calls[1][0].type).toBe(
|
|
112
|
+
FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_FAILURE
|
|
113
|
+
);
|
|
114
|
+
expect(dispatch.mock.calls[1][0].payload).toEqual(expect.any(Error));
|
|
115
|
+
expect(dispatch.mock.calls[1][0].payload.message).toBe('wrong time');
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { testReducerSnapshotWithFixtures } from '@theforeman/test';
|
|
2
|
-
|
|
3
1
|
import {
|
|
4
2
|
FOREMAN_TASKS_DASHBOARD_INIT,
|
|
5
3
|
FOREMAN_TASKS_DASHBOARD_UPDATE_TIME,
|
|
@@ -7,52 +5,120 @@ import {
|
|
|
7
5
|
FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST,
|
|
8
6
|
FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_SUCCESS,
|
|
9
7
|
FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_FAILURE,
|
|
8
|
+
TASKS_DASHBOARD_AVAILABLE_QUERY_STATES,
|
|
9
|
+
TASKS_DASHBOARD_AVAILABLE_TIMES,
|
|
10
|
+
TASKS_SUMMARY_ZERO,
|
|
10
11
|
} from '../TasksDashboardConstants';
|
|
11
12
|
import reducer from '../TasksDashboardReducer';
|
|
12
13
|
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
type: FOREMAN_TASKS_DASHBOARD_INIT,
|
|
23
|
-
payload: { time: 'some-time', query: 'some-query' },
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
'should handle FOREMAN_TASKS_DASHBOARD_UPDATE_TIME': {
|
|
27
|
-
action: {
|
|
28
|
-
type: FOREMAN_TASKS_DASHBOARD_UPDATE_TIME,
|
|
29
|
-
payload: 'some-time',
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
'should handle FOREMAN_TASKS_DASHBOARD_UPDATE_QUERY': {
|
|
33
|
-
action: {
|
|
34
|
-
type: FOREMAN_TASKS_DASHBOARD_UPDATE_QUERY,
|
|
35
|
-
payload: 'some-query',
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
'should handle FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST': {
|
|
39
|
-
action: {
|
|
40
|
-
type: FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST,
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
'should handle FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_SUCCESS': {
|
|
44
|
-
action: {
|
|
45
|
-
type: FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_SUCCESS,
|
|
46
|
-
payload: 'some-payload',
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
'should handle FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_FAILURE': {
|
|
50
|
-
action: {
|
|
51
|
-
type: FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_FAILURE,
|
|
52
|
-
payload: new Error('some error'),
|
|
53
|
-
},
|
|
54
|
-
},
|
|
14
|
+
const dashboardQuery = {
|
|
15
|
+
state: TASKS_DASHBOARD_AVAILABLE_QUERY_STATES.RUNNING,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const initialState = {
|
|
19
|
+
time: TASKS_DASHBOARD_AVAILABLE_TIMES.H24,
|
|
20
|
+
isLoadingTasksSummary: false,
|
|
21
|
+
error: null,
|
|
22
|
+
tasksSummary: TASKS_SUMMARY_ZERO,
|
|
55
23
|
};
|
|
56
24
|
|
|
57
|
-
|
|
58
|
-
|
|
25
|
+
const runReducer = (state, action) =>
|
|
26
|
+
reducer(state, action).asMutable({ deep: true });
|
|
27
|
+
|
|
28
|
+
describe('TasksDashboard reducer', () => {
|
|
29
|
+
it('should return the initial state', () => {
|
|
30
|
+
expect(runReducer(undefined, {})).toEqual(initialState);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should handle FOREMAN_TASKS_DASHBOARD_INIT', () => {
|
|
34
|
+
expect(
|
|
35
|
+
runReducer(undefined, {
|
|
36
|
+
type: FOREMAN_TASKS_DASHBOARD_INIT,
|
|
37
|
+
})
|
|
38
|
+
).toEqual({
|
|
39
|
+
...initialState,
|
|
40
|
+
query: undefined,
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should handle FOREMAN_TASKS_DASHBOARD_INIT with data', () => {
|
|
45
|
+
expect(
|
|
46
|
+
runReducer(undefined, {
|
|
47
|
+
type: FOREMAN_TASKS_DASHBOARD_INIT,
|
|
48
|
+
payload: {
|
|
49
|
+
time: TASKS_DASHBOARD_AVAILABLE_TIMES.WEEK,
|
|
50
|
+
query: dashboardQuery,
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
).toEqual({
|
|
54
|
+
...initialState,
|
|
55
|
+
time: TASKS_DASHBOARD_AVAILABLE_TIMES.WEEK,
|
|
56
|
+
query: dashboardQuery,
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should handle FOREMAN_TASKS_DASHBOARD_UPDATE_TIME', () => {
|
|
61
|
+
expect(
|
|
62
|
+
runReducer(undefined, {
|
|
63
|
+
type: FOREMAN_TASKS_DASHBOARD_UPDATE_TIME,
|
|
64
|
+
payload: TASKS_DASHBOARD_AVAILABLE_TIMES.WEEK,
|
|
65
|
+
})
|
|
66
|
+
).toEqual({
|
|
67
|
+
...initialState,
|
|
68
|
+
time: TASKS_DASHBOARD_AVAILABLE_TIMES.WEEK,
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should handle FOREMAN_TASKS_DASHBOARD_UPDATE_QUERY', () => {
|
|
73
|
+
expect(
|
|
74
|
+
runReducer(undefined, {
|
|
75
|
+
type: FOREMAN_TASKS_DASHBOARD_UPDATE_QUERY,
|
|
76
|
+
payload: dashboardQuery,
|
|
77
|
+
})
|
|
78
|
+
).toEqual({
|
|
79
|
+
...initialState,
|
|
80
|
+
query: dashboardQuery,
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should handle FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST', () => {
|
|
85
|
+
expect(
|
|
86
|
+
runReducer(undefined, {
|
|
87
|
+
type: FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST,
|
|
88
|
+
})
|
|
89
|
+
).toEqual({
|
|
90
|
+
...initialState,
|
|
91
|
+
isLoading: true,
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should handle FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_SUCCESS', () => {
|
|
96
|
+
expect(
|
|
97
|
+
runReducer(undefined, {
|
|
98
|
+
type: FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_SUCCESS,
|
|
99
|
+
payload: 'some-payload',
|
|
100
|
+
})
|
|
101
|
+
).toEqual({
|
|
102
|
+
...initialState,
|
|
103
|
+
tasksSummary: 'some-payload',
|
|
104
|
+
isLoading: false,
|
|
105
|
+
error: null,
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should handle FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_FAILURE', () => {
|
|
110
|
+
const error = new Error('some error');
|
|
111
|
+
|
|
112
|
+
expect(
|
|
113
|
+
runReducer(undefined, {
|
|
114
|
+
type: FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_FAILURE,
|
|
115
|
+
payload: error,
|
|
116
|
+
})
|
|
117
|
+
).toEqual({
|
|
118
|
+
...initialState,
|
|
119
|
+
tasksSummary: TASKS_SUMMARY_ZERO,
|
|
120
|
+
isLoading: false,
|
|
121
|
+
error,
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
});
|