tugboat 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. data/.gitignore +0 -1
  2. data/CHANGELOG.md +30 -0
  3. data/README.md +6 -4
  4. data/Rakefile +6 -0
  5. data/lib/tugboat/cli.rb +30 -7
  6. data/lib/tugboat/config.rb +16 -8
  7. data/lib/tugboat/middleware.rb +22 -10
  8. data/lib/tugboat/middleware/ask_for_credentials.rb +2 -1
  9. data/lib/tugboat/middleware/check_credentials.rb +1 -1
  10. data/lib/tugboat/middleware/confirm_action.rb +9 -5
  11. data/lib/tugboat/middleware/create_droplet.rb +2 -1
  12. data/lib/tugboat/middleware/find_droplet.rb +2 -2
  13. data/lib/tugboat/middleware/inject_configuration.rb +0 -1
  14. data/lib/tugboat/middleware/list_ssh_keys.rb +18 -0
  15. data/lib/tugboat/middleware/snapshot_droplet.rb +4 -1
  16. data/lib/tugboat/middleware/ssh_droplet.rb +8 -0
  17. data/lib/tugboat/version.rb +1 -1
  18. data/spec/cli/authorize_cli_spec.rb +37 -0
  19. data/spec/cli/create_cli_spec.rb +40 -0
  20. data/spec/cli/destroy_cli_spec.rb +93 -0
  21. data/spec/cli/droplets_cli_spec.rb +28 -0
  22. data/spec/cli/halt_cli_spec.rb +70 -0
  23. data/spec/cli/images_cli_spec.rb +53 -0
  24. data/spec/cli/info_cli_spec.rb +93 -0
  25. data/spec/cli/keys_cli_spec.rb +27 -0
  26. data/spec/cli/restart_cli_spec.rb +70 -0
  27. data/spec/cli/snapshot_cli_spec.rb +75 -0
  28. data/spec/cli/version_cli_spec.rb +20 -0
  29. data/spec/config_spec.rb +8 -15
  30. data/spec/fixtures/create_droplet.json +0 -0
  31. data/spec/fixtures/show_droplet.json +13 -0
  32. data/spec/fixtures/show_droplets.json +35 -0
  33. data/spec/fixtures/show_images.json +15 -0
  34. data/spec/fixtures/show_images_global.json +20 -0
  35. data/spec/fixtures/show_keys.json +13 -0
  36. data/spec/middleware/base_spec.rb +15 -0
  37. data/spec/middleware/inject_configuration_spec.rb +19 -0
  38. data/spec/shared/environment.rb +43 -0
  39. data/spec/spec_helper.rb +7 -0
  40. data/tmp/.gitkeep +0 -0
  41. data/tugboat.gemspec +7 -0
  42. metadata +141 -2
@@ -11,6 +11,14 @@ module Tugboat
11
11
  "-o", "UserKnownHostsFile=/dev/null",
12
12
  "-i", env["config"].ssh_key_path.to_s]
13
13
 
14
+ if env["user_droplet_ssh_port"]
15
+ options.push("-p", env["user_droplet_ssh_port"].to_s)
16
+ elsif env["config"].ssh_port
17
+ options.push("-p", env["config"].ssh_port.to_s)
18
+ else
19
+ options.push("-p", "22")
20
+ end
21
+
14
22
  host_string = "#{env["config"].ssh_user}@#{env["droplet_ip"]}"
15
23
 
16
24
  options << host_string
@@ -1,3 +1,3 @@
1
1
  module Tugboat
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ before :each do
7
+ @cli = Tugboat::CLI.new
8
+ end
9
+
10
+ describe "authorize" do
11
+ before do
12
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
13
+ to_return(:status => 200)
14
+ end
15
+
16
+ it "asks the right questions and checks credentials" do
17
+
18
+ $stdout.should_receive(:print).exactly(6).times
19
+ $stdout.should_receive(:print).with("Enter your client key: ")
20
+ $stdin.should_receive(:gets).and_return(client_key)
21
+ $stdout.should_receive(:print).with("Enter your API key: ")
22
+ $stdin.should_receive(:gets).and_return(api_key)
23
+ $stdout.should_receive(:print).with("Enter your SSH key path (optional, defaults to ~/.ssh/id_rsa): ")
24
+ $stdin.should_receive(:gets).and_return(ssh_key_path)
25
+ $stdout.should_receive(:print).with("Enter your SSH user (optional, defaults to #{ENV['USER']}): ")
26
+ $stdin.should_receive(:gets).and_return(ssh_user)
27
+ $stdout.should_receive(:print).with("Enter your SSH port number (optional, defaults to 22): ")
28
+ $stdin.should_receive(:gets).and_return(ssh_port)
29
+
30
+ @cli.authorize
31
+
32
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
33
+ end
34
+ end
35
+
36
+ end
37
+
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ before :each do
7
+ @cli = Tugboat::CLI.new
8
+ end
9
+
10
+ describe "create a droplet" do
11
+ it "with a name" do
12
+ stub_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id&name=#{droplet_name}&region_id&size_id&ssh_key_ids").
13
+ to_return(:status => 200, :body => '{"status":"OK"}')
14
+
15
+ @cli.create(droplet_name)
16
+
17
+ expect($stdout.string).to eq <<-eos
18
+ Queueing creation of droplet '#{droplet_name}'...done
19
+ eos
20
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id&name=#{droplet_name}&region_id&size_id&ssh_key_ids")).to have_been_made
21
+ end
22
+
23
+ it "with args" do
24
+ stub_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id=2672&name=#{droplet_name}&region_id=2&size_id=64&ssh_key_ids=1234").
25
+ to_return(:status => 200, :body => '{"status":"OK"}')
26
+
27
+ @cli.options = @cli.options.merge(:image => 2672, :size => 64, :region => 2, :keys => "1234")
28
+ @cli.create(droplet_name)
29
+
30
+ expect($stdout.string).to eq <<-eos
31
+ Queueing creation of droplet '#{droplet_name}'...done
32
+ eos
33
+
34
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/new?api_key=#{api_key}&client_id=#{client_key}&image_id=2672&name=foo&region_id=2&size_id=64&ssh_key_ids=1234")).to have_been_made
35
+ end
36
+ end
37
+
38
+
39
+ end
40
+
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ before :each do
7
+ @cli = Tugboat::CLI.new
8
+ end
9
+
10
+ describe "destroy" do
11
+ it "destroys a droplet with a fuzzy name" do
12
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
13
+ to_return(:status => 200, :body => fixture("show_droplets"))
14
+
15
+ stub_request(:delete, "https://api.digitalocean.com/droplets/100823/destroy?api_key=#{api_key}&client_id=#{client_key}").
16
+ to_return(:status => 200, :body => fixture("show_droplet"))
17
+
18
+ $stdin.should_receive(:gets).and_return("y")
19
+
20
+ @cli.destroy("foo")
21
+
22
+ expect($stdout.string).to eq <<-eos
23
+ Droplet fuzzy name provided. Finding droplet ID...done\e[0m, 100823 (foo)\nWarning! Potentially destructive action. Please confirm [y/n]: Queuing destroy for 100823 (foo)...done
24
+ eos
25
+
26
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
27
+ expect(a_request(:delete, "https://api.digitalocean.com/droplets/100823/destroy?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
28
+ end
29
+
30
+ it "destroys a droplet with an id" do
31
+ stub_request(:get, "https://api.digitalocean.com/droplets/#{droplet_id}?api_key=#{api_key}&client_id=#{client_key}").
32
+ to_return(:status => 200, :body => fixture("show_droplet"))
33
+
34
+ stub_request(:delete, "https://api.digitalocean.com/droplets/100823/destroy?api_key=#{api_key}&client_id=#{client_key}").
35
+ to_return(:status => 200, :body => fixture("show_droplet"))
36
+
37
+ $stdin.should_receive(:gets).and_return("y")
38
+
39
+ @cli.options = @cli.options.merge(:id => droplet_id)
40
+ @cli.destroy
41
+
42
+ expect($stdout.string).to eq <<-eos
43
+ Droplet id provided. Finding Droplet...done\e[0m, 100823 (foo)\nWarning! Potentially destructive action. Please confirm [y/n]: Queuing destroy for 100823 (foo)...done
44
+ eos
45
+
46
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/#{droplet_id}?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
47
+ expect(a_request(:delete, "https://api.digitalocean.com/droplets/100823/destroy?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
48
+ end
49
+
50
+
51
+ it "destroys a droplet with a name" do
52
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
53
+ to_return(:status => 200, :body => fixture("show_droplets"))
54
+
55
+ stub_request(:delete, "https://api.digitalocean.com/droplets/100823/destroy?api_key=#{api_key}&client_id=#{client_key}").
56
+ to_return(:status => 200, :body => fixture("show_droplet"))
57
+
58
+ $stdin.should_receive(:gets).and_return("y")
59
+
60
+ @cli.options = @cli.options.merge(:name => droplet_name)
61
+ @cli.destroy
62
+
63
+ expect($stdout.string).to eq <<-eos
64
+ Droplet name provided. Finding droplet ID...done\e[0m, 100823 (foo)\nWarning! Potentially destructive action. Please confirm [y/n]: Queuing destroy for 100823 (foo)...done
65
+ eos
66
+
67
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
68
+ expect(a_request(:delete, "https://api.digitalocean.com/droplets/100823/destroy?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
69
+ end
70
+
71
+
72
+ it "destroys a droplet with confirm flag set" do
73
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
74
+ to_return(:status => 200, :body => fixture("show_droplets"))
75
+
76
+ stub_request(:delete, "https://api.digitalocean.com/droplets/100823/destroy?api_key=#{api_key}&client_id=#{client_key}").
77
+ to_return(:status => 200, :body => fixture("show_droplet"))
78
+
79
+ @cli.options = @cli.options.merge(:name => droplet_name)
80
+ @cli.options = @cli.options.merge(:confirm => true)
81
+ @cli.destroy
82
+
83
+ expect($stdout.string).to eq <<-eos
84
+ Droplet name provided. Finding droplet ID...done\e[0m, 100823 (foo)
85
+ Queuing destroy for 100823 (foo)...done
86
+ eos
87
+
88
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
89
+ expect(a_request(:delete, "https://api.digitalocean.com/droplets/100823/destroy?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
90
+ end
91
+ end
92
+
93
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ before :each do
7
+ @cli = Tugboat::CLI.new
8
+ end
9
+
10
+ describe "droplets" do
11
+ it "shows a list" do
12
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
13
+ to_return(:status => 200, :body => fixture("show_droplets"))
14
+
15
+ @cli.droplets
16
+
17
+ expect($stdout.string).to eq <<-eos
18
+ test222 (ip: 33.33.33.10, status: \e[32mactive\e[0m, region: 1, id: 100823)
19
+ test223 (ip: 33.33.33.10, status: \e[32mactive\e[0m, region: 1, id: 100823)
20
+ foo (ip: 33.33.33.10, status: \e[31moff\e[0m, region: 1, id: 100823)
21
+ eos
22
+
23
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
24
+ end
25
+ end
26
+
27
+ end
28
+
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ before :each do
7
+ @cli = Tugboat::CLI.new
8
+ end
9
+
10
+ describe "halt" do
11
+ it "halts a droplet with a fuzzy name" do
12
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
13
+ to_return(:status => 200, :body => fixture("show_droplets"))
14
+
15
+ stub_request(:put, "https://api.digitalocean.com/droplets/100823/shutdown?api_key=#{api_key}&client_id=#{client_key}").
16
+ to_return(:status => 200, :body => fixture("show_droplet"))
17
+
18
+ @cli.halt("foo")
19
+
20
+ expect($stdout.string).to eq <<-eos
21
+ Droplet fuzzy name provided. Finding droplet ID...done\e[0m, 100823 (foo)
22
+ Queuing shutdown for 100823 (foo)...done
23
+ eos
24
+
25
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
26
+ expect(a_request(:put, "https://api.digitalocean.com/droplets/100823/shutdown?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
27
+ end
28
+
29
+ it "halts a droplet with an id" do
30
+ stub_request(:get, "https://api.digitalocean.com/droplets/#{droplet_id}?api_key=#{api_key}&client_id=#{client_key}").
31
+ to_return(:status => 200, :body => fixture("show_droplet"))
32
+
33
+ stub_request(:put, "https://api.digitalocean.com/droplets/100823/shutdown?api_key=#{api_key}&client_id=#{client_key}").
34
+ to_return(:status => 200, :body => fixture("show_droplet"))
35
+
36
+ @cli.options = @cli.options.merge(:id => droplet_id)
37
+ @cli.halt
38
+
39
+ expect($stdout.string).to eq <<-eos
40
+ Droplet id provided. Finding Droplet...done\e[0m, 100823 (foo)
41
+ Queuing shutdown for 100823 (foo)...done
42
+ eos
43
+
44
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/#{droplet_id}?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
45
+ expect(a_request(:put, "https://api.digitalocean.com/droplets/100823/shutdown?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
46
+ end
47
+
48
+
49
+ it "halts a droplet with a name" do
50
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
51
+ to_return(:status => 200, :body => fixture("show_droplets"))
52
+
53
+ stub_request(:put, "https://api.digitalocean.com/droplets/100823/shutdown?api_key=#{api_key}&client_id=#{client_key}").
54
+ to_return(:status => 200, :body => fixture("show_droplet"))
55
+
56
+ @cli.options = @cli.options.merge(:name => droplet_name)
57
+ @cli.halt
58
+
59
+ expect($stdout.string).to eq <<-eos
60
+ Droplet name provided. Finding droplet ID...done\e[0m, 100823 (foo)
61
+ Queuing shutdown for 100823 (foo)...done
62
+ eos
63
+
64
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
65
+ expect(a_request(:put, "https://api.digitalocean.com/droplets/100823/shutdown?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ before :each do
7
+ @cli = Tugboat::CLI.new
8
+ end
9
+
10
+ describe "images" do
11
+ it "shows a list" do
12
+ stub_request(:get, "https://api.digitalocean.com/images?api_key=#{api_key}&client_id=#{client_key}&filter=my_images").
13
+ to_return(:status => 200, :body => fixture("show_images"))
14
+
15
+ @cli.images
16
+
17
+ expect($stdout.string).to eq <<-eos
18
+ My Images:
19
+ NYTD Backup 1-18-2012 (id: 466, distro: Ubuntu)
20
+ NLP Final (id: 478, distro: Ubuntu)
21
+ eos
22
+
23
+ expect(a_request(:get, "https://api.digitalocean.com/images?api_key=#{api_key}&client_id=#{client_key}&filter=my_images")).to have_been_made
24
+ end
25
+
26
+ it "shows a global list" do
27
+ stub_request(:get, "https://api.digitalocean.com/images?api_key=#{api_key}&client_id=#{client_key}&filter=my_images").
28
+ to_return(:status => 200, :body => fixture("show_images"))
29
+
30
+ stub_request(:get, "https://api.digitalocean.com/images?api_key=#{api_key}&client_id=#{client_key}&filter=global").
31
+ to_return(:status => 200, :body => fixture("show_images_global"))
32
+
33
+ @cli.options = @cli.options.merge(:global => true)
34
+ @cli.images
35
+
36
+ expect($stdout.string).to eq <<-eos
37
+ My Images:
38
+ NYTD Backup 1-18-2012 (id: 466, distro: Ubuntu)
39
+ NLP Final (id: 478, distro: Ubuntu)
40
+
41
+ Global Images:
42
+ NYTD Backup 1-18-2012 (id: 466, distro: Ubuntu)
43
+ NLP Final (id: 478, distro: Ubuntu)
44
+ Global Final (id: 479, distro: Ubuntu)
45
+ eos
46
+
47
+ expect(a_request(:get, "https://api.digitalocean.com/images?api_key=#{api_key}&client_id=#{client_key}&filter=my_images")).to have_been_made
48
+ expect(a_request(:get, "https://api.digitalocean.com/images?api_key=#{api_key}&client_id=#{client_key}&filter=global")).to have_been_made
49
+ end
50
+ end
51
+
52
+ end
53
+
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ before :each do
7
+ @cli = Tugboat::CLI.new
8
+ end
9
+
10
+ describe "show" do
11
+ it "shows a droplet with a fuzzy name" do
12
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
13
+ to_return(:status => 200, :body => fixture("show_droplets"))
14
+
15
+ stub_request(:get, "https://api.digitalocean.com/droplets/100823?api_key=#{api_key}&client_id=#{client_key}").
16
+ to_return(:status => 200, :body => fixture("show_droplet"))
17
+
18
+ @cli.info("foo")
19
+
20
+ expect($stdout.string).to eq <<-eos
21
+ Droplet fuzzy name provided. Finding droplet ID...done\e[0m, 100823 (foo)
22
+
23
+ Name: foo
24
+ ID: 100823
25
+ Status: \e[32mactive\e[0m
26
+ IP: 33.33.33.10
27
+ Region ID: 1
28
+ Image ID: 420
29
+ Size ID: 33
30
+ Backups Active: false
31
+ eos
32
+
33
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
34
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/100823?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
35
+ end
36
+
37
+ it "shows a droplet with an id" do
38
+ stub_request(:get, "https://api.digitalocean.com/droplets/#{droplet_id}?api_key=#{api_key}&client_id=#{client_key}").
39
+ to_return(:status => 200, :body => fixture("show_droplet"))
40
+
41
+ stub_request(:get, "https://api.digitalocean.com/droplets/100823?api_key=#{api_key}&client_id=#{client_key}").
42
+ to_return(:status => 200, :body => fixture("show_droplet"))
43
+
44
+ @cli.options = @cli.options.merge(:id => droplet_id)
45
+ @cli.info
46
+
47
+ expect($stdout.string).to eq <<-eos
48
+ Droplet id provided. Finding Droplet...done\e[0m, 100823 (foo)
49
+
50
+ Name: foo
51
+ ID: 100823
52
+ Status: \e[32mactive\e[0m
53
+ IP: 33.33.33.10
54
+ Region ID: 1
55
+ Image ID: 420
56
+ Size ID: 33
57
+ Backups Active: false
58
+ eos
59
+
60
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/100823?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
61
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/#{droplet_id}?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
62
+ end
63
+
64
+ it "shows a droplet with a name" do
65
+ stub_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}").
66
+ to_return(:status => 200, :body => fixture("show_droplets"))
67
+
68
+ stub_request(:get, "https://api.digitalocean.com/droplets/100823?api_key=#{api_key}&client_id=#{client_key}").
69
+ to_return(:status => 200, :body => fixture("show_droplet"))
70
+
71
+ @cli.options = @cli.options.merge(:name => droplet_name)
72
+ @cli.info
73
+
74
+ expect($stdout.string).to eq <<-eos
75
+ Droplet name provided. Finding droplet ID...done\e[0m, 100823 (foo)
76
+
77
+ Name: foo
78
+ ID: 100823
79
+ Status: \e[32mactive\e[0m
80
+ IP: 33.33.33.10
81
+ Region ID: 1
82
+ Image ID: 420
83
+ Size ID: 33
84
+ Backups Active: false
85
+ eos
86
+
87
+ expect(a_request(:get, "https://api.digitalocean.com/droplets/100823?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
88
+ expect(a_request(:get, "https://api.digitalocean.com/droplets?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
89
+ end
90
+
91
+ end
92
+
93
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tugboat::CLI do
4
+ include_context "spec"
5
+
6
+ before :each do
7
+ @cli = Tugboat::CLI.new
8
+ end
9
+
10
+ describe "keys" do
11
+ it "shows a list" do
12
+ stub_request(:get, "https://api.digitalocean.com/ssh_keys?api_key=#{api_key}&client_id=#{client_key}").
13
+ to_return(:status => 200, :body => fixture("show_keys"))
14
+
15
+ @cli.keys
16
+
17
+ expect($stdout.string).to eq <<-eos
18
+ SSH Keys:
19
+ office-imac (id: 10)
20
+ macbook-air (id: 11)
21
+ eos
22
+
23
+ expect(a_request(:get, "https://api.digitalocean.com/ssh_keys?api_key=#{api_key}&client_id=#{client_key}")).to have_been_made
24
+ end
25
+ end
26
+ end
27
+