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.
- checksums.yaml +15 -0
- data/README.md +36 -0
- data/bin/turbot +17 -0
- data/data/cacert.pem +3988 -0
- data/lib/turbot/auth.rb +315 -0
- data/lib/turbot/cli.rb +38 -0
- data/lib/turbot/client/cisaurus.rb +25 -0
- data/lib/turbot/client/pgbackups.rb +113 -0
- data/lib/turbot/client/rendezvous.rb +111 -0
- data/lib/turbot/client/ssl_endpoint.rb +25 -0
- data/lib/turbot/client/turbot_postgresql.rb +148 -0
- data/lib/turbot/client.rb +757 -0
- data/lib/turbot/command/auth.rb +85 -0
- data/lib/turbot/command/base.rb +192 -0
- data/lib/turbot/command/bots.rb +326 -0
- data/lib/turbot/command/config.rb +123 -0
- data/lib/turbot/command/help.rb +179 -0
- data/lib/turbot/command/keys.rb +115 -0
- data/lib/turbot/command/logs.rb +34 -0
- data/lib/turbot/command/ssl.rb +43 -0
- data/lib/turbot/command/status.rb +51 -0
- data/lib/turbot/command/update.rb +47 -0
- data/lib/turbot/command/version.rb +23 -0
- data/lib/turbot/command.rb +304 -0
- data/lib/turbot/deprecated/help.rb +38 -0
- data/lib/turbot/deprecated.rb +5 -0
- data/lib/turbot/distribution.rb +9 -0
- data/lib/turbot/errors.rb +28 -0
- data/lib/turbot/excon.rb +11 -0
- data/lib/turbot/helpers/log_displayer.rb +70 -0
- data/lib/turbot/helpers/pg_dump_restore.rb +115 -0
- data/lib/turbot/helpers/turbot_postgresql.rb +213 -0
- data/lib/turbot/helpers.rb +521 -0
- data/lib/turbot/plugin.rb +165 -0
- data/lib/turbot/updater.rb +171 -0
- data/lib/turbot/version.rb +3 -0
- data/lib/turbot.rb +19 -0
- data/lib/vendor/turbot/okjson.rb +598 -0
- data/spec/helper/legacy_help.rb +16 -0
- data/spec/helper/pg_dump_restore_spec.rb +67 -0
- data/spec/schemas/dummy_schema.json +12 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +220 -0
- data/spec/support/display_message_matcher.rb +49 -0
- data/spec/support/dummy_api.rb +120 -0
- data/spec/support/openssl_mock_helper.rb +8 -0
- data/spec/support/organizations_mock_helper.rb +11 -0
- data/spec/turbot/auth_spec.rb +214 -0
- data/spec/turbot/client/pgbackups_spec.rb +43 -0
- data/spec/turbot/client/rendezvous_spec.rb +62 -0
- data/spec/turbot/client/ssl_endpoint_spec.rb +48 -0
- data/spec/turbot/client/turbot_postgresql_spec.rb +71 -0
- data/spec/turbot/client_spec.rb +548 -0
- data/spec/turbot/command/auth_spec.rb +38 -0
- data/spec/turbot/command/base_spec.rb +66 -0
- data/spec/turbot/command/bots_spec.rb +54 -0
- data/spec/turbot/command/config_spec.rb +143 -0
- data/spec/turbot/command/help_spec.rb +90 -0
- data/spec/turbot/command/keys_spec.rb +117 -0
- data/spec/turbot/command/logs_spec.rb +60 -0
- data/spec/turbot/command/status_spec.rb +48 -0
- data/spec/turbot/command/version_spec.rb +16 -0
- data/spec/turbot/command_spec.rb +131 -0
- data/spec/turbot/helpers/turbot_postgresql_spec.rb +181 -0
- data/spec/turbot/helpers_spec.rb +48 -0
- data/spec/turbot/plugin_spec.rb +172 -0
- data/spec/turbot/updater_spec.rb +44 -0
- data/templates/manifest.json +7 -0
- data/templates/scraper.py +5 -0
- data/templates/scraper.rb +6 -0
- 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
|