pogo 2.31.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 (93) hide show
  1. data/README.md +73 -0
  2. data/bin/pogo +22 -0
  3. data/data/cacert.pem +3988 -0
  4. data/lib/heroku.rb +22 -0
  5. data/lib/heroku/auth.rb +320 -0
  6. data/lib/heroku/cli.rb +38 -0
  7. data/lib/heroku/client.rb +764 -0
  8. data/lib/heroku/client/heroku_postgresql.rb +111 -0
  9. data/lib/heroku/client/pgbackups.rb +113 -0
  10. data/lib/heroku/client/rendezvous.rb +105 -0
  11. data/lib/heroku/client/ssl_endpoint.rb +25 -0
  12. data/lib/heroku/command.rb +273 -0
  13. data/lib/heroku/command/account.rb +23 -0
  14. data/lib/heroku/command/accounts.rb +34 -0
  15. data/lib/heroku/command/addons.rb +305 -0
  16. data/lib/heroku/command/apps.rb +311 -0
  17. data/lib/heroku/command/auth.rb +86 -0
  18. data/lib/heroku/command/base.rb +230 -0
  19. data/lib/heroku/command/certs.rb +148 -0
  20. data/lib/heroku/command/config.rb +137 -0
  21. data/lib/heroku/command/db.rb +218 -0
  22. data/lib/heroku/command/domains.rb +85 -0
  23. data/lib/heroku/command/drains.rb +46 -0
  24. data/lib/heroku/command/git.rb +65 -0
  25. data/lib/heroku/command/help.rb +163 -0
  26. data/lib/heroku/command/keys.rb +115 -0
  27. data/lib/heroku/command/labs.rb +161 -0
  28. data/lib/heroku/command/logs.rb +98 -0
  29. data/lib/heroku/command/maintenance.rb +61 -0
  30. data/lib/heroku/command/pg.rb +277 -0
  31. data/lib/heroku/command/pgbackups.rb +289 -0
  32. data/lib/heroku/command/plugins.rb +110 -0
  33. data/lib/heroku/command/ps.rb +232 -0
  34. data/lib/heroku/command/releases.rb +124 -0
  35. data/lib/heroku/command/run.rb +179 -0
  36. data/lib/heroku/command/sharing.rb +89 -0
  37. data/lib/heroku/command/ssl.rb +61 -0
  38. data/lib/heroku/command/stack.rb +62 -0
  39. data/lib/heroku/command/status.rb +51 -0
  40. data/lib/heroku/command/update.rb +47 -0
  41. data/lib/heroku/command/version.rb +23 -0
  42. data/lib/heroku/deprecated.rb +5 -0
  43. data/lib/heroku/deprecated/help.rb +38 -0
  44. data/lib/heroku/distribution.rb +9 -0
  45. data/lib/heroku/helpers.rb +517 -0
  46. data/lib/heroku/helpers/heroku_postgresql.rb +104 -0
  47. data/lib/heroku/plugin.rb +161 -0
  48. data/lib/heroku/updater.rb +158 -0
  49. data/lib/heroku/version.rb +3 -0
  50. data/lib/vendor/heroku/okjson.rb +598 -0
  51. data/spec/helper/legacy_help.rb +16 -0
  52. data/spec/heroku/auth_spec.rb +246 -0
  53. data/spec/heroku/client/heroku_postgresql_spec.rb +34 -0
  54. data/spec/heroku/client/pgbackups_spec.rb +43 -0
  55. data/spec/heroku/client/rendezvous_spec.rb +62 -0
  56. data/spec/heroku/client/ssl_endpoint_spec.rb +48 -0
  57. data/spec/heroku/client_spec.rb +564 -0
  58. data/spec/heroku/command/addons_spec.rb +585 -0
  59. data/spec/heroku/command/apps_spec.rb +351 -0
  60. data/spec/heroku/command/auth_spec.rb +38 -0
  61. data/spec/heroku/command/base_spec.rb +109 -0
  62. data/spec/heroku/command/certs_spec.rb +178 -0
  63. data/spec/heroku/command/config_spec.rb +144 -0
  64. data/spec/heroku/command/db_spec.rb +110 -0
  65. data/spec/heroku/command/domains_spec.rb +87 -0
  66. data/spec/heroku/command/drains_spec.rb +34 -0
  67. data/spec/heroku/command/git_spec.rb +116 -0
  68. data/spec/heroku/command/help_spec.rb +93 -0
  69. data/spec/heroku/command/keys_spec.rb +120 -0
  70. data/spec/heroku/command/labs_spec.rb +99 -0
  71. data/spec/heroku/command/logs_spec.rb +60 -0
  72. data/spec/heroku/command/maintenance_spec.rb +51 -0
  73. data/spec/heroku/command/pg_spec.rb +223 -0
  74. data/spec/heroku/command/pgbackups_spec.rb +280 -0
  75. data/spec/heroku/command/plugins_spec.rb +104 -0
  76. data/spec/heroku/command/ps_spec.rb +195 -0
  77. data/spec/heroku/command/releases_spec.rb +130 -0
  78. data/spec/heroku/command/run_spec.rb +86 -0
  79. data/spec/heroku/command/sharing_spec.rb +59 -0
  80. data/spec/heroku/command/ssl_spec.rb +32 -0
  81. data/spec/heroku/command/stack_spec.rb +46 -0
  82. data/spec/heroku/command/status_spec.rb +48 -0
  83. data/spec/heroku/command/version_spec.rb +16 -0
  84. data/spec/heroku/command_spec.rb +211 -0
  85. data/spec/heroku/helpers/heroku_postgresql_spec.rb +109 -0
  86. data/spec/heroku/helpers_spec.rb +48 -0
  87. data/spec/heroku/plugin_spec.rb +172 -0
  88. data/spec/heroku/updater_spec.rb +44 -0
  89. data/spec/spec.opts +1 -0
  90. data/spec/spec_helper.rb +209 -0
  91. data/spec/support/display_message_matcher.rb +49 -0
  92. data/spec/support/openssl_mock_helper.rb +8 -0
  93. metadata +220 -0
@@ -0,0 +1,585 @@
1
+ require "spec_helper"
2
+ require "heroku/command/addons"
3
+
4
+ module Heroku::Command
5
+ describe Addons do
6
+ before do
7
+ @addons = prepare_command(Addons)
8
+ stub_core.release("myapp", "current").returns( "name" => "v99" )
9
+ end
10
+
11
+ describe "index" do
12
+
13
+ before(:each) do
14
+ stub_core
15
+ api.post_app("name" => "myapp", "stack" => "cedar")
16
+ end
17
+
18
+ after(:each) do
19
+ api.delete_app("myapp")
20
+ end
21
+
22
+ it "should display no addons when none are configured" do
23
+ stderr, stdout = execute("addons")
24
+ stderr.should == ""
25
+ stdout.should == <<-STDOUT
26
+ myapp has no add-ons.
27
+ STDOUT
28
+ end
29
+
30
+ it "should list addons and attachments" do
31
+ Excon.stub(
32
+ {
33
+ :expects => 200,
34
+ :method => :get,
35
+ :path => %r{^/apps/myapp/addons$}
36
+ },
37
+ {
38
+ :body => Heroku::API::OkJson.encode([
39
+ { 'configured' => false, 'name' => 'deployhooks:email' },
40
+ { 'attachment_name' => 'HEROKU_POSTGRESQL_RED', 'configured' => true, 'name' => 'heroku-postgresql:ronin' },
41
+ { 'configured' => true, 'name' => 'deployhooks:http' }
42
+ ]),
43
+ :status => 200,
44
+ }
45
+ )
46
+ stderr, stdout = execute("addons")
47
+ stderr.should == ""
48
+ stdout.should == <<-STDOUT
49
+ === myapp Configured Add-ons
50
+ deployhooks:http
51
+ heroku-postgresql:ronin HEROKU_POSTGRESQL_RED
52
+
53
+ === myapp Add-ons to Configure
54
+ deployhooks:email https://api.heroku.com/myapps/myapp/addons/deployhooks:email
55
+
56
+ STDOUT
57
+ Excon.stubs.shift
58
+ end
59
+
60
+ end
61
+
62
+ describe "list" do
63
+ before do
64
+ stub_core.addons.returns([
65
+ { "name" => "cloudcounter:basic", "state" => "alpha" },
66
+ { "name" => "cloudcounter:pro", "state" => "public" },
67
+ { "name" => "cloudcounter:gold", "state" => "public" },
68
+ { "name" => "cloudcounter:old", "state" => "disabled" },
69
+ { "name" => "cloudcounter:platinum", "state" => "beta" }
70
+ ])
71
+ end
72
+
73
+ it "lists available addons" do
74
+ stderr, stdout = execute("addons:list")
75
+ stderr.should == ""
76
+ stdout.should == <<-STDOUT
77
+ === alpha
78
+ cloudcounter:basic
79
+
80
+ === available
81
+ cloudcounter:gold, pro
82
+
83
+ === beta
84
+ cloudcounter:platinum
85
+
86
+ === disabled
87
+ cloudcounter:old
88
+
89
+ STDOUT
90
+ end
91
+ end
92
+
93
+ describe 'v1-style command line params' do
94
+ it "understands foo=baz" do
95
+ @addons.stub!(:args).and_return(%w(my_addon foo=baz))
96
+ @addons.heroku.should_receive(:install_addon).with('myapp', 'my_addon', { 'foo' => 'baz' })
97
+ @addons.add
98
+ end
99
+
100
+ it "gives a deprecation notice with an example" do
101
+ stub_request(:post, %r{apps/myapp/addons/my_addon$}).
102
+ with(:body => {:config => {:foo => 'bar', :extra => "XXX"}}).
103
+ to_return(:body => Heroku::OkJson.encode({ 'price' => 'free' }))
104
+ Excon.stub(
105
+ {
106
+ :expects => 200,
107
+ :method => :get,
108
+ :path => %r{^/apps/myapp/releases/current}
109
+ },
110
+ {
111
+ :body => Heroku::API::OkJson.encode({ 'name' => 'v99' }),
112
+ :status => 200,
113
+ }
114
+ )
115
+ stderr, stdout = execute("addons:add my_addon --foo=bar extra=XXX")
116
+ stderr.should == ""
117
+ stdout.should == <<-STDOUT
118
+ Warning: non-unix style params have been deprecated, use --extra=XXX instead
119
+ Adding my_addon on myapp... done, v99 (free)
120
+ Use `heroku addons:docs my_addon` to view documentation.
121
+ STDOUT
122
+ Excon.stubs.shift
123
+ end
124
+ end
125
+
126
+ describe 'unix-style command line params' do
127
+ it "understands --foo=baz" do
128
+ @addons.stub!(:args).and_return(%w(my_addon --foo=baz))
129
+ @addons.heroku.should_receive(:install_addon).with('myapp', 'my_addon', { 'foo' => 'baz' })
130
+ @addons.add
131
+ end
132
+
133
+ it "understands --foo baz" do
134
+ @addons.stub!(:args).and_return(%w(my_addon --foo baz))
135
+ @addons.heroku.should_receive(:install_addon).with('myapp', 'my_addon', { 'foo' => 'baz' })
136
+ @addons.add
137
+ end
138
+
139
+ it "treats lone switches as true" do
140
+ @addons.stub!(:args).and_return(%w(my_addon --foo))
141
+ @addons.heroku.should_receive(:install_addon).with('myapp', 'my_addon', { 'foo' => true })
142
+ @addons.add
143
+ end
144
+
145
+ it "converts 'true' to boolean" do
146
+ @addons.stub!(:args).and_return(%w(my_addon --foo=true))
147
+ @addons.heroku.should_receive(:install_addon).with('myapp', 'my_addon', { 'foo' => true })
148
+ @addons.add
149
+ end
150
+
151
+ it "works with many config vars" do
152
+ @addons.stub!(:args).and_return(%w(my_addon --foo baz --bar yes --baz=foo --bab --bob=true))
153
+ @addons.heroku.should_receive(:install_addon).with('myapp', 'my_addon', { 'foo' => 'baz', 'bar' => 'yes', 'baz' => 'foo', 'bab' => true, 'bob' => true })
154
+ @addons.add
155
+ end
156
+
157
+ it "sends the variables to the server" do
158
+ stub_request(:post, %r{apps/myapp/addons/my_addon$}).
159
+ with(:body => {:config => { 'foo' => 'baz', 'bar' => 'yes', 'baz' => 'foo', 'bab' => 'true', 'bob' => 'true' }})
160
+ stderr, stdout = execute("addons:add my_addon --foo baz --bar yes --baz=foo --bab --bob=true")
161
+ stderr.should == ""
162
+ end
163
+
164
+ it "raises an error for spurious arguments" do
165
+ @addons.stub!(:args).and_return(%w(my_addon spurious))
166
+ lambda { @addons.add }.should raise_error(CommandFailed)
167
+ end
168
+ end
169
+
170
+ describe "mixed options" do
171
+ it "understands foo=bar and --baz=bar on the same line" do
172
+ @addons.stub!(:args).and_return(%w(my_addon foo=baz --baz=bar bob=true --bar))
173
+ @addons.heroku.should_receive(:install_addon).with('myapp', 'my_addon', { 'foo' => 'baz', 'baz' => 'bar', 'bar' => true, 'bob' => true })
174
+ @addons.add
175
+ end
176
+
177
+ it "sends the variables to the server" do
178
+ stub_request(:post, %r{apps/myapp/addons/my_addon$}).
179
+ with(:body => {:config => { 'foo' => 'baz', 'baz' => 'bar', 'bar' => 'true', 'bob' => 'true' }})
180
+ stderr, stdout = execute("addons:add my_addon foo=baz --baz=bar bob=true --bar")
181
+ stderr.should == ""
182
+ stdout.should include("Warning: non-unix style params have been deprecated, use --foo=baz --bob=true instead")
183
+ end
184
+ end
185
+
186
+ describe "fork and follow switches" do
187
+ it "should only resolve for heroku-postgresql addon" do
188
+ %w{fork follow}.each do |switch|
189
+ @addons.stub!(:args).and_return("addon --#{switch} HEROKU_POSTGRESQL_RED".split)
190
+ @addons.heroku.should_receive(:install_addon).
191
+ with('myapp', 'addon', {switch => 'HEROKU_POSTGRESQL_RED'})
192
+ @addons.add
193
+ end
194
+ end
195
+
196
+ it "should translate --fork and --follow" do
197
+ %w{fork follow}.each do |switch|
198
+ @addons.stub!(:app_config_vars).and_return({ 'HEROKU_POSTGRESQL_RED_URL' => 'foo'})
199
+ @addons.stub!(:args).and_return("heroku-postgresql --#{switch} HEROKU_POSTGRESQL_RED".split)
200
+ @addons.heroku.should_receive(:install_addon).with('myapp', 'heroku-postgresql', {switch => 'foo'})
201
+ @addons.add
202
+ end
203
+ end
204
+ end
205
+
206
+ describe 'adding' do
207
+ before do
208
+ @addons.stub!(:args).and_return(%w(my_addon))
209
+ Excon.stub(
210
+ {
211
+ :expects => 200,
212
+ :method => :get,
213
+ :path => %r{^/apps/myapp/releases/current}
214
+ },
215
+ {
216
+ :body => Heroku::API::OkJson.encode({ 'name' => 'v99' }),
217
+ :status => 200,
218
+ }
219
+ )
220
+ end
221
+ after do
222
+ Excon.stubs.shift
223
+ end
224
+
225
+
226
+ it "requires an addon name" do
227
+ @addons.stub!(:args).and_return([])
228
+ lambda { @addons.add }.should raise_error(CommandFailed)
229
+ end
230
+
231
+ it "adds an addon" do
232
+ @addons.stub!(:args).and_return(%w(my_addon))
233
+ @addons.heroku.should_receive(:install_addon).with('myapp', 'my_addon', {})
234
+ @addons.add
235
+ end
236
+
237
+ it "adds an addon with a price" do
238
+ stub_core.install_addon("myapp", "my_addon", {}).returns({ "price" => "free" })
239
+ stderr, stdout = execute("addons:add my_addon")
240
+ stderr.should == ""
241
+ stdout.should =~ /\(free\)/
242
+ end
243
+
244
+ it "adds an addon with a price and message" do
245
+ stub_core.install_addon("myapp", "my_addon", {}).returns({ "price" => "free", "message" => "foo" })
246
+ stderr, stdout = execute("addons:add my_addon")
247
+ stderr.should == ""
248
+ stdout.should == <<-OUTPUT
249
+ Adding my_addon on myapp... done, v99 (free)
250
+ foo
251
+ Use `heroku addons:docs my_addon` to view documentation.
252
+ OUTPUT
253
+ end
254
+
255
+ it "adds an addon with a price and multiline message" do
256
+ stub_core.install_addon("myapp", "my_addon", {}).returns({ "price" => "$200/mo", "message" => "foo\nbar" })
257
+ stderr, stdout = execute("addons:add my_addon")
258
+ stderr.should == ""
259
+ stdout.should == <<-OUTPUT
260
+ Adding my_addon on myapp... done, v99 ($200/mo)
261
+ foo
262
+ bar
263
+ Use `heroku addons:docs my_addon` to view documentation.
264
+ OUTPUT
265
+ end
266
+
267
+ it "displays an error with unexpected options" do
268
+ Heroku::Command.should_receive(:error).with("Unexpected arguments: bar")
269
+ run("addons:add redistogo -a foo bar")
270
+ end
271
+ end
272
+
273
+ describe 'upgrading' do
274
+ before do
275
+ @addons.stub!(:args).and_return(%w(my_addon))
276
+ Excon.stub(
277
+ {
278
+ :expects => 200,
279
+ :method => :get,
280
+ :path => %r{^/apps/myapp/releases/current}
281
+ },
282
+ {
283
+ :body => Heroku::API::OkJson.encode({ 'name' => 'v99' }),
284
+ :status => 200,
285
+ }
286
+ )
287
+ end
288
+ after do
289
+ Excon.stubs.shift
290
+ end
291
+
292
+ it "requires an addon name" do
293
+ @addons.stub!(:args).and_return([])
294
+ lambda { @addons.upgrade }.should raise_error(CommandFailed)
295
+ end
296
+
297
+ it "upgrades an addon" do
298
+ @addons.stub!(:args).and_return(%w(my_addon))
299
+ @addons.heroku.should_receive(:upgrade_addon).with('myapp', 'my_addon', {})
300
+ @addons.upgrade
301
+ end
302
+
303
+ it "upgrade an addon with config vars" do
304
+ @addons.stub!(:args).and_return(%w(my_addon --foo=baz))
305
+ @addons.heroku.should_receive(:upgrade_addon).with('myapp', 'my_addon', { 'foo' => 'baz' })
306
+ @addons.upgrade
307
+ end
308
+
309
+ it "adds an addon with a price" do
310
+ stub_core.upgrade_addon("myapp", "my_addon", {}).returns({ "price" => "free" })
311
+ stderr, stdout = execute("addons:upgrade my_addon")
312
+ stderr.should == ""
313
+ stdout.should == <<-OUTPUT
314
+ Upgrading to my_addon on myapp... done, v99 (free)
315
+ Use `heroku addons:docs my_addon` to view documentation.
316
+ OUTPUT
317
+ end
318
+
319
+ it "adds an addon with a price and message" do
320
+ stub_core.upgrade_addon("myapp", "my_addon", {}).returns({ "price" => "free", "message" => "Don't Panic" })
321
+ stderr, stdout = execute("addons:upgrade my_addon")
322
+ stderr.should == ""
323
+ stdout.should == <<-OUTPUT
324
+ Upgrading to my_addon on myapp... done, v99 (free)
325
+ Don't Panic
326
+ Use `heroku addons:docs my_addon` to view documentation.
327
+ OUTPUT
328
+ end
329
+ end
330
+
331
+ describe 'downgrading' do
332
+ before do
333
+ @addons.stub!(:args).and_return(%w(my_addon))
334
+ Excon.stub(
335
+ {
336
+ :expects => 200,
337
+ :method => :get,
338
+ :path => %r{^/apps/myapp/releases/current}
339
+ },
340
+ {
341
+ :body => Heroku::API::OkJson.encode({ 'name' => 'v99' }),
342
+ :status => 200,
343
+ }
344
+ )
345
+ end
346
+ after do
347
+ Excon.stubs.shift
348
+ end
349
+
350
+ it "requires an addon name" do
351
+ @addons.stub!(:args).and_return([])
352
+ lambda { @addons.downgrade }.should raise_error(CommandFailed)
353
+ end
354
+
355
+ it "downgrades an addon" do
356
+ @addons.stub!(:args).and_return(%w(my_addon))
357
+ @addons.heroku.should_receive(:upgrade_addon).with('myapp', 'my_addon', {})
358
+ @addons.downgrade
359
+ end
360
+
361
+ it "downgrade an addon with config vars" do
362
+ @addons.stub!(:args).and_return(%w(my_addon --foo=baz))
363
+ @addons.heroku.should_receive(:upgrade_addon).with('myapp', 'my_addon', { 'foo' => 'baz' })
364
+ @addons.downgrade
365
+ end
366
+
367
+ it "downgrades an addon with a price" do
368
+ stub_core.upgrade_addon("myapp", "my_addon", {}).returns({ "price" => "free" })
369
+ stderr, stdout = execute("addons:downgrade my_addon")
370
+ stderr.should == ""
371
+ stdout.should == <<-OUTPUT
372
+ Downgrading to my_addon on myapp... done, v99 (free)
373
+ Use `heroku addons:docs my_addon` to view documentation.
374
+ OUTPUT
375
+ end
376
+
377
+ it "downgrades an addon with a price and message" do
378
+ stub_core.upgrade_addon("myapp", "my_addon", {}).returns({ "price" => "free", "message" => "Don't Panic" })
379
+ stderr, stdout = execute("addons:downgrade my_addon")
380
+ stderr.should == ""
381
+ stdout.should == <<-OUTPUT
382
+ Downgrading to my_addon on myapp... done, v99 (free)
383
+ Don't Panic
384
+ Use `heroku addons:docs my_addon` to view documentation.
385
+ OUTPUT
386
+ end
387
+ end
388
+
389
+ it "asks the user to confirm billing when API responds with 402" do
390
+ @addons.stub!(:args).and_return(%w( addon1 ))
391
+ e = RestClient::RequestFailed.new
392
+ e.stub!(:http_code).and_return(402)
393
+ e.stub!(:http_body).and_return('{"error":"test"}')
394
+ @addons.heroku.should_receive(:install_addon).and_raise(e)
395
+ @addons.should_receive(:confirm_billing).and_return(false)
396
+ STDERR.should_receive(:puts).with(" ! test")
397
+ lambda { @addons.add }.should raise_error(SystemExit)
398
+ end
399
+
400
+ it "does not remove addons with no confirm" do
401
+ @addons.stub!(:args).and_return(%w( addon1 ))
402
+ @addons.should_receive(:confirm_command).once.and_return(false)
403
+ @addons.heroku.should_not_receive(:uninstall_addon)
404
+ @addons.remove
405
+ end
406
+
407
+ it "removes addons after prompting for confirmation" do
408
+ @addons.stub!(:args).and_return(%w( addon1 ))
409
+ @addons.should_receive(:confirm_command).once.and_return(true)
410
+ @addons.heroku.should_receive(:uninstall_addon).with('myapp', 'addon1', :confirm => "myapp")
411
+ @addons.remove
412
+ end
413
+
414
+ it "removes addons with confirm option" do
415
+ Heroku::Command.stub!(:current_options).and_return(:confirm => "myapp")
416
+ @addons.stub!(:args).and_return(%w( addon1 ))
417
+ @addons.heroku.should_receive(:uninstall_addon).with('myapp', 'addon1', :confirm => "myapp")
418
+ @addons.remove
419
+ end
420
+
421
+ describe "opening add-on docs" do
422
+
423
+ before(:each) do
424
+ stub_core
425
+ api.post_app("name" => "myapp", "stack" => "cedar")
426
+ end
427
+
428
+ after(:each) do
429
+ api.delete_app("myapp")
430
+ end
431
+
432
+ it "displays usage when no argument is specified" do
433
+ stderr, stdout = execute('addons:docs')
434
+ stderr.should == <<-STDERR
435
+ ! Usage: heroku addons:docs ADDON
436
+ ! Must specify ADDON to open docs for.
437
+ STDERR
438
+ stdout.should == ''
439
+ end
440
+
441
+ it "opens the addon if only one matches" do
442
+ require("launchy")
443
+ Launchy.should_receive(:open).with("https://devcenter.heroku.com/articles/redistogo").and_return(Thread.new {})
444
+ stderr, stdout = execute('addons:docs redistogo:nano')
445
+ stderr.should == ''
446
+ stdout.should == <<-STDOUT
447
+ Opening redistogo:nano docs... done
448
+ STDOUT
449
+ end
450
+
451
+ it "complains about ambiguity" do
452
+ Excon.stub(
453
+ {
454
+ :expects => 200,
455
+ :method => :get,
456
+ :path => %r{^/addons$}
457
+ },
458
+ {
459
+ :body => Heroku::API::OkJson.encode([
460
+ { 'name' => 'qux:foo' },
461
+ { 'name' => 'quux:bar' }
462
+ ]),
463
+ :status => 200,
464
+ }
465
+ )
466
+ stderr, stdout = execute('addons:docs qu')
467
+ stderr.should == <<-STDERR
468
+ ! Ambiguous addon name: qu
469
+ ! Perhaps you meant `qux:foo` or `quux:bar`.
470
+ STDERR
471
+ stdout.should == ''
472
+ Excon.stubs.shift
473
+ end
474
+
475
+ it "complains if no such addon exists" do
476
+ stderr, stdout = execute('addons:docs unknown')
477
+ stderr.should == <<-STDERR
478
+ ! `unknown` is not a heroku add-on.
479
+ ! See `heroku addons:list` for all available addons.
480
+ STDERR
481
+ stdout.should == ''
482
+ end
483
+
484
+ it "suggests alternatives if addon has typo" do
485
+ stderr, stdout = execute('addons:docs redisgoto')
486
+ stderr.should == <<-STDERR
487
+ ! `redisgoto` is not a heroku add-on.
488
+ ! Perhaps you meant `redistogo`.
489
+ ! See `heroku addons:list` for all available addons.
490
+ STDERR
491
+ stdout.should == ''
492
+ end
493
+
494
+ it "complains if addon is not installed" do
495
+ stderr, stdout = execute('addons:open deployhooks:http')
496
+ stderr.should == <<-STDOUT
497
+ ! Addon not installed: deployhooks:http
498
+ STDOUT
499
+ stdout.should == ''
500
+ end
501
+ end
502
+ describe "opening an addon" do
503
+
504
+ before(:each) do
505
+ stub_core
506
+ api.post_app("name" => "myapp", "stack" => "cedar")
507
+ end
508
+
509
+ after(:each) do
510
+ api.delete_app("myapp")
511
+ end
512
+
513
+ it "displays usage when no argument is specified" do
514
+ stderr, stdout = execute('addons:open')
515
+ stderr.should == <<-STDERR
516
+ ! Usage: heroku addons:open ADDON
517
+ ! Must specify ADDON to open.
518
+ STDERR
519
+ stdout.should == ''
520
+ end
521
+
522
+ it "opens the addon if only one matches" do
523
+ api.post_addon('myapp', 'redistogo:nano')
524
+ require("launchy")
525
+ Launchy.should_receive(:open).with("https://api.#{@addons.heroku.host}/myapps/myapp/addons/redistogo:nano").and_return(Thread.new {})
526
+ stderr, stdout = execute('addons:open redistogo:nano')
527
+ stderr.should == ''
528
+ stdout.should == <<-STDOUT
529
+ Opening redistogo:nano for myapp... done
530
+ STDOUT
531
+ end
532
+
533
+ it "complains about ambiguity" do
534
+ Excon.stub(
535
+ {
536
+ :expects => 200,
537
+ :method => :get,
538
+ :path => %r{^/apps/myapp/addons$}
539
+ },
540
+ {
541
+ :body => Heroku::API::OkJson.encode([
542
+ { 'name' => 'deployhooks:email' },
543
+ { 'name' => 'deployhooks:http' }
544
+ ]),
545
+ :status => 200,
546
+ }
547
+ )
548
+ stderr, stdout = execute('addons:open deployhooks')
549
+ stderr.should == <<-STDERR
550
+ ! Ambiguous addon name: deployhooks
551
+ ! Perhaps you meant `deployhooks:email` or `deployhooks:http`.
552
+ STDERR
553
+ stdout.should == ''
554
+ Excon.stubs.shift
555
+ end
556
+
557
+ it "complains if no such addon exists" do
558
+ stderr, stdout = execute('addons:open unknown')
559
+ stderr.should == <<-STDERR
560
+ ! `unknown` is not a heroku add-on.
561
+ ! See `heroku addons:list` for all available addons.
562
+ STDERR
563
+ stdout.should == ''
564
+ end
565
+
566
+ it "suggests alternatives if addon has typo" do
567
+ stderr, stdout = execute('addons:open redisgoto')
568
+ stderr.should == <<-STDERR
569
+ ! `redisgoto` is not a heroku add-on.
570
+ ! Perhaps you meant `redistogo`.
571
+ ! See `heroku addons:list` for all available addons.
572
+ STDERR
573
+ stdout.should == ''
574
+ end
575
+
576
+ it "complains if addon is not installed" do
577
+ stderr, stdout = execute('addons:open deployhooks:http')
578
+ stderr.should == <<-STDOUT
579
+ ! Addon not installed: deployhooks:http
580
+ STDOUT
581
+ stdout.should == ''
582
+ end
583
+ end
584
+ end
585
+ end