turbot 0.0.2

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 (71) hide show
  1. checksums.yaml +15 -0
  2. data/README.md +36 -0
  3. data/bin/turbot +17 -0
  4. data/data/cacert.pem +3988 -0
  5. data/lib/turbot/auth.rb +315 -0
  6. data/lib/turbot/cli.rb +38 -0
  7. data/lib/turbot/client/cisaurus.rb +25 -0
  8. data/lib/turbot/client/pgbackups.rb +113 -0
  9. data/lib/turbot/client/rendezvous.rb +111 -0
  10. data/lib/turbot/client/ssl_endpoint.rb +25 -0
  11. data/lib/turbot/client/turbot_postgresql.rb +148 -0
  12. data/lib/turbot/client.rb +757 -0
  13. data/lib/turbot/command/auth.rb +85 -0
  14. data/lib/turbot/command/base.rb +192 -0
  15. data/lib/turbot/command/bots.rb +326 -0
  16. data/lib/turbot/command/config.rb +123 -0
  17. data/lib/turbot/command/help.rb +179 -0
  18. data/lib/turbot/command/keys.rb +115 -0
  19. data/lib/turbot/command/logs.rb +34 -0
  20. data/lib/turbot/command/ssl.rb +43 -0
  21. data/lib/turbot/command/status.rb +51 -0
  22. data/lib/turbot/command/update.rb +47 -0
  23. data/lib/turbot/command/version.rb +23 -0
  24. data/lib/turbot/command.rb +304 -0
  25. data/lib/turbot/deprecated/help.rb +38 -0
  26. data/lib/turbot/deprecated.rb +5 -0
  27. data/lib/turbot/distribution.rb +9 -0
  28. data/lib/turbot/errors.rb +28 -0
  29. data/lib/turbot/excon.rb +11 -0
  30. data/lib/turbot/helpers/log_displayer.rb +70 -0
  31. data/lib/turbot/helpers/pg_dump_restore.rb +115 -0
  32. data/lib/turbot/helpers/turbot_postgresql.rb +213 -0
  33. data/lib/turbot/helpers.rb +521 -0
  34. data/lib/turbot/plugin.rb +165 -0
  35. data/lib/turbot/updater.rb +171 -0
  36. data/lib/turbot/version.rb +3 -0
  37. data/lib/turbot.rb +19 -0
  38. data/lib/vendor/turbot/okjson.rb +598 -0
  39. data/spec/helper/legacy_help.rb +16 -0
  40. data/spec/helper/pg_dump_restore_spec.rb +67 -0
  41. data/spec/schemas/dummy_schema.json +12 -0
  42. data/spec/spec.opts +1 -0
  43. data/spec/spec_helper.rb +220 -0
  44. data/spec/support/display_message_matcher.rb +49 -0
  45. data/spec/support/dummy_api.rb +120 -0
  46. data/spec/support/openssl_mock_helper.rb +8 -0
  47. data/spec/support/organizations_mock_helper.rb +11 -0
  48. data/spec/turbot/auth_spec.rb +214 -0
  49. data/spec/turbot/client/pgbackups_spec.rb +43 -0
  50. data/spec/turbot/client/rendezvous_spec.rb +62 -0
  51. data/spec/turbot/client/ssl_endpoint_spec.rb +48 -0
  52. data/spec/turbot/client/turbot_postgresql_spec.rb +71 -0
  53. data/spec/turbot/client_spec.rb +548 -0
  54. data/spec/turbot/command/auth_spec.rb +38 -0
  55. data/spec/turbot/command/base_spec.rb +66 -0
  56. data/spec/turbot/command/bots_spec.rb +54 -0
  57. data/spec/turbot/command/config_spec.rb +143 -0
  58. data/spec/turbot/command/help_spec.rb +90 -0
  59. data/spec/turbot/command/keys_spec.rb +117 -0
  60. data/spec/turbot/command/logs_spec.rb +60 -0
  61. data/spec/turbot/command/status_spec.rb +48 -0
  62. data/spec/turbot/command/version_spec.rb +16 -0
  63. data/spec/turbot/command_spec.rb +131 -0
  64. data/spec/turbot/helpers/turbot_postgresql_spec.rb +181 -0
  65. data/spec/turbot/helpers_spec.rb +48 -0
  66. data/spec/turbot/plugin_spec.rb +172 -0
  67. data/spec/turbot/updater_spec.rb +44 -0
  68. data/templates/manifest.json +7 -0
  69. data/templates/scraper.py +5 -0
  70. data/templates/scraper.rb +6 -0
  71. metadata +199 -0
@@ -0,0 +1,548 @@
1
+ require "spec_helper"
2
+ require "turbot/client"
3
+ require "turbot/helpers"
4
+ require 'turbot/command'
5
+
6
+ describe Turbot::Client do
7
+ include Turbot::Helpers
8
+
9
+ before do
10
+ @client = Turbot::Client.new(nil, nil)
11
+ @resource = mock('turbot rest resource')
12
+ @client.stub!(:extract_warning)
13
+ end
14
+
15
+ it "Client.auth -> get user details" do
16
+ user_info = { "api_key" => "abc" }
17
+ stub_request(:post, "https://foo:bar@api.turbot.com/login").to_return(:body => json_encode(user_info))
18
+ capture_stderr do # capture deprecation message
19
+ Turbot::Client.auth("foo", "bar").should == user_info
20
+ end
21
+ end
22
+
23
+ it "list -> get a list of this user's bots" do
24
+ stub_api_request(:get, "/bots").to_return(:body => <<-EOXML)
25
+ <?xml version='1.0' encoding='UTF-8'?>
26
+ <bots type="array">
27
+ <bot><name>example</name><owner>test@turbot.com</owner></bot>
28
+ <bot><name>example2</name><owner>test@turbot.com</owner></bot>
29
+ </bots>
30
+ EOXML
31
+ capture_stderr do # capture deprecation message
32
+ @client.list.should == [
33
+ ["example", "test@turbot.com"],
34
+ ["example2", "test@turbot.com"]
35
+ ]
36
+ end
37
+ end
38
+
39
+ it "info -> get bot attributes" do
40
+ stub_api_request(:get, "/bots/example").to_return(:body => <<-EOXML)
41
+ <?xml version='1.0' encoding='UTF-8'?>
42
+ <bot>
43
+ <blessed type='boolean'>true</blessed>
44
+ <created-at type='datetime'>2008-07-08T17:21:50-07:00</created-at>
45
+ <id type='integer'>49134</id>
46
+ <name>example</name>
47
+ <production type='boolean'>true</production>
48
+ <share-public type='boolean'>true</share-public>
49
+ <domain_name/>
50
+ </bot>
51
+ EOXML
52
+ @client.stub!(:list_collaborators).and_return([:jon, :mike])
53
+ @client.stub!(:installed_addons).and_return([:addon1])
54
+ capture_stderr do # capture deprecation message
55
+ @client.info('example').should == { :blessed => 'true', :created_at => '2008-07-08T17:21:50-07:00', :id => '49134', :name => 'example', :production => 'true', :share_public => 'true', :domain_name => nil, :collaborators => [:jon, :mike], :addons => [:addon1] }
56
+ end
57
+ end
58
+
59
+ it "create_request -> create a new blank bot" do
60
+ stub_api_request(:post, "/bots").with(:body => "").to_return(:body => <<-EOXML)
61
+ <?xml version="1.0" encoding="UTF-8"?>
62
+ <bot><name>untitled-123</name></bot>
63
+ EOXML
64
+ capture_stderr do # capture deprecation message
65
+ @client.create_request.should == "untitled-123"
66
+ end
67
+ end
68
+
69
+ it "create_request(name) -> create a new blank bot with a specified name" do
70
+ stub_api_request(:post, "/bots").with(:body => "bot[name]=newapp").to_return(:body => <<-EOXML)
71
+ <?xml version="1.0" encoding="UTF-8"?>
72
+ <bot><name>newapp</name></bot>
73
+ EOXML
74
+ capture_stderr do # capture deprecation message
75
+ @client.create_request("newapp").should == "newapp"
76
+ end
77
+ end
78
+
79
+ it "create_complete?(name) -> checks if a create request is complete" do
80
+ @response = mock('response')
81
+ @response.should_receive(:code).and_return(202)
82
+ @client.should_receive(:resource).and_return(@resource)
83
+ @resource.should_receive(:put).with({}, @client.turbot_headers).and_return(@response)
84
+ capture_stderr do # capture deprecation message
85
+ @client.create_complete?('example').should be_false
86
+ end
87
+ end
88
+
89
+ it "update(name, attributes) -> updates existing bots" do
90
+ stub_api_request(:put, "/bots/example").with(:body => "bot[mode]=production")
91
+ capture_stderr do # capture deprecation message
92
+ @client.update("example", :mode => 'production')
93
+ end
94
+ end
95
+
96
+ it "destroy(name) -> destroy the named bot" do
97
+ stub_api_request(:delete, "/bots/destroyme")
98
+ capture_stderr do # capture deprecation message
99
+ @client.destroy("destroyme")
100
+ end
101
+ end
102
+
103
+ it "rake(bot_name, cmd) -> run a rake command on the bot" do
104
+ stub_api_request(:post, "/bots/example/services").with(:body => "rake db:migrate").to_return(:body => "foo")
105
+ stub_api_request(:get, "/foo").to_return(:body => "output")
106
+ capture_stderr do # capture deprecation message
107
+ @client.rake('example', 'db:migrate')
108
+ end
109
+ end
110
+
111
+ it "console(bot_name, cmd) -> run a console command on the bot" do
112
+ stub_api_request(:post, "/bots/example/console").with(:body => "command=2%2B2")
113
+ @client.console('example', '2+2')
114
+ end
115
+
116
+ it "console(bot_name) { |c| } -> opens a console session, yields one accessor and closes it after the block" do
117
+ stub_api_request(:post, "/bots/example/consoles").to_return(:body => "consolename")
118
+ stub_api_request(:post, "/bots/example/consoles/consolename/command").with(:body => "command=1%2B1").to_return(:body => "2")
119
+ stub_api_request(:delete, "/bots/example/consoles/consolename")
120
+
121
+ @client.console('example') do |c|
122
+ c.run("1+1").should == '=> 2'
123
+ end
124
+ end
125
+
126
+ it "shows an error message when a console request fails" do
127
+ stub_request(:post, %r{.*/bots/example/console}).to_return({
128
+ :body => "ERRMSG", :status => 502
129
+ })
130
+ lambda { @client.console('example') }.should raise_error(Turbot::Client::AppCrashed, /Your application may have crashed/)
131
+ end
132
+
133
+ it "restart(bot_name) -> restarts the bot servers" do
134
+ stub_api_request(:delete, "/bots/example/server")
135
+ capture_stderr do # capture deprecation message
136
+ @client.restart('example')
137
+ end
138
+ end
139
+
140
+ describe "read_logs" do
141
+ describe "old style" do
142
+ before(:each) do
143
+ stub_api_request(:get, "/bots/example/logs?logplex=true").to_return(:body => "Use old logs")
144
+ stub_api_request(:get, "/bots/example/logs").to_return(:body => "oldlogs")
145
+ end
146
+
147
+ it "can read old style logs" do
148
+ @client.should_receive(:puts).with("oldlogs")
149
+ @client.read_logs("example")
150
+ end
151
+ end
152
+
153
+ describe "new style" do
154
+ before(:each) do
155
+ stub_api_request(:get, "/bots/example/logs?logplex=true").to_return(:body => "https://logplex.turbot.com/identifier")
156
+ stub_request(:get, "https://logplex.turbot.com/identifier").to_return(:body => "newlogs")
157
+ end
158
+
159
+ it "can read new style logs" do
160
+ @client.read_logs("example") do |logs|
161
+ logs.should == "newlogs"
162
+ end
163
+ end
164
+ end
165
+ end
166
+
167
+ it "logs(bot_name) -> returns recent output of the bot logs" do
168
+ stub_api_request(:get, "/bots/example/logs").to_return(:body => "log")
169
+ capture_stderr do # capture deprecation message
170
+ @client.logs('example').should == 'log'
171
+ end
172
+ end
173
+
174
+ it "can get the number of dynos" do
175
+ stub_api_request(:get, "/bots/example").to_return(:body => <<-EOXML)
176
+ <?xml version='1.0' encoding='UTF-8'?>
177
+ <bot>
178
+ <dynos type='integer'>5</dynos>
179
+ </bot>
180
+ EOXML
181
+ capture_stderr do # capture deprecation message
182
+ @client.dynos('example').should == 5
183
+ end
184
+ end
185
+
186
+ it "can get the number of workers" do
187
+ stub_api_request(:get, "/bots/example").to_return(:body => <<-EOXML)
188
+ <?xml version='1.0' encoding='UTF-8'?>
189
+ <bot>
190
+ <workers type='integer'>5</workers>
191
+ </bot>
192
+ EOXML
193
+ capture_stderr do # capture deprecation message
194
+ @client.workers('example').should == 5
195
+ end
196
+ end
197
+
198
+ it "set_dynos(bot_name, qty) -> scales the bot" do
199
+ stub_api_request(:put, "/bots/example/dynos").with(:body => "dynos=3")
200
+ capture_stderr do # capture deprecation message
201
+ @client.set_dynos('example', 3)
202
+ end
203
+ end
204
+
205
+ it "rake catches 502s and shows the bot crashlog" do
206
+ e = RestClient::RequestFailed.new
207
+ e.stub!(:http_code).and_return(502)
208
+ e.stub!(:http_body).and_return('the crashlog')
209
+ @client.should_receive(:post).and_raise(e)
210
+ capture_stderr do # capture deprecation message
211
+ lambda { @client.rake('example', '') }.should raise_error(Turbot::Client::AppCrashed)
212
+ end
213
+ end
214
+
215
+ it "rake passes other status codes (i.e., 500) as standard restclient exceptions" do
216
+ e = RestClient::RequestFailed.new
217
+ e.stub!(:http_code).and_return(500)
218
+ e.stub!(:http_body).and_return('not a crashlog')
219
+ @client.should_receive(:post).and_raise(e)
220
+ capture_stderr do # capture deprecation message
221
+ lambda { @client.rake('example', '') }.should raise_error(RestClient::RequestFailed)
222
+ end
223
+ end
224
+
225
+ describe "ps_scale" do
226
+ it "scales a process and returns the new count" do
227
+ stub_api_request(:post, "/bots/example/ps/scale").with(:body => { :type => "web", :qty => "5" }).to_return(:body => "5")
228
+ capture_stderr do # capture deprecation message
229
+ @client.ps_scale("example", :type => "web", :qty => "5").should == 5
230
+ end
231
+ end
232
+ end
233
+
234
+ describe "collaborators" do
235
+ it "list(bot_name) -> list bot collaborators" do
236
+ stub_api_request(:get, "/bots/example/collaborators").to_return(:body => <<-EOXML)
237
+ <?xml version="1.0" encoding="UTF-8"?>
238
+ <collaborators type="array">
239
+ <collaborator><email>joe@example.com</email></collaborator>
240
+ <collaborator><email>jon@example.com</email></collaborator>
241
+ </collaborators>
242
+ EOXML
243
+ capture_stderr do # capture deprecation message
244
+ @client.list_collaborators('example').should == [
245
+ { :email => 'joe@example.com' },
246
+ { :email => 'jon@example.com' }
247
+ ]
248
+ end
249
+ end
250
+
251
+ it "add_collaborator(bot_name, email) -> adds collaborator to bot" do
252
+ stub_api_request(:post, "/bots/example/collaborators").with(:body => "collaborator%5Bemail%5D=joe%40example.com")
253
+ capture_stderr do # capture deprecation message
254
+ @client.add_collaborator('example', 'joe@example.com')
255
+ end
256
+ end
257
+
258
+ it "remove_collaborator(bot_name, email) -> removes collaborator from bot" do
259
+ stub_api_request(:delete, "/bots/example/collaborators/joe%40example%2Ecom")
260
+ capture_stderr do # capture deprecation message
261
+ @client.remove_collaborator('example', 'joe@example.com')
262
+ end
263
+ end
264
+ end
265
+
266
+ describe "domain names" do
267
+ it "list(bot_name) -> list bot domain names" do
268
+ stub_api_request(:get, "/bots/example/domains").to_return(:body => <<-EOXML)
269
+ <?xml version="1.0" encoding="UTF-8"?>
270
+ <domains type="array">
271
+ <domain-name><domain>example1.com</domain></domain-name>
272
+ <domain-name><domain>example2.com</domain></domain-name>
273
+ </domains>
274
+ EOXML
275
+ capture_stderr do # capture deprecation message
276
+ @client.list_domains('example').should == [{:domain => 'example1.com'}, {:domain => 'example2.com'}]
277
+ end
278
+ end
279
+
280
+ it "add_domain(bot_name, domain) -> adds domain name to bot" do
281
+ stub_api_request(:post, "/bots/example/domains").with(:body => "example.com")
282
+ capture_stderr do # capture deprecation message
283
+ @client.add_domain('example', 'example.com')
284
+ end
285
+ end
286
+
287
+ it "remove_domain(bot_name, domain) -> removes domain name from bot" do
288
+ stub_api_request(:delete, "/bots/example/domains/example.com")
289
+ capture_stderr do # capture deprecation message
290
+ @client.remove_domain('example', 'example.com')
291
+ end
292
+ end
293
+
294
+ it "remove_domain(bot_name, domain) -> makes sure a domain is set" do
295
+ lambda do
296
+ capture_stderr do # capture deprecation message
297
+ @client.remove_domain('example', '')
298
+ end
299
+ end.should raise_error(ArgumentError)
300
+ end
301
+
302
+ it "remove_domains(bot_name) -> removes all domain names from bot" do
303
+ stub_api_request(:delete, "/bots/example/domains")
304
+ capture_stderr do # capture deprecation message
305
+ @client.remove_domains('example')
306
+ end
307
+ end
308
+
309
+ it "add_ssl(bot_name, pem, key) -> adds a ssl cert to the domain" do
310
+ stub_api_request(:post, "/bots/example/ssl").with do |request|
311
+ body = CGI::parse(request.body)
312
+ body["key"].first.should == "thekey"
313
+ body["pem"].first.should == "thepem"
314
+ end.to_return(:body => "{}")
315
+ @client.add_ssl('example', 'thepem', 'thekey')
316
+ end
317
+
318
+ it "remove_ssl(bot_name, domain) -> removes the ssl cert for the domain" do
319
+ stub_api_request(:delete, "/bots/example/domains/example.com/ssl")
320
+ @client.remove_ssl('example', 'example.com')
321
+ end
322
+ end
323
+
324
+ describe "SSH keys" do
325
+ it "fetches a list of the user's current keys" do
326
+ stub_api_request(:get, "/user/keys").to_return(:body => <<-EOXML)
327
+ <?xml version="1.0" encoding="UTF-8"?>
328
+ <keys type="array">
329
+ <key>
330
+ <contents>ssh-dss thekey== joe@workstation</contents>
331
+ </key>
332
+ </keys>
333
+ EOXML
334
+ capture_stderr do # capture deprecation message
335
+ @client.keys.should == [ "ssh-dss thekey== joe@workstation" ]
336
+ end
337
+ end
338
+
339
+ it "add_key(key) -> add an SSH key (e.g., the contents of id_rsa.pub) to the user" do
340
+ stub_api_request(:post, "/user/keys").with(:body => "a key")
341
+ capture_stderr do # capture deprecation message
342
+ @client.add_key('a key')
343
+ end
344
+ end
345
+
346
+ it "remove_key(key) -> remove an SSH key by name (user@box)" do
347
+ stub_api_request(:delete, "/user/keys/joe%40workstation")
348
+ capture_stderr do # capture deprecation message
349
+ @client.remove_key('joe@workstation')
350
+ end
351
+ end
352
+
353
+ it "remove_all_keys -> removes all SSH keys for the user" do
354
+ stub_api_request(:delete, "/user/keys")
355
+ capture_stderr do # capture deprecation message
356
+ @client.remove_all_keys
357
+ end
358
+ end
359
+
360
+ it "maintenance(bot_name, :on) -> sets maintenance mode for an bot" do
361
+ stub_api_request(:post, "/bots/example/server/maintenance").with(:body => "maintenance_mode=1")
362
+ capture_stderr do # capture deprecation message
363
+ @client.maintenance('example', :on)
364
+ end
365
+ end
366
+
367
+ it "maintenance(bot_name, :off) -> turns off maintenance mode for an bot" do
368
+ stub_api_request(:post, "/bots/example/server/maintenance").with(:body => "maintenance_mode=0")
369
+ capture_stderr do # capture deprecation message
370
+ @client.maintenance('example', :off)
371
+ end
372
+ end
373
+ end
374
+
375
+ describe "config vars" do
376
+ it "config_vars(bot_name) -> json hash of config vars for the bot" do
377
+ stub_api_request(:get, "/bots/example/config_vars").to_return(:body => '{"A":"one", "B":"two"}')
378
+ capture_stderr do # capture deprecation message
379
+ @client.config_vars('example').should == { 'A' => 'one', 'B' => 'two'}
380
+ end
381
+ end
382
+
383
+ it "add_config_vars(bot_name, vars)" do
384
+ stub_api_request(:put, "/bots/example/config_vars").with(:body => '{"x":"y"}')
385
+ capture_stderr do # capture deprecation message
386
+ @client.add_config_vars('example', {'x'=> 'y'})
387
+ end
388
+ end
389
+
390
+ it "remove_config_var(bot_name, key)" do
391
+ stub_api_request(:delete, "/bots/example/config_vars/mykey")
392
+ capture_stderr do # capture deprecation message
393
+ @client.remove_config_var('example', 'mykey')
394
+ end
395
+ end
396
+
397
+ it "clear_config_vars(bot_name) -> resets all config vars for this bot" do
398
+ stub_api_request(:delete, "/bots/example/config_vars")
399
+ capture_stderr do # capture deprecation message
400
+ @client.clear_config_vars('example')
401
+ end
402
+ end
403
+
404
+ it "can handle config vars with special characters" do
405
+ stub_api_request(:delete, "/bots/example/config_vars/foo%5Bbar%5D")
406
+ capture_stderr do # capture deprecation message
407
+ lambda { @client.remove_config_var('example', 'foo[bar]') }.should_not raise_error
408
+ end
409
+ end
410
+ end
411
+
412
+ describe "addons" do
413
+ it "addons -> array with addons available for installation" do
414
+ stub_api_request(:get, "/addons").to_return(:body => '[{"name":"addon1"}, {"name":"addon2"}]')
415
+ @client.addons.should == [{'name' => 'addon1'}, {'name' => 'addon2'}]
416
+ end
417
+
418
+ it "installed_addons(bot_name) -> array of installed addons" do
419
+ stub_api_request(:get, "/bots/example/addons").to_return(:body => '[{"name":"addon1"}]')
420
+ @client.installed_addons('example').should == [{'name' => 'addon1'}]
421
+ end
422
+
423
+ it "install_addon(bot_name, addon_name)" do
424
+ stub_api_request(:post, "/bots/example/addons/addon1")
425
+ @client.install_addon('example', 'addon1').should be_nil
426
+ end
427
+
428
+ it "upgrade_addon(bot_name, addon_name)" do
429
+ stub_api_request(:put, "/bots/example/addons/addon1")
430
+ @client.upgrade_addon('example', 'addon1').should be_nil
431
+ end
432
+
433
+ it "downgrade_addon(bot_name, addon_name)" do
434
+ stub_api_request(:put, "/bots/example/addons/addon1")
435
+ @client.downgrade_addon('example', 'addon1').should be_nil
436
+ end
437
+
438
+ it "uninstall_addon(bot_name, addon_name)" do
439
+ stub_api_request(:delete, "/bots/example/addons/addon1?").
440
+ to_return(:body => json_encode({"message" => nil, "price" => "free", "status" => "uninstalled"}))
441
+
442
+ @client.uninstall_addon('example', 'addon1').should be_true
443
+ end
444
+
445
+ it "uninstall_addon(bot_name, addon_name) with confirmation" do
446
+ stub_api_request(:delete, "/bots/example/addons/addon1?confirm=example").
447
+ to_return(:body => json_encode({"message" => nil, "price" => "free", "status" => "uninstalled"}))
448
+
449
+ @client.uninstall_addon('example', 'addon1', :confirm => "example").should be_true
450
+ end
451
+
452
+ it "install_addon(bot_name, addon_name) with response" do
453
+ stub_request(:post, "https://api.turbot.com/bots/example/addons/addon1").
454
+ to_return(:body => json_encode({'price' => 'free', 'message' => "Don't Panic"}))
455
+
456
+ @client.install_addon('example', 'addon1').
457
+ should == { 'price' => 'free', 'message' => "Don't Panic" }
458
+ end
459
+
460
+ it "upgrade_addon(bot_name, addon_name) with response" do
461
+ stub_request(:put, "https://api.turbot.com/bots/example/addons/addon1").
462
+ to_return(:body => json_encode('price' => 'free', 'message' => "Don't Panic"))
463
+
464
+ @client.upgrade_addon('example', 'addon1').
465
+ should == { 'price' => 'free', 'message' => "Don't Panic" }
466
+ end
467
+
468
+ it "downgrade_addon(bot_name, addon_name) with response" do
469
+ stub_request(:put, "https://api.turbot.com/bots/example/addons/addon1").
470
+ to_return(:body => json_encode('price' => 'free', 'message' => "Don't Panic"))
471
+
472
+ @client.downgrade_addon('example', 'addon1').
473
+ should == { 'price' => 'free', 'message' => "Don't Panic" }
474
+ end
475
+
476
+ it "uninstall_addon(bot_name, addon_name) with response" do
477
+ stub_api_request(:delete, "/bots/example/addons/addon1?").
478
+ to_return(:body => json_encode('price'=> 'free', 'message'=> "Don't Panic"))
479
+
480
+ @client.uninstall_addon('example', 'addon1').
481
+ should == { 'price' => 'free', 'message' => "Don't Panic" }
482
+ end
483
+ end
484
+
485
+ describe "internal" do
486
+ before do
487
+ @client = Turbot::Client.new(nil, nil)
488
+ end
489
+
490
+ it "creates a RestClient resource for making calls" do
491
+ @client.stub!(:host).and_return('turbot.com')
492
+ @client.stub!(:user).and_return('joe@example.com')
493
+ @client.stub!(:password).and_return('secret')
494
+
495
+ res = @client.resource('/xyz')
496
+
497
+ res.url.should == 'https://api.turbot.com/xyz'
498
+ res.user.should == 'joe@example.com'
499
+ res.password.should == 'secret'
500
+ end
501
+
502
+ it "appends the api. prefix to the host" do
503
+ @client.host = "turbot.com"
504
+ @client.resource('/xyz').url.should == 'https://api.turbot.com/xyz'
505
+ end
506
+
507
+ it "doesn't add the api. prefix to full hosts" do
508
+ @client.host = 'http://resource'
509
+ res = @client.resource('/xyz')
510
+ res.url.should == 'http://resource/xyz'
511
+ end
512
+
513
+ it "runs a callback when the API sets a warning header" do
514
+ response = mock('rest client response', :headers => { :x_turbot_warning => 'Warning' })
515
+ @client.should_receive(:resource).and_return(@resource)
516
+ @resource.should_receive(:get).and_return(response)
517
+ @client.on_warning { |msg| @callback = msg }
518
+ @client.get('test')
519
+ @callback.should == 'Warning'
520
+ end
521
+
522
+ it "doesn't run the callback twice for the same warning" do
523
+ response = mock('rest client response', :headers => { :x_turbot_warning => 'Warning' })
524
+ @client.stub!(:resource).and_return(@resource)
525
+ @resource.stub!(:get).and_return(response)
526
+ @client.on_warning { |msg| @callback_called ||= 0; @callback_called += 1 }
527
+ @client.get('test1')
528
+ @client.get('test2')
529
+ @callback_called.should == 1
530
+ end
531
+ end
532
+
533
+ describe "stacks" do
534
+ it "list_stacks(bot_name) -> json hash of available stacks" do
535
+ stub_api_request(:get, "/bots/example/stack?include_deprecated=false").to_return(:body => '{"stack":"one"}')
536
+ capture_stderr do # capture deprecation message
537
+ @client.list_stacks("example").should == { 'stack' => 'one' }
538
+ end
539
+ end
540
+
541
+ it "list_stacks(bot_name, include_deprecated=true) passes the deprecated option" do
542
+ stub_api_request(:get, "/bots/example/stack?include_deprecated=true").to_return(:body => '{"stack":"one"}')
543
+ capture_stderr do # capture deprecation message
544
+ @client.list_stacks("example", :include_deprecated => true).should == { 'stack' => 'one' }
545
+ end
546
+ end
547
+ end
548
+ end
@@ -0,0 +1,38 @@
1
+ require "spec_helper"
2
+ require "turbot/command/auth"
3
+
4
+ describe Turbot::Command::Auth do
5
+ describe "auth" do
6
+ it "displays turbot help auth" do
7
+ stderr, stdout = execute("auth")
8
+
9
+ stderr.should == ""
10
+ stdout.should include "Additional commands"
11
+ stdout.should include "auth:login"
12
+ stdout.should include "auth:logout"
13
+ end
14
+ end
15
+
16
+ describe "auth:token" do
17
+
18
+ it "displays the user's api key" do
19
+ stderr, stdout = execute("auth:token")
20
+ stderr.should == ""
21
+ stdout.should == <<-STDOUT
22
+ apikey01
23
+ STDOUT
24
+ end
25
+ end
26
+
27
+ describe "auth:whoami" do
28
+ it "displays the user's email address" do
29
+ stderr, stdout = execute("auth:whoami")
30
+ stderr.should == ""
31
+ stdout.should == <<-STDOUT
32
+ email@example.com
33
+ STDOUT
34
+ end
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,66 @@
1
+ require "spec_helper"
2
+ require "turbot/command/base"
3
+
4
+ module Turbot::Command
5
+ describe Base do
6
+ before do
7
+ @base = Base.new
8
+ @base.stub!(:display)
9
+ @client = mock('turbot client', :host => 'turbot.com')
10
+ end
11
+
12
+ describe "confirming" do
13
+ it "confirms the bot via --confirm" do
14
+ Turbot::Command.stub(:current_options).and_return(:confirm => "example")
15
+ @base.stub(:bot).and_return("example")
16
+ @base.confirm_command.should be_true
17
+ end
18
+
19
+ it "does not confirms the bot via --confirm on a mismatch" do
20
+ Turbot::Command.stub(:current_options).and_return(:confirm => "badapp")
21
+ @base.stub(:bot).and_return("example")
22
+ lambda { @base.confirm_command}.should raise_error CommandFailed
23
+ end
24
+
25
+ it "confirms the bot interactively via ask" do
26
+ @base.stub(:bot).and_return("example")
27
+ @base.stub(:ask).and_return("example")
28
+ Turbot::Command.stub(:current_options).and_return({})
29
+ @base.confirm_command.should be_true
30
+ end
31
+
32
+ it "fails if the interactive confirm doesn't match" do
33
+ @base.stub(:bot).and_return("example")
34
+ @base.stub(:ask).and_return("badresponse")
35
+ Turbot::Command.stub(:current_options).and_return({})
36
+ capture_stderr do
37
+ lambda { @base.confirm_command }.should raise_error(SystemExit)
38
+ end.should == <<-STDERR
39
+ ! Confirmation did not match example. Aborted.
40
+ STDERR
41
+ end
42
+ end
43
+
44
+ context "detecting the bot" do
45
+ it "attempts to find the bot via the --bot option" do
46
+ @base.stub!(:options).and_return(:bot => "example")
47
+ @base.bot.should == "example"
48
+ end
49
+
50
+ it "attempts to find the bot via TURBOT_BOT when not explicitly specified" do
51
+ ENV['TURBOT_BOT'] = "myenvapp"
52
+ @base.bot.should == "myenvapp"
53
+ @base.stub!(:options).and_return([])
54
+ @base.bot.should == "myenvapp"
55
+ ENV.delete('TURBOT_BOT')
56
+ end
57
+
58
+ it "overrides TURBOT_BOT when explicitly specified" do
59
+ ENV['TURBOT_BOT'] = "myenvapp"
60
+ @base.stub!(:options).and_return(:bot => "example")
61
+ @base.bot.should == "example"
62
+ ENV.delete('TURBOT_BOT')
63
+ end
64
+ end
65
+ end
66
+ end