Skip to content

Commit

Permalink
Merge pull request #212 from pearkes/pagination_with_specs
Browse files Browse the repository at this point in the history
Pagination regression fix for API 2.0
  • Loading branch information
petems committed Nov 22, 2015
2 parents 9b6a354 + e60abee commit 1a8426d
Show file tree
Hide file tree
Showing 24 changed files with 640 additions and 94 deletions.
15 changes: 15 additions & 0 deletions lib/tugboat/middleware/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@ def call(env)
@app.call(env)
end

# Get all pages of droplets
def get_droplet_list(ocean)
page = ocean.droplet.all(per_page: 200, page: 1)
if not page.paginated?
return page.droplets
end

Enumerator.new do |enum|
page.droplets.each { |drop| enum.yield drop }
for page_num in 2..page.last_page
page = ocean.droplet.all(per_page: 200, page: page_num)
page.droplets.each { |drop| enum.yield drop }
end
end
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/tugboat/middleware/check_credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def call(env)
# We use a harmless API call to check if the authentication will
# work.
begin
env['barge'].droplet.all.list
env['barge'].droplet.all({:per_page =>'1', :page =>'1'}).list
rescue Faraday::Error::ClientError => e
say "Authentication with DigitalOcean failed."
say "Error was: #{e}"
Expand Down
4 changes: 2 additions & 2 deletions lib/tugboat/middleware/find_droplet.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def call(env)
end

# Look for the droplet by an exact name match.
ocean.droplet.all.droplets.each do |d|
(get_droplet_list ocean).each do |d|
if d.name == user_droplet_name
env["droplet_id"] = d.id
env["droplet_name"] = "(#{d.name})"
Expand Down Expand Up @@ -86,7 +86,7 @@ def call(env)
found_droplets = []
choices = []

ocean.droplet.all.droplets.each_with_index do |d, i|
(get_droplet_list ocean).each do |d|
# Check to see if one of the droplet names have the fuzzy string.
if d.name.upcase.include? user_fuzzy_name.upcase
found_droplets << d
Expand Down
40 changes: 21 additions & 19 deletions lib/tugboat/middleware/list_droplets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,30 @@ class ListDroplets < Base
def call(env)
ocean = env['barge']

droplet_list = ocean.droplet.all.droplets
droplet_list = get_droplet_list ocean

if droplet_list.empty?
has_one = false
droplet_list.each do |droplet|
has_one = true

if droplet.private_ip_address
private_addr = droplet.networks.v4.detect { |address| address.type == 'private' }
private_ip = ", privateip: #{private_addr.ip_address}"
end

if droplet.status == "active"
status_color = GREEN
else
status_color = RED
end

public_addr = droplet.networks.v4.detect { |address| address.type == 'public' }
say "#{droplet.name} (ip: #{public_addr.ip_address}#{private_ip}, status: #{status_color}#{droplet.status}#{CLEAR}, region: #{droplet.region.slug}, id: #{droplet.id}#{env["include_urls"] ? droplet_id_to_url(droplet.id) : '' })"
end

if not has_one
say "You don't appear to have any droplets.", :red
say "Try creating one with #{GREEN}\`tugboat create\`#{CLEAR}"
else
droplet_list.each do |droplet|

if droplet.private_ip_address
private_addr = droplet.networks.v4.detect { |address| address.type == 'private' }
private_ip = ", privateip: #{private_addr.ip_address}"
end

if droplet.status == "active"
status_color = GREEN
else
status_color = RED
end

public_addr = droplet.networks.v4.detect { |address| address.type == 'public' }
say "#{droplet.name} (ip: #{public_addr.ip_address}#{private_ip}, status: #{status_color}#{droplet.status}#{CLEAR}, region: #{droplet.region.slug}, id: #{droplet.id}#{env["include_urls"] ? droplet_id_to_url(droplet.id) : '' })"
end
end

@app.call(env)
Expand Down
4 changes: 2 additions & 2 deletions spec/cli/authorize_cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
end

it "asks the right questions and checks credentials" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=1").
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'}).
to_return(:status => 200, :body => fixture('show_droplets'), :headers => {})

Expand Down Expand Up @@ -57,7 +57,7 @@
end

it "sets defaults if no input given" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=1").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>/Bearer/, 'Content-Type'=>'application/json', 'User-Agent'=>'Faraday v0.9.2'}).
to_return(:status => 200, :body => fixture('show_droplets'), :headers => {})

Expand Down
4 changes: 2 additions & 2 deletions spec/cli/debug_cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

it "gives full faraday logs" do
pending 'Debug flag not avaliable yet'
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture('show_droplets'), :headers => {})
@cli.droplets
Expand All @@ -28,7 +28,7 @@

it "gives full faraday logs with redacted API keys" do
pending 'Debug flag not avaliable yet'
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture('show_droplets'), :headers => {})
@cli.droplets
Expand Down
8 changes: 4 additions & 4 deletions spec/cli/destroy_cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

describe "destroy" do
it "destroys a droplet with a fuzzy name" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture('show_droplets'), :headers => {})

Expand Down Expand Up @@ -43,7 +43,7 @@


it "destroys a droplet with a name" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture('show_droplets'), :headers => {})

Expand All @@ -62,7 +62,7 @@
end

it "destroys a droplet with confirm flag set" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture('show_droplets'), :headers => {})

Expand All @@ -80,7 +80,7 @@
end

it "does not destroy a droplet if no is chosen" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture('show_droplets'), :headers => {})

Expand Down
40 changes: 32 additions & 8 deletions spec/cli/droplets_cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

describe "droplets" do
it "shows a list when droplets exist" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture("show_droplets"), :headers => {'Content-Type' => 'application/json'},)

Expand All @@ -17,11 +17,11 @@
example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164444)
eos

expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200")).to have_been_made
expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200")).to have_been_made
end

it "returns an error message when no droplets exist" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture("show_droplets_empty"), :headers => {'Content-Type' => 'application/json'},)

Expand All @@ -32,11 +32,11 @@
Try creating one with \e[32m`tugboat create`\e[0m
eos

expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200")).to have_been_made
expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200")).to have_been_made
end

it "shows no output when --quiet is set" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture("show_droplets"), :headers => {'Content-Type' => 'application/json'},)

Expand All @@ -46,11 +46,11 @@
# Should be /dev/null not stringIO
expect($stdout).to be_a File

expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200")).to have_been_made
expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200")).to have_been_made
end

it "includes urls when --include-urls is set" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture("show_droplets"), :headers => {'Content-Type' => 'application/json'},)

Expand All @@ -63,7 +63,31 @@
example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164444, url: 'https://cloud.digitalocean.com/droplets/3164444')
eos

expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200")).to have_been_made
expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200")).to have_been_made
end

it "paginates when multiple pages are returned" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture("show_droplets_paginated_first"), :headers => {'Content-Type' => 'application/json'},)

stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=2&per_page=200").
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'}).
to_return(:status => 200, :body => fixture("show_droplets_paginated_last"), :headers => {'Content-Type' => 'application/json'},)

@cli.options = @cli.options.merge("include_urls" => true)
@cli.droplets

expect($stdout.string).to eq <<-eos
page1example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, id: 6918990, url: 'https://cloud.digitalocean.com/droplets/6918990')
page1example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, id: 3164956, url: 'https://cloud.digitalocean.com/droplets/3164956')
page1example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164444, url: 'https://cloud.digitalocean.com/droplets/3164444')
page2example.com (ip: 104.236.32.182, status: \e[32mactive\e[0m, region: nyc3, id: 6918990, url: 'https://cloud.digitalocean.com/droplets/6918990')
page2example2.com (ip: 104.236.32.172, status: \e[32mactive\e[0m, region: nyc3, id: 3164956, url: 'https://cloud.digitalocean.com/droplets/3164956')
page2example3.com (ip: 104.236.32.173, status: \e[31moff\e[0m, region: nyc3, id: 3164444, url: 'https://cloud.digitalocean.com/droplets/3164444')
eos

expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200")).to have_been_made
end
end

Expand Down
8 changes: 4 additions & 4 deletions spec/cli/env_variable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

describe "DO_API_TOKEN=foobar" do
it "verifies with the ENV variable DO_API_TOKEN" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=1").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization'=>'Bearer env_variable', 'Content-Type'=>'application/json', 'User-Agent'=>'Faraday v0.9.2'}).
to_return(:status => 200, :body => fixture('show_droplets'), :headers => {})

Expand All @@ -15,11 +15,11 @@

@cli.verify
expect($stdout.string).to eq "Authentication with DigitalOcean was successful.\n"
expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200")).to have_been_made
expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=1")).to have_been_made
end

it "does not use ENV variable DO_API_TOKEN if empty" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=1").
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'}).
to_return(:status => 200, :body => fixture('show_droplets'), :headers => {})

Expand All @@ -29,7 +29,7 @@

@cli.verify
expect($stdout.string).to eq "Authentication with DigitalOcean was successful.\n"
expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200")).to have_been_made
expect(a_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=1")).to have_been_made
end
end
end
Expand Down
8 changes: 4 additions & 4 deletions spec/cli/halt_cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

describe "halt" do
it "halts a droplet with a fuzzy name" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture('show_droplets'), :headers => {})

Expand All @@ -23,7 +23,7 @@
end

it "halts a droplet hard when the hard option is used" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture('show_droplets'), :headers => {})

Expand Down Expand Up @@ -66,7 +66,7 @@


it "halts a droplet with a name" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture("show_droplets"), :headers => {'Content-Type' => 'application/json'},)

Expand All @@ -86,7 +86,7 @@


it "does not halt a droplet that is off" do
stub_request(:get, "https://api.digitalocean.com/v2/droplets?per_page=200").
stub_request(:get, "https://api.digitalocean.com/v2/droplets?page=1&per_page=200").
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'}).
to_return(:status => 200, :body => fixture("show_droplets"), :headers => {'Content-Type' => 'application/json'},)

Expand Down
Loading

0 comments on commit 1a8426d

Please sign in to comment.