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.
- data/README.md +73 -0
- data/bin/pogo +22 -0
- data/data/cacert.pem +3988 -0
- data/lib/heroku.rb +22 -0
- data/lib/heroku/auth.rb +320 -0
- data/lib/heroku/cli.rb +38 -0
- data/lib/heroku/client.rb +764 -0
- data/lib/heroku/client/heroku_postgresql.rb +111 -0
- data/lib/heroku/client/pgbackups.rb +113 -0
- data/lib/heroku/client/rendezvous.rb +105 -0
- data/lib/heroku/client/ssl_endpoint.rb +25 -0
- data/lib/heroku/command.rb +273 -0
- data/lib/heroku/command/account.rb +23 -0
- data/lib/heroku/command/accounts.rb +34 -0
- data/lib/heroku/command/addons.rb +305 -0
- data/lib/heroku/command/apps.rb +311 -0
- data/lib/heroku/command/auth.rb +86 -0
- data/lib/heroku/command/base.rb +230 -0
- data/lib/heroku/command/certs.rb +148 -0
- data/lib/heroku/command/config.rb +137 -0
- data/lib/heroku/command/db.rb +218 -0
- data/lib/heroku/command/domains.rb +85 -0
- data/lib/heroku/command/drains.rb +46 -0
- data/lib/heroku/command/git.rb +65 -0
- data/lib/heroku/command/help.rb +163 -0
- data/lib/heroku/command/keys.rb +115 -0
- data/lib/heroku/command/labs.rb +161 -0
- data/lib/heroku/command/logs.rb +98 -0
- data/lib/heroku/command/maintenance.rb +61 -0
- data/lib/heroku/command/pg.rb +277 -0
- data/lib/heroku/command/pgbackups.rb +289 -0
- data/lib/heroku/command/plugins.rb +110 -0
- data/lib/heroku/command/ps.rb +232 -0
- data/lib/heroku/command/releases.rb +124 -0
- data/lib/heroku/command/run.rb +179 -0
- data/lib/heroku/command/sharing.rb +89 -0
- data/lib/heroku/command/ssl.rb +61 -0
- data/lib/heroku/command/stack.rb +62 -0
- data/lib/heroku/command/status.rb +51 -0
- data/lib/heroku/command/update.rb +47 -0
- data/lib/heroku/command/version.rb +23 -0
- data/lib/heroku/deprecated.rb +5 -0
- data/lib/heroku/deprecated/help.rb +38 -0
- data/lib/heroku/distribution.rb +9 -0
- data/lib/heroku/helpers.rb +517 -0
- data/lib/heroku/helpers/heroku_postgresql.rb +104 -0
- data/lib/heroku/plugin.rb +161 -0
- data/lib/heroku/updater.rb +158 -0
- data/lib/heroku/version.rb +3 -0
- data/lib/vendor/heroku/okjson.rb +598 -0
- data/spec/helper/legacy_help.rb +16 -0
- data/spec/heroku/auth_spec.rb +246 -0
- data/spec/heroku/client/heroku_postgresql_spec.rb +34 -0
- data/spec/heroku/client/pgbackups_spec.rb +43 -0
- data/spec/heroku/client/rendezvous_spec.rb +62 -0
- data/spec/heroku/client/ssl_endpoint_spec.rb +48 -0
- data/spec/heroku/client_spec.rb +564 -0
- data/spec/heroku/command/addons_spec.rb +585 -0
- data/spec/heroku/command/apps_spec.rb +351 -0
- data/spec/heroku/command/auth_spec.rb +38 -0
- data/spec/heroku/command/base_spec.rb +109 -0
- data/spec/heroku/command/certs_spec.rb +178 -0
- data/spec/heroku/command/config_spec.rb +144 -0
- data/spec/heroku/command/db_spec.rb +110 -0
- data/spec/heroku/command/domains_spec.rb +87 -0
- data/spec/heroku/command/drains_spec.rb +34 -0
- data/spec/heroku/command/git_spec.rb +116 -0
- data/spec/heroku/command/help_spec.rb +93 -0
- data/spec/heroku/command/keys_spec.rb +120 -0
- data/spec/heroku/command/labs_spec.rb +99 -0
- data/spec/heroku/command/logs_spec.rb +60 -0
- data/spec/heroku/command/maintenance_spec.rb +51 -0
- data/spec/heroku/command/pg_spec.rb +223 -0
- data/spec/heroku/command/pgbackups_spec.rb +280 -0
- data/spec/heroku/command/plugins_spec.rb +104 -0
- data/spec/heroku/command/ps_spec.rb +195 -0
- data/spec/heroku/command/releases_spec.rb +130 -0
- data/spec/heroku/command/run_spec.rb +86 -0
- data/spec/heroku/command/sharing_spec.rb +59 -0
- data/spec/heroku/command/ssl_spec.rb +32 -0
- data/spec/heroku/command/stack_spec.rb +46 -0
- data/spec/heroku/command/status_spec.rb +48 -0
- data/spec/heroku/command/version_spec.rb +16 -0
- data/spec/heroku/command_spec.rb +211 -0
- data/spec/heroku/helpers/heroku_postgresql_spec.rb +109 -0
- data/spec/heroku/helpers_spec.rb +48 -0
- data/spec/heroku/plugin_spec.rb +172 -0
- data/spec/heroku/updater_spec.rb +44 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +209 -0
- data/spec/support/display_message_matcher.rb +49 -0
- data/spec/support/openssl_mock_helper.rb +8 -0
- metadata +220 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "heroku/command/sharing"
|
|
3
|
+
|
|
4
|
+
module Heroku::Command
|
|
5
|
+
describe Sharing do
|
|
6
|
+
|
|
7
|
+
before(:each) do
|
|
8
|
+
stub_core
|
|
9
|
+
api.post_app("name" => "myapp")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
after(:each) do
|
|
13
|
+
api.delete_app("myapp")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context("list") do
|
|
17
|
+
|
|
18
|
+
it "lists collaborators" do
|
|
19
|
+
api.post_collaborator("myapp", "collaborator@example.com")
|
|
20
|
+
stderr, stdout = execute("sharing")
|
|
21
|
+
stderr.should == ""
|
|
22
|
+
stdout.should == <<-STDOUT
|
|
23
|
+
=== myapp Collaborators
|
|
24
|
+
collaborator@example.com
|
|
25
|
+
email@example.com
|
|
26
|
+
|
|
27
|
+
STDOUT
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "adds collaborators with default access to view only" do
|
|
33
|
+
stderr, stdout = execute("sharing:add collaborator@example.com")
|
|
34
|
+
stderr.should == ""
|
|
35
|
+
stdout.should == <<-STDOUT
|
|
36
|
+
Adding collaborator@example.com to myapp collaborators... done
|
|
37
|
+
STDOUT
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "removes collaborators" do
|
|
41
|
+
api.post_collaborator("myapp", "collaborator@example.com")
|
|
42
|
+
stderr, stdout = execute("sharing:remove collaborator@example.com")
|
|
43
|
+
stderr.should == ""
|
|
44
|
+
stdout.should == <<-STDOUT
|
|
45
|
+
Removing collaborator@example.com from myapp collaborators... done
|
|
46
|
+
STDOUT
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "transfers ownership" do
|
|
50
|
+
api.post_collaborator("myapp", "collaborator@example.com")
|
|
51
|
+
stderr, stdout = execute("sharing:transfer collaborator@example.com")
|
|
52
|
+
stderr.should == ""
|
|
53
|
+
stdout.should == <<-STDOUT
|
|
54
|
+
Transferring myapp to collaborator@example.com... done
|
|
55
|
+
STDOUT
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "heroku/command/ssl"
|
|
3
|
+
|
|
4
|
+
module Heroku::Command
|
|
5
|
+
describe Ssl do
|
|
6
|
+
|
|
7
|
+
it "adds ssl certificates to domains" do
|
|
8
|
+
File.should_receive(:exists?).with('.git').and_return(false)
|
|
9
|
+
File.should_receive(:exists?).with('my.crt').and_return(true)
|
|
10
|
+
File.should_receive(:read).with('my.crt').and_return('crt contents')
|
|
11
|
+
File.should_receive(:exists?).with('my.key').and_return(true)
|
|
12
|
+
File.should_receive(:read).with('my.key').and_return('key contents')
|
|
13
|
+
expires_at = Time.now + 60 * 60 * 24 * 365
|
|
14
|
+
stub_core.add_ssl('myapp', 'crt contents', 'key contents').returns({"domain" => "example.com", "expires_at" => expires_at})
|
|
15
|
+
stderr, stdout = execute("ssl:add my.crt my.key")
|
|
16
|
+
stderr.should == ""
|
|
17
|
+
stdout.should == <<-STDOUT
|
|
18
|
+
Added certificate to example.com, expiring at #{expires_at}
|
|
19
|
+
STDOUT
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "removes certificates" do
|
|
23
|
+
stub_core.remove_ssl('myapp', 'example.com')
|
|
24
|
+
stderr, stdout = execute("ssl:remove example.com")
|
|
25
|
+
stderr.should == ""
|
|
26
|
+
stdout.should == <<-STDOUT
|
|
27
|
+
Removed certificate from example.com
|
|
28
|
+
STDOUT
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "heroku/command/stack"
|
|
3
|
+
|
|
4
|
+
module Heroku::Command
|
|
5
|
+
describe Stack do
|
|
6
|
+
describe "index" do
|
|
7
|
+
before(:each) do
|
|
8
|
+
stub_core
|
|
9
|
+
api.post_app("name" => "myapp", "stack" => "bamboo-mri-1.9.2")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
after(:each) do
|
|
13
|
+
api.delete_app("myapp")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "index should provide list" do
|
|
17
|
+
stderr, stdout = execute("stack")
|
|
18
|
+
stderr.should == ""
|
|
19
|
+
stdout.should == <<-STDOUT
|
|
20
|
+
=== myapp Available Stacks
|
|
21
|
+
aspen-mri-1.8.6
|
|
22
|
+
bamboo-ree-1.8.7
|
|
23
|
+
cedar (beta)
|
|
24
|
+
* bamboo-mri-1.9.2
|
|
25
|
+
|
|
26
|
+
STDOUT
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "migrate should succeed" do
|
|
30
|
+
stderr, stdout = execute("stack:migrate bamboo-ree-1.8.7")
|
|
31
|
+
stderr.should == ""
|
|
32
|
+
stdout.should == <<-STDOUT
|
|
33
|
+
-----> Preparing to migrate myapp
|
|
34
|
+
bamboo-mri-1.9.2 -> bamboo-ree-1.8.7
|
|
35
|
+
|
|
36
|
+
NOTE: Additional details here
|
|
37
|
+
|
|
38
|
+
-----> Migration prepared.
|
|
39
|
+
Run 'git push heroku master' to execute migration.
|
|
40
|
+
STDOUT
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "heroku/command/status"
|
|
3
|
+
|
|
4
|
+
module Heroku::Command
|
|
5
|
+
describe Status do
|
|
6
|
+
|
|
7
|
+
before(:each) do
|
|
8
|
+
stub_core
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "displays status information" do
|
|
12
|
+
Excon.stub(
|
|
13
|
+
{
|
|
14
|
+
:host => 'status.heroku.com',
|
|
15
|
+
:method => :get,
|
|
16
|
+
:path => '/api/v3/current-status.json'
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
:body => Heroku::API::OkJson.encode({"status"=>{"Production"=>"red", "Development"=>"red"}, "issues"=>[{"created_at"=>"2012-06-07T15:55:51Z", "id"=>372, "resolved"=>false, "title"=>"HTTP Routing Errors", "updated_at"=>"2012-06-07T16:14:37Z", "href"=>"https://status.heroku.com/api/v3/issues/372", "updates"=>[{"contents"=>"The number of applications seeing H99 errors is continuing to decrease as we continue to work toward a full resolution of the HTTP routing issues. The API is back online now as well. ", "created_at"=>"2012-06-07T17:47:26Z", "id"=>1088, "incident_id"=>372, "status_dev"=>"red", "status_prod"=>"red", "update_type"=>"update", "updated_at"=>"2012-06-07T17:47:26Z"}, {"contents"=>"Our engineers are continuing to work toward a full resolution of the HTTP routing issues. The API is currently in maintenance mode intentionally as we restore application operations. ", "created_at"=>"2012-06-07T17:16:40Z", "id"=>1086, "incident_id"=>372, "status_dev"=>"red", "status_prod"=>"red", "update_type"=>"update", "updated_at"=>"2012-06-07T17:26:55Z"}, {"contents"=>"Most applications are back online at this time. Our engineers are working on getting the remaining apps back online. ", "created_at"=>"2012-06-07T16:50:21Z", "id"=>1085, "incident_id"=>372, "status_dev"=>"red", "status_prod"=>"red", "update_type"=>"update", "updated_at"=>"2012-06-07T16:50:21Z"}, {"contents"=>"Our routing engineers have pushed out a patch to our routing tier. The platform is recovering and applications are coming back online. Our engineers are continuing to fully restore service.", "created_at"=>"2012-06-07T16:36:37Z", "id"=>1084, "incident_id"=>372, "status_dev"=>"red", "status_prod"=>"red", "update_type"=>"update", "updated_at"=>"2012-06-07T16:36:37Z"}, {"contents"=>"We have identified an issue with our routers that is causing errors on HTTP requests to applications. Engineers are working to resolve the issue.\r\n", "created_at"=>"2012-06-07T16:15:25Z", "id"=>1083, "incident_id"=>372, "status_dev"=>"red", "status_prod"=>"red", "update_type"=>"update", "updated_at"=>"2012-06-07T16:15:28Z"}, {"contents"=>"We have confirmed widespread errors on the platform. Our engineers are continuing to investigate.\r\n", "created_at"=>"2012-06-07T15:58:56Z", "id"=>1082, "incident_id"=>372, "status_dev"=>"red", "status_prod"=>"red", "update_type"=>"update", "updated_at"=>"2012-06-07T15:58:58Z"}, {"contents"=>"Our automated systems have detected potential platform errors. We are investigating.\r\n", "created_at"=>"2012-06-07T15:55:51Z", "id"=>1081, "incident_id"=>372, "status_dev"=>"yellow", "status_prod"=>"yellow", "update_type"=>"issue", "updated_at"=>"2012-06-07T15:55:55Z"}]}]}),
|
|
20
|
+
:status => 200
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
Heroku::Command::Status.any_instance.should_receive(:time_ago).and_return('2012/09/11 09:34:56 (~ 3h ago)', '2012/09/11 12:33:56 (~ 1m ago)', '2012/09/11 12:29:56 (~ 5m ago)', '2012/09/11 12:24:56 (~ 10m ago)', '2012/09/11 12:04:56 (~ 30m ago)', '2012/09/11 11:34:56 (~ 1h ago)', '2012/09/11 10:34:56 (~ 2h ago)', '2012/09/11 09:34:56 (~ 3h ago)')
|
|
25
|
+
|
|
26
|
+
stderr, stdout = execute("status")
|
|
27
|
+
stderr.should == ''
|
|
28
|
+
stdout.should == <<-STDOUT
|
|
29
|
+
=== Heroku Status
|
|
30
|
+
Development: red
|
|
31
|
+
Production: red
|
|
32
|
+
|
|
33
|
+
=== HTTP Routing Errors 2012/09/11 09:34:56 (~ 3h+)
|
|
34
|
+
2012/09/11 12:33:56 (~ 1m ago) update The number of applications seeing H99 errors is continuing to decrease as we continue to work toward a full resolution of the HTTP routing issues. The API is back online now as well.
|
|
35
|
+
2012/09/11 12:29:56 (~ 5m ago) update Our engineers are continuing to work toward a full resolution of the HTTP routing issues. The API is currently in maintenance mode intentionally as we restore application operations.
|
|
36
|
+
2012/09/11 12:24:56 (~ 10m ago) update Most applications are back online at this time. Our engineers are working on getting the remaining apps back online.
|
|
37
|
+
2012/09/11 12:04:56 (~ 30m ago) update Our routing engineers have pushed out a patch to our routing tier. The platform is recovering and applications are coming back online. Our engineers are continuing to fully restore service.
|
|
38
|
+
2012/09/11 11:34:56 (~ 1h ago) update We have identified an issue with our routers that is causing errors on HTTP requests to applications. Engineers are working to resolve the issue.
|
|
39
|
+
2012/09/11 10:34:56 (~ 2h ago) update We have confirmed widespread errors on the platform. Our engineers are continuing to investigate.
|
|
40
|
+
2012/09/11 09:34:56 (~ 3h ago) issue Our automated systems have detected potential platform errors. We are investigating.
|
|
41
|
+
|
|
42
|
+
STDOUT
|
|
43
|
+
|
|
44
|
+
Excon.stubs.shift
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "heroku/command/version"
|
|
3
|
+
|
|
4
|
+
module Heroku::Command
|
|
5
|
+
describe Version do
|
|
6
|
+
|
|
7
|
+
it "shows version info" do
|
|
8
|
+
stderr, stdout = execute("version")
|
|
9
|
+
stderr.should == ""
|
|
10
|
+
stdout.should == <<-STDOUT
|
|
11
|
+
#{Heroku.user_agent}
|
|
12
|
+
STDOUT
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "heroku/command"
|
|
3
|
+
require 'json' #FOR WEBMOCK
|
|
4
|
+
|
|
5
|
+
class FakeResponse
|
|
6
|
+
|
|
7
|
+
attr_accessor :body, :headers
|
|
8
|
+
|
|
9
|
+
def initialize(attributes)
|
|
10
|
+
self.body, self.headers = attributes[:body], attributes[:headers]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_s
|
|
14
|
+
body
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe Heroku::Command do
|
|
20
|
+
before {
|
|
21
|
+
Heroku::Command.load
|
|
22
|
+
stub_core # setup fake auth
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe "when the command requires confirmation" do
|
|
26
|
+
|
|
27
|
+
let(:response_that_requires_confirmation) do
|
|
28
|
+
{:status => 423,
|
|
29
|
+
:headers => { :x_confirmation_required => 'my_addon' },
|
|
30
|
+
:body => 'terms of service required'}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context "when the app is unknown" do
|
|
34
|
+
context "and the user includes --confirm APP" do
|
|
35
|
+
it "should set --app to APP and not ask for confirmation" do
|
|
36
|
+
stub_request(:post, %r{apps/XXX/addons/my_addon$}).
|
|
37
|
+
with(:body => {:confirm => "XXX"})
|
|
38
|
+
run "addons:add my_addon --confirm XXX"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context "and the user includes --confirm APP --app APP2" do
|
|
43
|
+
it "should warn that the app and confirm do not match and not continue" do
|
|
44
|
+
capture_stderr do
|
|
45
|
+
run "addons:add my_addon --confirm APP --app APP2"
|
|
46
|
+
end.should == " ! Mismatch between --app and --confirm\n"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context "and the app is known" do
|
|
52
|
+
before do
|
|
53
|
+
any_instance_of(Heroku::Command::Base) do |base|
|
|
54
|
+
stub(base).app.returns("myapp")
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context "and the user includes --confirm WRONGAPP" do
|
|
59
|
+
it "should not allow include the option" do
|
|
60
|
+
stub_request(:post, %r{apps/myapp/addons/my_addon$}).
|
|
61
|
+
with(:body => "")
|
|
62
|
+
run "addons:add my_addon --confirm XXX"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
context "and the user includes --confirm APP" do
|
|
67
|
+
it "should set --app to APP and not ask for confirmation" do
|
|
68
|
+
stub_request(:post, %r{apps/myapp/addons/my_addon$}).
|
|
69
|
+
with(:body => {:confirm => 'myapp'})
|
|
70
|
+
|
|
71
|
+
run "addons:add my_addon --confirm myapp"
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context "and the user didn't include a confirm flag" do
|
|
76
|
+
it "should ask the user for confirmation" do
|
|
77
|
+
stub(Heroku::Command).confirm_command.returns(true)
|
|
78
|
+
stub_request(:post, %r{apps/myapp/addons/my_addon$}).
|
|
79
|
+
to_return(response_that_requires_confirmation).then.
|
|
80
|
+
to_return({:status => 200})
|
|
81
|
+
|
|
82
|
+
run "addons:add my_addon"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "should not continue if the confirmation does not match" do
|
|
86
|
+
Heroku::Command.stub(:current_options).and_return(:confirm => 'not_myapp')
|
|
87
|
+
|
|
88
|
+
lambda do
|
|
89
|
+
Heroku::Command.confirm_command('myapp')
|
|
90
|
+
end.should raise_error(Heroku::Command::CommandFailed)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "should not continue if the user doesn't confirm" do
|
|
94
|
+
stub(Heroku::Command).confirm_command.returns(false)
|
|
95
|
+
stub_request(:post, %r{apps/myapp/addons/my_addon$}).
|
|
96
|
+
to_return(response_that_requires_confirmation).then.
|
|
97
|
+
to_raise(Heroku::Command::CommandFailed)
|
|
98
|
+
|
|
99
|
+
run "addons:add my_addon"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
describe "parsing errors" do
|
|
106
|
+
it "extracts error messages from response when available in XML" do
|
|
107
|
+
Heroku::Command.extract_error('<errors><error>Invalid app name</error></errors>').should == 'Invalid app name'
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "extracts error messages from response when available in JSON" do
|
|
111
|
+
Heroku::Command.extract_error("{\"error\":\"Invalid app name\"}").should == 'Invalid app name'
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "extracts error messages from response when available in plain text" do
|
|
115
|
+
response = FakeResponse.new(:body => "Invalid app name", :headers => { :content_type => "text/plain; charset=UTF8" })
|
|
116
|
+
Heroku::Command.extract_error(response).should == 'Invalid app name'
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "shows Internal Server Error when the response doesn't contain a XML or JSON" do
|
|
120
|
+
Heroku::Command.extract_error('<h1>HTTP 500</h1>').should == "Internal server error.\nRun 'heroku status' to check for known platform issues."
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "shows Internal Server Error when the response is not plain text" do
|
|
124
|
+
response = FakeResponse.new(:body => "Foobar", :headers => { :content_type => "application/xml" })
|
|
125
|
+
Heroku::Command.extract_error(response).should == "Internal server error.\nRun 'heroku status' to check for known platform issues."
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "allows a block to redefine the default error" do
|
|
129
|
+
Heroku::Command.extract_error("Foobar") { "Ok!" }.should == 'Ok!'
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it "doesn't format the response if set to raw" do
|
|
133
|
+
Heroku::Command.extract_error("Foobar", :raw => true) { "Ok!" }.should == 'Ok!'
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "handles a nil body in parse_error_xml" do
|
|
137
|
+
lambda { Heroku::Command.parse_error_xml(nil) }.should_not raise_error
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it "handles a nil body in parse_error_json" do
|
|
141
|
+
lambda { Heroku::Command.parse_error_json(nil) }.should_not raise_error
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "correctly resolves commands" do
|
|
146
|
+
class Heroku::Command::Test; end
|
|
147
|
+
class Heroku::Command::Test::Multiple; end
|
|
148
|
+
|
|
149
|
+
require "heroku/command/help"
|
|
150
|
+
require "heroku/command/apps"
|
|
151
|
+
|
|
152
|
+
Heroku::Command.parse("unknown").should be_nil
|
|
153
|
+
Heroku::Command.parse("list").should include(:klass => Heroku::Command::Apps, :method => :index)
|
|
154
|
+
Heroku::Command.parse("apps").should include(:klass => Heroku::Command::Apps, :method => :index)
|
|
155
|
+
Heroku::Command.parse("apps:create").should include(:klass => Heroku::Command::Apps, :method => :create)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
context "help" do
|
|
159
|
+
it "works as a prefix" do
|
|
160
|
+
heroku("help ps:scale").should =~ /scale processes by/
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it "works as an option" do
|
|
164
|
+
heroku("ps:scale -h").should =~ /scale processes by/
|
|
165
|
+
heroku("ps:scale --help").should =~ /scale processes by/
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
context "when no commands match" do
|
|
170
|
+
|
|
171
|
+
it "displays the version if --version is used" do
|
|
172
|
+
heroku("--version").should == <<-STDOUT
|
|
173
|
+
#{Heroku.user_agent}
|
|
174
|
+
STDOUT
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it "suggests similar commands if there are any" do
|
|
178
|
+
original_stderr, original_stdout = $stderr, $stdout
|
|
179
|
+
$stderr = captured_stderr = StringIO.new
|
|
180
|
+
$stdout = captured_stdout = StringIO.new
|
|
181
|
+
begin
|
|
182
|
+
execute("aps")
|
|
183
|
+
rescue SystemExit
|
|
184
|
+
end
|
|
185
|
+
captured_stderr.string.should == <<-STDERR
|
|
186
|
+
! `aps` is not a heroku command.
|
|
187
|
+
! Perhaps you meant `apps` or `ps`.
|
|
188
|
+
! See `heroku help` for a list of available commands.
|
|
189
|
+
STDERR
|
|
190
|
+
captured_stdout.string.should == ""
|
|
191
|
+
$stderr, $stdout = original_stderr, original_stdout
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it "does not suggest similar commands if there are none" do
|
|
195
|
+
original_stderr, original_stdout = $stderr, $stdout
|
|
196
|
+
$stderr = captured_stderr = StringIO.new
|
|
197
|
+
$stdout = captured_stdout = StringIO.new
|
|
198
|
+
begin
|
|
199
|
+
execute("sandwich")
|
|
200
|
+
rescue SystemExit
|
|
201
|
+
end
|
|
202
|
+
captured_stderr.string.should == <<-STDERR
|
|
203
|
+
! `sandwich` is not a heroku command.
|
|
204
|
+
! See `heroku help` for a list of available commands.
|
|
205
|
+
STDERR
|
|
206
|
+
captured_stdout.string.should == ""
|
|
207
|
+
$stderr, $stdout = original_stderr, original_stdout
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
end
|
|
211
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "heroku/helpers/heroku_postgresql"
|
|
3
|
+
|
|
4
|
+
include Heroku::Helpers::HerokuPostgresql
|
|
5
|
+
|
|
6
|
+
describe Heroku::Helpers::HerokuPostgresql do
|
|
7
|
+
|
|
8
|
+
before do
|
|
9
|
+
subject.stub(:app_config_vars) { app_config_vars }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
let(:app_config_vars) do
|
|
13
|
+
{
|
|
14
|
+
"DATABASE_URL" => "postgres://default",
|
|
15
|
+
"HEROKU_POSTGRESQL_BLACK_URL" => "postgres://black",
|
|
16
|
+
"HEROKU_POSTGRESQL_IVORY_URL" => "postgres://default",
|
|
17
|
+
"SHARED_DATABASE_URL" => "postgres://shared"
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "resolves DATABASE" do
|
|
22
|
+
subject.hpg_resolve('DATABASE').should == [
|
|
23
|
+
"HEROKU_POSTGRESQL_IVORY (DATABASE_URL)",
|
|
24
|
+
"postgres://default"
|
|
25
|
+
]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "resolves SHARED_DATABASE" do
|
|
29
|
+
subject.hpg_resolve('SHARED_DATABASE').should == [
|
|
30
|
+
"SHARED_DATABASE",
|
|
31
|
+
"postgres://shared"
|
|
32
|
+
]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "resolves default using NAME" do
|
|
36
|
+
subject.hpg_resolve("IVORY").should == [
|
|
37
|
+
"HEROKU_POSTGRESQL_IVORY (DATABASE_URL)",
|
|
38
|
+
"postgres://default"
|
|
39
|
+
]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "resolves non-default using NAME" do
|
|
43
|
+
subject.hpg_resolve("BLACK").should == [
|
|
44
|
+
"HEROKU_POSTGRESQL_BLACK",
|
|
45
|
+
"postgres://black"
|
|
46
|
+
]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "resolves default using NAME_URL" do
|
|
50
|
+
subject.hpg_resolve("IVORY_URL").should == [
|
|
51
|
+
"HEROKU_POSTGRESQL_IVORY (DATABASE_URL)",
|
|
52
|
+
"postgres://default"
|
|
53
|
+
]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "resolves non-default using NAME_URL" do
|
|
57
|
+
subject.hpg_resolve("BLACK_URL").should == [
|
|
58
|
+
"HEROKU_POSTGRESQL_BLACK",
|
|
59
|
+
"postgres://black"
|
|
60
|
+
]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "resolves default using lowercase" do
|
|
64
|
+
subject.hpg_resolve("ivory").should == [
|
|
65
|
+
"HEROKU_POSTGRESQL_IVORY (DATABASE_URL)",
|
|
66
|
+
"postgres://default"
|
|
67
|
+
]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "resolves non-default using lowercase" do
|
|
71
|
+
subject.hpg_resolve("black").should == [
|
|
72
|
+
"HEROKU_POSTGRESQL_BLACK",
|
|
73
|
+
"postgres://black"
|
|
74
|
+
]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "throws an error if it doesnt exist" do
|
|
78
|
+
subject.should_receive(:error).with("Unknown database: VIOLET. Valid options are: DATABASE, HEROKU_POSTGRESQL_BLACK, HEROKU_POSTGRESQL_IVORY, SHARED_DATABASE")
|
|
79
|
+
subject.hpg_resolve("violet")
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context "default" do
|
|
83
|
+
|
|
84
|
+
it "errors if there is no default" do
|
|
85
|
+
subject.should_receive(:error).with("Unknown database. Valid options are: DATABASE, HEROKU_POSTGRESQL_BLACK, HEROKU_POSTGRESQL_IVORY, SHARED_DATABASE")
|
|
86
|
+
subject.hpg_resolve(nil)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "uses the default if nothing specified" do
|
|
90
|
+
subject.hpg_resolve(nil, "DATABASE_URL").should == [
|
|
91
|
+
"HEROKU_POSTGRESQL_IVORY (DATABASE_URL)",
|
|
92
|
+
"postgres://default"
|
|
93
|
+
]
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
context "uri" do
|
|
99
|
+
|
|
100
|
+
it "returns the uri directly" do
|
|
101
|
+
subject.hpg_resolve('postgres://uri', nil).should == [
|
|
102
|
+
nil,
|
|
103
|
+
'postgres://uri'
|
|
104
|
+
]
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
end
|