foreman-tasks 1.0.1 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -12
  3. data/.rubocop_todo.yml +34 -116
  4. data/README.md +2 -0
  5. data/app/controllers/foreman_tasks/api/recurring_logics_controller.rb +20 -1
  6. data/app/controllers/foreman_tasks/api/tasks_controller.rb +65 -10
  7. data/app/controllers/foreman_tasks/concerns/hosts_controller_extension.rb +1 -1
  8. data/app/controllers/foreman_tasks/recurring_logics_controller.rb +19 -0
  9. data/app/controllers/foreman_tasks/tasks_controller.rb +9 -14
  10. data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +1 -3
  11. data/app/lib/actions/helpers/humanizer.rb +1 -3
  12. data/app/lib/actions/proxy_action.rb +33 -12
  13. data/app/lib/foreman_tasks/concerns/polling_action_extensions.rb +12 -0
  14. data/app/models/foreman_tasks/concerns/action_triggering.rb +1 -1
  15. data/app/models/foreman_tasks/recurring_logic.rb +1 -0
  16. data/app/models/foreman_tasks/remote_task.rb +1 -0
  17. data/app/models/foreman_tasks/task.rb +8 -0
  18. data/app/models/foreman_tasks/task/dynflow_task.rb +2 -1
  19. data/app/models/foreman_tasks/task/search.rb +11 -1
  20. data/app/models/setting/foreman_tasks.rb +7 -2
  21. data/app/services/foreman_tasks/troubleshooting_help_generator.rb +0 -4
  22. data/app/services/ui_notifications/tasks/task_bulk_cancel.rb +36 -0
  23. data/app/services/ui_notifications/tasks/task_bulk_resume.rb +38 -0
  24. data/app/services/ui_notifications/tasks/task_bulk_stop.rb +36 -0
  25. data/app/views/foreman_tasks/api/recurring_logics/base.json.rabl +2 -1
  26. data/app/views/foreman_tasks/api/tasks/details.json.rabl +1 -1
  27. data/app/views/foreman_tasks/api/tasks/show.json.rabl +1 -1
  28. data/app/views/foreman_tasks/recurring_logics/index.html.erb +30 -0
  29. data/app/views/foreman_tasks/tasks/show.html.erb +3 -0
  30. data/config/routes.rb +8 -0
  31. data/db/migrate/20200517215015_rename_bookmarks_controller.rb +35 -0
  32. data/db/migrate/20200519093217_drop_dynflow_allow_dangerous_actions_setting.foreman_tasks.rb +5 -0
  33. data/db/migrate/20200611090846_add_task_lock_index_on_resource_type_and_task_id.rb +9 -0
  34. data/db/seeds.d/30-notification_blueprints.rb +21 -0
  35. data/foreman-tasks.gemspec +5 -6
  36. data/gemfile.d/foreman-tasks.rb +1 -0
  37. data/lib/foreman_tasks/dynflow/console_authorizer.rb +2 -2
  38. data/lib/foreman_tasks/engine.rb +17 -19
  39. data/lib/foreman_tasks/tasks/cleanup.rake +1 -1
  40. data/lib/foreman_tasks/tasks/export_tasks.rake +2 -2
  41. data/lib/foreman_tasks/test_extensions.rb +1 -1
  42. data/lib/foreman_tasks/version.rb +1 -1
  43. data/locale/action_names.rb +2 -2
  44. data/locale/en/LC_MESSAGES/foreman_tasks.mo +0 -0
  45. data/locale/en/foreman_tasks.po +270 -54
  46. data/locale/foreman_tasks.pot +630 -292
  47. data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
  48. data/locale/fr/foreman_tasks.po +817 -0
  49. data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
  50. data/locale/ja/foreman_tasks.po +817 -0
  51. data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
  52. data/locale/zh_CN/foreman_tasks.po +816 -0
  53. data/package.json +1 -2
  54. data/script/rails +2 -2
  55. data/script/travis_run_js_tests.sh +2 -2
  56. data/test/factories/task_factory.rb +34 -2
  57. data/test/foreman_tasks_test_helper.rb +4 -0
  58. data/test/lib/concerns/polling_action_extensions_test.rb +34 -0
  59. data/test/unit/actions/action_with_sub_plans_test.rb +1 -1
  60. data/test/unit/task_test.rb +160 -74
  61. data/webpack/ForemanTasks/Components/TaskActions/TaskAction.test.js +60 -0
  62. data/webpack/ForemanTasks/Components/TaskActions/TaskActionHelpers.js +67 -0
  63. data/webpack/ForemanTasks/Components/TaskActions/TaskActionHelpers.test.js +46 -0
  64. data/webpack/ForemanTasks/Components/TaskActions/TaskActionsConstants.js +16 -0
  65. data/webpack/ForemanTasks/Components/TaskActions/UnlockModals.js +60 -0
  66. data/webpack/ForemanTasks/Components/TaskActions/UnlockModals.test.js +14 -0
  67. data/webpack/ForemanTasks/Components/TaskActions/__snapshots__/TaskAction.test.js.snap +233 -0
  68. data/webpack/ForemanTasks/Components/TaskActions/__snapshots__/UnlockModals.test.js.snap +25 -0
  69. data/webpack/ForemanTasks/Components/TaskActions/index.js +115 -0
  70. data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +17 -3
  71. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +132 -165
  72. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +3 -12
  73. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +8 -1
  74. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +68 -3
  75. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskInfo.test.js +0 -1
  76. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/RunningSteps.test.js.snap +1 -1
  77. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +108 -75
  78. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +3 -9
  79. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +35 -5
  80. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +34 -14
  81. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +3 -4
  82. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +0 -6
  83. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +4 -10
  84. data/webpack/ForemanTasks/Components/TaskDetails/TasksDetailsHelper.js +6 -1
  85. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.fixtures.js +8 -0
  86. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +7 -1
  87. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +18 -2
  88. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +30 -13
  89. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +91 -0
  90. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +13 -4
  91. data/webpack/ForemanTasks/Components/TaskDetails/index.js +6 -8
  92. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardActions.js +1 -1
  93. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardConstants.js +5 -0
  94. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardHelper.js +3 -2
  95. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardActions.test.js +2 -2
  96. data/webpack/ForemanTasks/Components/TasksTable/Components/ActionSelectButton.js +14 -1
  97. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModal.js +83 -0
  98. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalActions.js +106 -0
  99. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalReducer.js +38 -0
  100. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalSelectors.js +45 -0
  101. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModal.test.js +36 -0
  102. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalActions.test.js +205 -0
  103. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalReducer.test.js +27 -0
  104. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalSelectors.test.js +54 -0
  105. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModal.test.js.snap +41 -0
  106. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalReducer.test.js.snap +19 -0
  107. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalSelectors.test.js.snap +30 -0
  108. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/index.js +29 -0
  109. data/webpack/ForemanTasks/Components/TasksTable/Components/SelectAllAlert.js +43 -0
  110. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ActionSelectButton.test.js +1 -0
  111. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/SelectAllAlert.test.js +29 -0
  112. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ActionSelectButton.test.js.snap +11 -0
  113. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/SelectAllAlert.test.js.snap +75 -0
  114. data/webpack/ForemanTasks/Components/TasksTable/SubTasksPage.js +4 -1
  115. data/webpack/ForemanTasks/Components/TasksTable/TasksBulkActions.js +247 -0
  116. data/webpack/ForemanTasks/Components/TasksTable/TasksTable.js +37 -19
  117. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +56 -92
  118. data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +19 -11
  119. data/webpack/ForemanTasks/Components/TasksTable/TasksTableHelpers.js +4 -3
  120. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +64 -73
  121. data/webpack/ForemanTasks/Components/TasksTable/TasksTableReducer.js +21 -2
  122. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSchema.js +2 -2
  123. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +13 -4
  124. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksBulkActions.test.js +147 -0
  125. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +3 -10
  126. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableActions.test.js +46 -74
  127. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableHelpers.test.js +17 -1
  128. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTablePage.test.js +9 -1
  129. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableReducer.test.js +22 -1
  130. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +4 -12
  131. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksBulkActions.test.js.snap +336 -0
  132. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +3 -12
  133. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableActions.test.js.snap +22 -158
  134. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +56 -132
  135. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableReducer.test.js.snap +34 -0
  136. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionHeaderCellFormatter.test.js +1 -1
  137. data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionHeaderCellFormatter.js +2 -2
  138. data/webpack/ForemanTasks/Components/TasksTable/index.js +10 -4
  139. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.js +47 -19
  140. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.test.js +61 -14
  141. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ActionButton.test.js.snap +80 -21
  142. data/webpack/ForemanTasks/Components/common/ClickConfirmation/ClickConfirmation.scss +9 -0
  143. data/webpack/ForemanTasks/Components/common/ClickConfirmation/ClickConfirmation.test.js +44 -0
  144. data/webpack/ForemanTasks/Components/common/ClickConfirmation/__snapshots__/ClickConfirmation.test.js.snap +52 -0
  145. data/webpack/ForemanTasks/Components/common/ClickConfirmation/index.js +59 -66
  146. data/webpack/ForemanTasks/Components/common/ToastsHelpers/ToastTypesConstants.js +11 -0
  147. data/webpack/ForemanTasks/Components/common/ToastsHelpers/index.js +15 -0
  148. data/webpack/ForemanTasks/ForemanTasksReducers.js +2 -0
  149. data/webpack/ForemanTasks/Routes/ForemanTasksRoutes.test.js +2 -1
  150. data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalHooks.js +2 -2
  151. data/webpack/__mocks__/foremanReact/components/ForemanModal/index.js +17 -3
  152. data/webpack/__mocks__/foremanReact/components/common/ActionButtons/ActionButtons.js +3 -0
  153. data/webpack/__mocks__/foremanReact/{API.js → redux/API.js} +1 -1
  154. metadata +76 -27
  155. data/webpack/ForemanTasks/Components/TasksTable/Components/CancelConfirm.js +0 -53
  156. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmationModals.js +0 -56
  157. data/webpack/ForemanTasks/Components/TasksTable/Components/ResumeConfirm.js +0 -52
  158. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/CancelConfirm.test.js +0 -26
  159. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ConfirmationModals.test.js +0 -24
  160. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ResumeConfirm.test.js +0 -26
  161. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/CancelConfirm.test.js.snap +0 -65
  162. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ConfirmationModals.test.js.snap +0 -30
  163. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ResumeConfirm.test.js.snap +0 -63
  164. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.js +0 -23
  165. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.test.js +0 -26
  166. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.js +0 -23
  167. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.test.js +0 -27
  168. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/CancelButton.test.js.snap +0 -15
  169. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ResumeButton.test.js.snap +0 -15
@@ -27,6 +27,7 @@
27
27
  "dependencies": {
28
28
  "c3": "^0.4.11",
29
29
  "humanize-duration": "^3.20.1",
30
+ "react-html-parser": "^2.0.2",
30
31
  "react-intl": "^2.8.0"
31
32
  },
32
33
  "devDependencies": {
@@ -38,10 +39,8 @@
38
39
  "@theforeman/vendor-dev": "^4.0.2",
39
40
  "babel-eslint": "^10.0.3",
40
41
  "eslint": "^6.7.2",
41
- "identity-obj-proxy": "^3.0.0",
42
42
  "jed": "^1.1.1",
43
43
  "prettier": "^1.13.5",
44
- "react-remarkable": "^1.1.3",
45
44
  "stylelint": "^9.3.0",
46
45
  "stylelint-config-standard": "^18.0.0",
47
46
  "surge": "^0.20.3"
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
3
 
4
- ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
- ENGINE_PATH = File.expand_path('../../lib/foreman_tasks/engine', __FILE__)
4
+ ENGINE_ROOT = File.expand_path('..', __dir__)
5
+ ENGINE_PATH = File.expand_path('../lib/foreman_tasks/engine', __dir__)
6
6
 
7
7
  require 'rails/all'
8
8
  require 'rails/engine/commands'
@@ -1,7 +1,7 @@
1
1
  #!/bin/bash
2
2
  set -ev
3
- if [[ $( git diff --name-only HEAD~1..HEAD webpack/ .travis.yml .babelrc .eslintrc package.json | wc -l ) -ne 0 ]]; then
3
+ if [[ $( git diff --name-only HEAD~1..HEAD webpack/ .travis.yml babel.config.js .eslintrc package.json | wc -l ) -ne 0 ]]; then
4
4
  npm run test;
5
- npm run coveralls;
5
+ npm run publish-coverage;
6
6
  npm run lint;
7
7
  fi
@@ -22,7 +22,7 @@ FactoryBot.define do
22
22
  execution_plan = ForemanTasks.dynflow.world.plan(Support::DummyDynflowAction)
23
23
  # remove the task created automatically by the persistence
24
24
  ForemanTasks::Task.where(:external_id => execution_plan.id).delete_all
25
- task.update_attributes!(:external_id => execution_plan.id)
25
+ task.update!(:external_id => execution_plan.id)
26
26
  if evaluator.sync_with_dynflow
27
27
  task.update_from_dynflow(execution_plan.to_hash)
28
28
  end
@@ -38,9 +38,41 @@ FactoryBot.define do
38
38
 
39
39
  trait :inconsistent_dynflow_task do
40
40
  after(:build) do |task|
41
- task.update_attributes!(:state => 'running')
41
+ task.update!(:state => 'running')
42
+ end
43
+ end
44
+
45
+ factory :task_with_locks do
46
+ # posts_count is declared as a transient attribute and available in
47
+ # attributes on the factory, as well as the callback via the evaluator
48
+ transient do
49
+ locks_count { 3 }
50
+ resource_id { 1 }
51
+ resource_type { 'type1' }
52
+ end
53
+
54
+ # the after(:create) yields two values; the user instance itself and the
55
+ # evaluator, which stores all values from the factory, including transient
56
+ # attributes; `create_list`'s second argument is the number of records
57
+ # to create and we make sure the user is associated properly to the post
58
+ after(:create) do |task, evaluator|
59
+ create_list(
60
+ :lock,
61
+ evaluator.locks_count,
62
+ task: task,
63
+ resource_type: evaluator.resource_type,
64
+ resource_id: evaluator.resource_id
65
+ )
42
66
  end
43
67
  end
44
68
  end
45
69
  end
70
+
71
+ factory :lock, :class => ForemanTasks::Lock do
72
+ name { 'read' }
73
+ resource_type { 'Katello::Repository' }
74
+ resource_id { 1 }
75
+ exclusive { true }
76
+ association :task, factory: :task_with_locks
77
+ end
46
78
  end
@@ -27,3 +27,7 @@ def wait_for(waiting_message = 'something to happen')
27
27
  end
28
28
  raise "waiting for #{waiting_message} was not successful"
29
29
  end
30
+
31
+ def on_postgresql?
32
+ ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
33
+ end
@@ -0,0 +1,34 @@
1
+ require 'foreman_tasks_test_helper'
2
+
3
+ module ForemanTasks
4
+ module Concerns
5
+ class PollingActionExtensionsTest < ::ActiveSupport::TestCase
6
+ class Action < ::Dynflow::Action
7
+ include ::Dynflow::Action::Polling
8
+ end
9
+
10
+ describe 'polling interval tuning' do
11
+ let(:default_intervals) { [0.5, 1, 2, 4, 8, 16] }
12
+
13
+ it 'is extends the polling action module' do
14
+ _(::Dynflow::Action::Polling.ancestors.first).must_equal ForemanTasks::Concerns::PollingActionExtensions
15
+ end
16
+
17
+ it 'does not modify polling intervals by default' do
18
+ _(Action.allocate.poll_intervals).must_equal default_intervals
19
+ end
20
+
21
+ it 'cannot make intervals shorter than 0.5 seconds' do
22
+ Setting.expects(:[]).with(:foreman_tasks_polling_multiplier).returns 0
23
+ _(Action.allocate.poll_intervals).must_equal(default_intervals.map { 0.5 })
24
+ end
25
+
26
+ it 'can be used to make the intervals longer' do
27
+ value = 5
28
+ Setting.expects(:[]).with(:foreman_tasks_polling_multiplier).returns value
29
+ _(Action.allocate.poll_intervals).must_equal(default_intervals.map { |i| i * value })
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -8,7 +8,7 @@ module ForemanTasks
8
8
  end
9
9
 
10
10
  # to be able to use the locking
11
- ::User.send(:include, ForemanTasks::Concerns::ActionSubject)
11
+ ::User.include ForemanTasks::Concerns::ActionSubject
12
12
 
13
13
  class ParentAction < Actions::ActionWithSubPlans
14
14
  def plan(user)
@@ -1,97 +1,133 @@
1
1
  require 'foreman_tasks_test_helper'
2
2
 
3
3
  class TasksTest < ActiveSupport::TestCase
4
- describe 'filtering by current user' do
5
- before do
6
- @original_current_user = User.current
7
- @user_one = FactoryBot.create(:user)
8
- @user_two = FactoryBot.create(:user)
4
+ describe 'search' do
5
+ describe 'by current user' do
6
+ before do
7
+ @original_current_user = User.current
8
+ @user_one = FactoryBot.create(:user)
9
+ @user_two = FactoryBot.create(:user)
9
10
 
10
- @task_one = FactoryBot.create(:some_task, :user => @user_one)
11
- FactoryBot.create(:some_task, :user => @user_two)
11
+ @task_one = FactoryBot.create(:some_task, :user => @user_one)
12
+ FactoryBot.create(:some_task, :user => @user_two)
12
13
 
13
- User.current = @user_one
14
- end
15
- after { User.current = @original_current_user }
14
+ User.current = @user_one
15
+ end
16
+ after { User.current = @original_current_user }
16
17
 
17
- test 'can search the tasks by current_user' do
18
- assert_equal [@task_one], ForemanTasks::Task.search_for('owner.id = current_user')
19
- end
18
+ test 'can search the tasks by current_user' do
19
+ assert_equal [@task_one], ForemanTasks::Task.search_for('owner.id = current_user')
20
+ end
20
21
 
21
- test 'can search by implicit search' do
22
- assert_equal [@task_one], ForemanTasks::Task.search_for(@task_one.label)
23
- end
22
+ test 'can search by implicit search' do
23
+ assert_equal [@task_one], ForemanTasks::Task.search_for(@task_one.label)
24
+ end
24
25
 
25
- test 'can search the tasks by current_user in combination with implicit search' do
26
- assert_equal [@task_one], ForemanTasks::Task.search_for("owner.id = current_user AND #{@task_one.label}")
27
- end
26
+ test 'can search the tasks by current_user in combination with implicit search' do
27
+ assert_equal [@task_one], ForemanTasks::Task.search_for("owner.id = current_user AND #{@task_one.label}")
28
+ end
28
29
 
29
- test 'can search the tasks by user' do
30
- assert_equal [@task_one], ForemanTasks::Task.search_for("user = #{@user_one.login}")
31
- end
30
+ test 'can search the tasks by user' do
31
+ assert_equal [@task_one], ForemanTasks::Task.search_for("user = #{@user_one.login}")
32
+ end
32
33
 
33
- test 'cannot search by arbitrary key' do
34
- proc { ForemanTasks::Task.search_for('user.my_key ~ 5') }.must_raise(ScopedSearch::QueryNotSupported)
35
- proc { ForemanTasks::Task.search_for('user. = 5') }.must_raise(ScopedSearch::QueryNotSupported)
36
- end
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)
37
+ end
37
38
 
38
- test 'can search the tasks by negated user' do
39
- assert_equal [@task_one], ForemanTasks::Task.search_for("user != #{@user_two.login}")
40
- assert_equal [@task_one], ForemanTasks::Task.search_for("user <> #{@user_two.login}")
41
- SecureRandom.stubs(:hex).returns('abc')
42
- assert_equal ForemanTasks::Task.search_for("user != #{@user_two.login}").to_sql,
43
- ForemanTasks::Task.search_for("user <> #{@user_two.login}").to_sql
44
- end
39
+ test 'can search the tasks by negated user' do
40
+ assert_equal [@task_one], ForemanTasks::Task.search_for("user != #{@user_two.login}")
41
+ assert_equal [@task_one], ForemanTasks::Task.search_for("user <> #{@user_two.login}")
42
+ SecureRandom.stubs(:hex).returns('abc')
43
+ assert_equal ForemanTasks::Task.search_for("user != #{@user_two.login}").to_sql,
44
+ ForemanTasks::Task.search_for("user <> #{@user_two.login}").to_sql
45
+ end
45
46
 
46
- test 'can search the tasks by user\'s id' do
47
- assert_equal [@task_one], ForemanTasks::Task.search_for("user.id = #{@user_one.id}")
48
- assert_equal [@task_one], ForemanTasks::Task.search_for("owner.id = #{@user_one.id}")
49
- assert_equal [@task_one], ForemanTasks::Task.search_for("user.id != #{@user_two.id}")
50
- assert_equal [@task_one], ForemanTasks::Task.search_for("owner.id != #{@user_two.id}")
51
- end
47
+ test 'can search the tasks by user\'s id' do
48
+ assert_equal [@task_one], ForemanTasks::Task.search_for("user.id = #{@user_one.id}")
49
+ assert_equal [@task_one], ForemanTasks::Task.search_for("owner.id = #{@user_one.id}")
50
+ assert_equal [@task_one], ForemanTasks::Task.search_for("user.id != #{@user_two.id}")
51
+ assert_equal [@task_one], ForemanTasks::Task.search_for("owner.id != #{@user_two.id}")
52
+ end
52
53
 
53
- test 'can search by array of user ids' do
54
- assert_equal [@task_one], ForemanTasks::Task.search_for("user.id ^ (#{@user_one.id})")
55
- assert_equal [@task_one], ForemanTasks::Task.search_for("owner.id ^ (#{@user_one.id})")
56
- assert_equal [@task_one], ForemanTasks::Task.search_for("user.id !^ (#{@user_two.id})")
57
- assert_equal [@task_one], ForemanTasks::Task.search_for("owner.id !^ (#{@user_two.id})")
58
- end
54
+ test 'can search by array of user ids' do
55
+ assert_equal [@task_one], ForemanTasks::Task.search_for("user.id ^ (#{@user_one.id})")
56
+ assert_equal [@task_one], ForemanTasks::Task.search_for("owner.id ^ (#{@user_one.id})")
57
+ assert_equal [@task_one], ForemanTasks::Task.search_for("user.id !^ (#{@user_two.id})")
58
+ assert_equal [@task_one], ForemanTasks::Task.search_for("owner.id !^ (#{@user_two.id})")
59
+ end
59
60
 
60
- test 'cannot glob on user\'s id' do
61
- proc { ForemanTasks::Task.search_for("user.id ~ something") }.must_raise(ScopedSearch::QueryNotSupported)
62
- proc { ForemanTasks::Task.search_for("user.id ~ 5") }.must_raise(ScopedSearch::QueryNotSupported)
63
- end
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)
64
+ end
64
65
 
65
- test 'can search the tasks by user with wildcards' do
66
- part = @user_one.login[1..-1] # search for '*ser1' if login is 'user1'
67
- # The following two should be equivalent
68
- assert_equal [@task_one], ForemanTasks::Task.search_for("user ~ #{part}")
69
- assert_equal [@task_one], ForemanTasks::Task.search_for("user ~ *#{part}*")
70
- SecureRandom.stubs(:hex).returns('abc')
71
- assert_equal ForemanTasks::Task.search_for("user ~ #{part}").to_sql,
72
- ForemanTasks::Task.search_for("user ~ *#{part}*").to_sql
73
- end
66
+ test 'can search the tasks by user with wildcards' do
67
+ part = @user_one.login[1..-1] # search for '*ser1' if login is 'user1'
68
+ # The following two should be equivalent
69
+ assert_equal [@task_one], ForemanTasks::Task.search_for("user ~ #{part}")
70
+ assert_equal [@task_one], ForemanTasks::Task.search_for("user ~ *#{part}*")
71
+ SecureRandom.stubs(:hex).returns('abc')
72
+ assert_equal ForemanTasks::Task.search_for("user ~ #{part}").to_sql,
73
+ ForemanTasks::Task.search_for("user ~ *#{part}*").to_sql
74
+ end
74
75
 
75
- test 'can search the tasks by user with negated wildcards' do
76
- part = @user_two.login[1..-1] # search for '*ser1' if login is 'user1'
77
- # The following two should be equivalent
78
- assert_equal [@task_one], ForemanTasks::Task.search_for("user !~ #{part}")
79
- assert_equal [@task_one], ForemanTasks::Task.search_for("user !~ *#{part}*")
80
- SecureRandom.stubs(:hex).returns('abc')
81
- assert_equal ForemanTasks::Task.search_for("user !~ #{part}").to_sql,
82
- ForemanTasks::Task.search_for("user !~ *#{part}*").to_sql
83
- end
76
+ test 'can search the tasks by user with negated wildcards' do
77
+ part = @user_two.login[1..-1] # search for '*ser1' if login is 'user1'
78
+ # The following two should be equivalent
79
+ assert_equal [@task_one], ForemanTasks::Task.search_for("user !~ #{part}")
80
+ assert_equal [@task_one], ForemanTasks::Task.search_for("user !~ *#{part}*")
81
+ SecureRandom.stubs(:hex).returns('abc')
82
+ assert_equal ForemanTasks::Task.search_for("user !~ #{part}").to_sql,
83
+ ForemanTasks::Task.search_for("user !~ *#{part}*").to_sql
84
+ end
84
85
 
85
- test 'can search the tasks by array' do
86
- assert_equal [@task_one], ForemanTasks::Task.search_for("user ^ (this_user, #{@user_one.login}, that_user)")
87
- end
86
+ test 'can search the tasks by array' do
87
+ assert_equal [@task_one], ForemanTasks::Task.search_for("user ^ (this_user, #{@user_one.login}, that_user)")
88
+ end
89
+
90
+ test 'can search the tasks by negated array' do
91
+ assert_equal [@task_one], ForemanTasks::Task.search_for("user !^ (this_user, #{@user_two.login}, that_user)")
92
+ end
88
93
 
89
- test 'can search the tasks by negated array' do
90
- assert_equal [@task_one], ForemanTasks::Task.search_for("user !^ (this_user, #{@user_two.login}, that_user)")
94
+ test 'properly returns username' do
95
+ assert_equal @task_one.username, @user_one.login
96
+ end
91
97
  end
92
98
 
93
- test 'properly returns username' do
94
- assert_equal @task_one.username, @user_one.login
99
+ describe 'by duration' do
100
+ before do
101
+ @task_one, @task_two = FactoryBot.create_list(:dynflow_task, 2).sort_by(&:id)
102
+ end
103
+
104
+ let(:scope) { ForemanTasks::Task.order(:id) }
105
+
106
+ it 'can search by seconds ' do
107
+ skip unless on_postgresql?
108
+ _(scope.search_for('duration < 2')).must_be :empty?
109
+ _(scope.search_for('duration = 2')).must_equal [@task_one, @task_two]
110
+ _(scope.search_for('duration < "2 seconds"')).must_be :empty?
111
+ _(scope.search_for('duration > "2 seconds"')).must_be :empty?
112
+ _(scope.search_for('duration = "2 seconds"')).must_equal [@task_one, @task_two]
113
+ _(scope.search_for('duration <= "2 seconds"')).must_equal [@task_one, @task_two]
114
+ _(scope.search_for('duration >= "2 seconds"')).must_equal [@task_one, @task_two]
115
+ end
116
+
117
+ it 'can search by other time intervals' do
118
+ skip unless on_postgresql?
119
+ %w[minutes hours days months years].each do |interval|
120
+ _(scope.search_for("duration < \"2 #{interval}\"")).must_equal [@task_one, @task_two]
121
+ _(scope.search_for("duration > \"2 #{interval}\"")).must_be :empty?
122
+ _(scope.search_for("duration = \"2 #{interval}\"")).must_be :empty?
123
+ _(scope.search_for("duration <= \"2 #{interval}\"")).must_equal [@task_one, @task_two]
124
+ _(scope.search_for("duration >= \"2 #{interval}\"")).must_be :empty?
125
+ end
126
+ end
127
+
128
+ it 'raises an exception if duration is unknown' do
129
+ proc { ForemanTasks::Task.search_for('duration = "25 potatoes"') }.must_raise ScopedSearch::QueryNotSupported
130
+ end
95
131
  end
96
132
  end
97
133
 
@@ -248,4 +284,54 @@ class TasksTest < ActiveSupport::TestCase
248
284
  task.execution_type.must_equal 'Delayed'
249
285
  end
250
286
  end
287
+
288
+ describe 'search for resource_ids' do
289
+ it 'finds tasks' do
290
+ label = 'label1'
291
+ resource_ids = [1, 2]
292
+ resource_type = 'restype1'
293
+
294
+ task1_old = FactoryBot.create(
295
+ :task_with_locks,
296
+ started_at: '2019-10-01 11:15:55',
297
+ ended_at: '2019-10-01 11:15:57',
298
+ resource_id: 1,
299
+ label: label,
300
+ resource_type: resource_type
301
+ )
302
+ task1_new = FactoryBot.create(
303
+ :task_with_locks,
304
+ started_at: '2019-10-02 11:15:55',
305
+ ended_at: '2019-10-02 11:15:57',
306
+ resource_id: 1,
307
+ label: label,
308
+ resource_type: resource_type
309
+ )
310
+ task2 = FactoryBot.create(
311
+ :task_with_locks,
312
+ started_at: '2019-10-03 11:15:55',
313
+ ended_at: '2019-10-03 11:15:57',
314
+ resource_id: 2,
315
+ label: label,
316
+ resource_type: resource_type
317
+ )
318
+ task3 = FactoryBot.create(
319
+ :task_with_locks,
320
+ started_at: '2019-10-03 11:15:55',
321
+ ended_at: '2019-10-03 11:15:57',
322
+ resource_id: 3,
323
+ label: label,
324
+ resource_type: 'another_type'
325
+ )
326
+
327
+ result = ForemanTasks::Task.search_for(
328
+ "resource_id ^ (#{resource_ids.join(',')}) and resource_type = #{resource_type}"
329
+ ).distinct
330
+ assert_equal 3, result.length
331
+ assert_includes result, task1_old
332
+ assert_includes result, task1_new
333
+ assert_includes result, task2
334
+ assert_not_includes result, task3
335
+ end
336
+ end
251
337
  end
@@ -0,0 +1,60 @@
1
+ import { testActionSnapshotWithFixtures } from '@theforeman/test';
2
+ import { API } from 'foremanReact/redux/API';
3
+ import {
4
+ cancelTaskRequest,
5
+ resumeTaskRequest,
6
+ forceCancelTaskRequest,
7
+ unlockTaskRequest,
8
+ } from './';
9
+
10
+ jest.mock('foremanReact/components/common/table', () => ({
11
+ getTableItemsAction: jest.fn(controller => controller),
12
+ }));
13
+
14
+ jest.mock('foremanReact/redux/API');
15
+
16
+ const task = ['some-id', 'some-name'];
17
+
18
+ const fixtures = {
19
+ 'should cancelTaskRequest and succeed': () => cancelTaskRequest(...task),
20
+ 'should cancelTaskRequest and fail': () => {
21
+ API.post.mockImplementation(() =>
22
+ Promise.reject(new Error('Network Error'))
23
+ );
24
+ return cancelTaskRequest(...task);
25
+ },
26
+
27
+ 'should resumeTaskRequest and succeed': () => {
28
+ API.post.mockImplementation(() => ({ data: 'some-data' }));
29
+ return resumeTaskRequest(...task);
30
+ },
31
+ 'should resumeTaskRequest and fail': () => {
32
+ API.post.mockImplementation(() =>
33
+ Promise.reject(new Error('Network Error'))
34
+ );
35
+ return resumeTaskRequest(...task);
36
+ },
37
+ 'should forceCancelTaskRequest and succeed': () => {
38
+ API.post.mockImplementation(() => ({ data: 'some-data' }));
39
+ return forceCancelTaskRequest(...task);
40
+ },
41
+ 'should forceCancelTaskRequest and fail': () => {
42
+ API.post.mockImplementation(() =>
43
+ Promise.reject(new Error('Network Error'))
44
+ );
45
+ return forceCancelTaskRequest(...task);
46
+ },
47
+ 'should unlockTaskRequest and succeed': () => {
48
+ API.post.mockImplementation(() => ({ data: 'some-data' }));
49
+ return unlockTaskRequest(...task);
50
+ },
51
+ 'should unlockTaskRequest and fail': () => {
52
+ API.post.mockImplementation(() =>
53
+ Promise.reject(new Error('Network Error'))
54
+ );
55
+ return forceCancelTaskRequest(...task);
56
+ },
57
+ };
58
+ describe('Tasks actions', () => {
59
+ testActionSnapshotWithFixtures(fixtures);
60
+ });