foreman_remote_execution 1.3.0 → 1.3.1

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 (84) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +28 -2
  3. data/.rubocop_todo.yml +0 -7
  4. data/Gemfile +1 -1
  5. data/app/controllers/api/v2/foreign_input_sets_controller.rb +1 -2
  6. data/app/controllers/api/v2/job_invocations_controller.rb +2 -2
  7. data/app/controllers/api/v2/job_templates_controller.rb +2 -3
  8. data/app/controllers/api/v2/remote_execution_features_controller.rb +1 -2
  9. data/app/controllers/api/v2/template_inputs_controller.rb +1 -2
  10. data/app/controllers/concerns/foreman/controller/parameters/job_template.rb +3 -3
  11. data/app/controllers/concerns/foreman/controller/parameters/template_input.rb +2 -2
  12. data/app/controllers/job_invocations_controller.rb +4 -7
  13. data/app/controllers/job_templates_controller.rb +2 -2
  14. data/app/controllers/remote_execution_features_controller.rb +1 -2
  15. data/app/helpers/remote_execution_helper.rb +22 -17
  16. data/app/lib/actions/remote_execution/run_host_job.rb +4 -10
  17. data/app/models/concerns/foreman_remote_execution/host_extensions.rb +29 -1
  18. data/app/models/host_status/execution_status.rb +1 -1
  19. data/app/models/input_template_renderer.rb +1 -1
  20. data/app/models/job_invocation.rb +12 -7
  21. data/app/models/job_invocation_composer.rb +15 -6
  22. data/app/models/job_invocation_task_group.rb +1 -1
  23. data/app/models/job_template.rb +45 -29
  24. data/app/models/job_template_importer.rb +21 -9
  25. data/app/models/remote_execution_feature.rb +4 -4
  26. data/app/models/setting/remote_execution.rb +7 -5
  27. data/app/models/ssh_execution_provider.rb +1 -3
  28. data/app/models/targeting.rb +6 -5
  29. data/app/models/template_invocation.rb +43 -1
  30. data/app/views/job_invocations/_form.html.erb +1 -1
  31. data/app/views/job_invocations/_tab_overview.html.erb +10 -1
  32. data/config/routes.rb +2 -2
  33. data/db/migrate/20150903192731_add_execution_to_interface.rb +6 -6
  34. data/db/migrate/20151215114631_add_host_id_to_template_invocation.rb +3 -2
  35. data/db/migrate/20160114120200_rename_job_categories.rb +1 -1
  36. data/db/migrate/20160127134031_add_advanced_to_template_input.rb +1 -1
  37. data/db/seeds.d/70-job_templates.rb +1 -1
  38. data/db/seeds.d/90-bookmarks.rb +1 -1
  39. data/doc/Gemfile +1 -1
  40. data/lib/foreman_remote_execution/engine.rb +1 -1
  41. data/lib/foreman_remote_execution/version.rb +1 -1
  42. data/lib/tasks/foreman_remote_execution_tasks.rake +1 -1
  43. data/locale/action_names.rb +1 -1
  44. data/locale/de/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  45. data/locale/de/foreman_remote_execution.po +39 -12
  46. data/locale/en/foreman_remote_execution.po +38 -11
  47. data/locale/en_GB/foreman_remote_execution.po +38 -11
  48. data/locale/es/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  49. data/locale/es/foreman_remote_execution.po +39 -12
  50. data/locale/foreman_remote_execution.pot +175 -141
  51. data/locale/fr/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  52. data/locale/fr/foreman_remote_execution.po +39 -12
  53. data/locale/ja/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  54. data/locale/ja/foreman_remote_execution.po +39 -12
  55. data/locale/ko/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  56. data/locale/ko/foreman_remote_execution.po +39 -12
  57. data/locale/pt_BR/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  58. data/locale/pt_BR/foreman_remote_execution.po +39 -12
  59. data/locale/ru/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  60. data/locale/ru/foreman_remote_execution.po +39 -12
  61. data/locale/zh_CN/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  62. data/locale/zh_CN/foreman_remote_execution.po +39 -12
  63. data/locale/zh_TW/LC_MESSAGES/foreman_remote_execution.mo +0 -0
  64. data/locale/zh_TW/foreman_remote_execution.po +39 -12
  65. data/test/benchmark/run_hosts_job_benchmark.rb +2 -2
  66. data/test/benchmark/targeting_benchmark.rb +2 -2
  67. data/test/factories/foreman_remote_execution_factories.rb +27 -2
  68. data/test/functional/api/v2/job_templates_controller_test.rb +1 -1
  69. data/test/test_plugin_helper.rb +2 -19
  70. data/test/unit/concerns/host_extensions_test.rb +54 -5
  71. data/test/unit/concerns/nic_extensions_test.rb +1 -1
  72. data/test/unit/execution_task_status_mapper_test.rb +1 -2
  73. data/test/unit/input_template_renderer_test.rb +1 -1
  74. data/test/unit/job_invocation_composer_test.rb +21 -29
  75. data/test/unit/job_invocation_test.rb +1 -2
  76. data/test/unit/job_template_effective_user_test.rb +1 -1
  77. data/test/unit/job_template_importer_test.rb +38 -20
  78. data/test/unit/job_template_test.rb +8 -8
  79. data/test/unit/remote_execution_feature_test.rb +6 -6
  80. data/test/unit/remote_execution_provider_test.rb +2 -1
  81. data/test/unit/targeting_test.rb +6 -6
  82. data/test/unit/template_input_test.rb +1 -1
  83. data/test/unit/template_invocation_input_value_test.rb +3 -3
  84. metadata +3 -3
@@ -91,7 +91,7 @@ module Api
91
91
  erb_data = @template.to_erb
92
92
  post :import, :template => erb_data
93
93
  assert_response :success
94
- assert JobTemplate.unscoped.find_by_name(new_name)
94
+ assert JobTemplate.unscoped.find_by(name: new_name)
95
95
  end
96
96
  end
97
97
 
@@ -1,26 +1,9 @@
1
1
  # This calls the main test_helper in Foreman-core
2
2
  require 'test_helper'
3
- require 'database_cleaner'
4
3
  require 'dynflow/testing'
5
4
 
6
5
  # Add plugin to FactoryGirl's paths
7
6
  FactoryGirl.definition_file_paths << File.join(File.dirname(__FILE__), 'factories')
7
+ # Add foreman tasks factories too
8
+ FactoryGirl.definition_file_paths << "#{ForemanTasks::Engine.root}/test/factories"
8
9
  FactoryGirl.reload
9
-
10
- # Foreman's setup doesn't handle cleaning up for Minitest::Spec
11
- DatabaseCleaner.strategy = :transaction
12
-
13
- class Minitest::Spec
14
- class << self
15
- alias_method :context, :describe
16
- end
17
-
18
- before :each do
19
- DatabaseCleaner.start
20
- Setting::RemoteExecution.load_defaults
21
- end
22
-
23
- after :each do
24
- DatabaseCleaner.clean
25
- end
26
- end
@@ -1,6 +1,9 @@
1
1
  require 'test_plugin_helper'
2
2
 
3
- describe ForemanRemoteExecution::HostExtensions do
3
+ class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase
4
+ before do
5
+ Setting::RemoteExecution.load_defaults
6
+ end
4
7
  let(:provider) { 'SSH' }
5
8
 
6
9
  before { User.current = FactoryGirl.build(:user, :admin) }
@@ -61,6 +64,52 @@ describe ForemanRemoteExecution::HostExtensions do
61
64
  end
62
65
  end
63
66
 
67
+ context 'scoped search' do
68
+ let(:job) do
69
+ job = FactoryGirl.create(:job_invocation, :with_task)
70
+ job.template_invocations << FactoryGirl.create(:template_invocation, :with_host, :with_failed_task)
71
+ job
72
+ end
73
+
74
+ let(:job2) do
75
+ job = FactoryGirl.create(:job_invocation, :with_task)
76
+ job.template_invocations << FactoryGirl.create(:template_invocation, :with_host, :with_failed_task)
77
+ job
78
+ end
79
+
80
+ it 'finds hosts for job_invocation.id' do
81
+ found_ids = Host.search_for("job_invocation.id = #{job.id}").map(&:id).sort
82
+ found_ids.must_equal job.template_invocations_host_ids.sort
83
+ end
84
+
85
+ it 'finds hosts by job_invocation.result' do
86
+ success, failed = job.template_invocations
87
+ .partition { |template| template.run_host_job_task.result == 'success' }
88
+ found_ids = Host.search_for('job_invocation.result = success').map(&:id)
89
+ found_ids.must_equal success.map(&:host_id)
90
+ found_ids = Host.search_for('job_invocation.result = failed').map(&:id)
91
+ found_ids.must_equal failed.map(&:host_id)
92
+ end
93
+
94
+ it 'finds hosts by job_invocation.id and job_invocation.result' do
95
+ # Force evaluation of the jobs
96
+ job
97
+ job2
98
+
99
+ Host.search_for("job_invocation.id = #{job.id}").count.must_equal 2
100
+ Host.search_for("job_invocation.id = #{job2.id}").count.must_equal 2
101
+ Host.search_for('job_invocation.result = success').count.must_equal 2
102
+ Host.search_for('job_invocation.result = failed').count.must_equal 2
103
+
104
+ success, failed = job.template_invocations
105
+ .partition { |template| template.run_host_job_task.result == 'success' }
106
+ found_ids = Host.search_for("job_invocation.id = #{job.id} AND job_invocation.result = success").map(&:id)
107
+ found_ids.must_equal success.map(&:host_id)
108
+ found_ids = Host.search_for("job_invocation.id = #{job.id} AND job_invocation.result = failed").map(&:id)
109
+ found_ids.must_equal failed.map(&:host_id)
110
+ end
111
+ end
112
+
64
113
  describe 'proxy determination strategies' do
65
114
  context 'subnet strategy' do
66
115
  let(:host) { FactoryGirl.build(:host, :with_execution) }
@@ -94,10 +143,10 @@ describe ForemanRemoteExecution::HostExtensions do
94
143
  end
95
144
 
96
145
  context 'global strategy' do
97
- let(:organization) { FactoryGirl.build(:organization) }
98
- let(:location) { FactoryGirl.build(:location) }
99
- let(:host) { FactoryGirl.build(:host, :organization => organization, :location => location) }
100
- let(:proxy_in_taxonomies) { FactoryGirl.create(:smart_proxy, :ssh, :organizations => [organization], :locations => [location]) }
146
+ let(:tax_organization) { FactoryGirl.build(:organization) }
147
+ let(:tax_location) { FactoryGirl.build(:location) }
148
+ let(:host) { FactoryGirl.build(:host, :organization => tax_organization, :location => tax_location) }
149
+ let(:proxy_in_taxonomies) { FactoryGirl.create(:smart_proxy, :ssh, :organizations => [tax_organization], :locations => [tax_location]) }
101
150
  let(:proxy_no_taxonomies) { FactoryGirl.create(:smart_proxy, :ssh) }
102
151
 
103
152
  context 'enabled' do
@@ -1,6 +1,6 @@
1
1
  require 'test_plugin_helper'
2
2
 
3
- describe ForemanRemoteExecution::NicExtensions do
3
+ class ForemanRemoteExecutionNicExtensionsTest < ActiveSupport::TestCase
4
4
  let(:host) { FactoryGirl.create(:host) }
5
5
 
6
6
  it 'sets the first primary interface as the execution interface' do
@@ -1,7 +1,6 @@
1
1
  require 'test_plugin_helper'
2
2
 
3
- describe HostStatus::ExecutionStatus::ExecutionTaskStatusMapper do
4
-
3
+ class ExecutionTaskStatusMapperTest < ActiveSupport::TestCase
5
4
  describe '.sql_conditions_for(status)' do
6
5
  let(:subject) { HostStatus::ExecutionStatus::ExecutionTaskStatusMapper }
7
6
 
@@ -1,6 +1,6 @@
1
1
  require 'test_plugin_helper'
2
2
 
3
- describe InputTemplateRenderer do
3
+ class InputTemplateRendererTest < ActiveSupport::TestCase
4
4
  context 'renderer for simple template without inputs' do
5
5
  let(:renderer) { InputTemplateRenderer.new(FactoryGirl.build(:job_template, :template => 'id <%= preview? %>')) }
6
6
 
@@ -2,24 +2,11 @@ require 'test_plugin_helper'
2
2
  RemoteExecutionProvider.register(:Ansible, OpenStruct)
3
3
  RemoteExecutionProvider.register(:Mcollective, OpenStruct)
4
4
 
5
- describe JobInvocationComposer do
5
+ class JobInvocationComposerTest < ActiveSupport::TestCase
6
6
  before do
7
- permission1 = Permission.find_by_name('view_job_templates')
8
- permission2 = Permission.find_by_name('view_bookmarks')
9
- permission3 = Permission.find_by_name('view_hosts')
10
- filter1 = FactoryGirl.build(:filter, :permissions => [permission1], :search => 'name ~ trying*')
11
- filter2 = FactoryGirl.build(:filter, :permissions => [permission2])
12
- filter3 = FactoryGirl.build(:filter, :permissions => [permission3])
13
- filter1.save
14
- filter2.save
15
- filter3.save
16
- role = FactoryGirl.build(:role)
17
- role.filters = filter1, filter2, filter3
18
- role.save
19
- User.current = FactoryGirl.build(:user)
20
- User.current.current_password = User.current.password
21
- User.current.roles << role
22
- User.current.save
7
+ setup_user('view', 'job_templates', 'name ~ trying*')
8
+ setup_user('view', 'bookmarks')
9
+ setup_user('view', 'hosts')
23
10
  end
24
11
 
25
12
  let(:trying_job_template_1) { FactoryGirl.create(:job_template, :job_category => 'trying_job_template_1', :name => 'trying1', :provider_type => 'SSH') }
@@ -213,8 +200,7 @@ describe JobInvocationComposer do
213
200
  trying_job_template_1.id.to_s => {
214
201
  :input_values => { input1.id.to_s => { :value => 'value1' }, unauthorized_input1.id.to_s => { :value => 'dropped' } }
215
202
  }
216
- }
217
- }
203
+ }}
218
204
  end
219
205
  let(:params) { { :job_invocation => { :providers => { :ssh => ssh_params } } }.with_indifferent_access }
220
206
  let(:invocations) { composer.pattern_template_invocations }
@@ -233,8 +219,7 @@ describe JobInvocationComposer do
233
219
  trying_job_template_1.id.to_s => {
234
220
  :effective_user => invocation_effective_user
235
221
  }
236
- }
237
- }
222
+ }}
238
223
  end
239
224
  let(:params) { { :job_invocation => { :providers => { :ssh => ssh_params } } }.with_indifferent_access }
240
225
  let(:template_invocation) do
@@ -382,7 +367,8 @@ describe JobInvocationComposer do
382
367
  :job_templates => {
383
368
  trying_job_template_1.id.to_s => {
384
369
  :input_values => { }
385
- } } }
370
+ }
371
+ } }
386
372
  end
387
373
  let(:params) { { :job_invocation => { :providers => { :ssh => ssh_params } } }.with_indifferent_access }
388
374
 
@@ -398,7 +384,8 @@ describe JobInvocationComposer do
398
384
  :job_templates => {
399
385
  trying_job_template_1.id.to_s => {
400
386
  :input_values => { input1.id.to_s => { :value => 'value1' } }
401
- } } }
387
+ }
388
+ } }
402
389
  end
403
390
  let(:params) { { :job_invocation => { :providers => { :ssh => ssh_params } } }.with_indifferent_access }
404
391
 
@@ -415,7 +402,8 @@ describe JobInvocationComposer do
415
402
  :job_templates => {
416
403
  trying_job_template_1.id.to_s => {
417
404
  :input_values => { input1.id.to_s => { :value => 'value1' } }
418
- } } }
405
+ }
406
+ } }
419
407
  end
420
408
  let(:params) do
421
409
  { :job_invocation => { :providers => { :ssh => ssh_params } }, :targeting => { :search_query => "name = #{host.name}" } }.with_indifferent_access
@@ -496,16 +484,15 @@ describe JobInvocationComposer do
496
484
  :job_templates => {
497
485
  trying_job_template_1.id.to_s => {
498
486
  :input_values => { input1.id.to_s => { :value => 'value1' } }
499
- } } }
487
+ }
488
+ } }
500
489
  end
501
490
  let(:params) do
502
491
  {
503
492
  :job_invocation => {
504
493
  :providers => { :ssh => ssh_params },
505
- :concurrency_control => {
506
- :level => 5,
507
- :time_span => 60
508
- }
494
+ :concurrency_level => 5,
495
+ :time_span => 60,
509
496
  },
510
497
  :targeting => {
511
498
  :search_query => "name = #{host.name}",
@@ -525,6 +512,11 @@ describe JobInvocationComposer do
525
512
  new_composer.job_category.must_equal existing.job_category
526
513
  end
527
514
 
515
+ it 'accepts additional host ids' do
516
+ new_composer = JobInvocationComposer.from_job_invocation(composer.job_invocation, { :host_ids => [host.id] })
517
+ new_composer.search_query.must_equal("name ^ (#{host.name})")
518
+ end
519
+
528
520
  it 'builds new targeting object which keeps search query' do
529
521
  new_composer.targeting.wont_equal existing.targeting
530
522
  new_composer.search_query.must_equal existing.targeting.search_query
@@ -1,7 +1,6 @@
1
1
  require 'test_plugin_helper'
2
2
 
3
- describe JobInvocation do
4
-
3
+ class JobInvocationTest < ActiveSupport::TestCase
5
4
  let(:job_invocation) { FactoryGirl.build(:job_invocation) }
6
5
  let(:template) { FactoryGirl.create(:job_template, :with_input) }
7
6
 
@@ -1,6 +1,6 @@
1
1
  require 'test_plugin_helper'
2
2
 
3
- describe JobTemplateEffectiveUser do
3
+ class JobTemplateEffectiveUserTest < ActiveSupport::TestCase
4
4
  let(:job_template) { FactoryGirl.build(:job_template, :job_category => '') }
5
5
  let(:effective_user) { job_template.effective_user }
6
6
 
@@ -1,6 +1,6 @@
1
1
  require 'test_plugin_helper'
2
2
 
3
- describe JobTemplateImporter do
3
+ class JobTemplateImporterTest < ActiveSupport::TestCase
4
4
  context 'importing a new template' do
5
5
  # JobTemplate tests handle most of this, we just check that the shim
6
6
  # correctly loads a template returns a hash
@@ -9,40 +9,58 @@ describe JobTemplateImporter do
9
9
  end
10
10
 
11
11
  let(:result) do
12
- name = "Community Service Restart"
12
+ name = 'Community Service Restart'
13
+ metadata = {
14
+ 'model' => 'JobTemplate',
15
+ 'kind' => 'job_template',
16
+ 'name' => 'Service Restart',
17
+ 'job_category' => 'Service Restart',
18
+ 'provider_type' => 'SSH',
19
+ 'feature' => remote_execution_feature.label,
20
+ 'template_inputs' => [
21
+ { 'name' => 'service_name', 'input_type' => 'user', 'required' => true },
22
+ { 'name' => 'verbose', 'input_type' => 'user' }
23
+ ]
24
+ }
13
25
  text = <<-END_TEMPLATE
14
26
  <%#
15
- model: JobTemplateImporter
16
- kind: job_template
17
- name: Service Restart
18
- job_category: Service Restart
19
- provider_type: SSH
20
- feature: #{remote_execution_feature.label}
21
- template_inputs:
22
- - name: service_name
23
- input_type: user
24
- required: true
25
- - name: verbose
26
- input_type: user
27
+ #{YAML.dump(metadata)}
27
28
  %>
28
29
 
29
30
  service <%= input("service_name") %> restart
30
31
  END_TEMPLATE
31
32
 
32
- # This parameter is unused but foreman_templates will supply it
33
- # so we test it's accepted
34
- metadata = "unused"
35
-
36
33
  JobTemplateImporter.import!(name, text, metadata)
37
34
  end
38
35
 
39
- let(:template) { JobTemplate.find_by_name 'Community Service Restart' }
36
+ let(:template) { JobTemplate.find_by name: 'Community Service Restart' }
40
37
 
41
38
  it 'returns a valid foreman_templates hash' do
42
39
  result[:status].must_equal true
43
40
  result[:result].must_equal ' Created Template :Community Service Restart'
44
- result[:old].must_equal nil
41
+ result[:old].must_be_nil
45
42
  result[:new].must_equal template.template.squish
46
43
  end
47
44
  end
45
+
46
+ context 'updating locked template' do
47
+ it 'does not update locked template' do
48
+ name = 'Locked job template'
49
+ template = FactoryGirl.create(:job_template, :locked => true, :name => name)
50
+ res = JobTemplateImporter.import!(name, 'some text', 'metadata')
51
+ assert_equal "Skipping Template #{template.id}:#{template.name} - template is locked", res[:result]
52
+ end
53
+
54
+ it 'updates locked template' do
55
+ name = 'Locked job template again'
56
+ metadata = {
57
+ 'model' => 'JobTemplate',
58
+ 'kind' => 'job_template',
59
+ 'name' => name
60
+ }
61
+ template = FactoryGirl.create(:job_template, :locked => true, :name => name)
62
+ res = JobTemplateImporter.import!(name, 'some text', metadata, true)
63
+ assert_equal " Updated Template #{template.id}:Locked job template again", res[:result]
64
+ end
65
+ end
48
66
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_plugin_helper'
2
2
 
3
- describe JobTemplate do
3
+ class JobTemplateTest < ActiveSupport::TestCase
4
4
  context 'when creating a template' do
5
5
  let(:job_template) { FactoryGirl.build(:job_template, :job_category => '') }
6
6
  let(:template_with_inputs) do
@@ -96,7 +96,7 @@ describe JobTemplate do
96
96
  service <%= input("service_name") %> restart
97
97
  END_TEMPLATE
98
98
 
99
- JobTemplate.import!(template, :default => true)
99
+ JobTemplate.import_raw!(template, :default => true)
100
100
  end
101
101
 
102
102
  let(:template_with_input_sets) do
@@ -114,7 +114,7 @@ describe JobTemplate do
114
114
  service <%= input("service_name") %> restart
115
115
  END_TEMPLATE
116
116
 
117
- JobTemplate.import!(template_with_input_sets, :default => true)
117
+ JobTemplate.import_raw!(template_with_input_sets, :default => true)
118
118
  end
119
119
 
120
120
  it 'sets the name' do
@@ -162,7 +162,7 @@ describe JobTemplate do
162
162
  echo input(:banner_message)
163
163
  END_TEMPLATE
164
164
 
165
- JobTemplate.import!(template, :default => true)
165
+ JobTemplate.import_raw!(template, :default => true)
166
166
  end
167
167
 
168
168
  let(:existing) do
@@ -184,7 +184,7 @@ describe JobTemplate do
184
184
  ping -c 5 <%= input("hostname") %>
185
185
  END_TEMPLATE
186
186
 
187
- JobTemplate.import!(template, :default => true)
187
+ JobTemplate.import_raw!(template, :default => true)
188
188
  end
189
189
 
190
190
  let(:updated) do
@@ -213,12 +213,12 @@ describe JobTemplate do
213
213
 
214
214
  it 'will not overwrite by default' do
215
215
  existing
216
- refute JobTemplate.import!(updated)
216
+ refute JobTemplate.import_raw!(updated)
217
217
  end
218
218
 
219
219
  let(:synced_template) do
220
220
  existing
221
- JobTemplate.import!(updated, :update => true)
221
+ JobTemplate.import_raw!(updated, :update => true)
222
222
  existing.reload
223
223
  end
224
224
 
@@ -263,7 +263,7 @@ describe JobTemplate do
263
263
  old_name = exportable_template.name
264
264
  exportable_template.update_attributes(:name => "#{old_name}_renamed")
265
265
 
266
- imported = JobTemplate.import!(erb)
266
+ imported = JobTemplate.import_raw!(erb)
267
267
  imported.name.must_equal old_name
268
268
  imported.template_inputs.first.to_export.must_equal exportable_template.template_inputs.first.to_export
269
269
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_plugin_helper'
2
2
 
3
- describe RemoteExecutionFeature do
3
+ class RemoteExecutionFeatureTest < ActiveSupport::TestCase
4
4
  should validate_presence_of(:name)
5
5
  should validate_presence_of(:label)
6
6
  should validate_uniqueness_of(:name)
@@ -40,10 +40,10 @@ describe RemoteExecutionFeature do
40
40
  input_value.value.must_equal 'zsh'
41
41
  input_value.template_input.name.must_equal 'package'
42
42
 
43
- composer.targeting.search_query.must_equal "name = #{host.name}"
43
+ composer.targeting.search_query.must_equal "name ^ (#{host.name})"
44
44
  end
45
45
 
46
- it "updates the feature when attributes change" do
46
+ it 'updates the feature when attributes change' do
47
47
  updated_feature = RemoteExecutionFeature.register(install_feature.label, N_('Katello: Install package'),
48
48
  :description => 'New description',
49
49
  :provided_inputs => ['package', 'force'])
@@ -63,19 +63,19 @@ describe RemoteExecutionFeature do
63
63
  refute feature.host_action_button
64
64
  end
65
65
 
66
- it "creates a feature with host action flag" do
66
+ it 'creates a feature with host action flag' do
67
67
  feature = RemoteExecutionFeature.register('new_feature_that_does_not_exist_button', 'name', :host_action_button => true)
68
68
  feature.must_be :persisted?
69
69
  assert feature.host_action_button
70
70
  end
71
71
 
72
- it "created feature with host action flag can be found using named scope" do
72
+ it 'created feature with host action flag can be found using named scope' do
73
73
  feature = RemoteExecutionFeature.register('new_feature_that_does_not_exist_button', 'name', :host_action_button => true)
74
74
  assert_includes RemoteExecutionFeature.with_host_action_button, feature
75
75
  end
76
76
 
77
77
 
78
- it "updates a feature if it exists" do
78
+ it 'updates a feature if it exists' do
79
79
  existing = FactoryGirl.create(:remote_execution_feature, :name => 'existing_feature_withou_action_button')
80
80
  feature = RemoteExecutionFeature.register(existing.label, existing.name, :host_action_button => true)
81
81
  feature.must_be :persisted?