hammer_cli_foreman 0.10.2 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/config/foreman.yml +4 -0
  3. data/doc/release_notes.md +21 -5
  4. data/lib/hammer_cli_foreman/api/connection.rb +14 -5
  5. data/lib/hammer_cli_foreman/api/interactive_basic_auth.rb +17 -5
  6. data/lib/hammer_cli_foreman/api/session_authenticator_wrapper.rb +27 -8
  7. data/lib/hammer_cli_foreman/auth.rb +14 -10
  8. data/lib/hammer_cli_foreman/auth_source_ldap.rb +38 -34
  9. data/lib/hammer_cli_foreman/compute_resource.rb +24 -0
  10. data/lib/hammer_cli_foreman/filter.rb +6 -2
  11. data/lib/hammer_cli_foreman/host.rb +2 -7
  12. data/lib/hammer_cli_foreman/hostgroup.rb +1 -0
  13. data/lib/hammer_cli_foreman/id_resolver.rb +27 -7
  14. data/lib/hammer_cli_foreman/location.rb +1 -0
  15. data/lib/hammer_cli_foreman/organization.rb +1 -0
  16. data/lib/hammer_cli_foreman/references.rb +10 -2
  17. data/lib/hammer_cli_foreman/smart_class_parameter.rb +10 -1
  18. data/lib/hammer_cli_foreman/smart_variable.rb +24 -16
  19. data/lib/hammer_cli_foreman/subnet.rb +33 -3
  20. data/lib/hammer_cli_foreman/template.rb +1 -1
  21. data/lib/hammer_cli_foreman/testing/api_expectations.rb +3 -1
  22. data/lib/hammer_cli_foreman/user.rb +37 -3
  23. data/lib/hammer_cli_foreman/version.rb +1 -1
  24. data/locale/ca/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  25. data/locale/de/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  26. data/locale/en/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  27. data/locale/en_GB/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  28. data/locale/es/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  29. data/locale/fr/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  30. data/locale/it/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  31. data/locale/ja/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  32. data/locale/ko/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  33. data/locale/pt_BR/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  34. data/locale/ru/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  35. data/locale/zh_CN/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  36. data/locale/zh_TW/LC_MESSAGES/hammer-cli-foreman.mo +0 -0
  37. data/test/functional/filter_test.rb +146 -0
  38. data/test/functional/host_test.rb +12 -0
  39. data/test/functional/smart_variable_test.rb +4 -4
  40. data/test/functional/template_test.rb +20 -0
  41. data/test/functional/user_test.rb +13 -13
  42. data/test/unit/api/interactive_basic_auth_test.rb +18 -0
  43. data/test/unit/api/session_authenticator_wrapper_test.rb +72 -2
  44. data/test/unit/apipie_resource_mock.rb +3 -0
  45. data/test/unit/auth_source_ldap_test.rb +2 -3
  46. data/test/unit/commands_test.rb +1 -1
  47. data/test/unit/compute_resource_test.rb +24 -0
  48. data/test/unit/host_test.rb +1 -1
  49. data/test/unit/hostgroup_test.rb +1 -1
  50. data/test/unit/id_resolver_test.rb +59 -21
  51. data/test/unit/subnet_test.rb +1 -0
  52. data/test/unit/user_test.rb +7 -1
  53. metadata +35 -33
@@ -6,6 +6,18 @@ describe "host create" do
6
6
  let(:minimal_params_without_hosgroup) { ['--location-id=1', '--organization-id=1', '--name=test'] }
7
7
  let(:minimal_params) { ['--hostgroup-id=1'] + minimal_params_without_hosgroup }
8
8
 
9
+ it "accepts hostgroup title" do
10
+ api_expects_search(:hostgroups, { :title => 'test/hg1' }).returns(index_response([{ 'id' => '83' }]))
11
+ api_expects(:hosts, :create, 'Create host with interfaces params') do |par|
12
+ par['host']['hostgroup_id'] == '83'
13
+ end.returns({})
14
+
15
+ expected_result = success_result("Host created\n")
16
+
17
+ result = run_cmd(cmd + minimal_params_without_hosgroup + ['--hostgroup-title=test/hg1'])
18
+ assert_cmd(expected_result, result)
19
+ end
20
+
9
21
  it "passes interface attributes to server" do
10
22
  params = ['--interface', 'identifier=eth0,ip=10.0.0.4,primary=true,provision=true']
11
23
 
@@ -3,13 +3,13 @@ require File.join(File.dirname(__FILE__), 'test_helper')
3
3
  describe 'smart-variable update' do
4
4
  let(:cmd) { %w(smart-variable update) }
5
5
 
6
- it 'allows to save new name' do
7
- params = ['--id=1', '--new-variable=name2']
6
+ it 'allows to save new name and override value order' do
7
+ params = ['--id=1', '--new-variable=name2', '--override-value-order=\'fqdn\',\'hostgroup\',\'domain\',\'os\'']
8
8
 
9
9
  expected_result = success_result("Smart variable [name2] updated\n")
10
10
 
11
11
  api_expects(:smart_variables, :update, 'Update the variable') do |par|
12
- par['smart_variable']['variable'] == 'name2'
12
+ (par['smart_variable']['variable'] == 'name2') && (par['smart_variable']['override_value_order'] == "fqdn\nhostgroup\ndomain\nos")
13
13
  end.returns(
14
14
  'description' => '',
15
15
  'parameter_type' => 'string',
@@ -18,7 +18,7 @@ describe 'smart-variable update' do
18
18
  'hidden_value' => '*****',
19
19
  'validator_type' => '',
20
20
  'validator_rule' => nil,
21
- 'override_value_order' => 'fqdn\nhostgroup\nos\ndomain',
21
+ 'override_value_order' => 'fqdn\nhostgroup\ndomain\nos',
22
22
  'merge_overrides' => false,
23
23
  'merge_default' => false,
24
24
  'avoid_duplicates' => false,
@@ -77,4 +77,24 @@ describe 'template' do
77
77
  assert_cmd(success_result("Provisioning template cloned\n"), result)
78
78
  end
79
79
  end
80
+
81
+ describe 'update' do
82
+ before do
83
+ @cmd = %w(template update)
84
+ end
85
+
86
+ it "doesn't send snippet flag when --type is undefined" do
87
+ params = ['--id=1', '--locked=true']
88
+
89
+ api_expects(:template_kinds, :index, 'Get list of template kinds').returns(index_response([]))
90
+ api_expects(:config_templates, :update, 'Update the template') do |par|
91
+ par['config_template']['locked'] == true &&
92
+ par['config_template']['snippet'].nil?
93
+ end.returns(:name => 'A', :value => '1')
94
+
95
+ result = run_cmd(@cmd + params)
96
+
97
+ assert_cmd(success_result("Provisioning template updated\n"), result)
98
+ end
99
+ end
80
100
  end
@@ -2,17 +2,17 @@ require File.join(File.dirname(__FILE__), 'test_helper')
2
2
 
3
3
  describe "user" do
4
4
  let(:minimal_params) { ['--login', 'jane', '--mail', 'jane@test.org', '--password', 'secret', '--auth-source-id', '1'] }
5
+ let(:update_params) { ['--login', 'jane'] }
5
6
  let(:user) { { 'id' => '32', 'login' => 'jane' } }
6
7
 
7
8
  def expect_with_minimal_params(action, message, &block)
8
- api_expects(:users, action, message) do |par|
9
- user = par['user']
10
- user['login'] == 'jane' &&
11
- user['mail'] == 'jane@test.org' &&
12
- user['password'] == 'secret' &&
13
- user['auth_source_id'] == '1' &&
14
- yield(par)
15
- end
9
+ api_expects(:users, action, message).with_params({
10
+ 'user' => {'login' => 'jane', 'mail' => 'jane@test.org', 'password' => 'secret', 'auth_source_id' => '1'}})
11
+ end
12
+
13
+ def expect_with_update_params(action, message, &block)
14
+ api_expects(:users, action, message).with_params({
15
+ 'user' => {'login' => 'jane'}})
16
16
  end
17
17
 
18
18
  describe "create" do
@@ -55,14 +55,14 @@ describe "user" do
55
55
 
56
56
  api_expects_search(:users, { :login => 'jane' }).returns(index_response([user]))
57
57
  api_expects_search(:organizations, { :name => 'Org1' }).returns(index_response([{ 'id' => '3' }]))
58
- expect_with_minimal_params(:update, 'Update user with default org') do |par|
58
+ expect_with_update_params(:update, 'Update user with default org') do |par|
59
59
  par['id'] == '32' &&
60
60
  par['user']['default_organization_id'] == '3'
61
61
  end.returns(user)
62
-
63
62
  expected_result = success_result("User [jane] updated\n")
64
63
 
65
- result = run_cmd(cmd + minimal_params + params)
64
+ result = run_cmd(cmd + update_params + params)
65
+
66
66
  assert_cmd(expected_result, result)
67
67
  end
68
68
 
@@ -71,14 +71,14 @@ describe "user" do
71
71
 
72
72
  api_expects_search(:users, { :login => 'jane' }).returns(index_response([user]))
73
73
  api_expects_search(:locations, { :name => 'Loc1' }).returns(index_response([{ 'id' => '4' }]))
74
- expect_with_minimal_params(:update, 'Update user with default loc') do |par|
74
+ expect_with_update_params(:update, 'Update user with default loc') do |par|
75
75
  par['id'] == '32' &&
76
76
  par['user']['default_location_id'] == '4'
77
77
  end.returns(user)
78
78
 
79
79
  expected_result = success_result("User [jane] updated\n")
80
80
 
81
- result = run_cmd(cmd + minimal_params + params)
81
+ result = run_cmd(cmd + update_params + params)
82
82
  assert_cmd(expected_result, result)
83
83
  end
84
84
  end
@@ -83,4 +83,22 @@ describe HammerCLIForeman::Api::InteractiveBasicAuth do
83
83
  assert_nil new_ex
84
84
  end
85
85
  end
86
+
87
+ describe '#set_credentials' do
88
+ let(:auth) { HammerCLIForeman::Api::InteractiveBasicAuth.new(nil, nil) }
89
+
90
+ it 'sets username and password' do
91
+ auth.set_credentials('admin', 'password')
92
+ assert_equal 'admin', auth.user
93
+ end
94
+ end
95
+
96
+ describe '#clear' do
97
+ let(:auth) { HammerCLIForeman::Api::InteractiveBasicAuth.new('user', 'password') }
98
+
99
+ it 'clears username and password' do
100
+ auth.clear
101
+ assert_nil auth.user
102
+ end
103
+ end
86
104
  end
@@ -96,13 +96,14 @@ describe HammerCLIForeman::Api::SessionAuthenticatorWrapper do
96
96
  end
97
97
  end
98
98
 
99
- it "drops the session when usernames don't match" do
99
+ it "keeps the session and sets cuser_changed flag when usernames don't match and " do
100
100
  prepare_session_storage :session_id => 'SOME_SESSION_ID' do |auth, dir|
101
101
  wrapped_auth.expects(:authenticate).with(request, args)
102
102
  wrapped_auth.expects(:user).returns('other_user')
103
103
  auth.authenticate(request, args)
104
104
 
105
- refute File.exist?(session_file(dir))
105
+ assert File.exist?(session_file(dir))
106
+ assert auth.user_changed?
106
107
  end
107
108
  end
108
109
 
@@ -194,6 +195,28 @@ describe HammerCLIForeman::Api::SessionAuthenticatorWrapper do
194
195
  assert File.exist?(session_file(dir))
195
196
  end
196
197
  end
198
+
199
+ context 'when user has changed' do
200
+ it 'sets a special error message' do
201
+ prepare_session_storage :session_id => 'SOME_SESSION_ID' do |auth, dir|
202
+ auth.force_user_change
203
+ ex = RestClient::Unauthorized.new
204
+ new_ex = auth.error(ex)
205
+
206
+ assert_equal "Invalid username or password, continuing with session for 'admin'", new_ex.message
207
+ end
208
+ end
209
+
210
+ it 'keeps the previous session' do
211
+ prepare_session_storage :session_id => 'SOME_SESSION_ID' do |auth, dir|
212
+ auth.force_user_change
213
+ ex = RestClient::Unauthorized.new
214
+ auth.error(ex)
215
+
216
+ assert File.exist?(session_file(dir))
217
+ end
218
+ end
219
+ end
197
220
  end
198
221
 
199
222
  context 'when there is no existing session' do
@@ -284,4 +307,51 @@ describe HammerCLIForeman::Api::SessionAuthenticatorWrapper do
284
307
  end
285
308
  end
286
309
  end
310
+
311
+ describe '#user_changed?' do
312
+ it 'is false by default' do
313
+ prepare_session_storage do |auth, dir|
314
+ refute auth.user_changed?
315
+ end
316
+ end
317
+ end
318
+
319
+ describe '#force_user_change' do
320
+ it 'sets force user change flag' do
321
+ prepare_session_storage do |auth, dir|
322
+ auth.force_user_change
323
+ assert auth.user_changed?
324
+ end
325
+ end
326
+ end
327
+
328
+ describe '#set_credentials' do
329
+ it 'passes credentials to a wrapped authenticator' do
330
+ prepare_session_storage do |auth, dir|
331
+ wrapped_auth.expects(:set_credentials).with('admin', 'password')
332
+ auth.set_credentials('admin', 'password')
333
+ end
334
+ end
335
+
336
+ it "doesn't pass the credentials when a wrapped autneticator doesn't support it" do
337
+ prepare_session_storage do |auth, dir|
338
+ auth.set_credentials('admin', 'password')
339
+ end
340
+ end
341
+ end
342
+
343
+ describe '#clear' do
344
+ it 'passes clear to a wrapped authenticator' do
345
+ prepare_session_storage do |auth, dir|
346
+ wrapped_auth.expects(:clear)
347
+ auth.clear
348
+ end
349
+ end
350
+
351
+ it "doesn't pass clear when a wrapped autneticator doesn't support it" do
352
+ prepare_session_storage do |auth, dir|
353
+ auth.clear
354
+ end
355
+ end
356
+ end
287
357
  end
@@ -41,6 +41,9 @@ module ResourceMocks
41
41
  ResourceMocks.mock_action_call(:compute_resources, :available_images, [])
42
42
  end
43
43
 
44
+ def self.compute_resources_available_networks
45
+ ResourceMocks.mock_action_call(:compute_resources, :available_networks, [])
46
+ end
44
47
 
45
48
  def self.organizations_index
46
49
  ResourceMocks.mock_action_call(:organizations, :index, {
@@ -28,7 +28,7 @@ describe HammerCLIForeman::AuthSourceLdap do
28
28
  it_should_print_column "Id"
29
29
  it_should_print_column "LDAPS\\?"
30
30
  it_should_print_column "Port"
31
- it_should_print_column "Server Type"
31
+ it_should_print_column "Server"
32
32
  end
33
33
 
34
34
  end
@@ -47,8 +47,7 @@ describe HammerCLIForeman::AuthSourceLdap do
47
47
  context "output" do
48
48
  with_params ["--id=1"] do
49
49
  it_should_print_n_records 1
50
- it_should_print_column "Name"
51
- it_should_print_column "Id"
50
+ it_should_print_columns ["Server", "Account", "Attribute mappings", "Locations", "Organizations"]
52
51
  end
53
52
  end
54
53
 
@@ -160,7 +160,7 @@ describe HammerCLIForeman::Command do
160
160
  out, err = capture_io do
161
161
  com.run(['--location', 'loc']).wont_equal HammerCLI::EX_OK
162
162
  end
163
- err.must_equal "Error: Could not find location, please set one of options --location, --location-id.\n"
163
+ err.must_equal "Error: Could not find location, please set one of options --location, --location-title, --location-id.\n"
164
164
 
165
165
  end
166
166
 
@@ -94,5 +94,29 @@ describe HammerCLIForeman::ComputeResource do
94
94
 
95
95
  end
96
96
 
97
+ context "AvailableNetworksCommand" do
98
+ before do
99
+ ResourceMocks.compute_resources_available_networks
100
+ end
101
+
102
+ let(:cmd) { HammerCLIForeman::ComputeResource::AvailableNetworksCommand.new("", ctx) }
103
+
104
+ context "parameters" do
105
+ it_should_accept "id", ["--id=1"]
106
+ it_should_accept "name", ["--name=arch"]
107
+ # it_should_fail_with "no params", [] # TODO: temporarily disabled, parameters are checked in the id resolver
108
+ # it_should_fail_with "name or id missing", ["--new-name=arch2"] # TODO: temporarily disabled, parameters are checked in the id resolver
109
+ end
110
+
111
+ context "output" do
112
+ let(:expected_record_count) { count_records(cmd.resource.call(:available_networks)) }
113
+
114
+ with_params ["--name=testcr"] do
115
+ it_should_print_n_records
116
+ it_should_print_columns ["Name", "Id"]
117
+ end
118
+ end
119
+
120
+ end
97
121
 
98
122
  end
@@ -48,7 +48,7 @@ describe HammerCLIForeman::Host do
48
48
  it_should_print_columns ["Host Group", "Compute Resource", "Compute Profile", "Environment"]
49
49
  it_should_print_columns ["Puppet CA Id", "Puppet Master Id", "Cert name"]
50
50
  it_should_print_columns ["Managed", "Installed at", "Last report"]
51
- it_should_print_columns ["Network", "Network interfaces", "Operating system", "Parameters", "Additional info"]
51
+ it_should_print_columns ["Network", "Network interfaces", "Operating system", "Parameters", "All parameters", "Additional info"]
52
52
  end
53
53
  end
54
54
 
@@ -43,7 +43,7 @@ describe HammerCLIForeman::Hostgroup do
43
43
  it_should_print_n_records 1
44
44
  it_should_print_columns ["Id", "Name", "Title", "Operating System", "Subnet"]
45
45
  it_should_print_columns ["Domain", "Environment", "Puppetclasses", "Parent Id"]
46
- it_should_print_columns ["Parameters"]
46
+ it_should_print_columns ["Parameters", "Description"]
47
47
  end
48
48
  end
49
49
 
@@ -62,6 +62,10 @@ describe HammerCLIForeman::IdResolver do
62
62
 
63
63
 
64
64
  describe "resolving ids" do
65
+ let(:john_id) { 11 }
66
+ let(:john) { {"id" => john_id, "name" => "John Doe"} }
67
+ let(:jane_id) { 22 }
68
+ let(:jane) { {"id" => jane_id, "name" => "Jane Doe"} }
65
69
 
66
70
  it "must define methods for all resources" do
67
71
  expected_method_names = api.resources.map(&:singular_name).collect{|r| "#{r}_id"}
@@ -93,10 +97,7 @@ describe HammerCLIForeman::IdResolver do
93
97
  end
94
98
 
95
99
  it "raises exception when multiple resources are found" do
96
- ResourceMocks.mock_action_call(:users, :index, [
97
- {"id" => 11, "name" => "user11"},
98
- {"id" => 22, "name" => "user22"}
99
- ])
100
+ ResourceMocks.mock_action_call(:users, :index, [john, jane])
100
101
 
101
102
  err = resolver_run.must_raise HammerCLIForeman::ResolverError
102
103
  err.message.must_equal "found more than one user"
@@ -107,7 +108,7 @@ describe HammerCLIForeman::IdResolver do
107
108
  ( resource == :users &&
108
109
  action == :index &&
109
110
  params[:search] == "name = \"John Doe\"")
110
- end.returns({"id" => 1, "name" => "John Doe"})
111
+ end.returns(john)
111
112
 
112
113
  resolver_run.call
113
114
  end
@@ -119,17 +120,15 @@ describe HammerCLIForeman::IdResolver do
119
120
  end
120
121
 
121
122
  it "returns id of the resource" do
122
- ResourceMocks.mock_action_call(:users, :index, [
123
- {"id" => 11, "name" => "John Doe"}
124
- ])
123
+ ResourceMocks.mock_action_call(:users, :index, [john])
125
124
 
126
- resolver_run.call.must_equal 11
125
+ resolver_run.call.must_equal john_id
127
126
  end
128
127
 
129
128
  end
130
129
 
131
130
  describe "searching dependent resources" do
132
- let(:resolver_run) { proc { resolver.post_id({"option_name" => "Post 11", "option_user_name" => "User 22"}) } }
131
+ let(:resolver_run) { proc { resolver.post_id({"option_name" => "Post 11", "option_user_name" => "John Doe"}) } }
133
132
 
134
133
  it "raises exception when no resource is found" do
135
134
  ResourceMocks.mock_action_call(:posts, :index, [])
@@ -141,10 +140,7 @@ describe HammerCLIForeman::IdResolver do
141
140
 
142
141
  it "raises exception when multiple resources are found" do
143
142
  ResourceMocks.mock_action_call(:posts, :index, [])
144
- ResourceMocks.mock_action_call(:users, :index, [
145
- {"id" => 11, "name" => "user1"},
146
- {"id" => 22, "name" => "user2"}
147
- ])
143
+ ResourceMocks.mock_action_call(:users, :index, [john, jane])
148
144
 
149
145
  err = resolver_run.must_raise HammerCLIForeman::ResolverError
150
146
  err.message.must_equal "found more than one user"
@@ -154,8 +150,8 @@ describe HammerCLIForeman::IdResolver do
154
150
  ApipieBindings::API.any_instance.expects(:call).with() do |resource, action, params, headers, opts|
155
151
  ( resource == :users &&
156
152
  action == :index &&
157
- params[:search] == "name = \"User 22\"")
158
- end.returns({"id" => 22, "name" => "User 22"})
153
+ params[:search] == "name = \"John Doe\"")
154
+ end.returns(john)
159
155
 
160
156
  ApipieBindings::API.any_instance.expects(:call).with() do |resource, action, params, headers, opts|
161
157
  ( resource == :posts &&
@@ -178,9 +174,7 @@ describe HammerCLIForeman::IdResolver do
178
174
  end
179
175
 
180
176
  describe 'searching for puppetclasses' do
181
- let(:resolver_run) { proc { resolver.puppetclass_ids('option_names' => ['apache::mod::authnz_ldap', 'git::params', 'apache::dev']) } }
182
-
183
- it "returns ids of the classes" do
177
+ before do
184
178
  ResourceMocks.mock_action_call(:puppetclasses, :index, {
185
179
  'apache' => [
186
180
  { 'id' => 70, 'name' => 'apache::dev', 'created_at' => '2015-01-27T07:24:57.134Z', 'updated_at' => '2015-03-05T17:27:54.282Z' },
@@ -188,9 +182,53 @@ describe HammerCLIForeman::IdResolver do
188
182
  ],
189
183
  'git' => [
190
184
  { 'id' => 85, 'name' => 'git::params', 'created_at' => '2015-01-27T07:24:57.306Z', 'updated_at' => '2015-01-27T07:24:57.306Z' }
191
- ] })
185
+ ]
186
+ })
187
+ end
188
+
189
+ it "returns ids from options" do
190
+ result = resolver.user_ids({"option_ids" => [4, 5], "option_names" => ['apache::dev']})
191
+ assert_equal [4, 5], result
192
+ end
193
+
194
+ it "returns ids of the classes" do
195
+ class_names = ['apache::mod::authnz_ldap', 'git::params', 'apache::dev']
196
+ assert_equal [70, 27, 85], resolver.puppetclass_ids('option_names' => class_names)
197
+ end
198
+
199
+ it 'returns empty array for empty class array' do
200
+ assert_equal [], resolver.puppetclass_ids('option_names' => [])
201
+ end
202
+ end
203
+
204
+ describe "searching for multiple resources" do
205
+ it "returns ids from options" do
206
+ result = resolver.user_ids({"option_ids" => [4, 5], "option_names" => ["some", "names"]})
207
+ assert_equal [4, 5], result
208
+ end
209
+
210
+ it "finds multiple ids" do
211
+ ApipieBindings::API.any_instance.expects(:call).with() do |resource, action, params, headers, opts|
212
+ ( resource == :users &&
213
+ action == :index &&
214
+ params[:search] == "name = \"John Doe\" or name = \"Jane Doe\"")
215
+ end.returns([john, jane])
216
+
217
+ assert_equal [john_id, jane_id], resolver.user_ids({"option_names" => ["John Doe", "Jane Doe"]})
218
+ end
219
+
220
+ it "raises exception when wrong number of resources is found" do
221
+ ResourceMocks.mock_action_call(:users, :index, [john])
222
+
223
+ assert_raises HammerCLIForeman::ResolverError do
224
+ resolver.user_ids({"option_names" => ["John Doe", "Jane Doe"]})
225
+ end
226
+ end
227
+
228
+ it "returns empty array for empty input" do
229
+ ResourceMocks.mock_action_call(:users, :index, [john, jane])
192
230
 
193
- resolver_run.call.must_equal [70, 27, 85]
231
+ assert_equal [], resolver.user_ids({"option_names" => []})
194
232
  end
195
233
  end
196
234
  end