foreman-tasks 2.0.3 → 3.0.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.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/js_tests.yml +31 -0
  3. data/.github/workflows/ruby_tests.yml +74 -0
  4. data/.rubocop.yml +12 -4
  5. data/.rubocop_todo.yml +32 -25
  6. data/Gemfile +5 -0
  7. data/app/controllers/foreman_tasks/api/tasks_controller.rb +50 -63
  8. data/app/controllers/foreman_tasks/concerns/parameters/triggering.rb +1 -1
  9. data/app/controllers/foreman_tasks/recurring_logics_controller.rb +7 -0
  10. data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +3 -3
  11. data/app/models/foreman_tasks/recurring_logic.rb +1 -1
  12. data/app/models/foreman_tasks/task.rb +11 -0
  13. data/app/models/foreman_tasks/task/dynflow_task.rb +27 -33
  14. data/app/models/foreman_tasks/task/search.rb +1 -1
  15. data/app/models/foreman_tasks/task/status_explicator.rb +1 -1
  16. data/app/models/foreman_tasks/triggering.rb +1 -1
  17. data/app/models/setting/foreman_tasks.rb +9 -9
  18. data/app/services/foreman_tasks/dashboard_table_filter.rb +5 -1
  19. data/app/views/foreman_tasks/api/tasks/index.json.rabl +2 -0
  20. data/app/views/foreman_tasks/layouts/react.html.erb +1 -2
  21. data/app/views/foreman_tasks/recurring_logics/index.html.erb +3 -1
  22. data/app/views/foreman_tasks/tasks/dashboard/_latest_tasks_in_error_warning.html.erb +1 -1
  23. data/app/views/foreman_tasks/tasks/dashboard/_tasks_status.html.erb +1 -1
  24. data/app/views/foreman_tasks/tasks/show.html.erb +1 -6
  25. data/config/routes.rb +2 -1
  26. data/db/migrate/20200517215015_rename_bookmarks_controller.rb +2 -2
  27. data/db/seeds.d/30-notification_blueprints.rb +7 -7
  28. data/db/seeds.d/61-foreman_tasks_bookmarks.rb +1 -1
  29. data/foreman-tasks.gemspec +1 -0
  30. data/lib/foreman_tasks/cleaner.rb +4 -6
  31. data/lib/foreman_tasks/dynflow/configuration.rb +1 -1
  32. data/lib/foreman_tasks/dynflow/persistence.rb +4 -6
  33. data/lib/foreman_tasks/engine.rb +2 -2
  34. data/lib/foreman_tasks/version.rb +1 -1
  35. data/package.json +0 -1
  36. data/test/controllers/api/recurring_logics_controller_test.rb +1 -1
  37. data/test/controllers/api/tasks_controller_test.rb +17 -7
  38. data/test/controllers/tasks_controller_test.rb +6 -6
  39. data/test/core/unit/runner_test.rb +20 -20
  40. data/test/core/unit/task_launcher_test.rb +8 -8
  41. data/test/helpers/foreman_tasks/foreman_tasks_helper_test.rb +7 -7
  42. data/test/helpers/foreman_tasks/tasks_helper_test.rb +3 -3
  43. data/test/lib/actions/middleware/keep_current_request_id_test.rb +3 -3
  44. data/test/support/history_tasks_builder.rb +1 -1
  45. data/test/tasks/generate_task_actions_test.rb +1 -1
  46. data/test/unit/actions/action_with_sub_plans_test.rb +2 -2
  47. data/test/unit/actions/bulk_action_test.rb +6 -6
  48. data/test/unit/actions/proxy_action_test.rb +20 -20
  49. data/test/unit/actions/recurring_action_test.rb +30 -32
  50. data/test/unit/cleaner_test.rb +24 -24
  51. data/test/unit/dashboard_table_filter_test.rb +5 -5
  52. data/test/unit/otp_manager_test.rb +2 -2
  53. data/test/unit/proxy_selector_test.rb +9 -9
  54. data/test/unit/recurring_logic_test.rb +32 -32
  55. data/test/unit/remote_task_test.rb +2 -2
  56. data/test/unit/task_groups_test.rb +4 -4
  57. data/test/unit/task_test.rb +26 -18
  58. data/test/unit/triggering_test.rb +8 -8
  59. data/test/unit/troubleshooting_help_generator_test.rb +6 -6
  60. data/test/unit/ui_notifications_test.rb +11 -11
  61. data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +3 -3
  62. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +8 -157
  63. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskButtons.js +168 -0
  64. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +6 -7
  65. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskSkeleton.js +48 -0
  66. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +1 -1
  67. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +12 -70
  68. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskButtons.test.js +95 -0
  69. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +78 -225
  70. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskButtons.test.js.snap +212 -0
  71. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +8 -4
  72. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +87 -70
  73. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +10 -0
  74. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +48 -125
  75. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +3 -16
  76. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +55 -29
  77. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.fixtures.js +2 -2
  78. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +6 -0
  79. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +2 -18
  80. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +77 -27
  81. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +14 -101
  82. data/webpack/ForemanTasks/Components/TaskDetails/index.js +6 -3
  83. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.scss +4 -0
  84. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/OtherInfo.js +53 -0
  85. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/OtherInfo.test.js +14 -0
  86. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.js +27 -19
  87. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.scss +14 -0
  88. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.test.js +1 -34
  89. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/{StoppedTasksCardHelper.js → StoppedTasksCardTable.js} +28 -1
  90. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCardTable.test.js +54 -0
  91. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/OtherInfo.test.js.snap +48 -0
  92. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCard.test.js.snap +60 -1367
  93. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCardTable.test.js.snap +960 -0
  94. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/__snapshots__/TasksCardsGrid.test.js.snap +14 -11
  95. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardConstants.js +2 -0
  96. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardSelectors.js +17 -11
  97. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardSelectors.test.js +26 -14
  98. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboard.test.js.snap +14 -11
  99. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboardSelectors.test.js.snap +38 -22
  100. data/webpack/ForemanTasks/Components/TasksTable/TasksTableHelpers.js +0 -8
  101. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +13 -4
  102. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.scss +0 -10
  103. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +0 -2
  104. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionNameCellFormatter.test.js.snap +3 -1
  105. data/webpack/ForemanTasks/Components/TasksTable/formatters/actionNameCellFormatter.js +6 -1
  106. data/webpack/ForemanTasks/Components/common/urlHelpers.js +7 -0
  107. data/webpack/ForemanTasks/ForemanTasksReducers.js +0 -2
  108. data/webpack/__mocks__/foremanReact/common/helpers.js +2 -0
  109. data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +10 -0
  110. data/webpack/__mocks__/foremanReact/redux/API/index.js +10 -0
  111. data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware.js +5 -0
  112. metadata +21 -13
  113. data/.travis.yml +0 -7
  114. data/app/assets/stylesheets/foreman_tasks/tasks.scss +0 -9
  115. data/script/travis_run_js_tests.sh +0 -7
  116. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +0 -38
  117. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsReducer.test.js +0 -33
  118. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsReducer.test.js.snap +0 -26
  119. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/integration.test.js.snap +0 -122
  120. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +0 -72
  121. data/webpack/__mocks__/foremanReact/redux/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
@@ -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,15 @@ 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
+ end
131
+ end
132
+
133
+ context 'by taxonomies' do
134
+ test 'can search by taxonomies using IN' do
135
+ assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('location_id ^ (1)').first }
136
+ assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('organization_id ^ (1)').first }
137
+ assert_nothing_raised(PG::SyntaxError) { ForemanTasks::Task.search_for('organization_id = 1').first }
130
138
  end
131
139
  end
132
140
  end
@@ -176,13 +184,13 @@ class TasksTest < ActiveSupport::TestCase
176
184
  let(:inconsistent_task) { FactoryBot.create(:dynflow_task, :inconsistent_dynflow_task) }
177
185
 
178
186
  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'
187
+ _(consistent_task.state).must_equal 'planned'
188
+ _(inconsistent_task.state).must_equal 'running'
181
189
 
182
190
  ForemanTasks::Task::DynflowTask.consistency_check
183
191
 
184
- consistent_task.reload.state.must_equal 'planned'
185
- inconsistent_task.reload.state.must_equal 'planned'
192
+ _(consistent_task.reload.state).must_equal 'planned'
193
+ _(inconsistent_task.reload.state).must_equal 'planned'
186
194
  end
187
195
  end
188
196
 
@@ -190,8 +198,8 @@ class TasksTest < ActiveSupport::TestCase
190
198
  it 'when scheduled to the future, the label and action is set properly' do
191
199
  job = Support::DummyActiveJob.set(:wait => 12.hours).perform_later
192
200
  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"
201
+ _(task.action).must_equal "Dummy action"
202
+ _(task.label).must_equal "Support::DummyActiveJob"
195
203
  end
196
204
  end
197
205
 
@@ -224,14 +232,14 @@ class TasksTest < ActiveSupport::TestCase
224
232
  :total => 0,
225
233
  :success => 0,
226
234
  :cancelled => 0,
227
- :pending => 0
235
+ :pending => 0,
228
236
  }
229
237
  end
230
238
  let(:task) { FactoryBot.create(:dynflow_task) }
231
239
 
232
240
  describe 'without sub tasks' do
233
241
  it 'calculates the progress report correctly' do
234
- task.sub_tasks_counts.must_equal result_base
242
+ _(task.sub_tasks_counts).must_equal result_base
235
243
  end
236
244
  end
237
245
 
@@ -242,7 +250,7 @@ class TasksTest < ActiveSupport::TestCase
242
250
 
243
251
  it 'calculate the progress report correctly' do
244
252
  expected_result = result_base.merge(:success => 1, :error => 1, :total => 2)
245
- task.sub_tasks_counts.must_equal expected_result
253
+ _(task.sub_tasks_counts).must_equal expected_result
246
254
  end
247
255
 
248
256
  it 'calculates the progress report correctly when using batch planning' do
@@ -252,11 +260,11 @@ class TasksTest < ActiveSupport::TestCase
252
260
 
253
261
  task.state = 'stopped'
254
262
  expected_result = result_base.merge(:cancelled => 23)
255
- task.sub_tasks_counts.must_equal expected_result
263
+ _(task.sub_tasks_counts).must_equal expected_result
256
264
 
257
265
  task.state = 'pending'
258
266
  expected_result = result_base.merge(:pending => 23)
259
- task.sub_tasks_counts.must_equal expected_result
267
+ _(task.sub_tasks_counts).must_equal expected_result
260
268
  end
261
269
  end
262
270
  end
@@ -278,10 +286,10 @@ class TasksTest < ActiveSupport::TestCase
278
286
 
279
287
  it 'can indicate it is delayed' do
280
288
  assert_not task.delayed?
281
- task.execution_type.must_equal 'Immediate'
289
+ _(task.execution_type).must_equal 'Immediate'
282
290
  task.start_at = Time.now.utc + 100
283
291
  assert task.delayed?
284
- task.execution_type.must_equal 'Delayed'
292
+ _(task.execution_type).must_equal 'Delayed'
285
293
  end
286
294
  end
287
295
 
@@ -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",
@@ -8,7 +8,7 @@ const RunningSteps = ({
8
8
  id,
9
9
  cancelStep,
10
10
  taskReload,
11
- taskProgressToggle,
11
+ taskReloadStart,
12
12
  }) => {
13
13
  if (!runningSteps.length) return <span>{__('No running steps')}</span>;
14
14
  return (
@@ -21,7 +21,7 @@ const RunningSteps = ({
21
21
  bsSize="small"
22
22
  onClick={() => {
23
23
  if (!taskReload) {
24
- taskProgressToggle();
24
+ taskReloadStart(id);
25
25
  }
26
26
  cancelStep(id, step.id);
27
27
  }}
@@ -59,7 +59,7 @@ RunningSteps.propTypes = {
59
59
  id: PropTypes.string.isRequired,
60
60
  cancelStep: PropTypes.func.isRequired,
61
61
  taskReload: PropTypes.bool.isRequired,
62
- taskProgressToggle: PropTypes.func.isRequired,
62
+ taskReloadStart: PropTypes.func.isRequired,
63
63
  };
64
64
 
65
65
  RunningSteps.defaultProps = {
@@ -1,159 +1,37 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
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 unlockModalActions = useForemanModal({
15
- id: UNLOCK_MODAL,
16
- });
17
- const forceUnlockModalActions = useForemanModal({
18
- id: FORCE_UNLOCK_MODAL,
19
- });
20
-
21
8
  const {
22
9
  taskReload,
23
- externalId,
24
10
  id,
25
- state,
26
- resumable,
27
- cancellable,
28
- hasSubTasks,
29
- parentTask,
30
- cancelTaskRequest,
31
- resumeTaskRequest,
32
11
  forceCancelTaskRequest,
33
12
  unlockTaskRequest,
34
13
  action,
35
- dynflowEnableConsole,
36
- taskProgressToggle,
37
- canEdit,
14
+ taskReloadStart,
38
15
  } = props;
39
16
  const forceUnlock = () => {
40
17
  if (!taskReload) {
41
- taskProgressToggle();
18
+ taskReloadStart(id);
42
19
  }
43
20
  forceCancelTaskRequest(id, action);
44
21
  };
45
22
  const unlock = () => {
46
23
  if (!taskReload) {
47
- taskProgressToggle();
24
+ taskReloadStart(id);
48
25
  }
49
26
  unlockTaskRequest(id, action);
50
27
  };
51
- const editActionsTitle = canEdit
52
- ? undefined
53
- : __('You do not have permission');
54
- const dynflowTitle = dynflowEnableConsole
55
- ? undefined
56
- : `dynflow_enable_console ${__('Setting is off')}`;
57
28
  return (
58
29
  <React.Fragment>
59
30
  <UnlockModal onClick={unlock} />
60
31
  <ForceUnlockModal onClick={forceUnlock} />
61
32
  <Grid>
62
33
  <Row>
63
- <Col xs={12}>
64
- <Button
65
- className="reload-button"
66
- bsSize="small"
67
- onClick={taskProgressToggle}
68
- >
69
- <span
70
- className={`glyphicon glyphicon-refresh ${
71
- taskReload ? 'spin' : ''
72
- }`}
73
- />
74
- {__(`${taskReload ? 'Stop' : 'Start'} auto-reloading`)}
75
- </Button>
76
- <Button
77
- className="dynflow-button"
78
- bsSize="small"
79
- href={`/foreman_tasks/dynflow/${externalId}`}
80
- disabled={!dynflowEnableConsole}
81
- rel="noopener noreferrer"
82
- target="_blank"
83
- >
84
- <span title={dynflowTitle} data-original-title={dynflowTitle}>
85
- {__('Dynflow console')}
86
- </span>
87
- </Button>
88
- <Button
89
- className="resume-button"
90
- bsSize="small"
91
- title={editActionsTitle}
92
- data-original-title={editActionsTitle}
93
- disabled={!canEdit || !resumable}
94
- onClick={() => {
95
- if (!taskReload) {
96
- taskProgressToggle();
97
- }
98
- resumeTaskRequest(id, action);
99
- }}
100
- >
101
- {__('Resume')}
102
- </Button>
103
- <Button
104
- className="cancel-button"
105
- bsSize="small"
106
- title={editActionsTitle}
107
- data-original-title={editActionsTitle}
108
- disabled={!canEdit || !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={!canEdit || state !== 'paused'}
140
- onClick={unlockModalActions.setModalOpen}
141
- title={editActionsTitle}
142
- data-original-title={editActionsTitle}
143
- >
144
- {__('Unlock')}
145
- </Button>
146
- <Button
147
- className="force-unlock-button"
148
- bsSize="small"
149
- disabled={!canEdit || state === 'stopped'}
150
- onClick={forceUnlockModalActions.setModalOpen}
151
- title={editActionsTitle}
152
- data-original-title={editActionsTitle}
153
- >
154
- {__('Force Unlock')}
155
- </Button>
156
- </Col>
34
+ <TaskButtons taskReloadStart={taskReloadStart} {...props} />
157
35
  </Row>
158
36
  <TaskInfo {...props} />
159
37
  </Grid>
@@ -163,39 +41,12 @@ const Task = props => {
163
41
 
164
42
  Task.propTypes = {
165
43
  ...TaskInfo.PropTypes,
166
- state: PropTypes.string,
167
- resumable: PropTypes.bool,
168
- cancellable: PropTypes.bool,
169
- refetchTaskDetails: PropTypes.func,
170
- hasSubTasks: PropTypes.bool,
171
- parentTask: PropTypes.string,
172
- taskReload: PropTypes.bool,
173
- taskReloadStop: PropTypes.func,
174
- timeoutId: PropTypes.number,
175
- externalId: PropTypes.string,
176
- id: PropTypes.string.isRequired,
177
- cancelTaskRequest: PropTypes.func,
178
- resumeTaskRequest: PropTypes.func,
179
- dynflowEnableConsole: PropTypes.bool,
180
- canEdit: PropTypes.bool,
44
+ ...TaskButtons.PropTypes,
181
45
  };
182
46
 
183
47
  Task.defaultProps = {
184
48
  ...TaskInfo.defaultProps,
185
- state: '',
186
- resumable: false,
187
- cancellable: false,
188
- refetchTaskDetails: () => null,
189
- hasSubTasks: false,
190
- parentTask: '',
191
- taskReload: false,
192
- taskReloadStop: () => null,
193
- timeoutId: null,
194
- externalId: '',
195
- cancelTaskRequest: () => null,
196
- resumeTaskRequest: () => null,
197
- dynflowEnableConsole: false,
198
- canEdit: false,
49
+ ...TaskButtons.defaultProps,
199
50
  };
200
51
 
201
52
  export default Task;