turbot 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +15 -0
  2. data/README.md +36 -0
  3. data/bin/turbot +17 -0
  4. data/data/cacert.pem +3988 -0
  5. data/lib/turbot/auth.rb +315 -0
  6. data/lib/turbot/cli.rb +38 -0
  7. data/lib/turbot/client/cisaurus.rb +25 -0
  8. data/lib/turbot/client/pgbackups.rb +113 -0
  9. data/lib/turbot/client/rendezvous.rb +111 -0
  10. data/lib/turbot/client/ssl_endpoint.rb +25 -0
  11. data/lib/turbot/client/turbot_postgresql.rb +148 -0
  12. data/lib/turbot/client.rb +757 -0
  13. data/lib/turbot/command/auth.rb +85 -0
  14. data/lib/turbot/command/base.rb +192 -0
  15. data/lib/turbot/command/bots.rb +326 -0
  16. data/lib/turbot/command/config.rb +123 -0
  17. data/lib/turbot/command/help.rb +179 -0
  18. data/lib/turbot/command/keys.rb +115 -0
  19. data/lib/turbot/command/logs.rb +34 -0
  20. data/lib/turbot/command/ssl.rb +43 -0
  21. data/lib/turbot/command/status.rb +51 -0
  22. data/lib/turbot/command/update.rb +47 -0
  23. data/lib/turbot/command/version.rb +23 -0
  24. data/lib/turbot/command.rb +304 -0
  25. data/lib/turbot/deprecated/help.rb +38 -0
  26. data/lib/turbot/deprecated.rb +5 -0
  27. data/lib/turbot/distribution.rb +9 -0
  28. data/lib/turbot/errors.rb +28 -0
  29. data/lib/turbot/excon.rb +11 -0
  30. data/lib/turbot/helpers/log_displayer.rb +70 -0
  31. data/lib/turbot/helpers/pg_dump_restore.rb +115 -0
  32. data/lib/turbot/helpers/turbot_postgresql.rb +213 -0
  33. data/lib/turbot/helpers.rb +521 -0
  34. data/lib/turbot/plugin.rb +165 -0
  35. data/lib/turbot/updater.rb +171 -0
  36. data/lib/turbot/version.rb +3 -0
  37. data/lib/turbot.rb +19 -0
  38. data/lib/vendor/turbot/okjson.rb +598 -0
  39. data/spec/helper/legacy_help.rb +16 -0
  40. data/spec/helper/pg_dump_restore_spec.rb +67 -0
  41. data/spec/schemas/dummy_schema.json +12 -0
  42. data/spec/spec.opts +1 -0
  43. data/spec/spec_helper.rb +220 -0
  44. data/spec/support/display_message_matcher.rb +49 -0
  45. data/spec/support/dummy_api.rb +120 -0
  46. data/spec/support/openssl_mock_helper.rb +8 -0
  47. data/spec/support/organizations_mock_helper.rb +11 -0
  48. data/spec/turbot/auth_spec.rb +214 -0
  49. data/spec/turbot/client/pgbackups_spec.rb +43 -0
  50. data/spec/turbot/client/rendezvous_spec.rb +62 -0
  51. data/spec/turbot/client/ssl_endpoint_spec.rb +48 -0
  52. data/spec/turbot/client/turbot_postgresql_spec.rb +71 -0
  53. data/spec/turbot/client_spec.rb +548 -0
  54. data/spec/turbot/command/auth_spec.rb +38 -0
  55. data/spec/turbot/command/base_spec.rb +66 -0
  56. data/spec/turbot/command/bots_spec.rb +54 -0
  57. data/spec/turbot/command/config_spec.rb +143 -0
  58. data/spec/turbot/command/help_spec.rb +90 -0
  59. data/spec/turbot/command/keys_spec.rb +117 -0
  60. data/spec/turbot/command/logs_spec.rb +60 -0
  61. data/spec/turbot/command/status_spec.rb +48 -0
  62. data/spec/turbot/command/version_spec.rb +16 -0
  63. data/spec/turbot/command_spec.rb +131 -0
  64. data/spec/turbot/helpers/turbot_postgresql_spec.rb +181 -0
  65. data/spec/turbot/helpers_spec.rb +48 -0
  66. data/spec/turbot/plugin_spec.rb +172 -0
  67. data/spec/turbot/updater_spec.rb +44 -0
  68. data/templates/manifest.json +7 -0
  69. data/templates/scraper.py +5 -0
  70. data/templates/scraper.rb +6 -0
  71. metadata +199 -0
@@ -0,0 +1,220 @@
1
+ $stdin = File.new("/dev/null")
2
+
3
+ require "rubygems"
4
+
5
+ require "excon"
6
+ Excon.defaults[:mock] = true
7
+
8
+ # ensure these are around for errors
9
+ # as their require is generally deferred
10
+ #require "turbot-api"
11
+ require "rest_client"
12
+
13
+ require "turbot/cli"
14
+ require "rspec"
15
+ require "rr"
16
+ require "fakefs/safe"
17
+ require 'tmpdir'
18
+ require "webmock/rspec"
19
+
20
+ include WebMock::API
21
+
22
+ WebMock::HttpLibAdapters::ExconAdapter.disable!
23
+
24
+ def api
25
+ Turbot::API.new(:api_key => "pass", :mock => true)
26
+ end
27
+
28
+ def org_api
29
+ Turbot::Client::Organizations.api(:mock => true)
30
+ end
31
+
32
+ def stub_api_request(method, path)
33
+ stub_request(method, "https://api.turbot.com#{path}")
34
+ end
35
+
36
+ def prepare_command(klass)
37
+ command = klass.new
38
+ command.stub!(:bot).and_return("example")
39
+ command.stub!(:ask).and_return("")
40
+ command.stub!(:display)
41
+ command.stub!(:hputs)
42
+ command.stub!(:hprint)
43
+ command.stub!(:turbot).and_return(mock('turbot client', :host => 'turbot.com'))
44
+ command
45
+ end
46
+
47
+ def execute(command_line)
48
+ extend RR::Adapters::RRMethods
49
+
50
+ args = command_line.split(" ")
51
+ command = args.shift
52
+
53
+ Turbot::Command.load
54
+ object, method = Turbot::Command.prepare_run(command, args)
55
+
56
+ any_instance_of(Turbot::Command::Base) do |base|
57
+ stub(base).bot.returns("example")
58
+ end
59
+
60
+ stub(Turbot::Auth).get_credentials.returns(['email@example.com', 'apikey01'])
61
+ stub(Turbot::Auth).api_key.returns('apikey01')
62
+
63
+ original_stdin, original_stderr, original_stdout = $stdin, $stderr, $stdout
64
+
65
+ $stdin = captured_stdin = StringIO.new
66
+ $stderr = captured_stderr = StringIO.new
67
+ $stdout = captured_stdout = StringIO.new
68
+ class << captured_stdout
69
+ def tty?
70
+ true
71
+ end
72
+ end
73
+
74
+ begin
75
+ object.send(method)
76
+ rescue SystemExit
77
+ ensure
78
+ $stdin, $stderr, $stdout = original_stdin, original_stderr, original_stdout
79
+ Turbot::Command.current_command = nil
80
+ end
81
+
82
+ [captured_stderr.string, captured_stdout.string]
83
+ end
84
+
85
+ def any_instance_of(klass, &block)
86
+ extend RR::Adapters::RRMethods
87
+ any_instance_of(klass, &block)
88
+ end
89
+
90
+ def run(command_line)
91
+ capture_stdout do
92
+ begin
93
+ Turbot::CLI.start(*command_line.split(" "))
94
+ rescue SystemExit
95
+ end
96
+ end
97
+ end
98
+
99
+ alias turbot run
100
+
101
+ def capture_stderr(&block)
102
+ original_stderr = $stderr
103
+ $stderr = captured_stderr = StringIO.new
104
+ begin
105
+ yield
106
+ ensure
107
+ $stderr = original_stderr
108
+ end
109
+ captured_stderr.string
110
+ end
111
+
112
+ def capture_stdout(&block)
113
+ original_stdout = $stdout
114
+ $stdout = captured_stdout = StringIO.new
115
+ begin
116
+ yield
117
+ ensure
118
+ $stdout = original_stdout
119
+ end
120
+ captured_stdout.string
121
+ end
122
+
123
+ def fail_command(message)
124
+ raise_error(Turbot::Command::CommandFailed, message)
125
+ end
126
+
127
+ def stub_core
128
+ @stubbed_core ||= begin
129
+ stubbed_core = nil
130
+ any_instance_of(Turbot::Client) do |core|
131
+ stubbed_core = stub(core)
132
+ end
133
+ stub(Turbot::Auth).user.returns("email@example.com")
134
+ stub(Turbot::Auth).password.returns("pass")
135
+ stub(Turbot::Client).auth.returns("apikey01")
136
+ stubbed_core
137
+ end
138
+ end
139
+
140
+ def stub_pg
141
+ @stubbed_pg ||= begin
142
+ stubbed_pg = nil
143
+ any_instance_of(Turbot::Client::TurbotPostgresql) do |pg|
144
+ stubbed_pg = stub(pg)
145
+ end
146
+ stubbed_pg
147
+ end
148
+ end
149
+
150
+ def stub_pgbackups
151
+ @stubbed_pgbackups ||= begin
152
+ stubbed_pgbackups = nil
153
+ any_instance_of(Turbot::Client::Pgbackups) do |pgbackups|
154
+ stubbed_pgbackups = stub(pgbackups)
155
+ end
156
+ stubbed_pgbackups
157
+ end
158
+ end
159
+
160
+ def stub_rendezvous
161
+ @stubbed_rendezvous ||= begin
162
+ stubbed_rendezvous = nil
163
+ any_instance_of(Turbot::Client::Rendezvous) do |rendezvous|
164
+ stubbed_rendezvous = stub(rendezvous)
165
+ end
166
+ stubbed_rendezvous
167
+ end
168
+ end
169
+
170
+ def stub_cisaurus
171
+ @stub_cisaurus ||= begin
172
+ stub_cisaurus = nil
173
+ any_instance_of(Turbot::Client::Cisaurus) do |cisaurus|
174
+ stub_cisaurus = stub(cisaurus)
175
+ end
176
+ stub_cisaurus
177
+ end
178
+ end
179
+
180
+ def with_blank_git_repository(&block)
181
+ sandbox = File.join(Dir.tmpdir, "turbot", Process.pid.to_s)
182
+ FileUtils.mkdir_p(sandbox)
183
+
184
+ old_dir = Dir.pwd
185
+ Dir.chdir(sandbox)
186
+
187
+ `git init`
188
+ block.call
189
+
190
+ FileUtils.rm_rf(sandbox)
191
+ ensure
192
+ Dir.chdir(old_dir)
193
+ end
194
+
195
+ module SandboxHelper
196
+ def bash(cmd)
197
+ `#{cmd}`
198
+ end
199
+ end
200
+
201
+ require "turbot/helpers"
202
+ module Turbot::Helpers
203
+ @home_directory = Dir.mktmpdir
204
+ undef_method :home_directory
205
+ def home_directory
206
+ @home_directory
207
+ end
208
+ end
209
+
210
+ require "support/display_message_matcher"
211
+ require "support/organizations_mock_helper"
212
+ require "support/dummy_api"
213
+
214
+ RSpec.configure do |config|
215
+ config.color_enabled = true
216
+ config.include DisplayMessageMatcher
217
+ config.order = 'rand'
218
+ config.before { Turbot::Helpers.error_with_failure = false }
219
+ config.after { RR.reset }
220
+ end
@@ -0,0 +1,49 @@
1
+ module DisplayMessageMatcher
2
+
3
+ def display_message(command, message)
4
+ DisplayMessageMatcher::DisplayMessage.new command, message
5
+ end
6
+
7
+ class DisplayMessage
8
+ def initialize(command, message)
9
+ @command = command
10
+ @message = message
11
+ end
12
+
13
+ def matches?(given_proc)
14
+ displayed_expected_message = false
15
+ @given_messages = []
16
+
17
+ @command.should_receive(:display).
18
+ any_number_of_times do |message, newline|
19
+ @given_messages << message
20
+ displayed_expected_message = displayed_expected_message ||
21
+ message == @message
22
+ end
23
+
24
+ given_proc.call
25
+
26
+ displayed_expected_message
27
+ end
28
+
29
+ def failure_message
30
+ "expected #{ @command } to display the message #{ @message.inspect } but #{ given_messages }"
31
+ end
32
+
33
+ def negative_failure_message
34
+ "expected #{ @command } to not display the message #{ @message.inspect } but it was displayed"
35
+ end
36
+
37
+ private
38
+
39
+ def given_messages
40
+ if @given_messages.empty?
41
+ 'no messages were displayed'
42
+ else
43
+ formatted_given_messages = @given_messages.map(&:inspect).join ', '
44
+ "the follow messages were displayed: #{ formatted_given_messages }"
45
+ end
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,120 @@
1
+ require 'json'
2
+
3
+ module Turbot
4
+ class API
5
+ def initialize(params)
6
+ @headers = params[:headers]
7
+ @host = params[:host]
8
+ @port = params[:port]
9
+ @username = params[:username]
10
+ @password = params[:password]
11
+ @scheme = params[:scheme]
12
+ @ssl_verify_peer = params[:ssl_verify_peer]
13
+ @api_key = params[:api_key] || get_api_key(@username, @password)
14
+ authenticate
15
+
16
+ end
17
+
18
+ def authenticate
19
+ # Try to authenticate at this stage - something like
20
+ #user_pass = ":#{@api_key}"
21
+ #options[:headers] = HEADERS.merge({
22
+ # 'Authorization' => "Basic #{Base64.encode64(user_pass).gsub("\n", '')}",
23
+ # }).merge(options[:headers])
24
+
25
+ # @connection = Excon.new("http://missions.opencorporates.com/login", options)
26
+
27
+ end
28
+
29
+ def get_user
30
+ # raise if not authenticated
31
+ # @connection.code < 400
32
+ end
33
+
34
+ def get_api_key(user, password)
35
+ # get the api key, raise exception if credentials broken
36
+ # this is a hash of the username and password plus salt
37
+ return "some-api-key"
38
+ end
39
+
40
+ def get_keys
41
+ # return an array of ssh keys
42
+ read_db("keys")
43
+ end
44
+
45
+ def post_key(key)
46
+ # receive ssh key and associate with account
47
+ append_db("keys", {"contents" => key})
48
+ end
49
+
50
+ def delete_key(key)
51
+ keys = read_db("keys")
52
+ keys.delete(key)
53
+ write_db("keys", keys)
54
+ end
55
+
56
+ def delete_keys
57
+ write_db("keys", [])
58
+ end
59
+
60
+ def post_bot(data)
61
+ # XXX need to implement this to make the config command pass...
62
+ # save an "bot" - we'll replace this with the bot stuff chris did
63
+ db = read_db("bot")
64
+ db[data["name"]] = data
65
+ write_db("bot", db)
66
+ end
67
+
68
+ def delete_bot(bot)
69
+ db = read_db("bot")
70
+ db.delete(bot)
71
+ write_db("bot", db)
72
+ end
73
+
74
+ def get_bots
75
+ read_db("bot", [])
76
+ end
77
+
78
+ def get_bot(bot)
79
+ db = read_db("bot_data", [])
80
+ db[bot]
81
+ end
82
+
83
+ def put_config_vars(bot, vars)
84
+ # Set vars for bot specified
85
+ config = read_db("config")
86
+ config[bot] = vars
87
+ write_db("config", config)
88
+ end
89
+
90
+ def get_config_vars(bot)
91
+ read_db("config", [])[bot]
92
+ end
93
+
94
+ def delete_config_var(bot, key)
95
+ db = read_db("config", [])
96
+ keys = db[bot]
97
+ keys.delete(key)
98
+ db[bot] = keys
99
+ write_db("config", db)
100
+ end
101
+
102
+ private
103
+
104
+ def write_db(name, data)
105
+ open("/tmp/#{name}", "w") do |f|
106
+ f.write(JSON.dump(data))
107
+ end
108
+ end
109
+
110
+ def read_db(name, default={})
111
+ JSON.parse(open("/tmp/#{name}", "r").read) rescue {}
112
+ end
113
+
114
+ def append_db(name, data)
115
+ db = read_db(name, [])
116
+ db << data
117
+ write_db(name, db)
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,8 @@
1
+ def mock_openssl
2
+ @ctx_mock = mock "SSLContext", :key= => nil, :cert= => nil, :ssl_version= => nil
3
+ @tcp_socket_mock = mock "TCPSocket", :close => true
4
+ @ssl_socket_mock = mock "SSLSocket", :sync= => true, :connect => true, :close => true, :to_io => $stdin
5
+
6
+ OpenSSL::SSL::SSLSocket.stub(:new).and_return(@ssl_socket_mock)
7
+ OpenSSL::SSL::SSLContext.stub(:new).and_return(@ctx_mock)
8
+ end
@@ -0,0 +1,11 @@
1
+ class Turbot::Client::Organizations
2
+
3
+ # stub GET /v1/user/info
4
+ Excon.stub(:expects => 200, :method => :get, :path => %r{^/v1/user/info$} ) do |params|
5
+ {
6
+ :body => "",
7
+ :status => 404
8
+ }
9
+ end
10
+
11
+ end
@@ -0,0 +1,214 @@
1
+ require "spec_helper"
2
+ require "turbot/auth"
3
+ require "turbot/helpers"
4
+
5
+ module Turbot
6
+ describe Auth do
7
+ include Turbot::Helpers
8
+
9
+ before do
10
+ ENV['TURBOT_API_KEY'] = nil
11
+
12
+ @cli = Turbot::Auth
13
+ @cli.stub!(:check)
14
+ @cli.stub!(:display)
15
+ @cli.stub!(:running_on_a_mac?).and_return(false)
16
+ @cli.credentials = nil
17
+
18
+ FakeFS.activate!
19
+
20
+ FakeFS::File.stub!(:stat).and_return(double('stat', :mode => "0600".to_i(8)))
21
+ FakeFS::FileUtils.stub!(:chmod)
22
+ FakeFS::File.stub!(:readlines) do |path|
23
+ File.read(path).split("\n").map {|line| "#{line}\n"}
24
+ end
25
+
26
+ FileUtils.mkdir_p(@cli.netrc_path.split("/")[0..-2].join("/"))
27
+
28
+ File.open(@cli.netrc_path, "w") do |file|
29
+ file.puts("machine api.turbot.com\n login user\n password pass\n")
30
+ file.puts("machine code.turbot.com\n login user\n password pass\n")
31
+ end
32
+ end
33
+
34
+ after do
35
+ FileUtils.rm_rf(@cli.netrc_path)
36
+ FakeFS.deactivate!
37
+ end
38
+
39
+
40
+ context "API key is set via environment variable" do
41
+ before do
42
+ ENV['TURBOT_API_KEY'] = "secret"
43
+ end
44
+
45
+ it "gets credentials from environment variables in preference to credentials file" do
46
+ @cli.read_credentials.should == ['', ENV['TURBOT_API_KEY']]
47
+ end
48
+
49
+ it "returns a blank username" do
50
+ @cli.user.should be_empty
51
+ end
52
+
53
+ it "returns the api key as the password" do
54
+ @cli.password.should == ENV['TURBOT_API_KEY']
55
+ end
56
+
57
+ it "does not overwrite credentials file with environment variable credentials" do
58
+ @cli.should_not_receive(:write_credentials)
59
+ @cli.read_credentials
60
+ end
61
+
62
+ context "reauthenticating" do
63
+ before do
64
+ @cli.stub!(:ask_for_credentials).and_return(['new_user', 'new_password'])
65
+ @cli.stub!(:check)
66
+ @cli.should_receive(:check_for_associated_ssh_key)
67
+ @cli.reauthorize
68
+ end
69
+ it "updates saved credentials" do
70
+ Netrc.read(@cli.netrc_path)["api.#{@cli.host}"].should == ['new_user', 'new_password']
71
+ end
72
+ it "returns environment variable credentials" do
73
+ @cli.read_credentials.should == ['', ENV['TURBOT_API_KEY']]
74
+ end
75
+ end
76
+
77
+ end
78
+
79
+ describe "#base_host" do
80
+ it "returns the host without the first part" do
81
+ @cli.base_host("http://foo.bar.com").should == "bar.com"
82
+ end
83
+
84
+ it "works with localhost" do
85
+ @cli.base_host("http://localhost:3000").should == "localhost"
86
+ end
87
+ end
88
+
89
+ it "asks for credentials when the file doesn't exist" do
90
+ @cli.delete_credentials
91
+ @cli.should_receive(:ask_for_credentials).and_return(["u", "p"])
92
+ @cli.should_receive(:check_for_associated_ssh_key)
93
+ @cli.user.should == 'u'
94
+ @cli.password.should == 'p'
95
+ end
96
+
97
+ it "writes credentials and uploads authkey when credentials are saved" do
98
+ @cli.stub!(:credentials)
99
+ @cli.stub!(:check)
100
+ @cli.stub!(:ask_for_credentials).and_return("username", "apikey")
101
+ @cli.should_receive(:write_credentials)
102
+ @cli.should_receive(:check_for_associated_ssh_key)
103
+ @cli.ask_for_and_save_credentials
104
+ end
105
+
106
+ it "save_credentials deletes the credentials when the upload authkey is unauthorized" do
107
+ @cli.stub!(:write_credentials)
108
+ @cli.stub!(:retry_login?).and_return(false)
109
+ @cli.stub!(:ask_for_credentials).and_return("username", "apikey")
110
+ @cli.stub!(:check) { raise Turbot::API::Errors::Unauthorized.new("Login Failed", Excon::Response.new) }
111
+ @cli.should_receive(:delete_credentials)
112
+ lambda { @cli.ask_for_and_save_credentials }.should raise_error(SystemExit)
113
+ end
114
+
115
+ it "asks for login again when not authorized, for three times" do
116
+ @cli.stub!(:read_credentials)
117
+ @cli.stub!(:write_credentials)
118
+ @cli.stub!(:delete_credentials)
119
+ @cli.stub!(:ask_for_credentials).and_return("username", "apikey")
120
+ @cli.stub!(:check) { raise Turbot::API::Errors::Unauthorized.new("Login Failed", Excon::Response.new) }
121
+ @cli.should_receive(:ask_for_credentials).exactly(3).times
122
+ lambda { @cli.ask_for_and_save_credentials }.should raise_error(SystemExit)
123
+ end
124
+
125
+ it "writes the login information to the credentials file for the 'turbot login' command" do
126
+ @cli.stub!(:ask_for_credentials).and_return(['one', 'two'])
127
+ @cli.stub!(:check)
128
+ @cli.should_receive(:check_for_associated_ssh_key)
129
+ @cli.reauthorize
130
+ Netrc.read(@cli.netrc_path)["api.#{@cli.host}"].should == (['one', 'two'])
131
+ end
132
+
133
+ it "migrates long api keys to short api keys" do
134
+ @cli.delete_credentials
135
+ api_key = "7e262de8cac430d8a250793ce8d5b334ae56b4ff15767385121145198a2b4d2e195905ef8bf7cfc5"
136
+ @cli.netrc["api.#{@cli.host}"] = ["user", api_key]
137
+
138
+ @cli.get_credentials.should == ["user", api_key[0,40]]
139
+ %w{api code}.each do |section|
140
+ Netrc.read(@cli.netrc_path)["#{section}.#{@cli.host}"].should == ["user", api_key[0,40]]
141
+ end
142
+ end
143
+
144
+ describe "automatic key uploading" do
145
+ before(:each) do
146
+ FileUtils.mkdir_p("#{@cli.home_directory}/.ssh")
147
+ @cli.stub!(:ask_for_credentials).and_return("username", "apikey")
148
+ end
149
+
150
+ describe "an account with existing keys" do
151
+ before :each do
152
+ @api = mock(Object)
153
+ @response = mock(Object)
154
+ @response.should_receive(:body).and_return(['existingkeys'])
155
+ @api.should_receive(:get_ssh_keys).and_return(@response)
156
+ @cli.should_receive(:api).and_return(@api)
157
+ end
158
+
159
+ it "should not do anything if the account already has keys" do
160
+ @cli.should_not_receive(:associate_key)
161
+ @cli.check_for_associated_ssh_key
162
+ end
163
+ end
164
+
165
+ describe "an account with no keys" do
166
+ before :each do
167
+ @api = mock(Object)
168
+ @response = mock(Object)
169
+ @response.should_receive(:body).and_return([])
170
+ @api.should_receive(:get_ssh_keys).and_return(@response)
171
+ @cli.should_receive(:api).and_return(@api)
172
+ end
173
+
174
+ describe "with zero public keys" do
175
+ it "should ask to generate a key" do
176
+ @cli.should_receive(:ask).and_return("y")
177
+ @cli.should_receive(:generate_ssh_key).with("id_rsa")
178
+ @cli.should_receive(:associate_key).with("#{@cli.home_directory}/.ssh/id_rsa.pub")
179
+ @cli.check_for_associated_ssh_key
180
+ end
181
+ end
182
+
183
+ describe "with one public key" do
184
+ before(:each) { FileUtils.touch("#{@cli.home_directory}/.ssh/id_rsa.pub") }
185
+ after(:each) { FileUtils.rm("#{@cli.home_directory}/.ssh/id_rsa.pub") }
186
+
187
+ it "should upload the key" do
188
+ @cli.should_receive(:associate_key).with("#{@cli.home_directory}/.ssh/id_rsa.pub")
189
+ @cli.check_for_associated_ssh_key
190
+ end
191
+ end
192
+
193
+ describe "with many public keys" do
194
+ before(:each) do
195
+ FileUtils.touch("#{@cli.home_directory}/.ssh/id_rsa.pub")
196
+ FileUtils.touch("#{@cli.home_directory}/.ssh/id_rsa2.pub")
197
+ end
198
+
199
+ after(:each) do
200
+ FileUtils.rm("#{@cli.home_directory}/.ssh/id_rsa.pub")
201
+ FileUtils.rm("#{@cli.home_directory}/.ssh/id_rsa2.pub")
202
+ end
203
+
204
+ it "should ask which key to upload" do
205
+ File.open("#{@cli.home_directory}/.ssh/id_rsa.pub", "w") { |f| f.puts }
206
+ @cli.should_receive(:associate_key).with("#{@cli.home_directory}/.ssh/id_rsa2.pub")
207
+ @cli.should_receive(:ask).and_return("2")
208
+ @cli.check_for_associated_ssh_key
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+ require "turbot/client/pgbackups"
3
+ require "turbot/helpers"
4
+
5
+ describe Turbot::Client::Pgbackups do
6
+
7
+ include Turbot::Helpers
8
+
9
+ let(:path) { "http://id:password@pgbackups.turbot.com" }
10
+ let(:client) { Turbot::Client::Pgbackups.new path+'/api' }
11
+ let(:transfer_path) { path + '/client/transfers' }
12
+
13
+ describe "api" do
14
+ let(:version) { Turbot::Client.version }
15
+
16
+ it 'still has a turbot gem version' do
17
+ version.should be
18
+ version.split(/\./).first.to_i.should >= 0
19
+ end
20
+
21
+ it 'includes the turbot gem version' do
22
+ stub_request(:get, transfer_path)
23
+ client.get_transfers
24
+ a_request(:get, transfer_path).with(
25
+ :headers => {'X-Turbot-Gem-Version' => version}
26
+ ).should have_been_made.once
27
+ end
28
+ end
29
+
30
+ describe "create transfers" do
31
+ it "sends a request to the client" do
32
+ stub_request(:post, transfer_path).to_return(
33
+ :body => json_encode({"message" => "success"}),
34
+ :status => 200
35
+ )
36
+
37
+ client.create_transfer("postgres://from", "postgres://to", "FROMNAME", "TO_NAME")
38
+
39
+ a_request(:post, transfer_path).should have_been_made.once
40
+ end
41
+ end
42
+
43
+ end