rhc 1.5.13 → 1.6.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/features/application.feature +1 -1
  2. data/features/cartridge.feature +10 -9
  3. data/features/geared_application.feature +3 -6
  4. data/features/lib/rhc_helper/app.rb +2 -2
  5. data/features/multiple_cartridge.feature +9 -8
  6. data/features/scaled_application.feature +5 -5
  7. data/features/step_definitions/application_steps.rb +4 -3
  8. data/features/step_definitions/cartridge_steps.rb +8 -1
  9. data/features/support/before_hooks.rb +12 -6
  10. data/features/support/env.rb +8 -1
  11. data/features/support/platform_support.rb +29 -0
  12. data/lib/rhc/command_runner.rb +33 -21
  13. data/lib/rhc/commands/account.rb +1 -1
  14. data/lib/rhc/commands/alias.rb +90 -7
  15. data/lib/rhc/commands/app.rb +15 -11
  16. data/lib/rhc/commands/cartridge.rb +9 -2
  17. data/lib/rhc/exceptions.rb +6 -0
  18. data/lib/rhc/helpers.rb +3 -0
  19. data/lib/rhc/output_helpers.rb +12 -3
  20. data/lib/rhc/rest.rb +3 -0
  21. data/lib/rhc/rest/alias.rb +50 -0
  22. data/lib/rhc/rest/application.rb +26 -2
  23. data/lib/rhc/rest/cartridge.rb +16 -1
  24. data/lib/rhc/rest/client.rb +24 -4
  25. data/lib/rhc/rest/mock.rb +66 -2
  26. data/lib/rhc/ssh_helpers.rb +2 -3
  27. data/lib/rhc/wizard.rb +6 -3
  28. data/spec/rhc/assets/cert.crt +22 -0
  29. data/spec/rhc/assets/cert_key_rsa +27 -0
  30. data/spec/rhc/assets/empty.txt +0 -0
  31. data/spec/rhc/cli_spec.rb +5 -0
  32. data/spec/rhc/commands/account_spec.rb +6 -6
  33. data/spec/rhc/commands/alias_spec.rb +179 -5
  34. data/spec/rhc/commands/app_spec.rb +2 -1
  35. data/spec/rhc/commands/authorization_spec.rb +9 -0
  36. data/spec/rhc/commands/cartridge_spec.rb +27 -0
  37. data/spec/rhc/commands/setup_spec.rb +2 -0
  38. data/spec/rhc/commands/sshkey_spec.rb +20 -1
  39. data/spec/rhc/helpers_spec.rb +1 -2
  40. data/spec/rhc/rest_client_spec.rb +26 -5
  41. data/spec/rhc/wizard_spec.rb +22 -0
  42. data/spec/spec_helper.rb +25 -2
  43. data/spec/wizard_spec_helper.rb +1 -1
  44. metadata +153 -144
@@ -122,7 +122,7 @@ module RHC
122
122
  error e.message
123
123
  nil
124
124
  rescue => e
125
- error e.message
125
+ debug e.message
126
126
  nil
127
127
  end
128
128
 
@@ -135,13 +135,12 @@ module RHC
135
135
  # which is basically the space-separated list of the SSH public key content
136
136
  def ssh_key_triple_for(key)
137
137
  begin
138
- file = File.open key
138
+ IO.read(key).chomp.split
139
139
  rescue Errno::ENOENT => e
140
140
  raise ::RHC::KeyFileNotExistentException.new("File '#{key}' does not exist.")
141
141
  rescue Errno::EACCES => e
142
142
  raise ::RHC::KeyFileAccessDeniedException.new("Access denied to '#{key}'.")
143
143
  end
144
- file.gets.chomp.split
145
144
  end
146
145
 
147
146
  def ssh_key_triple_for_default_key
@@ -245,7 +245,7 @@ module RHC
245
245
  key_fingerprint = fingerprint_for_default_key
246
246
  unless key_fingerprint
247
247
  paragraph do
248
- say "Your ssh public key at #{system_path(RHC::Config.ssh_pub_key_file_path)} is invalid or unreadable. "\
248
+ warn "Your ssh public key at #{system_path(RHC::Config.ssh_pub_key_file_path)} is invalid or unreadable. "\
249
249
  "Setup can not continue until you manually remove or fix your "\
250
250
  "public and private keys id_rsa keys."
251
251
  end
@@ -420,9 +420,8 @@ module RHC
420
420
  # Thus, we force an order with #sort to ensure spec passage on both.
421
421
  def setup_test_stage
422
422
  say "Checking common problems "
423
- tests = private_methods.select {|m| m.to_s.start_with? 'test_'}
424
423
  failed = false
425
- tests.sort.each do |test|
424
+ all_test_methods.sort.each do |test|
426
425
  begin
427
426
  send(test)
428
427
  print_dot unless failed
@@ -440,6 +439,10 @@ module RHC
440
439
  true
441
440
  end
442
441
 
442
+ def all_test_methods
443
+ private_methods.select {|m| m.to_s.start_with? 'test_'}
444
+ end
445
+
443
446
  # cached list of applications needed for test stage
444
447
  def applications
445
448
  @applications ||= rest_client.domains.map(&:applications).flatten
@@ -0,0 +1,22 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDoDCCAogCCQDzF8AJCHnrbjANBgkqhkiG9w0BAQUFADCBkTELMAkGA1UEBhMC
3
+ VVMxCzAJBgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxDzANBgNVBAoMBnJl
4
+ ZGhhdDESMBAGA1UECwwJb3BlbnNoaWZ0MRIwEAYDVQQDDAlvcGVuc2hpZnQxKDAm
5
+ BgkqhkiG9w0BCQEWGWluZm9Ab3BlbnNoaWZ0LnJlZGhhdC5jb20wHhcNMTMwMjE5
6
+ MjExMTQ4WhcNMTQwMjE5MjExMTQ4WjCBkTELMAkGA1UEBhMCVVMxCzAJBgNVBAgM
7
+ AkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxDzANBgNVBAoMBnJlZGhhdDESMBAGA1UE
8
+ CwwJb3BlbnNoaWZ0MRIwEAYDVQQDDAlvcGVuc2hpZnQxKDAmBgkqhkiG9w0BCQEW
9
+ GWluZm9Ab3BlbnNoaWZ0LnJlZGhhdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB
10
+ DwAwggEKAoIBAQDAEbH4MCi3iIDP1HS+/Xwu8SjdSc5WJX6htV7hJpmFZ8HohV/8
11
+ ba0v6aM9IJIIt+sIe2J62t/9G3leOdIHBxeACN4fV2l/iA/fvxvlnFKeD7sHm9Oc
12
+ Yj1H6YYJ57sIOf/oLDpJl6l3Rw8VC3+3W0/lzlVpA8qt7fpkiW7XQJCPplUSrdVC
13
+ 3okQ2T5NAod5+wVIOqELgE5bLX1LRs5VPsjytHkJ7rKXs55FHR3kpsoImn5xD0Ky
14
+ 6lRn8cIMolQoyN5HIGr8f5P+07hrHibve8jje/DKTssb5yEUAEmh6iGHQsRAnsUW
15
+ QoIEUOLqQCu9re2No4G52Kl2xQIjyJF7rCfxAgMBAAEwDQYJKoZIhvcNAQEFBQAD
16
+ ggEBAGHrya/ZkiAje2kHsOajXMlO2+y1iLfUDcRLuEWpUa8sI5EM4YtemQrsupFp
17
+ 8lVYG5C4Vh8476oF9t8Wex5eH3ocwbSvPIUqE07hdmrubiMq4wxFVRYq7g9lHAnx
18
+ l+bABuN/orbAcPcGAGg7AkXVoAc3Fza/ZcgMcw7NOtDTEss70V9OdgCfQUJL0KdO
19
+ hCO8bQ1EaEiq6zEh8RpZe8mu+f/GYATX1I+eJUc6F6cn83oJjE9bqAVzk7TzTHeK
20
+ EBKN50C14wWtXeG7n2+ugaVO+0xnvHeUrQBLHSRyOHqxXrQQ5XmzcaBiyI0f2IQM
21
+ Hst1BVXyX0n/L/ZoYYsv5juJmDo=
22
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEogIBAAKCAQEAwBGx+DAot4iAz9R0vv18LvEo3UnOViV+obVe4SaZhWfB6IVf
3
+ /G2tL+mjPSCSCLfrCHtietrf/Rt5XjnSBwcXgAjeH1dpf4gP378b5ZxSng+7B5vT
4
+ nGI9R+mGCee7CDn/6Cw6SZepd0cPFQt/t1tP5c5VaQPKre36ZIlu10CQj6ZVEq3V
5
+ Qt6JENk+TQKHefsFSDqhC4BOWy19S0bOVT7I8rR5Ce6yl7OeRR0d5KbKCJp+cQ9C
6
+ supUZ/HCDKJUKMjeRyBq/H+T/tO4ax4m73vI43vwyk7LG+chFABJoeohh0LEQJ7F
7
+ FkKCBFDi6kArva3tjaOBudipdsUCI8iRe6wn8QIDAQABAoIBAG/on4JVRRQSw8LU
8
+ LiWt+jI7ryyoOUH2XL8JtzuGSwLwvomlVJT2rmbxQXx3Qr8zsgziHzIn30RRQrkF
9
+ BXu0xRuDjzBBtSVqeJ1Mc4uoNncEAVxgjb5bewswZDnXPCGB8bosMtX4OPRXgdEo
10
+ PwTtfjMOsrMaU3hd5Xu4m81tQA2BvwOlx8aYDyH0jeTnervc5uRGbeTBQG4Bu40E
11
+ rWNmXvgNq2EzTAwbbN6Ma97gw9KgXnM4Nlh29Fxb5TBeUU9lkzuTZAZIDXKIm7AG
12
+ UwMbj/A038yAumYQtThTE/3e4W3rn7F2Vko900bC4aAC1KQOAzjIeQqzqkVxWTWq
13
+ 4SUFQAECgYEA/ODwifOTuI6hdZK6JRgc4wp6Rc0fkqHuxLzABXoIGuSVlWyimqIN
14
+ ZySAkpo5EW6DNraRJxNCOBmWeGPEhHGrea+JPiPEwCK0F7SxvSmg3jzNzw3Es31T
15
+ ecET7eDwuSOY9v4XDzLyiXXkEUUReD7Ng2hEYL+HaQrl5jWj4lxgq/ECgYEAwnCb
16
+ Krz7FwX8AqtFAEi6uUrc12k1xYKQfrwSxbfdK2vBBUpgB71Iq/fqP+1BittEljDG
17
+ 8f4jEtMBFfEPhLzGIHaI3UiHUHXS4GetA77TRgR8lnKKpj1FcMIY2iKU479707O5
18
+ Q08pgWRUDQ8BVg2ePgbo5QjLMc/rv7UF3AHvPAECgYB/auAIwqDGN6gHU/1TP4ke
19
+ pWLi1O55tfpXSzv+BnUbB96PQgPUop7aP7xBIlBrBiI7aVZOOBf/qHT3CF421geu
20
+ 8tHWa7NxlIrl/vgn9lfGYyDYmXlpb1amXLEsBVGGF/e1TGZWFDe9J5fZU9HvosVu
21
+ 1xTNIvSZ6xHYI2MGZcGYIQKBgEYeebaV5C7PV6xWu1F46O19U9rS9DM//H/XryVi
22
+ Qv4vo7IWuj7QQe7SPsXC98ntfPR0rqoCLf/R3ChfgGsr8H8wf/bc+v9HHj8S5E/f
23
+ dy1e3Nccg2ej3PDm7jNsGSlwmmUkAQGHAL7KwYzcBm1UB+bycvZ1j2FtS+UckPpg
24
+ MDgBAoGALD8PkxHb4U4DtbNFSYRrUdvS9heav/yph3lTMfifNkOir36io6v8RPgb
25
+ D2bHKKZgmYlTgJrxD45Er9agC5jclJO35QRU/OfGf3GcnABkBI7vlvUKADAo65Sq
26
+ weZkdJnbrIadcvLOHOzkKC9m+rxFTC9VoN1dwK2zwYvUXfa1VJA=
27
+ -----END RSA PRIVATE KEY-----
File without changes
@@ -95,6 +95,11 @@ describe RHC::CLI do
95
95
  context 'with --help' do
96
96
  before(:each){ @arguments = ['--help'] }
97
97
  it_should_behave_like 'a global help page'
98
+
99
+ context 'without a config file' do
100
+ before{ RHC::Wizard.stub(:has_configuration?).and_return(false) }
101
+ it_should_behave_like 'a global help page'
102
+ end
98
103
  end
99
104
 
100
105
  context 'with -h' do
@@ -23,14 +23,14 @@ describe RHC::Commands::Account do
23
23
  it('should show the maximum gears') { run_output.should =~ /Gears Allowed:\s*3/ }
24
24
  it { expect { run }.should exit_with_code(0) }
25
25
 
26
- context 'with a freeshift plan' do
27
- let(:user_plan_id){ 'freeshift' }
28
- it('should show') { run_output.should =~ /Plan:\s*FreeShift/ }
26
+ context 'with a free plan' do
27
+ let(:user_plan_id){ 'free' }
28
+ it('should show') { run_output.should =~ /Plan:\s*Free/ }
29
29
  end
30
30
 
31
- context 'with a megashift plan' do
32
- let(:user_plan_id){ 'megashift' }
33
- it('should show') { run_output.should =~ /Plan:\s*MegaShift/ }
31
+ context 'with a silver plan' do
32
+ let(:user_plan_id){ 'silver' }
33
+ it('should show') { run_output.should =~ /Plan:\s*Silver/ }
34
34
  end
35
35
 
36
36
  context 'with a arbitrary plan' do
@@ -8,10 +8,13 @@ describe RHC::Commands::Alias do
8
8
  let(:domain_0_links) { mock_response_links(mock_domain_links('mock_domain_0')) }
9
9
  let(:domain_1_links) { mock_response_links(mock_domain_links('mock_domain_1')) }
10
10
  let(:app_0_links) { mock_response_links(mock_app_links('mock_domain_0', 'mock_app_0')) }
11
+ let(:alias_0_links) { mock_response_links(mock_alias_links('mock_domain_0', 'mock_app_0', 'www.foo.bar')) }
11
12
  let!(:rest_client){ MockRestClient.new }
12
13
  before(:each) do
13
14
  user_config
14
- rest_client.add_domain("mock_domain_0").add_application("mock_app_0", "ruby-1.8.7")
15
+ domain = rest_client.add_domain("mock_domain_0")
16
+ domain.add_application("mock_app_0", "ruby-1.8.7").add_alias("www.foo.bar")
17
+ domain.add_application("mock_app_1", "ruby-1.8.7")
15
18
  stub_api_request(:any, client_links['LIST_DOMAINS']['relative']).
16
19
  to_return({ :body => {
17
20
  :type => 'domains',
@@ -74,6 +77,20 @@ describe RHC::Commands::Alias do
74
77
  }.to_json,
75
78
  :status => 200
76
79
  })
80
+ stub_api_request(:any, app_0_links['LIST_ALIASES']['relative'], false).
81
+ to_return({ :body => {
82
+ :type => 'aliases',
83
+ :data =>
84
+ [{ :domain_id => 'mock_domain_0',
85
+ :application_id => 'mock_app_0',
86
+ :id => 'www.foo.bar',
87
+ :certificate_added_at => nil,
88
+ :has_private_ssl_certificate => false,
89
+ :links => mock_response_links(mock_alias_links('mock_domain_0','mock_app_0', 'www.foo.bar')),
90
+ }]
91
+ }.to_json,
92
+ :status => 200
93
+ })
77
94
 
78
95
  end
79
96
 
@@ -110,15 +127,172 @@ describe RHC::Commands::Alias do
110
127
  end
111
128
  end
112
129
 
130
+ describe 'alias update-cert --help' do
131
+ let(:arguments) { ['alias', 'update-cert', '--help'] }
132
+
133
+ context 'help is run' do
134
+ it "should display help" do
135
+ expect { run }.should exit_with_code(0)
136
+ end
137
+ it('should output usage') { run_output.should match("Usage: rhc alias update-cert <application> <alias> --certificate FILE --private-key FILE [--passphrase passphrase]") }
138
+ end
139
+ end
140
+
141
+ describe 'alias delete-cert --help' do
142
+ let(:arguments) { ['alias', 'delete-cert', '--help'] }
143
+
144
+ context 'help is run' do
145
+ it "should display help" do
146
+ expect { run }.should exit_with_code(0)
147
+ end
148
+ it('should output usage') { run_output.should match("Usage: rhc alias delete-cert <application> <alias>") }
149
+ end
150
+ end
151
+
152
+ describe 'alias list --help' do
153
+ let(:arguments) { ['alias', 'list', '--help'] }
154
+
155
+ context 'help is run' do
156
+ it "should display help" do
157
+ expect { run }.should exit_with_code(0)
158
+ end
159
+ it('should output usage') { run_output.should match("Usage: rhc alias list <application>") }
160
+ end
161
+ end
162
+
113
163
  describe 'add alias' do
114
164
  let(:arguments) { ['alias', 'add', 'mock_app_0', 'www.foo.bar' ] }
115
165
  it { expect { run }.should exit_with_code(0) }
116
- it { run_output.should =~ /'add-alias' successful/m }
166
+ it { run_output.should =~ /Alias 'www.foo.bar' has been added/m }
117
167
  end
118
168
 
119
169
  describe 'remove alias' do
120
- let(:arguments) { ['alias', 'remove', 'mock_app_0', 'www.foo.bar' ] }
121
- it { expect { run }.should exit_with_code(0) }
122
- it { run_output.should =~ /'remove-alias' successful/m }
170
+ before do
171
+ rest_client.stub(:api_version_negotiated).and_return(1.4)
172
+ end
173
+ context 'remove alias successfully' do
174
+ let(:arguments) { ['alias', 'remove', 'mock_app_0', 'www.foo.bar' ] }
175
+ it { expect { run }.should exit_with_code(0) }
176
+ it { run_output.should =~ /Alias 'www.foo.bar' has been removed/m }
177
+ end
178
+ context 'remove alias with server api <= 1.3' do
179
+ let(:arguments) { ['alias', 'remove', 'mock_app_0', 'www.foo.bar' ] }
180
+ before do
181
+ rest_client.stub(:api_version_negotiated).and_return(1.3)
182
+ end
183
+ it { expect { run }.should exit_with_code(0) }
184
+ it { run_output.should =~ /Alias 'www.foo.bar' has been removed/m }
185
+ end
186
+ end
187
+
188
+ describe 'alias update-cert' do
189
+ before do
190
+ rest_client.stub(:api_version_negotiated).and_return(1.4)
191
+ end
192
+ context 'add valid certificate with valid private key without pass phrase' do
193
+ let(:arguments) { ['alias', 'update-cert', 'mock_app_0', 'www.foo.bar',
194
+ '--certificate', File.expand_path('../../assets/cert.crt', __FILE__),
195
+ '--private-key', File.expand_path('../../assets/cert_key_rsa', __FILE__) ] }
196
+ it { expect { run }.should exit_with_code(0) }
197
+ it { run_output.should =~ /SSL certificate successfully added/m }
198
+ end
199
+ context 'cert file not found' do
200
+ let(:arguments) { ['alias', 'update-cert', 'mock_app_0', 'www.foo.bar',
201
+ '--certificate', File.expand_path('../../assets/nothing.foo', __FILE__),
202
+ '--private-key', File.expand_path('../../assets/cert_key_rsa', __FILE__) ] }
203
+ it { expect { run }.should exit_with_code(1) }
204
+ it { run_output.should =~ /Certificate file not found/m }
205
+ end
206
+ context 'private key file not found' do
207
+ let(:arguments) { ['alias', 'update-cert', 'mock_app_0', 'www.foo.bar',
208
+ '--certificate', File.expand_path('../../assets/cert.crt', __FILE__),
209
+ '--private-key', File.expand_path('../../assets/nothing.foo', __FILE__) ] }
210
+ it { expect { run }.should exit_with_code(1) }
211
+ it { run_output.should =~ /Private key file not found/m }
212
+ end
213
+ context 'not existing certificate alias' do
214
+ let(:arguments) { ['alias', 'update-cert', 'mock_app_0', 'www.unicorns.com',
215
+ '--certificate', File.expand_path('../../assets/cert.crt', __FILE__),
216
+ '--private-key', File.expand_path('../../assets/cert_key_rsa', __FILE__) ] }
217
+ it { expect { run }.should exit_with_code(156) }
218
+ it { run_output.should =~ /Alias www.unicorns.com can't be found in application/m }
219
+ end
220
+ context 'fails if server does not support' do
221
+ let(:arguments) { ['alias', 'update-cert', 'mock_app_0', 'www.foo.bar',
222
+ '--certificate', File.expand_path('../../assets/cert.crt', __FILE__),
223
+ '--private-key', File.expand_path('../../assets/cert_key_rsa', __FILE__) ] }
224
+ before do
225
+ rest_client.stub(:api_version_negotiated).and_return(1.3)
226
+ end
227
+ it { expect { run }.should exit_with_code(1) }
228
+ it { run_output.should =~ /The server does not support SSL certificates for custom aliases/m }
229
+ end
230
+ context 'invalid certificate file (empty)' do
231
+ let(:arguments) { ['alias', 'update-cert', 'mock_app_0', 'www.foo.bar',
232
+ '--certificate', File.expand_path('../../assets/empty.txt', __FILE__),
233
+ '--private-key', File.expand_path('../../assets/cert_key_rsa', __FILE__) ] }
234
+ it { expect { run }.should exit_with_code(1) }
235
+ it { run_output.should =~ /Invalid certificate file/m }
236
+ end
237
+ context 'invalid private key file (empty)' do
238
+ let(:arguments) { ['alias', 'update-cert', 'mock_app_0', 'www.foo.bar',
239
+ '--certificate', File.expand_path('../../assets/cert.crt', __FILE__),
240
+ '--private-key', File.expand_path('../../assets/empty.txt', __FILE__) ] }
241
+ it { expect { run }.should exit_with_code(1) }
242
+ it { run_output.should =~ /Invalid private key file/m }
243
+ end
123
244
  end
245
+
246
+ describe 'alias delete-cert' do
247
+ before do
248
+ rest_client.stub(:api_version_negotiated).and_return(1.4)
249
+ end
250
+ context 'delete existing certificate' do
251
+ let(:arguments) { ['alias', 'delete-cert', 'mock_app_0', 'www.foo.bar', '--confirm'] }
252
+ it { expect { run }.should exit_with_code(0) }
253
+ it { run_output.should =~ /SSL certificate successfully deleted/m }
254
+ end
255
+ context 'delete not existing certificate' do
256
+ let(:arguments) { ['alias', 'delete-cert', 'mock_app_0', 'www.unicorns.com', '--confirm'] }
257
+ it { expect { run }.should exit_with_code(156) }
258
+ it { run_output.should =~ /Alias www.unicorns.com can't be found in application mock_app_0/m }
259
+ end
260
+ context 'fails if server does not support' do
261
+ let(:arguments) { ['alias', 'delete-cert', 'mock_app_0', 'www.foo.bar', '--confirm'] }
262
+ before do
263
+ rest_client.stub(:api_version_negotiated).and_return(1.3)
264
+ end
265
+ it { expect { run }.should exit_with_code(1) }
266
+ it { run_output.should =~ /The server does not support SSL certificates for custom aliases/m }
267
+ end
268
+ end
269
+
270
+ describe 'alias list' do
271
+ before do
272
+ rest_client.stub(:api_version_negotiated).and_return(1.4)
273
+ end
274
+ context 'list app with existing certificate' do
275
+ let(:arguments) { ['alias', 'list', 'mock_app_0'] }
276
+ it { expect { run }.should exit_with_code(0) }
277
+ it { run_output.should =~ /Has Certificate?/m }
278
+ it { run_output.should =~ /Certificate Added/m }
279
+ it { run_output.should =~ /www.foo.bar/m }
280
+ end
281
+ context 'list app without certificates' do
282
+ let(:arguments) { ['alias', 'list', 'mock_app_1'] }
283
+ it { expect { run }.should exit_with_code(0) }
284
+ it { run_output.should =~ /No aliases associated with the application mock_app_1/m }
285
+ end
286
+ context 'simple list is server does not support ssl certs' do
287
+ let(:arguments) { ['alias', 'list', 'mock_app_0'] }
288
+ before do
289
+ rest_client.stub(:api_version_negotiated).and_return(1.3)
290
+ end
291
+ it { expect { run }.should exit_with_code(0) }
292
+ it { run_output.should =~ /no/m }
293
+ it { run_output.should =~ /-/m }
294
+ it { run_output.should =~ /www.foo.bar/m }
295
+ end
296
+ end
297
+
124
298
  end
@@ -74,7 +74,7 @@ describe RHC::Commands::App do
74
74
  Resolv::Hosts.should_receive(:new).and_return(resolver)
75
75
  resolver.should_receive(:getaddress).with('app1-mockdomain.fake.foo').and_raise(ArgumentError)
76
76
  end
77
-
77
+
78
78
  it { expect { run }.should exit_with_code(0) }
79
79
  it { run_output.should match("Success") }
80
80
  end
@@ -109,6 +109,7 @@ describe RHC::Commands::App do
109
109
  it { expect { run }.should raise_error(RHC::CartridgeNotFoundException, "There are no cartridges that match 'nomatch_cart'.") }
110
110
  end
111
111
  end
112
+
112
113
  end
113
114
 
114
115
  describe 'cart matching behavior' do
@@ -42,6 +42,15 @@ describe RHC::Commands::Authorization do
42
42
 
43
43
  expect_an_unsupported_message
44
44
  end
45
+
46
+ describe '#run' do
47
+ let(:arguments) { ['authorization', '--h']}
48
+ context 'given --h' do
49
+ it 'should not raise SystemStackError' do
50
+ expect{ run }.should_not raise_error(SystemStackError)
51
+ end
52
+ end
53
+ end
45
54
 
46
55
  describe "#delete" do
47
56
  let(:arguments) { ['authorization', 'delete', 'foo', 'bar'] }
@@ -49,6 +49,7 @@ describe RHC::Commands::Cartridge do
49
49
  it{ run_output.should match /mock_standalone_cart\-1\s+Mock1 Cart\s+web/ }
50
50
  it{ run_output.should match /mock_standalone_cart\-2\s+web/ }
51
51
  it{ run_output.should match /mock_embedded_cart\-1\s+Mock1 Embedded Cart\s+addon/ }
52
+ it{ run_output.should match /premium_cart\-1 \(\*\)\s+Premium Cart\s+web/ }
52
53
  it{ expect{ run }.should exit_with_code(0) }
53
54
 
54
55
  context 'with verbose list' do
@@ -164,6 +165,17 @@ describe RHC::Commands::Cartridge do
164
165
  fail_with_code 155
165
166
  }
166
167
  end
168
+
169
+ context 'when cart is premium' do
170
+ let(:arguments) { ['cartridge', 'add', 'premium_cart', '-a', 'app1','--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
171
+ before(:each) do
172
+ domain = rest_client.add_domain("mock_domain")
173
+ app = domain.add_application("app1", "mock_type")
174
+ end
175
+ it {
176
+ succeed_with_message /This gear costs an additional \$0\.05 per gear after the first 3 gears\./
177
+ }
178
+ end
167
179
  end
168
180
 
169
181
  describe 'cartridge remove' do
@@ -306,6 +318,21 @@ describe RHC::Commands::Cartridge do
306
318
  end
307
319
  end
308
320
 
321
+ describe 'cartridge show' do
322
+ let(:arguments) { ['cartridge', 'show', 'premium_cart', '-a', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
323
+
324
+ before(:each) do
325
+ @rc = MockRestClient.new
326
+ domain = @rc.add_domain("mock_domain")
327
+ app = domain.add_application("app1", "mock_type")
328
+ app.cartridges << @rc.cartridges.find {|c| c.name == 'premium_cart'}
329
+ end
330
+
331
+ context 'when run with a premium cartridge' do
332
+ it { run_output.should match(/This gear costs an additional \$0\.05 per gear after the first 3 gears./) }
333
+ end
334
+ end
335
+
309
336
  describe 'cartridge show scaled' do
310
337
  let!(:rest_client){ MockRestClient.new }
311
338
  let(:arguments) { ['cartridge', 'show', 'mock_type', '-a', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
@@ -8,6 +8,8 @@ describe RHC::Commands::Setup do
8
8
  let(:instance){ subject.new }
9
9
  let!(:config){ base_config }
10
10
  before{ described_class.send(:public, *described_class.protected_instance_methods) }
11
+ before{ FakeFS::FileSystem.clear }
12
+ before{ RHC::Config.stub(:home_dir).and_return('/home/mock_user') }
11
13
 
12
14
  describe '#run' do
13
15
  it{ expects_running('setup').should call(:run).on(instance).with(no_args) }
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'rest_spec_helper'
2
3
  require 'rhc/commands/sshkey'
3
4
  require 'rhc/config'
4
5
 
@@ -58,6 +59,24 @@ describe RHC::Commands::Sshkey do
58
59
  rest_client.sshkeys.length.should == num_keys
59
60
  end
60
61
  end
62
+
63
+ it "does not throw an error on an empty file" do
64
+ FakeFS do
65
+ keys = rest_client.sshkeys
66
+ num_keys = keys.length
67
+ File.open('id_rsa.pub', 'w') do |f|
68
+ f << ''
69
+ end
70
+ expect { run }.should exit_with_code(128)
71
+ expect { run_output.should match(/Name:.* mockkey/) }
72
+ rest_client.sshkeys.length.should == num_keys
73
+ end
74
+ end
75
+
76
+ it "exits with status code Errno::EACCES::Errno" do
77
+ IO.should_receive(:read).and_return("ssh_foo bar")
78
+ expect { run }.should exit_with_code(128)
79
+ end
61
80
  end
62
81
 
63
82
  context "when adding an invalid key with --confirm" do
@@ -99,7 +118,7 @@ describe RHC::Commands::Sshkey do
99
118
  #end
100
119
 
101
120
  it "exits with status code Errno::EACCES::Errno" do
102
- File.should_receive(:open).and_raise(Errno::EACCES)
121
+ IO.should_receive(:read).and_raise(Errno::EACCES)
103
122
  expect { run }.should exit_with_code(128)
104
123
  end
105
124