pbox 1.17.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +7 -0
  2. data/COPYRIGHT +1 -0
  3. data/LICENSE +11 -0
  4. data/README.md +40 -0
  5. data/Rakefile +6 -0
  6. data/autocomplete/pbox_bash +1639 -0
  7. data/bin/pbox +37 -0
  8. data/conf/protonbox.conf +8 -0
  9. data/features/assets/deploy.tar.gz +0 -0
  10. data/features/core_feature.rb +178 -0
  11. data/features/deployments_feature.rb +127 -0
  12. data/features/domains_feature.rb +49 -0
  13. data/features/keys_feature.rb +37 -0
  14. data/features/members_feature.rb +166 -0
  15. data/lib/rhc/auth/basic.rb +64 -0
  16. data/lib/rhc/auth/token.rb +102 -0
  17. data/lib/rhc/auth/token_store.rb +53 -0
  18. data/lib/rhc/auth.rb +5 -0
  19. data/lib/rhc/autocomplete.rb +66 -0
  20. data/lib/rhc/autocomplete_templates/bash.erb +39 -0
  21. data/lib/rhc/cartridge_helpers.rb +118 -0
  22. data/lib/rhc/cli.rb +40 -0
  23. data/lib/rhc/command_runner.rb +186 -0
  24. data/lib/rhc/commands/account.rb +25 -0
  25. data/lib/rhc/commands/alias.rb +124 -0
  26. data/lib/rhc/commands/app.rb +701 -0
  27. data/lib/rhc/commands/apps.rb +20 -0
  28. data/lib/rhc/commands/authorization.rb +96 -0
  29. data/lib/rhc/commands/base.rb +174 -0
  30. data/lib/rhc/commands/cartridge.rb +326 -0
  31. data/lib/rhc/commands/deployment.rb +82 -0
  32. data/lib/rhc/commands/domain.rb +167 -0
  33. data/lib/rhc/commands/env.rb +142 -0
  34. data/lib/rhc/commands/git_clone.rb +29 -0
  35. data/lib/rhc/commands/logout.rb +51 -0
  36. data/lib/rhc/commands/member.rb +148 -0
  37. data/lib/rhc/commands/port_forward.rb +197 -0
  38. data/lib/rhc/commands/server.rb +40 -0
  39. data/lib/rhc/commands/setup.rb +60 -0
  40. data/lib/rhc/commands/snapshot.rb +137 -0
  41. data/lib/rhc/commands/ssh.rb +51 -0
  42. data/lib/rhc/commands/sshkey.rb +97 -0
  43. data/lib/rhc/commands/tail.rb +47 -0
  44. data/lib/rhc/commands/threaddump.rb +14 -0
  45. data/lib/rhc/commands.rb +396 -0
  46. data/lib/rhc/config.rb +320 -0
  47. data/lib/rhc/context_helper.rb +121 -0
  48. data/lib/rhc/core_ext.rb +202 -0
  49. data/lib/rhc/coverage_helper.rb +33 -0
  50. data/lib/rhc/deployment_helpers.rb +88 -0
  51. data/lib/rhc/exceptions.rb +232 -0
  52. data/lib/rhc/git_helpers.rb +91 -0
  53. data/lib/rhc/help_formatter.rb +55 -0
  54. data/lib/rhc/helpers.rb +477 -0
  55. data/lib/rhc/highline_extensions.rb +479 -0
  56. data/lib/rhc/json.rb +51 -0
  57. data/lib/rhc/output_helpers.rb +260 -0
  58. data/lib/rhc/rest/activation.rb +11 -0
  59. data/lib/rhc/rest/alias.rb +42 -0
  60. data/lib/rhc/rest/api.rb +87 -0
  61. data/lib/rhc/rest/application.rb +332 -0
  62. data/lib/rhc/rest/attributes.rb +36 -0
  63. data/lib/rhc/rest/authorization.rb +8 -0
  64. data/lib/rhc/rest/base.rb +79 -0
  65. data/lib/rhc/rest/cartridge.rb +154 -0
  66. data/lib/rhc/rest/client.rb +650 -0
  67. data/lib/rhc/rest/deployment.rb +18 -0
  68. data/lib/rhc/rest/domain.rb +98 -0
  69. data/lib/rhc/rest/environment_variable.rb +15 -0
  70. data/lib/rhc/rest/gear_group.rb +16 -0
  71. data/lib/rhc/rest/httpclient.rb +145 -0
  72. data/lib/rhc/rest/key.rb +44 -0
  73. data/lib/rhc/rest/membership.rb +105 -0
  74. data/lib/rhc/rest/mock.rb +1024 -0
  75. data/lib/rhc/rest/user.rb +32 -0
  76. data/lib/rhc/rest.rb +148 -0
  77. data/lib/rhc/ssh_helpers.rb +378 -0
  78. data/lib/rhc/tar_gz.rb +51 -0
  79. data/lib/rhc/usage_templates/command_help.erb +51 -0
  80. data/lib/rhc/usage_templates/command_syntax_help.erb +11 -0
  81. data/lib/rhc/usage_templates/help.erb +35 -0
  82. data/lib/rhc/usage_templates/missing_help.erb +1 -0
  83. data/lib/rhc/usage_templates/options_help.erb +12 -0
  84. data/lib/rhc/vendor/okjson.rb +600 -0
  85. data/lib/rhc/vendor/parseconfig.rb +178 -0
  86. data/lib/rhc/vendor/sshkey.rb +253 -0
  87. data/lib/rhc/vendor/zliby.rb +628 -0
  88. data/lib/rhc/version.rb +5 -0
  89. data/lib/rhc/wizard.rb +633 -0
  90. data/lib/rhc.rb +34 -0
  91. data/spec/coverage_helper.rb +89 -0
  92. data/spec/direct_execution_helper.rb +338 -0
  93. data/spec/keys/example.pem +23 -0
  94. data/spec/keys/example_private.pem +27 -0
  95. data/spec/keys/server.pem +19 -0
  96. data/spec/rest_spec_helper.rb +31 -0
  97. data/spec/rhc/assets/cert.crt +22 -0
  98. data/spec/rhc/assets/cert_key_rsa +27 -0
  99. data/spec/rhc/assets/empty.txt +0 -0
  100. data/spec/rhc/assets/env_vars.txt +7 -0
  101. data/spec/rhc/assets/env_vars_2.txt +1 -0
  102. data/spec/rhc/assets/foo.txt +1 -0
  103. data/spec/rhc/assets/targz_corrupted.tar.gz +1 -0
  104. data/spec/rhc/assets/targz_sample.tar.gz +0 -0
  105. data/spec/rhc/auth_spec.rb +442 -0
  106. data/spec/rhc/cli_spec.rb +188 -0
  107. data/spec/rhc/command_spec.rb +435 -0
  108. data/spec/rhc/commands/account_spec.rb +42 -0
  109. data/spec/rhc/commands/alias_spec.rb +333 -0
  110. data/spec/rhc/commands/app_spec.rb +754 -0
  111. data/spec/rhc/commands/apps_spec.rb +39 -0
  112. data/spec/rhc/commands/authorization_spec.rb +145 -0
  113. data/spec/rhc/commands/cartridge_spec.rb +641 -0
  114. data/spec/rhc/commands/deployment_spec.rb +286 -0
  115. data/spec/rhc/commands/domain_spec.rb +383 -0
  116. data/spec/rhc/commands/env_spec.rb +493 -0
  117. data/spec/rhc/commands/git_clone_spec.rb +80 -0
  118. data/spec/rhc/commands/logout_spec.rb +86 -0
  119. data/spec/rhc/commands/member_spec.rb +228 -0
  120. data/spec/rhc/commands/port_forward_spec.rb +217 -0
  121. data/spec/rhc/commands/server_spec.rb +69 -0
  122. data/spec/rhc/commands/setup_spec.rb +118 -0
  123. data/spec/rhc/commands/snapshot_spec.rb +179 -0
  124. data/spec/rhc/commands/ssh_spec.rb +163 -0
  125. data/spec/rhc/commands/sshkey_spec.rb +188 -0
  126. data/spec/rhc/commands/tail_spec.rb +81 -0
  127. data/spec/rhc/commands/threaddump_spec.rb +84 -0
  128. data/spec/rhc/config_spec.rb +407 -0
  129. data/spec/rhc/helpers_spec.rb +524 -0
  130. data/spec/rhc/highline_extensions_spec.rb +314 -0
  131. data/spec/rhc/json_spec.rb +30 -0
  132. data/spec/rhc/rest_application_spec.rb +248 -0
  133. data/spec/rhc/rest_client_spec.rb +752 -0
  134. data/spec/rhc/rest_spec.rb +740 -0
  135. data/spec/rhc/targz_spec.rb +55 -0
  136. data/spec/rhc/wizard_spec.rb +756 -0
  137. data/spec/spec_helper.rb +575 -0
  138. data/spec/wizard_spec_helper.rb +330 -0
  139. metadata +435 -0
@@ -0,0 +1,435 @@
1
+ require 'spec_helper'
2
+ require 'rhc/commands/base'
3
+ require 'rhc/exceptions'
4
+ require 'rest_spec_helper'
5
+
6
+ describe RHC::Commands::Base do
7
+
8
+ let!(:config){ base_config }
9
+
10
+ before{ c = RHC::Commands.instance_variable_get(:@commands); @saved_commands = c && c.dup || nil }
11
+ after do
12
+ (Kernel.send(:remove_const, subject) if subject.is_a?(Class)) rescue nil
13
+ RHC::Commands.instance_variable_set(:@commands, @saved_commands)
14
+ end
15
+
16
+ describe '#object_name' do
17
+ subject { described_class }
18
+ its(:object_name) { should == 'base' }
19
+
20
+ context 'when the class is at the root' do
21
+ subject do
22
+ Kernel.module_eval do
23
+ class StaticRootClass < RHC::Commands::Base; def run; 1; end; end
24
+ end
25
+ StaticRootClass
26
+ end
27
+ its(:object_name) { should == 'static-root-class' }
28
+ end
29
+ context 'when the class is nested in a module' do
30
+ subject do
31
+ Kernel.module_eval do
32
+ module Nested; class StaticRootClass < RHC::Commands::Base; def run; 1; end; end; end
33
+ end
34
+ Nested::StaticRootClass
35
+ end
36
+ its(:object_name) { should == 'static-root-class' }
37
+ end
38
+ end
39
+
40
+ describe '#inherited' do
41
+
42
+ let(:instance) { subject.new }
43
+ let(:commands) { RHC::Commands.send(:commands) }
44
+
45
+ context 'when dynamically instantiating without an object name' do
46
+ subject { const_for(Class.new(RHC::Commands::Base) { def run; 1; end }) }
47
+
48
+ it("should raise") { expect { subject }.to raise_exception( RHC::Commands::Base::InvalidCommand, /object_name/i ) }
49
+ end
50
+
51
+ context 'when dynamically instantiating with object_name' do
52
+ subject { const_for(Class.new(RHC::Commands::Base) { object_name :test; def run(args, options); 1; end }) }
53
+
54
+ it("should register itself") { expect { subject }.to change(commands, :length).by(1) }
55
+ it("should have an object name") { subject.object_name.should == 'test' }
56
+ it("should run with wizard") do
57
+ FakeFS do
58
+ wizard_run = false
59
+ RHC::Wizard.stub(:new) do |config|
60
+ RHC::Wizard.unstub!(:new)
61
+ w = RHC::Wizard.new(config)
62
+ w.stub(:run) { wizard_run = true }
63
+ w
64
+ end
65
+
66
+ expects_running('test').should call(:run).on(instance).with(no_args)
67
+ wizard_run.should be_false
68
+
69
+ stderr.should match("You have not yet configured the ProtonBox client tools")
70
+ end
71
+ end
72
+ end
73
+
74
+ context 'when statically defined' do
75
+ subject do
76
+ Kernel.module_eval do
77
+ module Nested
78
+ class Static < RHC::Commands::Base
79
+ suppress_wizard
80
+ def run(args, options); 1; end
81
+ end
82
+ end
83
+ end
84
+ Nested::Static
85
+ end
86
+
87
+ it("should register itself") { expect { subject }.to change(commands, :length).by(1) }
88
+ it("should have an object name of the class") { subject.object_name.should == 'static' }
89
+ it("invokes the right method") { expects_running('static').should call(:run).on(instance).with(no_args) }
90
+ end
91
+
92
+ context 'when a command calls exit' do
93
+ subject do
94
+ Kernel.module_eval do
95
+ class Failing < RHC::Commands::Base
96
+ def run
97
+ exit 2
98
+ end
99
+ end
100
+ end
101
+ Failing
102
+ end
103
+
104
+ it("invokes the right method") { expects_running('failing').should call(:run).on(instance).with(no_args) }
105
+ it{ expects_running('failing').should exit_with_code(2) }
106
+ end
107
+
108
+ context 'when statically defined with no default method' do
109
+ subject do
110
+ Kernel.module_eval do
111
+ class Static < RHC::Commands::Base
112
+ suppress_wizard
113
+
114
+ def test; 1; end
115
+
116
+ argument :testarg, "Test arg", ["--testarg testarg"]
117
+ summary "Test command execute"
118
+ alias_action :exe, :deprecated => true
119
+ def execute(testarg); 1; end
120
+
121
+ argument :args, "Test arg list", ['--tests ARG'], :type => :list, :default => lambda{ |d,a| d[a] = 'a1' }
122
+ summary "Test command execute-list"
123
+ def execute_list(args); 1; end
124
+
125
+ argument :arg1, "Test arg", ['--test'], :optional => true, :default => 1
126
+ argument :arg2, "Test arg list", ['--test2'], :type => :list, :optional => true
127
+ argument :arg3, "Test arg list", ['--test3'], :type => :list, :optional => true
128
+ summary "Test command execute-vararg"
129
+ def execute_vararg(arg1, arg2, arg3); 1; end
130
+
131
+ argument :arg1, "Test arg", ['--test'], :allow_nil => true, :default => 'def'
132
+ argument :arg2, "Test arg list", ['--test2'], :type => :list, :optional => true
133
+ summary "Test command execute-vararg-2"
134
+ def execute_vararg_2(arg1, arg2, arg3); 1; end
135
+
136
+ =begin
137
+ # Replace me with a default test case
138
+ RHC::Helpers.global_option '--test-context', 'Test', :context => :context_var
139
+ def execute_implicit
140
+ end
141
+
142
+ argument :testarg, "Test arg", ["--testarg testarg"], :context => :context_var
143
+ summary "Test command execute"
144
+ def execute_context_arg(testarg); 1; end
145
+ =end
146
+
147
+ def raise_error
148
+ raise StandardError.new("test exception")
149
+ end
150
+ def raise_exception
151
+ raise Exception.new("test exception")
152
+ end
153
+
154
+ protected
155
+ def context_var
156
+ "contextual"
157
+ end
158
+ end
159
+ end
160
+ Static
161
+ end
162
+
163
+ it("should register itself") { expect { subject }.to change(commands, :length).by(7) }
164
+ it("should have an object name of the class") { subject.object_name.should == 'static' }
165
+
166
+ context 'and when test is called' do
167
+ it { expects_running('static-test').should call(:test).on(instance).with(no_args) }
168
+ end
169
+
170
+ context 'and when execute is called with argument' do
171
+ it { expects_running('static-execute', 'simplearg').should call(:execute).on(instance).with('simplearg') }
172
+ end
173
+ context 'and when execute is called with argument switch' do
174
+ it { expects_running('static-execute', '--testarg', 'switcharg').should call(:execute).on(instance).with('switcharg') }
175
+ end
176
+ context 'and when execute is called with same argument and switch' do
177
+ it { expects_running('statis-execute', 'duparg', '--testarg', 'duparg2').should exit_with_code(1) }
178
+ end
179
+
180
+ context 'and when the provided option is ambiguous' do
181
+ it { expects_running('static-execute', '-t', '--trace').should raise_error(OptionParser::AmbiguousOption) }
182
+ end
183
+
184
+ context 'and when execute is called with too many arguments' do
185
+ it { expects_running('static-execute', 'arg1', 'arg2').should exit_with_code(1) }
186
+ end
187
+
188
+ context 'and when execute is called with a missing argument' do
189
+ it { expects_running('static-execute').should exit_with_code(1) }
190
+ end
191
+
192
+ context 'and when execute_list is called' do
193
+ it('should expose a default') { expects_running('static-execute-list', '--trace').should call(:execute_list).on(instance).with(['a1']) }
194
+ it('should handle a default') { expects_running('static-execute-list').should call(:execute_list).on(instance).with(['a1']) }
195
+ it { expects_running('static-execute-list', '1', '2', '3').should call(:execute_list).on(instance).with(['1', '2', '3']) }
196
+ it { expects_running('static-execute-list', '1', '2', '3').should call(:execute_list).on(instance).with(['1', '2', '3']) }
197
+ it('should raise an error') { expects_running('static-execute-list', '--trace', '1', '--', '2', '3').should raise_error(ArgumentError) }
198
+ it('should make the option an array') { expects_running('static-execute-list', '--tests', '1').should call(:execute_list).on(instance).with(['1']) }
199
+ it('should make the option available') { command_for('static-execute-list', '1', '2', '3').send(:options).tests.should == ['1','2','3'] }
200
+ end
201
+
202
+ context 'and when execute_vararg is called' do
203
+ it{ expects_running('static-execute-vararg').should call(:execute_vararg).on(instance).with(1, [], []) }
204
+ it{ expects_running('static-execute-vararg', '1', '2', '3').should call(:execute_vararg).on(instance).with('1', ['2', '3'], []) }
205
+ it("handles a list separator"){ expects_running('static-execute-vararg', '1', '2', '--', '3').should call(:execute_vararg).on(instance).with('1', ['2'], ['3']) }
206
+ it{ command_for('static-execute-vararg', '1', '2', '--', '3').send(:options).test.should == '1' }
207
+ it{ command_for('static-execute-vararg', '1', '2', '--', '3').send(:options).test2.should == ['2'] }
208
+ it{ command_for('static-execute-vararg', '1', '2', '--', '3').send(:options).test3.should == ['3'] }
209
+ it{ command_for('static-execute-vararg', '--', '2', '3').send(:options).test.should == 1 }
210
+ it{ command_for('static-execute-vararg', '--', '2', '3').send(:options).test2.should == ['2', '3'] }
211
+ it{ command_for('static-execute-vararg', '--', '2', '3').send(:options).test3.should == [] }
212
+ it{ command_for('static-execute-vararg', '--', '--', '3').send(:options).test.should == 1 }
213
+ it('should exclude the right'){ command_for('static-execute-vararg', '--', '--', '3').send(:options).test2.should == [] }
214
+ it{ command_for('static-execute-vararg', '--', '--', '3').send(:options).test3.should == ['3'] }
215
+ end
216
+ context 'and when execute_vararg_2 is called' do
217
+ it('should get 2 arguments'){ expects_running('static-execute-vararg-2', '1', '2', '3').should call(:execute_vararg_2).on(instance).with('1', ['2', '3']) }
218
+ it('should have default argument'){ expects_running('static-execute-vararg-2', '--', '2', '3').should call(:execute_vararg_2).on(instance).with('def', ['2', '3']) }
219
+ it{ command_for('static-execute-vararg-2', '1', '2', '3').send(:options).test.should == '1' }
220
+ it{ command_for('static-execute-vararg-2', '1', '2', '3').send(:options).test2.should == ['2', '3'] }
221
+ end
222
+ context 'and when an error is raised in a call' do
223
+ it { expects_running('static-raise-error').should raise_error(StandardError, "test exception") }
224
+ end
225
+
226
+ context 'and when an exception is raised in a call' do
227
+ it { expects_running('static-raise-exception').should raise_error(Exception, "test exception") }
228
+ end
229
+
230
+ context 'and when an exception is raised in a call with --trace option' do
231
+ it { expects_running('static-raise-exception', "--trace").should raise_error(Exception, "test exception") }
232
+ end
233
+
234
+ context 'and when deprecated alias is called' do
235
+ it("prints a warning") do
236
+ expects_running('static', 'exe', "arg").should call(:execute).on(instance).with('arg')
237
+ stderr.should match("Warning: This command is deprecated. Please use 'pbox static-execute' instead.")
238
+ end
239
+ end
240
+
241
+ context 'and when deprecated alias is called with DISABLE_DEPRECATED env var' do
242
+ before { ENV['DISABLE_DEPRECATED'] = '1' }
243
+ after { ENV['DISABLE_DEPRECATED'] = nil }
244
+ it("raises an error") { expects_running('static', 'exe', 'arg', '--trace').should raise_error(RHC::DeprecatedError) }
245
+ end
246
+ end
247
+ end
248
+
249
+ describe "find_domain" do
250
+ let(:instance){ subject }
251
+ let(:rest_client){ subject.send(:rest_client) }
252
+ let(:options){ subject.send(:options) }
253
+ def expects_method(*args)
254
+ expect{ subject.send(:find_domain, *args) }
255
+ end
256
+ before{ subject.stub(:namespace_context).and_return(nil) }
257
+
258
+ it("should raise without params"){ expects_method(nil).to raise_error(ArgumentError, /You must specify a domain with -n/) }
259
+ it("should handle namespace param"){ options[:namespace] = 'domain_o'; expects_method.to call(:find_domain).on(rest_client).with('domain_o') }
260
+
261
+ context "with a context" do
262
+ before{ subject.stub(:namespace_context).and_return('domain_s') }
263
+ it("should handle namespace param"){ expects_method.to call(:find_domain).on(rest_client).with('domain_s') }
264
+ end
265
+ end
266
+
267
+ describe "find_app" do
268
+ let(:instance){ subject }
269
+ let(:rest_client){ subject.send(:rest_client) }
270
+ let(:options){ subject.send(:options) }
271
+ def expects_method(*args)
272
+ expect{ subject.send(:find_app, *args) }
273
+ end
274
+ before{ subject.stub(:namespace_context).and_return('domain_s') }
275
+
276
+ it("should raise without params"){ expects_method(nil).to raise_error(ArgumentError, /You must specify an application with -a/) }
277
+
278
+ context "when looking for an app" do
279
+ it("should raise without app") { expects_method.to raise_error(ArgumentError, /You must specify an application with -a, or run this command/) }
280
+ it("should handle namespace param"){ options[:namespace] = 'domain_o'; expects_method.to raise_error(ArgumentError, /You must specify an application with -a, or run this command/) }
281
+ it("should accept app param") { options[:app] = 'app_o'; expects_method.to call(:find_application).on(rest_client).with('domain_s', 'app_o', {}) }
282
+ it("should split app param") { options[:app] = 'domain_o/app_o'; expects_method.to call(:find_application).on(rest_client).with('domain_o', 'app_o', {}) }
283
+ it("should find gear groups") { options[:app] = 'domain_o/app_o'; expects_method(:with_gear_groups => true, :include => :cartridges).to call(:find_application_gear_groups).on(rest_client).with('domain_o', 'app_o', {:include => :cartridges}) }
284
+ end
285
+ end
286
+
287
+ describe "find_domain_or_app" do
288
+ let(:instance){ subject }
289
+ let(:rest_client){ subject.send(:rest_client) }
290
+ let(:options){ subject.send(:options) }
291
+ before{ subject.stub(:namespace_context).and_return('domain_s') }
292
+ def expects_method(*args)
293
+ expect{ subject.send(:find_app_or_domain, *args) }
294
+ end
295
+
296
+ it("should not infer domain") { expects_method.to raise_error(ArgumentError, /You must specify a domain with -n, or an application with -a/) }
297
+ it("should assume domain with -n") { options[:namespace] = 'domain_o'; expects_method.to call(:find_domain).on(rest_client).with('domain_o') }
298
+ it("should infer -n when -a is available"){ options[:app] = 'app_o'; expects_method.to call(:find_application).on(rest_client).with('domain_s', 'app_o') }
299
+ it("should split -a param") { options[:app] = 'domain_o/app_o'; expects_method.to call(:find_application).on(rest_client).with('domain_o', 'app_o') }
300
+
301
+ context "when an app context is available" do
302
+ before{ subject.instance_variable_set(:@local_git_config, {:app => 'app_s'}) }
303
+ it("should ignore the app context"){ options[:namespace] = 'domain_o'; expects_method(nil).to call(:find_domain).on(rest_client).with('domain_o') }
304
+ end
305
+ end
306
+
307
+ describe "rest_client" do
308
+ let(:instance){ subject }
309
+ before{ RHC::Rest::Client.any_instance.stub(:api_version_negotiated).and_return(1.4) }
310
+
311
+ context "when initializing the object" do
312
+ let(:auth){ double('auth') }
313
+ let(:basic_auth){ double('basic_auth') }
314
+ before{ RHC::Auth::Basic.should_receive(:new).at_least(1).times.with{ |arg| arg.should == instance.send(:options) }.and_return(basic_auth) }
315
+ before{ RHC::Auth::Token.stub(:new).with{ |arg, arg2, arg3| [arg, arg2, arg3].should == [instance.send(:options), basic_auth, instance.send(:token_store)] }.and_return(auth) }
316
+
317
+ context "with no options" do
318
+ before{ subject.should_receive(:client_from_options).with(:auth => basic_auth) }
319
+ it("should create only a basic auth object"){ subject.send(:rest_client) }
320
+ end
321
+
322
+ context "with use_authorization_tokens" do
323
+ before{ subject.send(:options).use_authorization_tokens = true }
324
+ before{ subject.should_receive(:client_from_options).with(:auth => auth) }
325
+ it("should create a token auth object"){ subject.send(:rest_client) }
326
+ end
327
+
328
+ it { subject.send(:rest_client).should be_a(RHC::Rest::Client) }
329
+ it { subject.send(:rest_client).should equal subject.send(:rest_client) }
330
+ end
331
+
332
+ context "from a command line" do
333
+ subject{ Class.new(RHC::Commands::Base){ object_name :test; def run; 0; end } }
334
+ let(:instance) { subject.new }
335
+ let(:rest_client){ command_for(*arguments).send(:rest_client) }
336
+ let(:basic_auth){ auth = rest_client.send(:auth); auth.is_a?(RHC::Auth::Basic) ? auth : auth.send(:auth) }
337
+ let(:stored_token){ nil }
338
+ before{ instance.send(:token_store).stub(:get).and_return(nil) unless stored_token }
339
+
340
+ context "with credentials" do
341
+ let(:arguments){ ['test', '-l', 'foo', '-p', 'bar'] }
342
+ it { expect{ rest_client.user }.to call(:user).on(rest_client) }
343
+ end
344
+
345
+ context "without password" do
346
+ let(:username){ 'foo' }
347
+ let(:password){ 'bar' }
348
+ let(:arguments){ ['test', '-l', username, '--server', mock_uri] }
349
+ before{ stub_api; challenge{ stub_user(:user => username, :password => password) } }
350
+ before{ basic_auth.should_receive(:ask).and_return(password) }
351
+ it("asks for password") { rest_client.user }
352
+ end
353
+
354
+ context "without name or password" do
355
+ let(:username){ 'foo' }
356
+ let(:password){ 'bar' }
357
+ let(:arguments){ ['test', '--server', mock_uri] }
358
+ before{ stub_api; challenge{ stub_user(:user => username, :password => password) } }
359
+ before{ basic_auth.should_receive(:ask).ordered.and_return(username) }
360
+ before{ basic_auth.should_receive(:ask).ordered.and_return(password) }
361
+ it("asks for password") { rest_client.user }
362
+ end
363
+
364
+ context "with token" do
365
+ let(:username){ 'foo' }
366
+ let(:token){ 'a_token' }
367
+ let(:arguments){ ['test', '--token', token, '--server', mock_uri] }
368
+ before{ stub_api(:token => token); stub_user(:token => token) }
369
+ it("calls the server") { rest_client.user }
370
+ end
371
+
372
+ context "with username and a stored token" do
373
+ let(:username){ 'foo' }
374
+ let(:stored_token){ 'a_token' }
375
+ let(:arguments){ ['test', '-l', username, '--server', mock_uri] }
376
+ before{ stub_api; stub_user(:token => stored_token) }
377
+
378
+ context "when tokens are not allowed" do
379
+ it("calls the server") { rest_client.send(:auth).is_a? RHC::Auth::Basic }
380
+ it("does not have a token set") { command_for(*arguments).send(:token_for_user).should be_nil }
381
+ end
382
+
383
+ context "when tokens are allowed" do
384
+ let!(:config){ base_config{ |c, d| d.add('use_authorization_tokens', 'true') } }
385
+ before{ instance.send(:token_store).should_receive(:get).with{ |user, server| user.should == username; server.should == instance.send(:protonbox_server) }.and_return(stored_token) }
386
+ it("has token set") { command_for(*arguments).send(:token_for_user).should == stored_token }
387
+ it("calls the server") { rest_client.user }
388
+ end
389
+ end
390
+
391
+ context "with username and tokens enabled" do
392
+ let!(:config){ base_config{ |c, d| d.add('use_authorization_tokens', 'true') } }
393
+ let(:username){ 'foo' }
394
+ let(:auth_token){ double(:token => 'a_token') }
395
+ let(:arguments){ ['test', '-l', username, '--server', mock_uri] }
396
+ before{ instance.send(:token_store).should_receive(:get).with{ |user, server| user.should == username; server.should == instance.send(:protonbox_server) }.and_return(nil) }
397
+ before{ stub_api(false, true); stub_api_request(:get, 'broker/rest/user', false).to_return{ |request| request.headers['Authorization'] =~ /Bearer/ ? simple_user(username) : {:status => 401} } }
398
+ it("should attempt to create a new token") do
399
+ rest_client.should_receive(:new_session).ordered.and_return(auth_token)
400
+ rest_client.user
401
+ end
402
+ end
403
+
404
+ context "with username and tokens enabled against a server without tokens" do
405
+ let!(:config){ base_config{ |c, d| d.add('use_authorization_tokens', 'true') } }
406
+ let(:username){ 'foo' }
407
+ let(:arguments){ ['test', '-l', username, '--server', mock_uri] }
408
+ before{ instance.send(:token_store).should_receive(:get).with{ |user, server| user.should == username; server.should == instance.send(:protonbox_server) }.and_return(nil) }
409
+ before do
410
+ stub_api(false, false)
411
+ stub_api_request(:get, 'broker/rest/user', false).to_return{ |request| request.headers['Authorization'] =~ /Basic/ ? simple_user(username) : {:status => 401, :headers => {'WWW-Authenticate' => 'Basic realm="protonbox broker"'} } }
412
+ stub_api_request(:get, 'broker/rest/user', {:user => username, :password => 'password'}).to_return{ simple_user(username) }
413
+ end
414
+ it("should prompt for password") do
415
+ basic_auth.should_receive(:ask).once.and_return('password')
416
+ rest_client.user
417
+ end
418
+ end
419
+ end
420
+ end
421
+ end
422
+
423
+ describe Commander::Command::Options do
424
+ it{ subject.foo = 'bar'; subject.foo.should == 'bar' }
425
+ it{ subject.foo = 'bar'; subject.respond_to?(:foo).should be_true }
426
+ it{ subject.foo = lambda{ 'bar' }; subject.foo.should == 'bar' }
427
+ it{ subject.foo = lambda{ 'bar' }; subject[:foo].should == 'bar' }
428
+ it{ subject.foo = lambda{ 'bar' }; subject['foo'].should == 'bar' }
429
+ it{ subject.foo = lambda{ 'bar' }; subject.__hash__[:foo].should be_a Proc }
430
+ it{ subject[:foo] = lambda{ 'bar' }; subject.foo.should == 'bar' }
431
+ it{ subject['foo'] = lambda{ 'bar' }; subject.foo.should == 'bar' }
432
+ it{ subject.is_a?(Commander::Command::Options).should be_true }
433
+ it{ expect{ subject.barf? }.to raise_error(NoMethodError) }
434
+ it{ Commander::Command::Options.new(:foo => 1).foo.should == 1 }
435
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ require 'rest_spec_helper'
3
+ require 'rhc'
4
+ require 'rhc/commands/account'
5
+
6
+ describe RHC::Commands::Account do
7
+
8
+ describe '#run' do
9
+ let(:arguments) { ['account'] }
10
+ let(:username) { 'foo' }
11
+ let(:password) { 'pass' }
12
+ let(:server) { mock_uri }
13
+ before{ user_config }
14
+ before do
15
+ stub_api
16
+ challenge{ stub_user }
17
+ end
18
+
19
+ it('should display the correct user') { run_output.should =~ /Login #{username}/ }
20
+ it('should display the correct server') { run_output.should =~ /on #{server}/ }
21
+ it('should not show') { run_output.should_not =~ /Plan:/ }
22
+ it('should show the gear capabilities') { run_output.should =~ /Allowed Gear Sizes:\s*small/ }
23
+ it('should show the consumed gears') { run_output.should =~ /Gears Used:\s*0/ }
24
+ it('should show the maximum gears') { run_output.should =~ /Gears Allowed:\s*3/ }
25
+ it { expect { run }.to exit_with_code(0) }
26
+
27
+ context 'with a free plan' do
28
+ let(:user_plan_id){ 'free' }
29
+ it('should show') { run_output.should =~ /Plan:\s*Free/ }
30
+ end
31
+
32
+ context 'with a silver plan' do
33
+ let(:user_plan_id){ 'silver' }
34
+ it('should show') { run_output.should =~ /Plan:\s*Silver/ }
35
+ end
36
+
37
+ context 'with a arbitrary plan' do
38
+ let(:user_plan_id){ 'other' }
39
+ it('should show') { run_output.should =~ /Plan:\s*Other/ }
40
+ end
41
+ end
42
+ end