foreman-tasks 1.2.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/js_tests.yml +31 -0
- data/.github/workflows/ruby_tests.yml +74 -0
- data/.rubocop.yml +12 -4
- data/.rubocop_todo.yml +32 -25
- data/Gemfile +5 -0
- data/README.md +2 -0
- data/app/controllers/foreman_tasks/api/tasks_controller.rb +36 -60
- data/app/controllers/foreman_tasks/concerns/parameters/triggering.rb +1 -1
- data/app/controllers/foreman_tasks/recurring_logics_controller.rb +7 -0
- data/app/controllers/foreman_tasks/tasks_controller.rb +6 -3
- data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +3 -3
- data/app/lib/actions/proxy_action.rb +1 -1
- data/app/models/foreman_tasks/recurring_logic.rb +1 -1
- data/app/models/foreman_tasks/task.rb +11 -0
- data/app/models/foreman_tasks/task/dynflow_task.rb +29 -33
- data/app/models/foreman_tasks/task/status_explicator.rb +1 -1
- data/app/models/foreman_tasks/triggering.rb +1 -1
- data/app/models/setting/foreman_tasks.rb +9 -9
- data/app/services/foreman_tasks/dashboard_table_filter.rb +5 -1
- data/app/views/foreman_tasks/api/tasks/index.json.rabl +2 -0
- data/app/views/foreman_tasks/api/tasks/show.json.rabl +2 -0
- data/app/views/foreman_tasks/recurring_logics/index.html.erb +3 -1
- data/config/routes.rb +2 -1
- data/db/migrate/20200517215015_rename_bookmarks_controller.rb +2 -2
- data/db/migrate/20200611090846_add_task_lock_index_on_resource_type_and_task_id.rb +9 -0
- data/db/seeds.d/30-notification_blueprints.rb +7 -7
- data/db/seeds.d/61-foreman_tasks_bookmarks.rb +1 -1
- data/lib/foreman_tasks/cleaner.rb +4 -6
- data/lib/foreman_tasks/dynflow/configuration.rb +1 -1
- data/lib/foreman_tasks/dynflow/persistence.rb +4 -6
- data/lib/foreman_tasks/engine.rb +2 -7
- data/lib/foreman_tasks/tasks/cleanup.rake +2 -2
- data/lib/foreman_tasks/tasks/dynflow.rake +6 -0
- data/lib/foreman_tasks/tasks/export_tasks.rake +1 -1
- data/lib/foreman_tasks/version.rb +1 -1
- data/locale/en/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/en/foreman_tasks.po +50 -20
- data/locale/foreman_tasks.pot +173 -126
- data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/fr/foreman_tasks.po +817 -0
- data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/ja/foreman_tasks.po +817 -0
- data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
- data/locale/zh_CN/foreman_tasks.po +816 -0
- data/package.json +1 -1
- data/script/npm_link_foreman_js.sh +26 -0
- data/test/controllers/api/recurring_logics_controller_test.rb +1 -1
- data/test/controllers/api/tasks_controller_test.rb +17 -7
- data/test/controllers/tasks_controller_test.rb +6 -6
- data/test/core/unit/runner_test.rb +20 -20
- data/test/core/unit/task_launcher_test.rb +8 -8
- data/test/helpers/foreman_tasks/foreman_tasks_helper_test.rb +7 -7
- data/test/helpers/foreman_tasks/tasks_helper_test.rb +3 -3
- data/test/lib/actions/middleware/keep_current_request_id_test.rb +3 -3
- data/test/support/history_tasks_builder.rb +1 -1
- data/test/tasks/generate_task_actions_test.rb +1 -1
- data/test/unit/actions/action_with_sub_plans_test.rb +2 -2
- data/test/unit/actions/bulk_action_test.rb +6 -6
- data/test/unit/actions/proxy_action_test.rb +20 -20
- data/test/unit/actions/recurring_action_test.rb +30 -32
- data/test/unit/cleaner_test.rb +24 -24
- data/test/unit/dashboard_table_filter_test.rb +5 -5
- data/test/unit/otp_manager_test.rb +2 -2
- data/test/unit/proxy_selector_test.rb +9 -9
- data/test/unit/recurring_logic_test.rb +32 -32
- data/test/unit/remote_task_test.rb +2 -2
- data/test/unit/task_groups_test.rb +4 -4
- data/test/unit/task_test.rb +18 -18
- data/test/unit/triggering_test.rb +8 -8
- data/test/unit/troubleshooting_help_generator_test.rb +6 -6
- data/test/unit/ui_notifications_test.rb +11 -11
- data/webpack/ForemanTasks/Components/TaskActions/TaskAction.test.js +2 -2
- data/webpack/ForemanTasks/Components/TaskActions/index.js +1 -1
- data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +17 -3
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +8 -153
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskButtons.js +168 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +6 -7
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskSkeleton.js +48 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +8 -1
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +13 -70
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskButtons.test.js +95 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/RunningSteps.test.js.snap +1 -1
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +78 -208
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskButtons.test.js.snap +212 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +8 -4
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +100 -53
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +3 -14
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +57 -95
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +3 -12
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +57 -28
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.fixtures.js +8 -0
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +8 -1
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +6 -6
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +84 -12
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +25 -21
- data/webpack/ForemanTasks/Components/TaskDetails/index.js +8 -3
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.scss +4 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/OtherInfo.js +53 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/OtherInfo.test.js +14 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.js +27 -19
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.scss +14 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.test.js +1 -34
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/{StoppedTasksCardHelper.js → StoppedTasksCardTable.js} +28 -1
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCardTable.test.js +54 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/OtherInfo.test.js.snap +48 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCard.test.js.snap +60 -1367
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCardTable.test.js.snap +960 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/__snapshots__/TasksCardsGrid.test.js.snap +14 -11
- data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardActions.js +1 -1
- data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardConstants.js +2 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardSelectors.js +17 -11
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardActions.test.js +2 -2
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardSelectors.test.js +26 -14
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboard.test.js.snap +14 -11
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboardSelectors.test.js.snap +38 -22
- data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalSelectors.js +1 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalSelectors.test.js +1 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalSelectors.test.js.snap +2 -0
- data/webpack/ForemanTasks/Components/TasksTable/TasksBulkActions.js +25 -8
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +3 -3
- data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +6 -2
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +1 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksBulkActions.test.js +15 -2
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +1 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTablePage.test.js +2 -1
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +1 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksBulkActions.test.js.snap +48 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +1 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +39 -5
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionCellFormatter.test.js.snap +1 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/selectionCellFormatter.test.js.snap +2 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/actionCellFormatter.test.js +1 -1
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionCellFormatter.test.js +1 -1
- data/webpack/ForemanTasks/Components/TasksTable/formatters/actionCellFormatter.js +10 -7
- data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionCellFormatter.js +7 -0
- data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.js +39 -31
- data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.test.js +17 -8
- data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ActionButton.test.js.snap +8 -0
- data/webpack/ForemanTasks/Components/common/urlHelpers.js +7 -0
- data/webpack/ForemanTasks/ForemanTasksReducers.js +0 -2
- data/webpack/__mocks__/foremanReact/common/helpers.js +2 -0
- data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +10 -0
- data/webpack/__mocks__/foremanReact/redux/API/index.js +10 -0
- data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware.js +5 -0
- metadata +29 -11
- data/.travis.yml +0 -5
- data/script/travis_run_js_tests.sh +0 -7
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +0 -38
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsReducer.test.js +0 -33
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsReducer.test.js.snap +0 -26
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/integration.test.js.snap +0 -122
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +0 -67
- data/webpack/__mocks__/foremanReact/API.js +0 -7
@@ -24,8 +24,8 @@ module ForemanTasks
|
|
24
24
|
RemoteTask.batch_trigger('a_operation', remote_tasks)
|
25
25
|
remote_tasks.each do |remote_task|
|
26
26
|
remote_task.reload
|
27
|
-
remote_task.state.must_equal 'triggered'
|
28
|
-
remote_task.remote_task_id.must_equal((remote_task.id + 5).to_s)
|
27
|
+
_(remote_task.state).must_equal 'triggered'
|
28
|
+
_(remote_task.remote_task_id).must_equal((remote_task.id + 5).to_s)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -55,18 +55,18 @@ module ForemanTasks
|
|
55
55
|
|
56
56
|
it 'has the task group assigned' do
|
57
57
|
task = spawn_task.call ChildAction
|
58
|
-
task.task_groups.map(&:id).must_equal [1]
|
58
|
+
_(task.task_groups.map(&:id)).must_equal [1]
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'tasks inherit task groups correctly' do
|
62
62
|
children_count = 3
|
63
63
|
task = spawn_task.call ParentAction, children_count
|
64
64
|
# Parent task has task groups of its children
|
65
|
-
task.task_groups.map(&:id).sort.must_equal [1, 2, 3, 4]
|
65
|
+
_(task.task_groups.map(&:id).sort).must_equal [1, 2, 3, 4]
|
66
66
|
# Children have the parent's and their own, they don't have their siblings' task groups
|
67
|
-
task.sub_tasks.count.must_equal children_count
|
67
|
+
_(task.sub_tasks.count).must_equal children_count
|
68
68
|
task.sub_tasks.each do |sub_task|
|
69
|
-
sub_task.task_groups.map(&:id).sort.must_equal [1, sub_task.input[:id]].sort
|
69
|
+
_(sub_task.task_groups.map(&:id).sort).must_equal [1, sub_task.input[:id]].sort
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
data/test/unit/task_test.rb
CHANGED
@@ -32,8 +32,8 @@ class TasksTest < ActiveSupport::TestCase
|
|
32
32
|
end
|
33
33
|
|
34
34
|
test 'cannot search by arbitrary key' do
|
35
|
-
proc { ForemanTasks::Task.search_for('user.my_key ~ 5') }.must_raise(ScopedSearch::QueryNotSupported)
|
36
|
-
proc { ForemanTasks::Task.search_for('user. = 5') }.must_raise(ScopedSearch::QueryNotSupported)
|
35
|
+
_ { proc { ForemanTasks::Task.search_for('user.my_key ~ 5') } }.must_raise(ScopedSearch::QueryNotSupported)
|
36
|
+
_ { proc { ForemanTasks::Task.search_for('user. = 5') } }.must_raise(ScopedSearch::QueryNotSupported)
|
37
37
|
end
|
38
38
|
|
39
39
|
test 'can search the tasks by negated user' do
|
@@ -59,8 +59,8 @@ class TasksTest < ActiveSupport::TestCase
|
|
59
59
|
end
|
60
60
|
|
61
61
|
test 'cannot glob on user\'s id' do
|
62
|
-
proc { ForemanTasks::Task.search_for("user.id ~ something") }.must_raise(ScopedSearch::QueryNotSupported)
|
63
|
-
proc { ForemanTasks::Task.search_for("user.id ~ 5") }.must_raise(ScopedSearch::QueryNotSupported)
|
62
|
+
_ { proc { ForemanTasks::Task.search_for("user.id ~ something") } }.must_raise(ScopedSearch::QueryNotSupported)
|
63
|
+
_ { proc { ForemanTasks::Task.search_for("user.id ~ 5") } }.must_raise(ScopedSearch::QueryNotSupported)
|
64
64
|
end
|
65
65
|
|
66
66
|
test 'can search the tasks by user with wildcards' do
|
@@ -126,7 +126,7 @@ class TasksTest < ActiveSupport::TestCase
|
|
126
126
|
end
|
127
127
|
|
128
128
|
it 'raises an exception if duration is unknown' do
|
129
|
-
proc { ForemanTasks::Task.search_for('duration = "25 potatoes"') }.must_raise ScopedSearch::QueryNotSupported
|
129
|
+
_ { proc { ForemanTasks::Task.search_for('duration = "25 potatoes"') } }.must_raise ScopedSearch::QueryNotSupported
|
130
130
|
end
|
131
131
|
end
|
132
132
|
end
|
@@ -176,13 +176,13 @@ class TasksTest < ActiveSupport::TestCase
|
|
176
176
|
let(:inconsistent_task) { FactoryBot.create(:dynflow_task, :inconsistent_dynflow_task) }
|
177
177
|
|
178
178
|
it 'ensures the tasks marked as running are really running in Dynflow' do
|
179
|
-
consistent_task.state.must_equal 'planned'
|
180
|
-
inconsistent_task.state.must_equal 'running'
|
179
|
+
_(consistent_task.state).must_equal 'planned'
|
180
|
+
_(inconsistent_task.state).must_equal 'running'
|
181
181
|
|
182
182
|
ForemanTasks::Task::DynflowTask.consistency_check
|
183
183
|
|
184
|
-
consistent_task.reload.state.must_equal 'planned'
|
185
|
-
inconsistent_task.reload.state.must_equal 'planned'
|
184
|
+
_(consistent_task.reload.state).must_equal 'planned'
|
185
|
+
_(inconsistent_task.reload.state).must_equal 'planned'
|
186
186
|
end
|
187
187
|
end
|
188
188
|
|
@@ -190,8 +190,8 @@ class TasksTest < ActiveSupport::TestCase
|
|
190
190
|
it 'when scheduled to the future, the label and action is set properly' do
|
191
191
|
job = Support::DummyActiveJob.set(:wait => 12.hours).perform_later
|
192
192
|
task = ForemanTasks::Task.find_by!(:external_id => job.provider_job_id)
|
193
|
-
task.action.must_equal "Dummy action"
|
194
|
-
task.label.must_equal "Support::DummyActiveJob"
|
193
|
+
_(task.action).must_equal "Dummy action"
|
194
|
+
_(task.label).must_equal "Support::DummyActiveJob"
|
195
195
|
end
|
196
196
|
end
|
197
197
|
|
@@ -224,14 +224,14 @@ class TasksTest < ActiveSupport::TestCase
|
|
224
224
|
:total => 0,
|
225
225
|
:success => 0,
|
226
226
|
:cancelled => 0,
|
227
|
-
:pending => 0
|
227
|
+
:pending => 0,
|
228
228
|
}
|
229
229
|
end
|
230
230
|
let(:task) { FactoryBot.create(:dynflow_task) }
|
231
231
|
|
232
232
|
describe 'without sub tasks' do
|
233
233
|
it 'calculates the progress report correctly' do
|
234
|
-
task.sub_tasks_counts.must_equal result_base
|
234
|
+
_(task.sub_tasks_counts).must_equal result_base
|
235
235
|
end
|
236
236
|
end
|
237
237
|
|
@@ -242,7 +242,7 @@ class TasksTest < ActiveSupport::TestCase
|
|
242
242
|
|
243
243
|
it 'calculate the progress report correctly' do
|
244
244
|
expected_result = result_base.merge(:success => 1, :error => 1, :total => 2)
|
245
|
-
task.sub_tasks_counts.must_equal expected_result
|
245
|
+
_(task.sub_tasks_counts).must_equal expected_result
|
246
246
|
end
|
247
247
|
|
248
248
|
it 'calculates the progress report correctly when using batch planning' do
|
@@ -252,11 +252,11 @@ class TasksTest < ActiveSupport::TestCase
|
|
252
252
|
|
253
253
|
task.state = 'stopped'
|
254
254
|
expected_result = result_base.merge(:cancelled => 23)
|
255
|
-
task.sub_tasks_counts.must_equal expected_result
|
255
|
+
_(task.sub_tasks_counts).must_equal expected_result
|
256
256
|
|
257
257
|
task.state = 'pending'
|
258
258
|
expected_result = result_base.merge(:pending => 23)
|
259
|
-
task.sub_tasks_counts.must_equal expected_result
|
259
|
+
_(task.sub_tasks_counts).must_equal expected_result
|
260
260
|
end
|
261
261
|
end
|
262
262
|
end
|
@@ -278,10 +278,10 @@ class TasksTest < ActiveSupport::TestCase
|
|
278
278
|
|
279
279
|
it 'can indicate it is delayed' do
|
280
280
|
assert_not task.delayed?
|
281
|
-
task.execution_type.must_equal 'Immediate'
|
281
|
+
_(task.execution_type).must_equal 'Immediate'
|
282
282
|
task.start_at = Time.now.utc + 100
|
283
283
|
assert task.delayed?
|
284
|
-
task.execution_type.must_equal 'Delayed'
|
284
|
+
_(task.execution_type).must_equal 'Delayed'
|
285
285
|
end
|
286
286
|
end
|
287
287
|
|
@@ -3,28 +3,28 @@ require 'foreman_tasks_test_helper'
|
|
3
3
|
class TriggeringTest < ActiveSupport::TestCase
|
4
4
|
describe 'validation' do
|
5
5
|
it 'is valid when immediate' do
|
6
|
-
FactoryBot.build(:triggering).must_be :valid?
|
6
|
+
_(FactoryBot.build(:triggering)).must_be :valid?
|
7
7
|
end
|
8
8
|
|
9
9
|
it 'is validates future execution' do
|
10
10
|
triggering = FactoryBot.build(:triggering, :future)
|
11
|
-
triggering.must_be :valid?
|
11
|
+
_(triggering).must_be :valid?
|
12
12
|
triggering.start_before = triggering.start_at - 120
|
13
|
-
triggering.wont_be :valid?
|
13
|
+
_(triggering).wont_be :valid?
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'is invalid when recurring logic is invalid' do
|
17
17
|
triggering = FactoryBot.build(:triggering, :recurring)
|
18
|
-
triggering.must_be :valid?
|
18
|
+
_(triggering).must_be :valid?
|
19
19
|
triggering.recurring_logic.stubs(:valid?).returns(false)
|
20
|
-
triggering.wont_be :valid?
|
20
|
+
_(triggering).wont_be :valid?
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'cannot have mode set to arbitrary value' do
|
25
25
|
triggering = FactoryBot.build(:triggering)
|
26
|
-
triggering.must_be :valid?
|
27
|
-
proc { triggering.mode = 'bogus' }.must_raise ArgumentError
|
28
|
-
proc { triggering.mode = 27 }.must_raise ArgumentError
|
26
|
+
_(triggering).must_be :valid?
|
27
|
+
_ { proc { triggering.mode = 'bogus' } }.must_raise ArgumentError
|
28
|
+
_ { proc { triggering.mode = 27 } }.must_raise ArgumentError
|
29
29
|
end
|
30
30
|
end
|
@@ -29,8 +29,8 @@ module ForemanTasks
|
|
29
29
|
|
30
30
|
it 'generates html from the main action troubleshooting_info' do
|
31
31
|
generated_html = subject.generate_html
|
32
|
-
generated_html.must_include "A paused task represents a process that has not finished properly"
|
33
|
-
generated_html.must_include %(See <a href="#{expected_troubleshooting_url}">troubleshooting documentation</a> for more details on how to resolve the issue)
|
32
|
+
_(generated_html).must_include "A paused task represents a process that has not finished properly"
|
33
|
+
_(generated_html).must_include %(See <a href="#{expected_troubleshooting_url}">troubleshooting documentation</a> for more details on how to resolve the issue)
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'exposes link details' do
|
@@ -48,10 +48,10 @@ module ForemanTasks
|
|
48
48
|
|
49
49
|
it 'includes additional description in generated html' do
|
50
50
|
generated_html = subject.generate_html
|
51
|
-
generated_html.must_include 'A paused task represents a process that has not finished properly'
|
52
|
-
generated_html.must_match %r{See <a href=".*">troubleshooting documentation</a> for more details on how to resolve the issue}
|
53
|
-
generated_html.must_include 'This task requires special handling'
|
54
|
-
generated_html.must_include 'Investigate <a href="/additional_troubleshooting_page">custom link</a> on more details for this custom error'
|
51
|
+
_(generated_html).must_include 'A paused task represents a process that has not finished properly'
|
52
|
+
_(generated_html).must_match %r{See <a href=".*">troubleshooting documentation</a> for more details on how to resolve the issue}
|
53
|
+
_(generated_html).must_include 'This task requires special handling'
|
54
|
+
_(generated_html).must_include 'Investigate <a href="/additional_troubleshooting_page">custom link</a> on more details for this custom error'
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'includes additional links' do
|
@@ -23,11 +23,11 @@ module ForemanTasks
|
|
23
23
|
it 'notifies all admins about current amount of paused tasks when some paused task occurs' do
|
24
24
|
trigger_task
|
25
25
|
notification = user_notifications(admin_user).first
|
26
|
-
notification.message.must_equal "There is 1 paused task in the system that need attention"
|
26
|
+
_(notification.message).must_equal "There is 1 paused task in the system that need attention"
|
27
27
|
links = notification.actions['links']
|
28
|
-
links.must_include('href' => '/foreman_tasks/tasks?search=state%3Dpaused',
|
28
|
+
_(links).must_include('href' => '/foreman_tasks/tasks?search=state%3Dpaused',
|
29
29
|
'title' => 'List of tasks')
|
30
|
-
links.must_include('name' => 'troubleshooting',
|
30
|
+
_(links).must_include('name' => 'troubleshooting',
|
31
31
|
'title' => 'Troubleshooting Documentation',
|
32
32
|
'description' => 'See %{link} for more details on how to resolve the issue',
|
33
33
|
'href' => "https://theforeman.org/manuals/#{SETTINGS[:version].short}/tasks_troubleshooting.html#",
|
@@ -37,19 +37,19 @@ module ForemanTasks
|
|
37
37
|
it 'aggregates the notification when multiple tasks get paused' do
|
38
38
|
trigger_task
|
39
39
|
recipient1 = NotificationRecipient.find_by(user_id: admin_user)
|
40
|
-
recipient1.notification.message.must_match(/1 paused task/)
|
40
|
+
_(recipient1.notification.message).must_match(/1 paused task/)
|
41
41
|
|
42
42
|
new_admin_user = FactoryBot.create(:user, :admin)
|
43
43
|
|
44
44
|
trigger_task
|
45
45
|
|
46
|
-
NotificationRecipient.find_by(id: recipient1.id).must_be_nil
|
47
|
-
Notification.find_by(id: recipient1.notification.id).must_be_nil
|
46
|
+
_(NotificationRecipient.find_by(id: recipient1.id)).must_be_nil
|
47
|
+
_(Notification.find_by(id: recipient1.notification.id)).must_be_nil
|
48
48
|
recipient2 = NotificationRecipient.find_by(user_id: admin_user)
|
49
|
-
recipient2.notification.message.must_match(/2 paused tasks/)
|
49
|
+
_(recipient2.notification.message).must_match(/2 paused tasks/)
|
50
50
|
|
51
51
|
new_recipient = NotificationRecipient.find_by(user_id: new_admin_user)
|
52
|
-
new_recipient.notification.must_equal recipient2.notification
|
52
|
+
_(new_recipient.notification).must_equal recipient2.notification
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -59,11 +59,11 @@ module ForemanTasks
|
|
59
59
|
notifications = user_notifications(task_owner)
|
60
60
|
assert_equal 1, notifications.size, 'Only notification for the main action should be triggered'
|
61
61
|
notification = notifications.first
|
62
|
-
notification.message.must_equal "The task 'Dummy pause action' got paused"
|
62
|
+
_(notification.message).must_equal "The task 'Dummy pause action' got paused"
|
63
63
|
links = notification.actions['links']
|
64
|
-
links.must_include("href" => "/foreman_tasks/tasks/#{task.id}",
|
64
|
+
_(links).must_include("href" => "/foreman_tasks/tasks/#{task.id}",
|
65
65
|
"title" => "Task Details")
|
66
|
-
links.must_include('name' => 'troubleshooting',
|
66
|
+
_(links).must_include('name' => 'troubleshooting',
|
67
67
|
'title' => 'Troubleshooting Documentation',
|
68
68
|
'description' => 'See %{link} for more details on how to resolve the issue',
|
69
69
|
'href' => "https://theforeman.org/manuals/#{SETTINGS[:version].short}/tasks_troubleshooting.html#Support::DummyPauseAction",
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { testActionSnapshotWithFixtures } from '@theforeman/test';
|
2
|
-
import API from 'foremanReact/API';
|
2
|
+
import { API } from 'foremanReact/redux/API';
|
3
3
|
import {
|
4
4
|
cancelTaskRequest,
|
5
5
|
resumeTaskRequest,
|
@@ -11,7 +11,7 @@ jest.mock('foremanReact/components/common/table', () => ({
|
|
11
11
|
getTableItemsAction: jest.fn(controller => controller),
|
12
12
|
}));
|
13
13
|
|
14
|
-
jest.mock('foremanReact/API');
|
14
|
+
jest.mock('foremanReact/redux/API');
|
15
15
|
|
16
16
|
const task = ['some-id', 'some-name'];
|
17
17
|
|
@@ -3,7 +3,13 @@ import PropTypes from 'prop-types';
|
|
3
3
|
import { Alert, Button } from 'patternfly-react';
|
4
4
|
import { translate as __ } from 'foremanReact/common/I18n';
|
5
5
|
|
6
|
-
const RunningSteps = ({
|
6
|
+
const RunningSteps = ({
|
7
|
+
runningSteps,
|
8
|
+
id,
|
9
|
+
cancelStep,
|
10
|
+
taskReload,
|
11
|
+
taskReloadStart,
|
12
|
+
}) => {
|
7
13
|
if (!runningSteps.length) return <span>{__('No running steps')}</span>;
|
8
14
|
return (
|
9
15
|
<div>
|
@@ -13,8 +19,12 @@ const RunningSteps = ({ runningSteps }) => {
|
|
13
19
|
<p>
|
14
20
|
<Button
|
15
21
|
bsSize="small"
|
16
|
-
|
17
|
-
|
22
|
+
onClick={() => {
|
23
|
+
if (!taskReload) {
|
24
|
+
taskReloadStart(id);
|
25
|
+
}
|
26
|
+
cancelStep(id, step.id);
|
27
|
+
}}
|
18
28
|
>
|
19
29
|
{__('Cancel')}
|
20
30
|
</Button>
|
@@ -46,6 +56,10 @@ const RunningSteps = ({ runningSteps }) => {
|
|
46
56
|
|
47
57
|
RunningSteps.propTypes = {
|
48
58
|
runningSteps: PropTypes.array,
|
59
|
+
id: PropTypes.string.isRequired,
|
60
|
+
cancelStep: PropTypes.func.isRequired,
|
61
|
+
taskReload: PropTypes.bool.isRequired,
|
62
|
+
taskReloadStart: PropTypes.func.isRequired,
|
49
63
|
};
|
50
64
|
|
51
65
|
RunningSteps.defaultProps = {
|
@@ -1,64 +1,27 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import
|
3
|
-
import { Grid, Row, Col, Button } from 'patternfly-react';
|
4
|
-
import { translate as __ } from 'foremanReact/common/I18n';
|
5
|
-
import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
|
2
|
+
import { Grid, Row } from 'patternfly-react';
|
6
3
|
import TaskInfo from './TaskInfo';
|
7
|
-
import {
|
8
|
-
UNLOCK_MODAL,
|
9
|
-
FORCE_UNLOCK_MODAL,
|
10
|
-
} from '../../TaskActions/TaskActionsConstants';
|
11
4
|
import { ForceUnlockModal, UnlockModal } from '../../TaskActions/UnlockModals';
|
5
|
+
import { TaskButtons } from './TaskButtons';
|
12
6
|
|
13
7
|
const Task = props => {
|
14
|
-
const taskProgressToggle = () => {
|
15
|
-
const {
|
16
|
-
timeoutId,
|
17
|
-
refetchTaskDetails,
|
18
|
-
id,
|
19
|
-
loading,
|
20
|
-
taskReloadStop,
|
21
|
-
taskReloadStart,
|
22
|
-
} = props;
|
23
|
-
if (timeoutId) {
|
24
|
-
taskReloadStop(timeoutId);
|
25
|
-
} else {
|
26
|
-
taskReloadStart(timeoutId, refetchTaskDetails, id, loading);
|
27
|
-
}
|
28
|
-
};
|
29
|
-
|
30
|
-
const unlockModalActions = useForemanModal({
|
31
|
-
id: UNLOCK_MODAL,
|
32
|
-
});
|
33
|
-
const forceUnlockModalActions = useForemanModal({
|
34
|
-
id: FORCE_UNLOCK_MODAL,
|
35
|
-
});
|
36
|
-
|
37
8
|
const {
|
38
9
|
taskReload,
|
39
|
-
externalId,
|
40
10
|
id,
|
41
|
-
state,
|
42
|
-
resumable,
|
43
|
-
cancellable,
|
44
|
-
hasSubTasks,
|
45
|
-
parentTask,
|
46
|
-
cancelTaskRequest,
|
47
|
-
resumeTaskRequest,
|
48
11
|
forceCancelTaskRequest,
|
49
12
|
unlockTaskRequest,
|
50
13
|
action,
|
51
|
-
|
14
|
+
taskReloadStart,
|
52
15
|
} = props;
|
53
16
|
const forceUnlock = () => {
|
54
17
|
if (!taskReload) {
|
55
|
-
|
18
|
+
taskReloadStart(id);
|
56
19
|
}
|
57
20
|
forceCancelTaskRequest(id, action);
|
58
21
|
};
|
59
22
|
const unlock = () => {
|
60
23
|
if (!taskReload) {
|
61
|
-
|
24
|
+
taskReloadStart(id);
|
62
25
|
}
|
63
26
|
unlockTaskRequest(id, action);
|
64
27
|
};
|
@@ -68,88 +31,7 @@ const Task = props => {
|
|
68
31
|
<ForceUnlockModal onClick={forceUnlock} />
|
69
32
|
<Grid>
|
70
33
|
<Row>
|
71
|
-
<
|
72
|
-
<Button
|
73
|
-
className="reload-button"
|
74
|
-
bsSize="small"
|
75
|
-
onClick={taskProgressToggle}
|
76
|
-
>
|
77
|
-
<span
|
78
|
-
className={`glyphicon glyphicon-refresh ${
|
79
|
-
taskReload ? 'spin' : ''
|
80
|
-
}`}
|
81
|
-
/>
|
82
|
-
{__(`${taskReload ? 'Stop' : 'Start'} auto-reloading`)}
|
83
|
-
</Button>
|
84
|
-
<Button
|
85
|
-
className="dynflow-button"
|
86
|
-
bsSize="small"
|
87
|
-
href={`/foreman_tasks/dynflow/${externalId}`}
|
88
|
-
disabled={!dynflowEnableConsole}
|
89
|
-
>
|
90
|
-
{__('Dynflow console')}
|
91
|
-
</Button>
|
92
|
-
<Button
|
93
|
-
className="resume-button"
|
94
|
-
bsSize="small"
|
95
|
-
disabled={!resumable}
|
96
|
-
onClick={() => {
|
97
|
-
if (!taskReload) {
|
98
|
-
taskProgressToggle();
|
99
|
-
}
|
100
|
-
resumeTaskRequest(id, action);
|
101
|
-
}}
|
102
|
-
>
|
103
|
-
{__('Resume')}
|
104
|
-
</Button>
|
105
|
-
<Button
|
106
|
-
className="cancel-button"
|
107
|
-
bsSize="small"
|
108
|
-
disabled={!cancellable}
|
109
|
-
onClick={() => {
|
110
|
-
if (!taskReload) {
|
111
|
-
taskProgressToggle();
|
112
|
-
}
|
113
|
-
cancelTaskRequest(id, action);
|
114
|
-
}}
|
115
|
-
>
|
116
|
-
{__('Cancel')}
|
117
|
-
</Button>
|
118
|
-
{parentTask && (
|
119
|
-
<Button
|
120
|
-
className="parent-button"
|
121
|
-
bsSize="small"
|
122
|
-
href={`/foreman_tasks/tasks/${parentTask}`}
|
123
|
-
>
|
124
|
-
{__('Parent task')}
|
125
|
-
</Button>
|
126
|
-
)}
|
127
|
-
{hasSubTasks && (
|
128
|
-
<Button
|
129
|
-
className="subtask-button"
|
130
|
-
bsSize="small"
|
131
|
-
href={`/foreman_tasks/tasks/${id}/sub_tasks`}
|
132
|
-
>
|
133
|
-
{__('Sub tasks')}
|
134
|
-
</Button>
|
135
|
-
)}
|
136
|
-
<Button
|
137
|
-
className="unlock-button"
|
138
|
-
bsSize="small"
|
139
|
-
disabled={state !== 'paused'}
|
140
|
-
onClick={unlockModalActions.setModalOpen}
|
141
|
-
>
|
142
|
-
{__('Unlock')}
|
143
|
-
</Button>
|
144
|
-
<Button
|
145
|
-
className="force-unlock-button"
|
146
|
-
bsSize="small"
|
147
|
-
disabled={state === 'stopped'}
|
148
|
-
onClick={forceUnlockModalActions.setModalOpen}
|
149
|
-
>
|
150
|
-
{__('Force Unlock')}
|
151
|
-
</Button>
|
152
|
-
</Col>
|
34
|
+
<TaskButtons taskReloadStart={taskReloadStart} {...props} />
|
153
35
|
</Row>
|
154
36
|
<TaskInfo {...props} />
|
155
37
|
</Grid>
|
@@ -159,39 +41,12 @@ const Task = props => {
|
|
159
41
|
|
160
42
|
Task.propTypes = {
|
161
43
|
...TaskInfo.PropTypes,
|
162
|
-
|
163
|
-
resumable: PropTypes.bool,
|
164
|
-
cancellable: PropTypes.bool,
|
165
|
-
refetchTaskDetails: PropTypes.func,
|
166
|
-
hasSubTasks: PropTypes.bool,
|
167
|
-
parentTask: PropTypes.string,
|
168
|
-
taskReload: PropTypes.bool,
|
169
|
-
taskReloadStop: PropTypes.func,
|
170
|
-
taskReloadStart: PropTypes.func,
|
171
|
-
timeoutId: PropTypes.number,
|
172
|
-
externalId: PropTypes.string,
|
173
|
-
id: PropTypes.string.isRequired,
|
174
|
-
cancelTaskRequest: PropTypes.func,
|
175
|
-
resumeTaskRequest: PropTypes.func,
|
176
|
-
dynflowEnableConsole: PropTypes.bool,
|
44
|
+
...TaskButtons.PropTypes,
|
177
45
|
};
|
178
46
|
|
179
47
|
Task.defaultProps = {
|
180
48
|
...TaskInfo.defaultProps,
|
181
|
-
|
182
|
-
resumable: false,
|
183
|
-
cancellable: false,
|
184
|
-
refetchTaskDetails: () => null,
|
185
|
-
hasSubTasks: false,
|
186
|
-
parentTask: '',
|
187
|
-
taskReload: false,
|
188
|
-
taskReloadStop: () => null,
|
189
|
-
taskReloadStart: () => null,
|
190
|
-
timeoutId: null,
|
191
|
-
externalId: '',
|
192
|
-
cancelTaskRequest: () => null,
|
193
|
-
resumeTaskRequest: () => null,
|
194
|
-
dynflowEnableConsole: false,
|
49
|
+
...TaskButtons.defaultProps,
|
195
50
|
};
|
196
51
|
|
197
52
|
export default Task;
|