tugboat 3.1.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -1
  3. data/CODE_OF_CONDUCT.md +46 -0
  4. data/lib/tugboat/cli.rb +7 -1
  5. data/lib/tugboat/config.rb +11 -1
  6. data/lib/tugboat/middleware.rb +2 -0
  7. data/lib/tugboat/middleware/ask_for_credentials.rb +2 -1
  8. data/lib/tugboat/middleware/base.rb +31 -13
  9. data/lib/tugboat/middleware/check_snapshot_parameters.rb +16 -0
  10. data/lib/tugboat/middleware/info_droplet.rb +2 -2
  11. data/lib/tugboat/middleware/inject_client.rb +10 -1
  12. data/lib/tugboat/middleware/list_droplets.rb +5 -3
  13. data/lib/tugboat/version.rb +1 -1
  14. data/spec/cli/add_key_spec.rb +7 -9
  15. data/spec/cli/authorize_cli_spec.rb +4 -34
  16. data/spec/cli/config_cli_spec.rb +10 -5
  17. data/spec/cli/create_cli_spec.rb +20 -17
  18. data/spec/cli/debug_cli_spec.rb +11 -12
  19. data/spec/cli/destroy_cli_spec.rb +35 -12
  20. data/spec/cli/destroy_image_cli_spec.rb +12 -10
  21. data/spec/cli/droplets_cli_spec.rb +74 -48
  22. data/spec/cli/env_variable_spec.rb +4 -4
  23. data/spec/cli/halt_cli_spec.rb +16 -13
  24. data/spec/cli/help_cli_spec.rb +4 -4
  25. data/spec/cli/images_cli_spec.rb +9 -7
  26. data/spec/cli/info_cli_spec.rb +120 -50
  27. data/spec/cli/info_image_cli_spec.rb +24 -23
  28. data/spec/cli/keys_cli_spec.rb +3 -3
  29. data/spec/cli/password_reset_cli_spec.rb +12 -12
  30. data/spec/cli/rebuild_cli_spec.rb +31 -24
  31. data/spec/cli/regions_cli_spec.rb +3 -3
  32. data/spec/cli/resize_cli_spec.rb +16 -16
  33. data/spec/cli/restart_cli_spec.rb +32 -11
  34. data/spec/cli/sizes_cli_spec.rb +3 -3
  35. data/spec/cli/snapshot_cli_spec.rb +25 -9
  36. data/spec/cli/ssh_cli_spec.rb +10 -10
  37. data/spec/cli/start_cli_spec.rb +15 -15
  38. data/spec/cli/verify_cli_spec.rb +4 -7
  39. data/spec/cli/version_cli_spec.rb +1 -2
  40. data/spec/cli/wait_cli_spec.rb +16 -16
  41. data/spec/config_spec.rb +7 -1
  42. data/spec/fixtures/show_droplets.json +7 -4
  43. data/spec/fixtures/show_droplets_paginated_first.json +10 -7
  44. data/spec/fixtures/show_droplets_paginated_last.json +11 -5
  45. data/spec/fixtures/show_droplets_private_ip.json +7 -4
  46. data/spec/middleware/base_spec.rb +1 -2
  47. data/spec/middleware/check_configuration_spec.rb +1 -1
  48. data/spec/middleware/check_credentials_spec.rb +1 -1
  49. data/spec/middleware/check_droplet_active_spec.rb +1 -1
  50. data/spec/middleware/check_droplet_inactive_spec.rb +1 -1
  51. data/spec/middleware/find_droplet_spec.rb +3 -5
  52. data/spec/middleware/find_image_spec.rb +3 -5
  53. data/spec/middleware/ssh_droplet_spec.rb +5 -10
  54. data/spec/shared/environment.rb +2 -18
  55. data/tugboat.gemspec +1 -2
  56. metadata +8 -6
@@ -5,14 +5,14 @@ describe Tugboat::CLI do
5
5
 
6
6
  describe 'config' do
7
7
  it 'shows the full config' do
8
- cli.config
9
-
10
- expect($stdout.string).to eq <<-eos
8
+ expected_string = <<-eos
11
9
  Current Config\x20
12
10
  Path: #{Dir.pwd}/tmp/tugboat
13
11
  ---
14
12
  authentication:
15
13
  access_token: foo
14
+ connection:
15
+ timeout: '15'
16
16
  ssh:
17
17
  ssh_user: baz
18
18
  ssh_key_path: ~/.ssh/id_rsa2
@@ -26,18 +26,21 @@ defaults:
26
26
  backups_enabled: 'false'
27
27
  ip6: 'false'
28
28
  eos
29
+
30
+ expect { cli.config }.to output(expected_string).to_stdout
29
31
  end
30
32
 
31
33
  it 'hides sensitive data if option given' do
32
34
  cli.options = cli.options.merge(hide: true)
33
- cli.config
34
35
 
35
- expect($stdout.string).to eq <<-eos
36
+ expected_string = <<-eos
36
37
  Current Config (Keys Redacted)
37
38
  Path: #{Dir.pwd}/tmp/tugboat
38
39
  ---
39
40
  authentication:
40
41
  access_token:\x20\x20[REDACTED]
42
+ connection:
43
+ timeout: '15'
41
44
  ssh:
42
45
  ssh_user: baz
43
46
  ssh_key_path: ~/.ssh/id_rsa2
@@ -51,6 +54,8 @@ defaults:
51
54
  backups_enabled: 'false'
52
55
  ip6: 'false'
53
56
  eos
57
+
58
+ expect { cli.config }.to output(expected_string).to_stdout
54
59
  end
55
60
  end
56
61
  end
@@ -10,11 +10,11 @@ describe Tugboat::CLI do
10
10
  headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
11
11
  to_return(status: 200, body: fixture('create_droplet'), headers: {})
12
12
 
13
- cli.create(droplet_name)
14
-
15
- expect($stdout.string).to eq <<-eos
13
+ expected_string = <<-eos
16
14
  Queueing creation of droplet '#{droplet_name}'...Droplet created! Droplet ID is 3164494
17
15
  eos
16
+
17
+ expect { cli.create(droplet_name) }.to output(expected_string).to_stdout
18
18
  end
19
19
 
20
20
  it 'with args does not use defaults from configuration' do
@@ -24,11 +24,12 @@ Queueing creation of droplet '#{droplet_name}'...Droplet created! Droplet ID is
24
24
  to_return(status: 200, body: fixture('create_droplet'), headers: {})
25
25
 
26
26
  cli.options = cli.options.merge(image: 'ubuntu-12-04-x64', size: '1gb', region: 'nyc3', keys: 'foo_bar_key')
27
- cli.create('example.com')
28
27
 
29
- expect($stdout.string).to eq <<-eos
28
+ expected_string = <<-eos
30
29
  Queueing creation of droplet 'example.com'...Droplet created! Droplet ID is 3164494
31
30
  eos
31
+
32
+ expect { cli.create('example.com') }.to output(expected_string).to_stdout
32
33
  end
33
34
 
34
35
  it 'with ip6 enable args' do
@@ -38,11 +39,12 @@ Queueing creation of droplet 'example.com'...Droplet created! Droplet ID is 3164
38
39
  to_return(status: 200, body: fixture('create_droplet'), headers: {})
39
40
 
40
41
  cli.options = cli.options.merge(ip6: 'true')
41
- cli.create('example.com')
42
42
 
43
- expect($stdout.string).to eq <<-eos
43
+ expected_string = <<-eos
44
44
  Queueing creation of droplet 'example.com'...Droplet created! Droplet ID is 3164494
45
45
  eos
46
+
47
+ expect { cli.create('example.com') }.to output(expected_string).to_stdout
46
48
  end
47
49
 
48
50
  it 'with user data args' do
@@ -52,26 +54,28 @@ Queueing creation of droplet 'example.com'...Droplet created! Droplet ID is 3164
52
54
  to_return(status: 200, body: fixture('create_droplet'), headers: {})
53
55
 
54
56
  cli.options = cli.options.merge(user_data: project_path + '/spec/fixtures/user_data.sh')
55
- cli.create('example.com')
56
57
 
57
- expect($stdout.string).to eq <<-eos
58
+ expected_string = <<-eos
58
59
  Queueing creation of droplet 'example.com'...Droplet created! Droplet ID is 3164494
59
60
  eos
61
+
62
+ expect { cli.create('example.com') }.to output(expected_string).to_stdout
60
63
  end
61
64
 
62
65
  it 'fails when user data file does not exist' do
63
66
  cli.options = cli.options.merge(user_data: '/foo/bar/baz.sh')
64
- expect { cli.create('example.com') }.to raise_error(SystemExit)
65
67
 
66
- expect($stdout.string).to eq <<-eos
68
+ expected_string = <<-eos
67
69
  Queueing creation of droplet 'example.com'...Could not find file: /foo/bar/baz.sh, check your user_data setting
68
70
  eos
71
+
72
+ expect { expect { cli.create('example.com') }.to raise_error(SystemExit) }.to output(expected_string).to_stdout
69
73
  end
70
74
 
71
75
  context "doesn't create a droplet when mistyping help command" do
72
76
  ['help', '--help', '-h'].each do |help_attempt|
73
77
  it "tugboat create #{help_attempt}" do
74
- help_text = <<-eos
78
+ expected_string = <<-eos
75
79
  Usage:
76
80
  rspec create NAME
77
81
 
@@ -89,8 +93,7 @@ Options:
89
93
  Create a droplet.
90
94
  eos
91
95
 
92
- cli.create(help_attempt)
93
- expect($stdout.string).to eq help_text
96
+ expect { cli.create(help_attempt) }.to output(expected_string).to_stdout
94
97
  end
95
98
  end
96
99
  end
@@ -101,11 +104,11 @@ eos
101
104
  headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
102
105
  to_return(status: 200, body: fixture('create_droplet'), headers: {})
103
106
 
104
- cli.create('somethingblahblah--help')
105
-
106
- expect($stdout.string).to eq <<-eos
107
+ expected_string = <<-eos
107
108
  Queueing creation of droplet 'somethingblahblah--help'...Droplet created! Droplet ID is 3164494
108
109
  eos
110
+
111
+ expect { cli.create('somethingblahblah--help') }.to output(expected_string).to_stdout
109
112
  end
110
113
  end
111
114
  end
@@ -17,16 +17,15 @@ describe Tugboat::CLI do
17
17
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
18
18
  to_return(status: 200, body: fixture('show_droplets'), headers: {})
19
19
 
20
- stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
20
+ stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20').
21
21
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
22
22
  to_return(status: 200, body: fixture('show_droplets'), headers: {})
23
23
 
24
- cli.droplets
24
+ debug_droplets_expectation = expect { cli.droplets }
25
25
 
26
- expect($stdout.string).to include 'Started GET request to: https://api.digitalocean.com/v2/droplets?page=1&per_page=200'
27
- expect($stdout.string).to include 'DEBUG -- : Request Headers:'
28
-
29
- expect($stdout.string).to include 'Bearer foo'
26
+ debug_droplets_expectation.to output(%r{DEBUG -- : Request Headers:}).to_stdout
27
+ debug_droplets_expectation.to output(%r{Bearer foo}).to_stdout
28
+ debug_droplets_expectation.to output(%r{Started GET request to}).to_stdout
30
29
  end
31
30
  end
32
31
 
@@ -44,15 +43,15 @@ describe Tugboat::CLI do
44
43
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
45
44
  to_return(status: 200, body: fixture('show_droplets'), headers: {})
46
45
 
47
- stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
46
+ stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20').
48
47
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
49
48
  to_return(status: 200, body: fixture('show_droplets'), headers: {})
50
- cli.droplets
51
-
52
- expect($stdout.string).to include 'Started GET request to: https://api.digitalocean.com/v2/droplets?page=1&per_page=200'
53
- expect($stdout.string).to include 'DEBUG -- : Request Headers:'
54
49
 
55
- expect($stdout.string).not_to include 'Bearer foo'
50
+ debug_droplets_expectation = expect { cli.droplets }
51
+ debug_droplets_expectation.to output(%r{Started GET request to}).to_stdout
52
+ debug_droplets_expectation.to output(%r{DEBUG -- : Request Headers:}).to_stdout
53
+ debug_droplets_expectation.to output(%r{Bearer \[TOKEN REDACTED\]}).to_stdout
54
+ debug_droplets_expectation.not_to output(%r{Bearer foo}).to_stdout
56
55
  end
57
56
  end
58
57
  end
@@ -19,11 +19,11 @@ describe Tugboat::CLI do
19
19
 
20
20
  expect($stdin).to receive(:gets).and_return('y')
21
21
 
22
- cli.destroy('example.com')
23
-
24
- expect($stdout.string).to eq <<-eos
22
+ expected_string = <<-eos
25
23
  Droplet fuzzy name provided. Finding droplet ID...done\e[0m, 6918990 (example.com)\nWarning! Potentially destructive action. Please confirm [y/n]: Queuing destroy for 6918990 (example.com)...Deletion Successful!
26
24
  eos
25
+
26
+ expect { cli.destroy('example.com') }.to output(expected_string).to_stdout
27
27
  end
28
28
 
29
29
  it 'destroys a droplet with an id' do
@@ -38,11 +38,12 @@ eos
38
38
  expect($stdin).to receive(:gets).and_return('y')
39
39
 
40
40
  cli.options = cli.options.merge(id: '6918990')
41
- cli.destroy
42
41
 
43
- expect($stdout.string).to eq <<-eos
42
+ expected_string = <<-eos
44
43
  Droplet id provided. Finding Droplet...done\e[0m, 6918990 (example.com)\nWarning! Potentially destructive action. Please confirm [y/n]: Queuing destroy for 6918990 (example.com)...Deletion Successful!
45
44
  eos
45
+
46
+ expect { cli.destroy }.to output(expected_string).to_stdout
46
47
  end
47
48
 
48
49
  it 'destroys a droplet with a name' do
@@ -61,11 +62,12 @@ Droplet id provided. Finding Droplet...done\e[0m, 6918990 (example.com)\nWarning
61
62
  expect($stdin).to receive(:gets).and_return('y')
62
63
 
63
64
  cli.options = cli.options.merge(name: 'example.com')
64
- cli.destroy
65
65
 
66
- expect($stdout.string).to eq <<-eos
66
+ expected_string = <<-eos
67
67
  Droplet name provided. Finding droplet ID...done\e[0m, 6918990 (example.com)\nWarning! Potentially destructive action. Please confirm [y/n]: Queuing destroy for 6918990 (example.com)...Deletion Successful!
68
68
  eos
69
+
70
+ expect { cli.destroy }.to output(expected_string).to_stdout
69
71
  end
70
72
 
71
73
  it 'destroys a droplet with confirm flag set' do
@@ -82,12 +84,13 @@ Droplet name provided. Finding droplet ID...done\e[0m, 6918990 (example.com)\nWa
82
84
  to_return(status: 204, body: '', headers: {})
83
85
 
84
86
  cli.options = cli.options.merge(name: 'example.com', confirm: true)
85
- cli.destroy
86
87
 
87
- expect($stdout.string).to eq <<-eos
88
+ expected_string = <<-eos
88
89
  Droplet name provided. Finding droplet ID...done\e[0m, 6918990 (example.com)
89
90
  Queuing destroy for 6918990 (example.com)...Deletion Successful!
90
91
  eos
92
+
93
+ expect { cli.destroy }.to output(expected_string).to_stdout
91
94
  end
92
95
 
93
96
  it 'does not destroy a droplet if no is chosen' do
@@ -101,11 +104,31 @@ Queuing destroy for 6918990 (example.com)...Deletion Successful!
101
104
 
102
105
  expect($stdin).to receive(:gets).and_return('n')
103
106
 
104
- expect { cli.destroy('example.com') }.to raise_error(SystemExit)
105
-
106
- expect($stdout.string).to eq <<-eos
107
+ expected_string = <<-eos
107
108
  Droplet fuzzy name provided. Finding droplet ID...done\e[0m, 6918990 (example.com)\nWarning! Potentially destructive action. Please confirm [y/n]: Aborted due to user request.
108
109
  eos
110
+
111
+ expect { cli.destroy('example.com') }.to raise_error(SystemExit).and output(expected_string).to_stdout
112
+ end
113
+
114
+ it 'raises SystemExit when a request fails' do
115
+ stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1').
116
+ with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
117
+ to_return(status: 200, body: fixture('show_droplets'), headers: {})
118
+
119
+ stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
120
+ with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
121
+ to_return(status: 200, body: fixture('show_droplets'), headers: {})
122
+
123
+ stub_request(:delete, 'https://api.digitalocean.com/v2/droplets/6918990').
124
+ with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
125
+ to_return(headers: { 'Content-Type' => 'application/json' }, status: 500, body: '{"status":"ERROR","message":"Some error"}')
126
+
127
+ expect($stdin).to receive(:gets).and_return('y')
128
+
129
+ cli.options = cli.options.merge(name: 'example.com')
130
+
131
+ expect { cli.destroy }.to raise_error(SystemExit).and output(%r{Failed to destroy Droplet: Some error}).to_stdout
109
132
  end
110
133
  end
111
134
  end
@@ -15,11 +15,11 @@ describe Tugboat::CLI do
15
15
 
16
16
  expect($stdin).to receive(:gets).and_return('y')
17
17
 
18
- cli.destroy_image('My application image')
19
-
20
- expect($stdout.string).to eq <<-eos
18
+ expected_string = <<-eos
21
19
  Image fuzzy name provided. Finding image ID...done\e[0m, 6376601 (My application image)\nWarning! Potentially destructive action. Please confirm [y/n]: Queuing destroy image for 6376601 (My application image)...Image deletion successful!
22
20
  eos
21
+
22
+ expect { cli.destroy_image('My application image') }.to output(expected_string).to_stdout
23
23
  end
24
24
 
25
25
  it 'destroys an image with an id' do
@@ -34,11 +34,12 @@ Image fuzzy name provided. Finding image ID...done\e[0m, 6376601 (My application
34
34
  expect($stdin).to receive(:gets).and_return('y')
35
35
 
36
36
  cli.options = cli.options.merge(id: 6_376_601)
37
- cli.destroy_image
38
37
 
39
- expect($stdout.string).to eq <<-eos
38
+ expected_string = <<-eos
40
39
  Image id provided. Finding Image...done\e[0m, 6376601 (My application image)\nWarning! Potentially destructive action. Please confirm [y/n]: Queuing destroy image for 6376601 (My application image)...Image deletion successful!
41
40
  eos
41
+
42
+ expect { cli.destroy_image }.to output(expected_string).to_stdout
42
43
  end
43
44
 
44
45
  it 'destroys an image with a name' do
@@ -52,10 +53,10 @@ Image id provided. Finding Image...done\e[0m, 6376601 (My application image)\nWa
52
53
 
53
54
  expect($stdin).to receive(:gets).and_return('y')
54
55
 
55
- cli.options = cli.options.merge(name: 'My application image')
56
- cli.destroy_image
56
+ expected_string = "Image name provided. Finding Image...done\e[0m, 6376601 (My application image)\nWarning! Potentially destructive action. Please confirm [y/n]: Queuing destroy image for 6376601 (My application image)...Image deletion successful!\n"
57
57
 
58
- expect($stdout.string).to eq "Image name provided. Finding Image...done\e[0m, 6376601 (My application image)\nWarning! Potentially destructive action. Please confirm [y/n]: Queuing destroy image for 6376601 (My application image)...Image deletion successful!\n"
58
+ cli.options = cli.options.merge(name: 'My application image')
59
+ expect { cli.destroy_image }.to output(expected_string).to_stdout
59
60
  end
60
61
 
61
62
  it 'destroys an image with confirm flag set' do
@@ -69,11 +70,12 @@ Image id provided. Finding Image...done\e[0m, 6376601 (My application image)\nWa
69
70
 
70
71
  cli.options = cli.options.merge(name: 'My application image')
71
72
  cli.options = cli.options.merge(confirm: true)
72
- cli.destroy_image('NLP Final')
73
73
 
74
- expect($stdout.string).to eq <<-eos
74
+ expected_string = <<-eos
75
75
  Image name provided. Finding Image...done\e[0m, 6376601 (My application image)\nQueuing destroy image for 6376601 (My application image)...Image deletion successful!
76
76
  eos
77
+
78
+ expect { cli.destroy_image('NLP Final') }.to output(expected_string).to_stdout
77
79
  end
78
80
  end
79
81
  end
@@ -9,19 +9,20 @@ describe Tugboat::CLI do
9
9
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
10
10
  to_return(status: 200, body: fixture('show_droplets'), headers: {})
11
11
 
12
- stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
12
+ stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20').
13
13
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
14
14
  to_return(status: 200, body: fixture('show_droplets'), headers: { 'Content-Type' => 'application/json' })
15
15
 
16
- cli.droplets
17
-
18
- expect($stdout.string).to eq <<-eos
19
- example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, id: 6918990)
20
- example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, id: 3164956)
21
- example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164444)
16
+ expected_string = <<-eos
17
+ example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, size: 512mb, id: 6918990)
18
+ example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, size: 512mb, id: 3164956)
19
+ example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, size: 512mb, id: 3164444)
22
20
  eos
23
21
 
24
- expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200')).to have_been_made
22
+ expect { cli.droplets }.to output(expected_string).to_stdout
23
+
24
+ expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1')).to have_been_made.twice
25
+ expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20')).to have_been_made
25
26
  end
26
27
 
27
28
  it 'shows a private IP if droplet in list has private IP' do
@@ -29,19 +30,21 @@ example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164
29
30
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
30
31
  to_return(status: 200, body: fixture('show_droplets'), headers: {})
31
32
 
32
- stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
33
+ stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20').
33
34
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
34
35
  to_return(status: 200, body: fixture('show_droplets_private_ip'), headers: { 'Content-Type' => 'application/json' })
35
36
 
36
- cli.droplets
37
37
 
38
- expect($stdout.string).to eq <<-eos
39
- exampleprivate.com (ip: 104.236.32.182, private_ip: 10.131.99.89, status: \e[32mactive\e[0m, region: nyc3, id: 6918990)
40
- example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, id: 3164956)
41
- example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164444)
38
+ expected_string = <<-eos
39
+ exampleprivate.com (ip: 104.236.32.182, private_ip: 10.131.99.89, status: \e[32mactive\e[0m, region: nyc3, size: 512mb, id: 6918990)
40
+ example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, size: 512mb, id: 3164956)
41
+ example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, size: 512mb, id: 3164444)
42
42
  eos
43
43
 
44
- expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200')).to have_been_made
44
+ expect { cli.droplets }.to output(expected_string).to_stdout
45
+
46
+ expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1')).to have_been_made.twice
47
+ expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20')).to have_been_made
45
48
  end
46
49
 
47
50
  it 'returns an error message when no droplets exist' do
@@ -49,18 +52,19 @@ example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164
49
52
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
50
53
  to_return(status: 200, body: fixture('show_droplets'), headers: {})
51
54
 
52
- stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
55
+ stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20').
53
56
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
54
57
  to_return(status: 200, body: fixture('show_droplets_empty'), headers: { 'Content-Type' => 'application/json' })
55
58
 
56
- cli.droplets
57
-
58
- expect($stdout.string).to eq <<-eos
59
+ expected_string = <<-eos
59
60
  You don't appear to have any droplets.
60
61
  Try creating one with \e[32m`tugboat create`\e[0m
61
62
  eos
62
63
 
63
- expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200')).to have_been_made
64
+ expect { cli.droplets }.to output(expected_string).to_stdout
65
+
66
+ expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1')).to have_been_made.twice
67
+ expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20')).to have_been_made
64
68
  end
65
69
 
66
70
  it 'shows no output when --quiet is set' do
@@ -68,17 +72,15 @@ Try creating one with \e[32m`tugboat create`\e[0m
68
72
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
69
73
  to_return(status: 200, body: fixture('show_droplets'), headers: {})
70
74
 
71
- stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
75
+ stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20').
72
76
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
73
77
  to_return(status: 200, body: fixture('show_droplets'), headers: { 'Content-Type' => 'application/json' })
74
78
 
75
79
  cli.options = cli.options.merge(quiet: true)
76
- cli.droplets
80
+ expect { cli.droplets }.not_to output.to_stderr
77
81
 
78
- # Should be /dev/null not stringIO
79
- expect($stdout).to be_a File
80
-
81
- expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200')).to have_been_made
82
+ expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1')).to have_been_made.twice
83
+ expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20')).to have_been_made
82
84
  end
83
85
 
84
86
  it 'includes urls when --include-urls is set' do
@@ -86,48 +88,72 @@ Try creating one with \e[32m`tugboat create`\e[0m
86
88
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
87
89
  to_return(status: 200, body: fixture('show_droplets'), headers: {})
88
90
 
89
- stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
91
+ stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20').
90
92
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
91
93
  to_return(status: 200, body: fixture('show_droplets'), headers: { 'Content-Type' => 'application/json' })
92
94
 
93
95
  cli.options = cli.options.merge('include_urls' => true)
94
- cli.droplets
95
96
 
96
- expect($stdout.string).to eq <<-eos
97
- example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, id: 6918990, url: 'https://cloud.digitalocean.com/droplets/6918990')
98
- example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, id: 3164956, url: 'https://cloud.digitalocean.com/droplets/3164956')
99
- example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164444, url: 'https://cloud.digitalocean.com/droplets/3164444')
97
+ expected_string = <<-eos
98
+ example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, size: 512mb, id: 6918990, url: 'https://cloud.digitalocean.com/droplets/6918990')
99
+ example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, size: 512mb, id: 3164956, url: 'https://cloud.digitalocean.com/droplets/3164956')
100
+ example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, size: 512mb, id: 3164444, url: 'https://cloud.digitalocean.com/droplets/3164444')
100
101
  eos
101
102
 
102
- expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200')).to have_been_made
103
+ expect { cli.droplets }.to output(expected_string).to_stdout
104
+
105
+ expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1')).to have_been_made.twice
106
+ expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=20')).to have_been_made
103
107
  end
104
108
 
105
- it 'paginates when multiple pages are returned' do
109
+ it 'allows specifying per_page' do
106
110
  stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1').
107
111
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
108
112
  to_return(status: 200, body: fixture('show_droplets'), headers: {})
109
113
 
110
- stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200').
114
+ stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=3').
111
115
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
112
- to_return(status: 200, body: fixture('show_droplets_paginated_first'), headers: { 'Content-Type' => 'application/json' })
116
+ to_return(status: 200, body: fixture('show_droplets_paginated_first'), headers: {})
113
117
 
114
- stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=2&per_page=200').
118
+ stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=2&per_page=3').
115
119
  with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
116
120
  to_return(status: 200, body: fixture('show_droplets_paginated_last'), headers: { 'Content-Type' => 'application/json' })
117
121
 
118
- cli.options = cli.options.merge('include_urls' => true)
119
- cli.droplets
120
-
121
- expect($stdout.string).to eq <<-eos
122
- page1example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, id: 6918990, url: 'https://cloud.digitalocean.com/droplets/6918990')
123
- page1example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, id: 3164956, url: 'https://cloud.digitalocean.com/droplets/3164956')
124
- page1example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164444, url: 'https://cloud.digitalocean.com/droplets/3164444')
125
- page2example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, id: 6918990, url: 'https://cloud.digitalocean.com/droplets/6918990')
126
- page2example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, id: 3164956, url: 'https://cloud.digitalocean.com/droplets/3164956')
127
- page2example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164444, url: 'https://cloud.digitalocean.com/droplets/3164444')
122
+
123
+ cli.options = cli.options.merge('per_page' => '3')
124
+
125
+ expected_string = <<-eos
126
+ page1example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, size: 512mb, id: 6918990)
127
+ page1example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, size: 512mb, id: 3164956)
128
+ page1example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, size: 512mb, id: 3164444)
129
+ page2example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, size: 512mb, id: 6918990)
130
+ page2example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, size: 512mb, id: 3164956)
131
+ page2example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, size: 512mb, id: 3164444)
128
132
  eos
129
133
 
130
- expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=200')).to have_been_made
134
+ expect { cli.droplets }.to output(expected_string).to_stdout
135
+
136
+ expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=3')).to have_been_made
137
+ expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=2&per_page=3')).to have_been_made
131
138
  end
139
+
140
+ it 'shows error on failure in initial stage' do
141
+ stub_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1').
142
+ with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer foo', 'Content-Type' => 'application/json', 'User-Agent' => 'Faraday v0.9.2' }).
143
+ to_return(headers: { 'Content-Type' => 'text/html' }, status: 401, body: fixture('401'))
144
+
145
+ expected_string = <<-eos
146
+ Failed to connect to DigitalOcean. Reason given from API:
147
+ 401: {
148
+ \"id\": \"unauthorized\",
149
+ \"message\": \"Unable to authenticate you.\"
150
+ }
151
+ eos
152
+
153
+ expect { cli.droplets }.to raise_error(SystemExit).and output(expected_string).to_stdout
154
+
155
+ expect(a_request(:get, 'https://api.digitalocean.com/v2/droplets?page=1&per_page=1')).to have_been_made.once
156
+ end
157
+
132
158
  end
133
159
  end