foreman-tasks 12.1.1 → 12.2.2
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/Gemfile +2 -0
- data/app/views/foreman_tasks/api/tasks/show.json.rabl +1 -1
- data/foreman-tasks.gemspec +1 -3
- data/lib/foreman_tasks/version.rb +1 -1
- data/test/controllers/api/tasks_controller_test.rb +2 -2
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Dependencies.js +69 -58
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Errors.js +25 -5
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Locks.js +170 -43
- data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +12 -4
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +217 -201
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskSkeleton.js +30 -34
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Dependencies.test.js +90 -29
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Errors.test.js +50 -27
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Locks.test.js +256 -23
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Raw.test.js +44 -22
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +56 -24
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +42 -22
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskInfo.test.js +45 -54
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +65 -25
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +37 -13
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +53 -8
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/PausedTasksCard.test.js +53 -7
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/RunningTasksCard.test.js +53 -7
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.js +5 -4
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.test.js +44 -14
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.js +6 -5
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.js +5 -4
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.scss +3 -8
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.test.js +75 -34
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChart.test.js +57 -34
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChartHelper.test.js +23 -9
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/TasksCardsGrid.fixtures.js +14 -11
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/TasksCardsGrid.js +19 -21
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/TasksCardsGrid.test.js +63 -14
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/Components/TimeDropDown/TimeDropDown.js +9 -17
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/Components/TimeDropDown/TimeDropDown.test.js +49 -13
- metadata +2 -46
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Errors.test.js.snap +0 -77
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Locks.test.js.snap +0 -116
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Raw.test.js.snap +0 -174
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/RunningSteps.test.js.snap +0 -62
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +0 -127
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +0 -580
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +0 -172
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +0 -52
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/__snapshots__/PausedTasksCard.test.js.snap +0 -38
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/__snapshots__/RunningTasksCard.test.js.snap +0 -38
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/__snapshots__/ScheduledTasksCard.test.js.snap +0 -97
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/__snapshots__/TasksDonutCard.test.js.snap +0 -183
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/__snapshots__/TasksDonutChart.test.js.snap +0 -302
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/__snapshots__/TasksDonutChartHelper.test.js.snap +0 -21
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/__snapshots__/TasksCardsGrid.test.js.snap +0 -210
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/Components/TimeDropDown/__snapshots__/TimeDropDown.test.js.snap +0 -85
|
@@ -1,36 +1,59 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
2
4
|
|
|
3
5
|
import Errors from '../Errors';
|
|
4
6
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
failedSteps: [
|
|
13
|
-
{
|
|
14
|
-
error: {
|
|
15
|
-
exception_class: 'RuntimeError',
|
|
16
|
-
message:
|
|
17
|
-
'Action Actions::Katello::EventQueue::Monitor is already active',
|
|
18
|
-
backtrace: [
|
|
19
|
-
"/home/vagrant/.gem/ruby/gems/dynflow-1.2.3/lib/dynflow/action/singleton.rb:15:in `rescue in singleton_lock!'",
|
|
20
|
-
"/home/vagrant/.gem/ruby/gems/dynflow-1.2.3/lib/dynflow/action/singleton.rb:12:in `singleton_lock!'",
|
|
21
|
-
],
|
|
22
|
-
},
|
|
23
|
-
action_class: 'Actions::Katello::EventQueue::Monitor',
|
|
24
|
-
state: 'error',
|
|
25
|
-
input:
|
|
26
|
-
'{"locale"=>"en",\n "current_request_id"=>nil,\n "current_user_id"=>4,\n "current_organization_id"=>nil,\n "current_location_id"=>nil}\n',
|
|
27
|
-
output: '{}\n',
|
|
28
|
-
},
|
|
7
|
+
const failedStepFixture = {
|
|
8
|
+
error: {
|
|
9
|
+
exception_class: 'RuntimeError',
|
|
10
|
+
message: 'Action Actions::Katello::EventQueue::Monitor is already active',
|
|
11
|
+
backtrace: [
|
|
12
|
+
"/home/vagrant/.gem/ruby/gems/dynflow-1.2.3/lib/dynflow/action/singleton.rb:15:in `rescue in singleton_lock!'",
|
|
13
|
+
"/home/vagrant/.gem/ruby/gems/dynflow-1.2.3/lib/dynflow/action/singleton.rb:12:in `singleton_lock!'",
|
|
29
14
|
],
|
|
30
15
|
},
|
|
16
|
+
action_class: 'Actions::Katello::EventQueue::Monitor',
|
|
17
|
+
state: 'error',
|
|
18
|
+
input:
|
|
19
|
+
'{"locale"=>"en",\n "current_request_id"=>nil,\n "current_user_id"=>4,\n "current_organization_id"=>nil,\n "current_location_id"=>nil}\n',
|
|
20
|
+
output: '{}\n',
|
|
31
21
|
};
|
|
32
22
|
|
|
33
23
|
describe('Errors', () => {
|
|
34
|
-
|
|
35
|
-
|
|
24
|
+
it('renders warning when execution plan is missing', () => {
|
|
25
|
+
render(<Errors failedSteps={[]} executionPlan={null} />);
|
|
26
|
+
expect(
|
|
27
|
+
screen.getByText(/execution plan data not available/i)
|
|
28
|
+
).toBeInTheDocument();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('renders success state when there are no failed steps', () => {
|
|
32
|
+
render(<Errors failedSteps={[]} executionPlan={{ state: 'paused' }} />);
|
|
33
|
+
const noErrors = screen.getAllByText(/^no errors$/i);
|
|
34
|
+
expect(noErrors.length).toBeGreaterThanOrEqual(1);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('renders failed step details when failedSteps is non-empty', () => {
|
|
38
|
+
const { container } = render(
|
|
39
|
+
<Errors
|
|
40
|
+
executionPlan={{ state: 'paused', cancellable: false }}
|
|
41
|
+
failedSteps={[failedStepFixture]}
|
|
42
|
+
/>
|
|
43
|
+
);
|
|
44
|
+
const stepAlert = container.querySelector(
|
|
45
|
+
'[data-ouia-component-id="task-error-0"]'
|
|
46
|
+
);
|
|
47
|
+
expect(stepAlert).toBeInTheDocument();
|
|
48
|
+
expect(stepAlert).toHaveClass('pf-m-inline');
|
|
49
|
+
expect(
|
|
50
|
+
screen.getByText('Actions::Katello::EventQueue::Monitor')
|
|
51
|
+
).toBeInTheDocument();
|
|
52
|
+
expect(screen.getByText(/runtimeerror/i)).toBeInTheDocument();
|
|
53
|
+
expect(
|
|
54
|
+
screen.getByText(
|
|
55
|
+
/action actions::katello::eventqueue::monitor is already active/i
|
|
56
|
+
)
|
|
57
|
+
).toBeInTheDocument();
|
|
58
|
+
});
|
|
36
59
|
});
|
|
@@ -1,28 +1,261 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
2
4
|
|
|
3
5
|
import Locks from '../Locks';
|
|
4
6
|
|
|
5
|
-
const fixtures = {
|
|
6
|
-
'render without Props': {},
|
|
7
|
-
'render with Props': {
|
|
8
|
-
locks: [
|
|
9
|
-
{
|
|
10
|
-
name: 'task_owner',
|
|
11
|
-
exclusive: false,
|
|
12
|
-
resource_type: 'User',
|
|
13
|
-
resource_id: 4,
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
name: 'task_owner2',
|
|
17
|
-
exclusive: false,
|
|
18
|
-
resource_type: 'User',
|
|
19
|
-
resource_id: 2,
|
|
20
|
-
},
|
|
21
|
-
],
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
|
|
25
7
|
describe('Locks', () => {
|
|
26
|
-
|
|
27
|
-
|
|
8
|
+
it('renders empty state when there are no locks', () => {
|
|
9
|
+
const { container } = render(<Locks locks={[]} />);
|
|
10
|
+
expect(
|
|
11
|
+
screen.getByRole('heading', { name: /no resources/i })
|
|
12
|
+
).toBeInTheDocument();
|
|
13
|
+
expect(
|
|
14
|
+
screen.getByText(
|
|
15
|
+
/no resources currently associated with this task/i
|
|
16
|
+
)
|
|
17
|
+
).toBeInTheDocument();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('renders non-exclusive section with rows when there are only non-exclusive locks', () => {
|
|
21
|
+
render(
|
|
22
|
+
<Locks
|
|
23
|
+
locks={[
|
|
24
|
+
{
|
|
25
|
+
name: 'task_owner',
|
|
26
|
+
exclusive: false,
|
|
27
|
+
resource_type: 'User',
|
|
28
|
+
resource_id: 4,
|
|
29
|
+
link: null,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'task_owner2',
|
|
33
|
+
exclusive: false,
|
|
34
|
+
resource_type: 'User',
|
|
35
|
+
resource_id: 2,
|
|
36
|
+
link: null,
|
|
37
|
+
},
|
|
38
|
+
]}
|
|
39
|
+
/>
|
|
40
|
+
);
|
|
41
|
+
expect(
|
|
42
|
+
screen.getByRole('heading', { name: 'Non-exclusive resources' })
|
|
43
|
+
).toBeInTheDocument();
|
|
44
|
+
expect(
|
|
45
|
+
screen.getByText(
|
|
46
|
+
/other tasks can access the resource simultaneously/i
|
|
47
|
+
)
|
|
48
|
+
).toBeInTheDocument();
|
|
49
|
+
expect(screen.getAllByText('User')).toHaveLength(2);
|
|
50
|
+
expect(screen.getByText('id: 4')).toBeInTheDocument();
|
|
51
|
+
expect(screen.getByText('id: 2')).toBeInTheDocument();
|
|
52
|
+
expect(
|
|
53
|
+
screen.queryByRole('heading', { name: 'Exclusive resources' })
|
|
54
|
+
).not.toBeInTheDocument();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('renders exclusive section when there are only exclusive locks', () => {
|
|
58
|
+
render(
|
|
59
|
+
<Locks
|
|
60
|
+
locks={[
|
|
61
|
+
{
|
|
62
|
+
name: 'host_lock',
|
|
63
|
+
exclusive: true,
|
|
64
|
+
resource_type: 'Host',
|
|
65
|
+
resource_id: 1,
|
|
66
|
+
link: '/hosts/1',
|
|
67
|
+
},
|
|
68
|
+
]}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
expect(
|
|
72
|
+
screen.getByRole('heading', { name: 'Exclusive resources' })
|
|
73
|
+
).toBeInTheDocument();
|
|
74
|
+
expect(
|
|
75
|
+
screen.getByText(
|
|
76
|
+
/only this task can access the resource/i
|
|
77
|
+
)
|
|
78
|
+
).toBeInTheDocument();
|
|
79
|
+
expect(screen.getByRole('link', { name: 'Host' })).toHaveAttribute(
|
|
80
|
+
'href',
|
|
81
|
+
'/hosts/1'
|
|
82
|
+
);
|
|
83
|
+
expect(screen.getByText('id: 1')).toBeInTheDocument();
|
|
84
|
+
expect(
|
|
85
|
+
screen.queryByRole('heading', { name: 'Non-exclusive resources' })
|
|
86
|
+
).not.toBeInTheDocument();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('renders both sections when locks are mixed', () => {
|
|
90
|
+
render(
|
|
91
|
+
<Locks
|
|
92
|
+
locks={[
|
|
93
|
+
{
|
|
94
|
+
name: 'a',
|
|
95
|
+
exclusive: false,
|
|
96
|
+
resource_type: 'Smart proxy',
|
|
97
|
+
resource_id: 7,
|
|
98
|
+
link: null,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'b',
|
|
102
|
+
exclusive: true,
|
|
103
|
+
resource_type: 'Host managed',
|
|
104
|
+
resource_id: 1,
|
|
105
|
+
link: null,
|
|
106
|
+
},
|
|
107
|
+
]}
|
|
108
|
+
/>
|
|
109
|
+
);
|
|
110
|
+
expect(
|
|
111
|
+
screen.getByRole('heading', { name: 'Non-exclusive resources' })
|
|
112
|
+
).toBeInTheDocument();
|
|
113
|
+
expect(
|
|
114
|
+
screen.getByRole('heading', { name: 'Exclusive resources' })
|
|
115
|
+
).toBeInTheDocument();
|
|
116
|
+
expect(
|
|
117
|
+
screen.getByText(
|
|
118
|
+
/other tasks can access the resource simultaneously/i
|
|
119
|
+
)
|
|
120
|
+
).toBeInTheDocument();
|
|
121
|
+
expect(
|
|
122
|
+
screen.getByText(/only this task can access the resource/i)
|
|
123
|
+
).toBeInTheDocument();
|
|
124
|
+
expect(screen.getByText('Smart proxy')).toBeInTheDocument();
|
|
125
|
+
expect(screen.getByText('Host managed')).toBeInTheDocument();
|
|
126
|
+
expect(screen.getByText('id: 7')).toBeInTheDocument();
|
|
127
|
+
expect(screen.getByText('id: 1')).toBeInTheDocument();
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('renders a link for non-exclusive locks when lock.link is set', () => {
|
|
131
|
+
render(
|
|
132
|
+
<Locks
|
|
133
|
+
locks={[
|
|
134
|
+
{
|
|
135
|
+
name: 'proxy',
|
|
136
|
+
exclusive: false,
|
|
137
|
+
resource_type: 'Smart proxy',
|
|
138
|
+
resource_id: 7,
|
|
139
|
+
link: '/smart_proxies/7',
|
|
140
|
+
},
|
|
141
|
+
]}
|
|
142
|
+
/>
|
|
143
|
+
);
|
|
144
|
+
const link = screen.getByRole('link', { name: 'Smart proxy' });
|
|
145
|
+
expect(link).toHaveAttribute('href', '/smart_proxies/7');
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('formats string resource_id values in the row label', () => {
|
|
149
|
+
render(
|
|
150
|
+
<Locks
|
|
151
|
+
locks={[
|
|
152
|
+
{
|
|
153
|
+
name: 'x',
|
|
154
|
+
exclusive: false,
|
|
155
|
+
resource_type: 'Custom',
|
|
156
|
+
resource_id: 'uuid-abc',
|
|
157
|
+
link: null,
|
|
158
|
+
},
|
|
159
|
+
]}
|
|
160
|
+
/>
|
|
161
|
+
);
|
|
162
|
+
expect(screen.getByText('id: uuid-abc')).toBeInTheDocument();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('sets ouia ids on populated container, tables, rows, and resource links', () => {
|
|
166
|
+
const { container } = render(
|
|
167
|
+
<Locks
|
|
168
|
+
locks={[
|
|
169
|
+
{
|
|
170
|
+
name: 'ne',
|
|
171
|
+
exclusive: false,
|
|
172
|
+
resource_type: 'A',
|
|
173
|
+
resource_id: 1,
|
|
174
|
+
link: '/non-exclusive/1',
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: 'ex',
|
|
178
|
+
exclusive: true,
|
|
179
|
+
resource_type: 'B',
|
|
180
|
+
resource_id: 2,
|
|
181
|
+
link: '/exclusive/2',
|
|
182
|
+
},
|
|
183
|
+
]}
|
|
184
|
+
/>
|
|
185
|
+
);
|
|
186
|
+
expect(
|
|
187
|
+
container.querySelector('[data-ouia-component-id="task-locks-populated"]')
|
|
188
|
+
).toBeInTheDocument();
|
|
189
|
+
expect(
|
|
190
|
+
container.querySelector(
|
|
191
|
+
'[data-ouia-component-id="task-locks-non-exclusive-table"]'
|
|
192
|
+
)
|
|
193
|
+
).toBeInTheDocument();
|
|
194
|
+
expect(
|
|
195
|
+
container.querySelector(
|
|
196
|
+
'[data-ouia-component-id="task-locks-exclusive-table"]'
|
|
197
|
+
)
|
|
198
|
+
).toBeInTheDocument();
|
|
199
|
+
expect(
|
|
200
|
+
container.querySelector(
|
|
201
|
+
'[data-ouia-component-id="task-locks-non-exclusive-row-0"]'
|
|
202
|
+
)
|
|
203
|
+
).toBeInTheDocument();
|
|
204
|
+
expect(
|
|
205
|
+
container.querySelector(
|
|
206
|
+
'[data-ouia-component-id="task-locks-exclusive-row-0"]'
|
|
207
|
+
)
|
|
208
|
+
).toBeInTheDocument();
|
|
209
|
+
expect(
|
|
210
|
+
container.querySelector(
|
|
211
|
+
'[data-ouia-component-id="task-locks-non-exclusive-resource-type-link-0"]'
|
|
212
|
+
)
|
|
213
|
+
).toBeInTheDocument();
|
|
214
|
+
expect(
|
|
215
|
+
container.querySelector(
|
|
216
|
+
'[data-ouia-component-id="task-locks-exclusive-resource-type-link-0"]'
|
|
217
|
+
)
|
|
218
|
+
).toBeInTheDocument();
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('does not render resource_type as a link when lock.link is absent', () => {
|
|
222
|
+
render(
|
|
223
|
+
<Locks
|
|
224
|
+
locks={[
|
|
225
|
+
{
|
|
226
|
+
name: 'ex',
|
|
227
|
+
exclusive: true,
|
|
228
|
+
resource_type: 'Host managed',
|
|
229
|
+
resource_id: 1,
|
|
230
|
+
link: null,
|
|
231
|
+
},
|
|
232
|
+
]}
|
|
233
|
+
/>
|
|
234
|
+
);
|
|
235
|
+
expect(
|
|
236
|
+
screen.queryByRole('link', { name: 'Host managed' })
|
|
237
|
+
).not.toBeInTheDocument();
|
|
238
|
+
expect(screen.getByText('Host managed')).toBeInTheDocument();
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('does not set resource-type link ouia id when lock.link is absent', () => {
|
|
242
|
+
const { container } = render(
|
|
243
|
+
<Locks
|
|
244
|
+
locks={[
|
|
245
|
+
{
|
|
246
|
+
name: 'ne',
|
|
247
|
+
exclusive: false,
|
|
248
|
+
resource_type: 'Thing',
|
|
249
|
+
resource_id: 1,
|
|
250
|
+
link: null,
|
|
251
|
+
},
|
|
252
|
+
]}
|
|
253
|
+
/>
|
|
254
|
+
);
|
|
255
|
+
expect(
|
|
256
|
+
container.querySelector(
|
|
257
|
+
'[data-ouia-component-id="task-locks-non-exclusive-resource-type-link-0"]'
|
|
258
|
+
)
|
|
259
|
+
).not.toBeInTheDocument();
|
|
260
|
+
});
|
|
28
261
|
});
|
|
@@ -1,27 +1,49 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
2
4
|
|
|
3
5
|
import Raw from '../Raw';
|
|
4
6
|
|
|
5
|
-
const fixtures = {
|
|
6
|
-
'render without Props': {},
|
|
7
|
-
'render with Props': {
|
|
8
|
-
startedAt: '2019-06-17 16:04:09 +0300',
|
|
9
|
-
endedAt: '2019-06-17 16:05:09 +0300',
|
|
10
|
-
id: '6b0d6db2-e9ab-40da-94e5-b6842ac50bd0',
|
|
11
|
-
label: 'Actions::Katello::EventQueue::Monitor',
|
|
12
|
-
input: {
|
|
13
|
-
locale: 'en',
|
|
14
|
-
current_request_id: 1,
|
|
15
|
-
current_user_id: 4,
|
|
16
|
-
current_organization_id: 2,
|
|
17
|
-
current_location_id: 3,
|
|
18
|
-
},
|
|
19
|
-
output: {},
|
|
20
|
-
externalId: 'test',
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
|
|
24
7
|
describe('Raw', () => {
|
|
25
|
-
|
|
26
|
-
|
|
8
|
+
it('renders id and label when minimal props are given', () => {
|
|
9
|
+
render(
|
|
10
|
+
<Raw
|
|
11
|
+
id="x"
|
|
12
|
+
label=""
|
|
13
|
+
startedAt=""
|
|
14
|
+
endedAt=""
|
|
15
|
+
input={[]}
|
|
16
|
+
output={{}}
|
|
17
|
+
externalId=""
|
|
18
|
+
/>
|
|
19
|
+
);
|
|
20
|
+
expect(screen.getByText('x')).toBeInTheDocument();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('renders raw task fields from props', () => {
|
|
24
|
+
render(
|
|
25
|
+
<Raw
|
|
26
|
+
startedAt="2019-06-17 16:04:09 +0300"
|
|
27
|
+
endedAt="2019-06-17 16:05:09 +0300"
|
|
28
|
+
id="6b0d6db2-e9ab-40da-94e5-b6842ac50bd0"
|
|
29
|
+
label="Actions::Katello::EventQueue::Monitor"
|
|
30
|
+
input={{
|
|
31
|
+
locale: 'en',
|
|
32
|
+
current_request_id: 1,
|
|
33
|
+
current_user_id: 4,
|
|
34
|
+
current_organization_id: 2,
|
|
35
|
+
current_location_id: 3,
|
|
36
|
+
}}
|
|
37
|
+
output={{}}
|
|
38
|
+
externalId="test"
|
|
39
|
+
/>
|
|
40
|
+
);
|
|
41
|
+
expect(
|
|
42
|
+
screen.getByText('6b0d6db2-e9ab-40da-94e5-b6842ac50bd0')
|
|
43
|
+
).toBeInTheDocument();
|
|
44
|
+
expect(
|
|
45
|
+
screen.getByText('Actions::Katello::EventQueue::Monitor')
|
|
46
|
+
).toBeInTheDocument();
|
|
47
|
+
expect(screen.getByText(/"locale":/)).toBeInTheDocument();
|
|
48
|
+
});
|
|
27
49
|
});
|
|
@@ -1,36 +1,68 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
2
4
|
|
|
3
5
|
import RunningSteps from '../RunningSteps';
|
|
4
6
|
|
|
5
|
-
const
|
|
7
|
+
const baseProps = {
|
|
6
8
|
id: 'task-id1',
|
|
7
9
|
taskReload: true,
|
|
8
10
|
cancelStep: jest.fn(),
|
|
9
11
|
taskReloadStart: jest.fn(),
|
|
10
12
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
{
|
|
21
|
-
cancellable: false,
|
|
22
|
-
id: 1,
|
|
23
|
-
action_class: 'test',
|
|
24
|
-
state: 'paused',
|
|
25
|
-
input:
|
|
26
|
-
'{"locale"=>"en",\n "current_request_id"=>nil,\n "current_user_id"=>4,\n "current_organization_id"=>nil,\n "current_location_id"=>nil}\n',
|
|
27
|
-
output: '{}\n',
|
|
28
|
-
},
|
|
29
|
-
],
|
|
30
|
-
},
|
|
13
|
+
|
|
14
|
+
const sampleStep = {
|
|
15
|
+
cancellable: false,
|
|
16
|
+
id: 1,
|
|
17
|
+
action_class: 'test',
|
|
18
|
+
state: 'paused',
|
|
19
|
+
input:
|
|
20
|
+
'{"locale"=>"en",\n "current_request_id"=>nil,\n "current_user_id"=>4,\n "current_organization_id"=>nil,\n "current_location_id"=>nil}\n',
|
|
21
|
+
output: '{}\n',
|
|
31
22
|
};
|
|
32
23
|
|
|
33
24
|
describe('RunningSteps', () => {
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
it('renders empty message when there are no running steps', () => {
|
|
26
|
+
render(<RunningSteps {...baseProps} runningSteps={[]} />);
|
|
27
|
+
expect(screen.getByText(/no running steps/i)).toBeInTheDocument();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('renders running step fields and Cancel when step is cancellable', () => {
|
|
31
|
+
const cancelStep = jest.fn();
|
|
32
|
+
render(
|
|
33
|
+
<RunningSteps
|
|
34
|
+
{...baseProps}
|
|
35
|
+
cancelStep={cancelStep}
|
|
36
|
+
runningSteps={[
|
|
37
|
+
{
|
|
38
|
+
...sampleStep,
|
|
39
|
+
cancellable: true,
|
|
40
|
+
id: 99,
|
|
41
|
+
},
|
|
42
|
+
]}
|
|
43
|
+
/>
|
|
44
|
+
);
|
|
45
|
+
expect(
|
|
46
|
+
screen.getByRole('heading', { name: 'Warning alert: Running step 1' })
|
|
47
|
+
).toBeInTheDocument();
|
|
48
|
+
expect(screen.getByText('test')).toBeInTheDocument();
|
|
49
|
+
expect(screen.getByText('paused')).toBeInTheDocument();
|
|
50
|
+
fireEvent.click(screen.getByRole('button', { name: /cancel/i }));
|
|
51
|
+
expect(cancelStep).toHaveBeenCalledWith('task-id1', 99);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('uses sprintf so each running step title shows a 1-based step index', () => {
|
|
55
|
+
render(
|
|
56
|
+
<RunningSteps
|
|
57
|
+
{...baseProps}
|
|
58
|
+
runningSteps={[sampleStep, { ...sampleStep, id: 2, state: 'running' }]}
|
|
59
|
+
/>
|
|
60
|
+
);
|
|
61
|
+
expect(
|
|
62
|
+
screen.getByRole('heading', { name: 'Warning alert: Running step 1' })
|
|
63
|
+
).toBeInTheDocument();
|
|
64
|
+
expect(
|
|
65
|
+
screen.getByRole('heading', { name: 'Warning alert: Running step 2' })
|
|
66
|
+
).toBeInTheDocument();
|
|
67
|
+
});
|
|
36
68
|
});
|
|
@@ -1,26 +1,46 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
2
4
|
import { STATUS } from 'foremanReact/constants';
|
|
5
|
+
|
|
3
6
|
import Task from '../Task';
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
canEdit: true,
|
|
19
|
-
status: STATUS.RESOLVED,
|
|
20
|
-
taskProgressToggle: jest.fn(),
|
|
21
|
-
taskReloadStart: jest.fn(),
|
|
22
|
-
},
|
|
23
|
-
};
|
|
8
|
+
describe('Task', () => {
|
|
9
|
+
it('renders task controls from TaskButtons with minimal props', () => {
|
|
10
|
+
render(
|
|
11
|
+
<Task
|
|
12
|
+
id="test"
|
|
13
|
+
taskReloadStart={jest.fn()}
|
|
14
|
+
taskProgressToggle={jest.fn()}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
expect(
|
|
18
|
+
screen.getByRole('button', { name: /start auto-reloading/i })
|
|
19
|
+
).toBeInTheDocument();
|
|
20
|
+
});
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
it('renders parent task and sub tasks links when provided', () => {
|
|
23
|
+
render(
|
|
24
|
+
<Task
|
|
25
|
+
id="test"
|
|
26
|
+
state="paused"
|
|
27
|
+
hasSubTasks
|
|
28
|
+
dynflowEnableConsole
|
|
29
|
+
parentTask="parent-id"
|
|
30
|
+
taskReload
|
|
31
|
+
canEdit
|
|
32
|
+
status={STATUS.RESOLVED}
|
|
33
|
+
taskProgressToggle={jest.fn()}
|
|
34
|
+
taskReloadStart={jest.fn()}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
expect(screen.getByRole('link', { name: /parent task/i })).toHaveAttribute(
|
|
38
|
+
'href',
|
|
39
|
+
'/foreman_tasks/tasks/parent-id'
|
|
40
|
+
);
|
|
41
|
+
expect(screen.getByRole('link', { name: /sub tasks/i })).toHaveAttribute(
|
|
42
|
+
'href',
|
|
43
|
+
'/foreman_tasks/tasks/test/sub_tasks'
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
});
|