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,178 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "heroku/command/certs"
|
|
3
|
+
|
|
4
|
+
module Heroku::Command
|
|
5
|
+
describe Certs do
|
|
6
|
+
let(:certificate_details) {
|
|
7
|
+
<<-CERTIFICATE_DETAILS.chomp
|
|
8
|
+
Common Name(s): example.org
|
|
9
|
+
Expires At: 2013-08-01 21:34 UTC
|
|
10
|
+
Issuer: /C=US/ST=California/L=San Francisco/O=Heroku by Salesforce/CN=secure.example.org
|
|
11
|
+
Starts At: 2012-08-01 21:34 UTC
|
|
12
|
+
Subject: /C=US/ST=California/L=San Francisco/O=Heroku by Salesforce/CN=secure.example.org
|
|
13
|
+
SSL certificate is self signed.
|
|
14
|
+
CERTIFICATE_DETAILS
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let(:endpoint) {
|
|
18
|
+
{ 'cname' => 'tokyo-1050.herokussl.com',
|
|
19
|
+
'ssl_cert' => {
|
|
20
|
+
'ca_signed?' => false,
|
|
21
|
+
'cert_domains' => [ 'example.org' ],
|
|
22
|
+
'starts_at' => "2012-08-01 21:34:23 UTC",
|
|
23
|
+
'expires_at' => "2013-08-01 21:34:23 UTC",
|
|
24
|
+
'issuer' => '/C=US/ST=California/L=San Francisco/O=Heroku by Salesforce/CN=secure.example.org',
|
|
25
|
+
'subject' => '/C=US/ST=California/L=San Francisco/O=Heroku by Salesforce/CN=secure.example.org',
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
let(:endpoint2) {
|
|
30
|
+
{ 'cname' => 'akita-7777.herokussl.com',
|
|
31
|
+
'ssl_cert' => {
|
|
32
|
+
'ca_signed?' => true,
|
|
33
|
+
'cert_domains' => [ 'heroku.com' ],
|
|
34
|
+
'starts_at' => "2012-08-01 21:34:23 UTC",
|
|
35
|
+
'expires_at' => "2013-08-01 21:34:23 UTC",
|
|
36
|
+
'issuer' => '/C=US/ST=California/L=San Francisco/O=Heroku by Salesforce/CN=secure.example.org',
|
|
37
|
+
'subject' => '/C=US/ST=California/L=San Francisco/O=Heroku by Salesforce/CN=secure.example.org',
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
describe "certs" do
|
|
43
|
+
it "shows a list of certs" do
|
|
44
|
+
stub_core.ssl_endpoint_list("myapp").returns([endpoint, endpoint2])
|
|
45
|
+
stderr, stdout = execute("certs")
|
|
46
|
+
stdout.should == <<-STDOUT
|
|
47
|
+
Endpoint Common Name(s) Expires Trusted
|
|
48
|
+
------------------------ -------------- -------------------- -------
|
|
49
|
+
tokyo-1050.herokussl.com example.org 2013-08-01 21:34 UTC False
|
|
50
|
+
akita-7777.herokussl.com heroku.com 2013-08-01 21:34 UTC True
|
|
51
|
+
STDOUT
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "warns about no SSL Endpoints if the app has no certs" do
|
|
55
|
+
stub_core.ssl_endpoint_list("myapp").returns([])
|
|
56
|
+
stderr, stdout = execute("certs")
|
|
57
|
+
stdout.should == <<-STDOUT
|
|
58
|
+
myapp has no SSL Endpoints.
|
|
59
|
+
Use `heroku certs:add PEM KEY` to add one.
|
|
60
|
+
STDOUT
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe "certs:add" do
|
|
65
|
+
it "adds an endpoint" do
|
|
66
|
+
File.should_receive(:read).with("pem_file").and_return("pem content")
|
|
67
|
+
File.should_receive(:read).with("key_file").and_return("key content")
|
|
68
|
+
stub_core.ssl_endpoint_add('myapp', 'pem content', 'key content').returns(endpoint)
|
|
69
|
+
|
|
70
|
+
stderr, stdout = execute("certs:add pem_file key_file")
|
|
71
|
+
stdout.should == <<-STDOUT
|
|
72
|
+
Adding SSL Endpoint to myapp... done
|
|
73
|
+
myapp now served by tokyo-1050.herokussl.com
|
|
74
|
+
Certificate details:
|
|
75
|
+
#{certificate_details}
|
|
76
|
+
STDOUT
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "shows usage if two arguments are not provided" do
|
|
80
|
+
lambda { execute("certs:add") }.should raise_error(CommandFailed, /Usage:/)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
describe "certs:info" do
|
|
85
|
+
it "shows certificate details" do
|
|
86
|
+
stub_core.ssl_endpoint_list("myapp").returns([endpoint])
|
|
87
|
+
stub_core.ssl_endpoint_info('myapp', 'tokyo-1050.herokussl.com').returns(endpoint)
|
|
88
|
+
|
|
89
|
+
stderr, stdout = execute("certs:info")
|
|
90
|
+
stdout.should == <<-STDOUT
|
|
91
|
+
Fetching SSL Endpoint tokyo-1050.herokussl.com info for myapp... done
|
|
92
|
+
Certificate details:
|
|
93
|
+
#{certificate_details}
|
|
94
|
+
STDOUT
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "shows an error if an app has no endpoints" do
|
|
98
|
+
stub_core.ssl_endpoint_list("myapp").returns([])
|
|
99
|
+
|
|
100
|
+
stderr, stdout = execute("certs:info")
|
|
101
|
+
stderr.should == <<-STDERR
|
|
102
|
+
! myapp has no SSL Endpoints.
|
|
103
|
+
STDERR
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe "certs:remove" do
|
|
108
|
+
it "removes an endpoint" do
|
|
109
|
+
stub_core.ssl_endpoint_list("myapp").returns([endpoint])
|
|
110
|
+
stub_core.ssl_endpoint_remove('myapp', 'tokyo-1050.herokussl.com').returns(endpoint)
|
|
111
|
+
|
|
112
|
+
stderr, stdout = execute("certs:remove")
|
|
113
|
+
stdout.should include "Removing SSL Endpoint tokyo-1050.herokussl.com from myapp..."
|
|
114
|
+
stdout.should include "NOTE: Billing is still active. Remove SSL Endpoint add-on to stop billing."
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "shows an error if an app has no endpoints" do
|
|
118
|
+
stub_core.ssl_endpoint_list("myapp").returns([])
|
|
119
|
+
|
|
120
|
+
stderr, stdout = execute("certs:remove")
|
|
121
|
+
stderr.should == <<-STDERR
|
|
122
|
+
! myapp has no SSL Endpoints.
|
|
123
|
+
STDERR
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
describe "certs:update" do
|
|
128
|
+
before do
|
|
129
|
+
File.should_receive(:read).with("pem_file").and_return("pem content")
|
|
130
|
+
File.should_receive(:read).with("key_file").and_return("key content")
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "updates an endpoint" do
|
|
134
|
+
stub_core.ssl_endpoint_list("myapp").returns([endpoint])
|
|
135
|
+
stub_core.ssl_endpoint_update('myapp', 'tokyo-1050.herokussl.com', 'pem content', 'key content').returns(endpoint)
|
|
136
|
+
|
|
137
|
+
stderr, stdout = execute("certs:update pem_file key_file")
|
|
138
|
+
stdout.should == <<-STDOUT
|
|
139
|
+
Updating SSL Endpoint tokyo-1050.herokussl.com for myapp... done
|
|
140
|
+
Updated certificate details:
|
|
141
|
+
#{certificate_details}
|
|
142
|
+
STDOUT
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "shows an error if an app has no endpoints" do
|
|
146
|
+
stub_core.ssl_endpoint_list("myapp").returns([])
|
|
147
|
+
|
|
148
|
+
stderr, stdout = execute("certs:update pem_file key_file")
|
|
149
|
+
stderr.should == <<-STDERR
|
|
150
|
+
! myapp has no SSL Endpoints.
|
|
151
|
+
STDERR
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
describe "certs:rollback" do
|
|
156
|
+
it "performs a rollback on an endpoint" do
|
|
157
|
+
stub_core.ssl_endpoint_list("myapp").returns([endpoint])
|
|
158
|
+
stub_core.ssl_endpoint_rollback('myapp', 'tokyo-1050.herokussl.com').returns(endpoint)
|
|
159
|
+
|
|
160
|
+
stderr, stdout = execute("certs:rollback")
|
|
161
|
+
stdout.should == <<-STDOUT
|
|
162
|
+
Rolling back SSL Endpoint tokyo-1050.herokussl.com for myapp... done
|
|
163
|
+
New active certificate details:
|
|
164
|
+
#{certificate_details}
|
|
165
|
+
STDOUT
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it "shows an error if an app has no endpoints" do
|
|
169
|
+
stub_core.ssl_endpoint_list("myapp").returns([])
|
|
170
|
+
|
|
171
|
+
stderr, stdout = execute("certs:rollback")
|
|
172
|
+
stderr.should == <<-STDERR
|
|
173
|
+
! myapp has no SSL Endpoints.
|
|
174
|
+
STDERR
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "heroku/command/config"
|
|
3
|
+
|
|
4
|
+
module Heroku::Command
|
|
5
|
+
describe Config do
|
|
6
|
+
before(:each) do
|
|
7
|
+
stub_core
|
|
8
|
+
api.post_app("name" => "myapp", "stack" => "cedar")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
after(:each) do
|
|
12
|
+
api.delete_app("myapp")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "shows all configs" do
|
|
16
|
+
api.put_config_vars("myapp", { 'FOO_BAR' => 'one', 'BAZ_QUX' => 'two' })
|
|
17
|
+
stderr, stdout = execute("config")
|
|
18
|
+
stderr.should == ""
|
|
19
|
+
stdout.should == <<-STDOUT
|
|
20
|
+
=== myapp Config Vars
|
|
21
|
+
BAZ_QUX: two
|
|
22
|
+
FOO_BAR: one
|
|
23
|
+
STDOUT
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "does not trim long values" do
|
|
27
|
+
api.put_config_vars("myapp", { 'LONG' => 'A' * 60 })
|
|
28
|
+
stderr, stdout = execute("config")
|
|
29
|
+
stderr.should == ""
|
|
30
|
+
stdout.should == <<-STDOUT
|
|
31
|
+
=== myapp Config Vars
|
|
32
|
+
LONG: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
33
|
+
STDOUT
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "handles when value is nil" do
|
|
37
|
+
api.put_config_vars("myapp", { 'FOO_BAR' => 'one', 'BAZ_QUX' => nil })
|
|
38
|
+
stderr, stdout = execute("config")
|
|
39
|
+
stderr.should == ""
|
|
40
|
+
stdout.should == <<-STDOUT
|
|
41
|
+
=== myapp Config Vars
|
|
42
|
+
BAZ_QUX:
|
|
43
|
+
FOO_BAR: one
|
|
44
|
+
STDOUT
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "handles when value is a boolean" do
|
|
48
|
+
api.put_config_vars("myapp", { 'FOO_BAR' => 'one', 'BAZ_QUX' => true })
|
|
49
|
+
stderr, stdout = execute("config")
|
|
50
|
+
stderr.should == ""
|
|
51
|
+
stdout.should == <<-STDOUT
|
|
52
|
+
=== myapp Config Vars
|
|
53
|
+
BAZ_QUX: true
|
|
54
|
+
FOO_BAR: one
|
|
55
|
+
STDOUT
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "shows configs in a shell compatible format" do
|
|
59
|
+
api.put_config_vars("myapp", { 'A' => 'one', 'B' => 'two three' })
|
|
60
|
+
stderr, stdout = execute("config --shell")
|
|
61
|
+
stderr.should == ""
|
|
62
|
+
stdout.should == <<-STDOUT
|
|
63
|
+
A=one
|
|
64
|
+
B=two three
|
|
65
|
+
STDOUT
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "shows a single config for get" do
|
|
69
|
+
api.put_config_vars("myapp", { 'LONG' => 'A' * 60 })
|
|
70
|
+
stderr, stdout = execute("config:get LONG")
|
|
71
|
+
stderr.should == ""
|
|
72
|
+
stdout.should == <<-STDOUT
|
|
73
|
+
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
74
|
+
STDOUT
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context("set") do
|
|
78
|
+
|
|
79
|
+
it "sets config vars" do
|
|
80
|
+
stderr, stdout = execute("config:set A=1 B=2")
|
|
81
|
+
stderr.should == ""
|
|
82
|
+
stdout.should == <<-STDOUT
|
|
83
|
+
Setting config vars and restarting myapp... done, v1
|
|
84
|
+
A: 1
|
|
85
|
+
B: 2
|
|
86
|
+
STDOUT
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "allows config vars with = in the value" do
|
|
90
|
+
stderr, stdout = execute("config:set A=b=c")
|
|
91
|
+
stderr.should == ""
|
|
92
|
+
stdout.should == <<-STDOUT
|
|
93
|
+
Setting config vars and restarting myapp... done, v1
|
|
94
|
+
A: b=c
|
|
95
|
+
STDOUT
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "sets config vars without changing case" do
|
|
99
|
+
stderr, stdout = execute("config:set a=b")
|
|
100
|
+
stderr.should == ""
|
|
101
|
+
stdout.should == <<-STDOUT
|
|
102
|
+
Setting config vars and restarting myapp... done, v1
|
|
103
|
+
a: b
|
|
104
|
+
STDOUT
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
describe "config:unset" do
|
|
110
|
+
|
|
111
|
+
it "exits with a help notice when no keys are provides" do
|
|
112
|
+
stderr, stdout = execute("config:unset")
|
|
113
|
+
stderr.should == <<-STDERR
|
|
114
|
+
! Usage: heroku config:unset KEY1 [KEY2 ...]
|
|
115
|
+
! Must specify KEY to unset.
|
|
116
|
+
STDERR
|
|
117
|
+
stdout.should == ""
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
context "when one key is provided" do
|
|
121
|
+
|
|
122
|
+
it "unsets a single key" do
|
|
123
|
+
stderr, stdout = execute("config:unset A")
|
|
124
|
+
stderr.should == ""
|
|
125
|
+
stdout.should == <<-STDOUT
|
|
126
|
+
Unsetting A and restarting myapp... done, v1
|
|
127
|
+
STDOUT
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
context "when more than one key is provided" do
|
|
132
|
+
|
|
133
|
+
it "unsets all given keys" do
|
|
134
|
+
stderr, stdout = execute("config:unset A B")
|
|
135
|
+
stderr.should == ""
|
|
136
|
+
stdout.should == <<-STDOUT
|
|
137
|
+
Unsetting A and restarting myapp... done, v1
|
|
138
|
+
Unsetting B and restarting myapp... done, v2
|
|
139
|
+
STDOUT
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "heroku/command/db"
|
|
3
|
+
|
|
4
|
+
module Heroku::Command
|
|
5
|
+
describe Db do
|
|
6
|
+
before do
|
|
7
|
+
@db = prepare_command(Db)
|
|
8
|
+
@taps_client = mock('taps client')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "pull database" do
|
|
12
|
+
pending("requires taps") unless taps_available?
|
|
13
|
+
@db.stub!(:args).and_return(['postgres://postgres@localhost/db'])
|
|
14
|
+
opts = { :database_url => 'postgres://postgres@localhost/db', :default_chunksize => 1000, :indexes_first => true }
|
|
15
|
+
@db.should_receive(:taps_client).with(:pull, opts)
|
|
16
|
+
@db.should_receive(:confirm_command).and_return(true)
|
|
17
|
+
@db.pull
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "push database" do
|
|
21
|
+
pending("requires taps") unless taps_available?
|
|
22
|
+
@db.stub!(:args).and_return(['postgres://postgres@localhost/db'])
|
|
23
|
+
opts = { :database_url => 'postgres://postgres@localhost/db', :default_chunksize => 1000, :indexes_first => true }
|
|
24
|
+
@db.should_receive(:taps_client).with(:push, opts)
|
|
25
|
+
@db.should_receive(:confirm_command).and_return(true)
|
|
26
|
+
@db.push
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "without PostgreSQL" do
|
|
30
|
+
it "defaults host to 127.0.0.1 with a username" do
|
|
31
|
+
@db.send(:uri_hash_to_url, {'scheme' => 'db', 'username' => 'user', 'path' => 'database'}).should == 'db://user@127.0.0.1/database'
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe "with PostgreSQL" do
|
|
36
|
+
it "handles lack of host as UNIX domain socket connection" do
|
|
37
|
+
@db.send(:uri_hash_to_url, {'scheme' => 'postgres', 'path' => 'database'}).should == 'postgres:/database'
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "handles the lack of a username properly" do
|
|
42
|
+
@db.send(:uri_hash_to_url, {'scheme' => 'db', 'path' => 'database'}).should == 'db://127.0.0.1/database'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "handles integer port number" do
|
|
46
|
+
@db.send(:uri_hash_to_url, {'scheme' => 'db', 'path' => 'database', 'port' => 9000}).should == 'db://127.0.0.1:9000/database'
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "maps --tables to the taps table_filter option" do
|
|
50
|
+
@db.stub!(:args).and_return(["sqlite://local.db"])
|
|
51
|
+
@db.stub!(:options).and_return(:tables => "tags,countries")
|
|
52
|
+
opts = @db.send(:parse_taps_opts)
|
|
53
|
+
opts[:table_filter].should == "(^tags$|^countries$)"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "handles both a url and a --confirm on the command line" do
|
|
57
|
+
pending("requires taps") unless taps_available?
|
|
58
|
+
Heroku::Command.stub!(:current_options).and_return(:confirm => "myapp")
|
|
59
|
+
@db.stub!(:args).and_return(["mysql://user:pass@host/db"])
|
|
60
|
+
opts = { :database_url => 'mysql://user:pass@host/db', :default_chunksize => 1000, :indexes_first => true }
|
|
61
|
+
@db.should_receive(:taps_client).with(:pull, opts)
|
|
62
|
+
@db.pull
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "handles no url and --confirm on the command line" do
|
|
66
|
+
pending("requires taps") unless taps_available?
|
|
67
|
+
Heroku::Command.stub!(:current_options).and_return(:confirm => "myapp")
|
|
68
|
+
opts = { :database_url => 'mysql://user:pass@host/db', :default_chunksize => 1000, :indexes_first => true }
|
|
69
|
+
@db.should_receive(:parse_database_yml).and_return("mysql://user:pass@host/db")
|
|
70
|
+
@db.should_receive(:taps_client).with(:pull, opts)
|
|
71
|
+
@db.pull
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "works with a file-based url" do
|
|
75
|
+
pending("requires taps") unless taps_available?
|
|
76
|
+
url = "sqlite://tmp/foo.db"
|
|
77
|
+
Heroku::Command.stub(:current_options).and_return(:confirm => "myapp")
|
|
78
|
+
@db.stub(:args).and_return([url])
|
|
79
|
+
@db.should_receive(:taps_client).with(:pull, hash_including(:database_url => url))
|
|
80
|
+
@db.pull
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
describe "with erb in the database.yml" do
|
|
84
|
+
before do
|
|
85
|
+
@rails_env = ENV["RAILS_ENV"]
|
|
86
|
+
ENV["RAILS_ENV"] = "development"
|
|
87
|
+
|
|
88
|
+
FakeFS.activate!
|
|
89
|
+
FileUtils.mkdir_p "config"
|
|
90
|
+
File.open("config/database.yml", "w") do |file|
|
|
91
|
+
file.puts <<-YAML
|
|
92
|
+
development:
|
|
93
|
+
adapter: db
|
|
94
|
+
host: localhost
|
|
95
|
+
database: <%= 'db'+'1' %>
|
|
96
|
+
YAML
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
after do
|
|
101
|
+
FakeFS.deactivate!
|
|
102
|
+
ENV["RAILS_ENV"] = @rails_env
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "handles ERB code in YAML" do
|
|
106
|
+
@db.send(:parse_database_yml).should == 'db://localhost/db1?encoding=utf8'
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "heroku/command/domains"
|
|
3
|
+
|
|
4
|
+
module Heroku::Command
|
|
5
|
+
describe Domains do
|
|
6
|
+
|
|
7
|
+
before(:all) do
|
|
8
|
+
api.post_app("name" => "myapp", "stack" => "cedar")
|
|
9
|
+
api.post_addon("myapp", "custom_domains:basic")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
after(:all) do
|
|
13
|
+
api.delete_app("myapp")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
before(:each) do
|
|
17
|
+
stub_core
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context("index") do
|
|
21
|
+
|
|
22
|
+
it "lists message with no domains" do
|
|
23
|
+
stderr, stdout = execute("domains")
|
|
24
|
+
stderr.should == ""
|
|
25
|
+
stdout.should == <<-STDOUT
|
|
26
|
+
myapp has no domain names.
|
|
27
|
+
STDOUT
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "lists domains when some exist" do
|
|
31
|
+
api.post_domain("myapp", "example.com")
|
|
32
|
+
stderr, stdout = execute("domains")
|
|
33
|
+
stderr.should == ""
|
|
34
|
+
stdout.should == <<-STDOUT
|
|
35
|
+
=== myapp Domain Names
|
|
36
|
+
example.com
|
|
37
|
+
|
|
38
|
+
STDOUT
|
|
39
|
+
api.delete_domain("myapp", "example.com")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "adds domain names" do
|
|
45
|
+
stderr, stdout = execute("domains:add example.com")
|
|
46
|
+
stderr.should == ""
|
|
47
|
+
stdout.should == <<-STDOUT
|
|
48
|
+
Adding example.com to myapp... done
|
|
49
|
+
STDOUT
|
|
50
|
+
api.delete_domain("myapp", "example.com")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "shows usage if no domain specified for add" do
|
|
54
|
+
stderr, stdout = execute("domains:add")
|
|
55
|
+
stderr.should == <<-STDERR
|
|
56
|
+
! Usage: heroku domains:add DOMAIN
|
|
57
|
+
! Must specify DOMAIN to add.
|
|
58
|
+
STDERR
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "removes domain names" do
|
|
62
|
+
api.post_domain("myapp", "example.com")
|
|
63
|
+
stderr, stdout = execute("domains:remove example.com")
|
|
64
|
+
stderr.should == ""
|
|
65
|
+
stdout.should == <<-STDOUT
|
|
66
|
+
Removing example.com from myapp... done
|
|
67
|
+
STDOUT
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "shows usage if no domain specified for remove" do
|
|
71
|
+
stderr, stdout = execute("domains:remove")
|
|
72
|
+
stderr.should == <<-STDERR
|
|
73
|
+
! Usage: heroku domains:remove DOMAIN
|
|
74
|
+
! Must specify DOMAIN to remove.
|
|
75
|
+
STDERR
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "removes all domain names" do
|
|
79
|
+
stub_core.remove_domains("myapp")
|
|
80
|
+
stderr, stdout = execute("domains:clear")
|
|
81
|
+
stderr.should == ""
|
|
82
|
+
stdout.should == <<-STDOUT
|
|
83
|
+
Removing all domain names from myapp... done
|
|
84
|
+
STDOUT
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|