Skip to content

Commit

Permalink
Merge b1ee738 into f6765d4
Browse files Browse the repository at this point in the history
  • Loading branch information
jodosha committed Jul 19, 2018
2 parents f6765d4 + b1ee738 commit 5874b68
Show file tree
Hide file tree
Showing 11 changed files with 322 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/dnsimple/client/clients.rb
Expand Up @@ -212,10 +212,12 @@ class VanityNameServersService < ClientService

require_relative 'zones'
require_relative 'zones_records'
require_relative 'zones_distributions'

class ZonesService < ClientService
include Client::Zones
include Client::ZonesRecords
include Client::ZonesDistributions
end


Expand Down
47 changes: 47 additions & 0 deletions lib/dnsimple/client/zones_distributions.rb
@@ -0,0 +1,47 @@
module Dnsimple
class Client
module ZonesDistributions

# Checks if a zone change is fully distributed to all DNSimple name
# servers across the globe.
#
# @see https://developer.dnsimple.com/v2/zones/#checkZoneDistribution
#
# @param account_id [Integer] the account ID
# @param zone_id [#to_s] the zone name
# @param options [Hash]
# @return [Dnsimple::Response<Dnsimple::Struct::ZoneDistribution>]
#
# @raise [Dnsimple::NotFoundError]
# @raise [Dnsimple::RequestError]
def zone_distribution(account_id, zone_id, options = {})
response = client.get(Client.versioned("/%s/zones/%s/distribution" % [account_id, zone_id]), options)

Dnsimple::Response.new(response, Struct::ZoneDistribution.new(response["data"]))
end

# Checks if a zone record is fully distributed to all DNSimple name
# servers across the globe.
#
# @see https://developer.dnsimple.com/v2/zones/records/#checkZoneRecordDistribution
#
# @example Get record 123 in zone "example.com"
# client.zones.zone_record_distribution(1010, "example.com", 123)
#
# @param [Integer] account_id the account ID
# @param [String] zone_id the zone name
# @param [Integer] record_id the record ID
# @param [Hash] options
# @return [Dnsimple::Response<Dnsimple::Struct::ZoneDistribution>]
#
# @raise [Dnsimple::NotFoundError]
# @raise [Dnsimple::RequestError]
def zone_record_distribution(account_id, zone_id, record_id, options = {})
response = client.get(Client.versioned("/%s/zones/%s/records/%s/distribution" % [account_id, zone_id, record_id]), options)

Dnsimple::Response.new(response, Struct::ZoneDistribution.new(response["data"]))
end

end
end
end
1 change: 1 addition & 0 deletions lib/dnsimple/struct.rb
Expand Up @@ -42,5 +42,6 @@ def initialize(attributes = {})
require_relative 'struct/whois_privacy'
require_relative 'struct/zone'
require_relative 'struct/zone_file'
require_relative 'struct/zone_distribution'
require_relative 'struct/webhook'
require_relative 'struct/whoami'
11 changes: 11 additions & 0 deletions lib/dnsimple/struct/zone_distribution.rb
@@ -0,0 +1,11 @@
module Dnsimple
module Struct

class ZoneDistribution < Base
# @return [Boolean] true if the zone is properly distributed across
# all DNSimple name servers.
attr_accessor :distributed
end

end
end
135 changes: 135 additions & 0 deletions spec/dnsimple/client/zones_distributions_spec.rb
@@ -0,0 +1,135 @@
require 'spec_helper'

describe Dnsimple::Client, ".zones" do

subject { described_class.new(base_url: "https://api.dnsimple.test", access_token: "a1b2c3").zones }

describe "#zone_distribution" do
let(:account_id) { 1010 }

before do
stub_request(:get, %r{/v2/#{account_id}/zones/.+$})
.to_return(read_http_fixture("checkZoneDistribution/success.http"))
end

it "builds the correct request" do
subject.zone_distribution(account_id, zone = "example.com")

expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/zones/#{zone}/distribution")
.with(headers: { 'Accept' => 'application/json' })
end

it "returns the zone distribution check with true when the zone is fully distributed" do
response = subject.zone_distribution(account_id, "example.com")
expect(response).to be_a(Dnsimple::Response)

result = response.data
expect(result).to be_a(Dnsimple::Struct::ZoneDistribution)
expect(result.distributed).to be(true)
end

it "returns the zone distribution check with false when the zone isn't fully distributed" do
stub_request(:get, %r{/v2/#{account_id}/zones/.+$})
.to_return(read_http_fixture("checkZoneDistribution/failure.http"))

response = subject.zone_distribution(account_id, "example.com")
expect(response).to be_a(Dnsimple::Response)

result = response.data
expect(result).to be_a(Dnsimple::Struct::ZoneDistribution)
expect(result.distributed).to be(false)
end

it "raises an error when the server wasn't able to complete the check" do
stub_request(:get, %r{/v2/#{account_id}/zones/.+$})
.to_return(read_http_fixture("checkZoneDistribution/error.http"))

expect {
subject.zone_distribution(account_id, "example.com")
}.to raise_error(Dnsimple::RequestError, "Could not query zone, connection timed out")
end

context "when the zone does not exist" do
it "raises NotFoundError" do
stub_request(:get, %r{/v2})
.to_return(read_http_fixture("notfound-zone.http"))

expect {
subject.zone_distribution(account_id, "example.com")
}.to raise_error(Dnsimple::NotFoundError)
end
end
end


describe "#zone_record_distribution" do
let(:account_id) { 1010 }
let(:zone_id) { "example.com" }
let(:record_id) { 5 }

before do
stub_request(:get, %r{/v2/#{account_id}/zones/#{zone_id}/records/#{record_id}/distribution$})
.to_return(read_http_fixture("checkZoneRecordDistribution/success.http"))
end

it "builds the correct request" do
subject.zone_record_distribution(account_id, zone_id, record_id)

expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/zones/#{zone_id}/records/#{record_id}/distribution")
.with(headers: { 'Accept' => 'application/json' })
end

it "returns the zone record distribution check with true when the zone is fully distributed" do
response = subject.zone_record_distribution(account_id, zone_id, record_id)
expect(response).to be_a(Dnsimple::Response)

result = response.data
expect(result).to be_a(Dnsimple::Struct::ZoneDistribution)
expect(result.distributed).to be(true)
end

it "returns the zone distribution check with false when the zone isn't fully distributed" do
stub_request(:get, %r{/v2/#{account_id}/zones/#{zone_id}/records/#{record_id}/distribution$})
.to_return(read_http_fixture("checkZoneRecordDistribution/failure.http"))

response = subject.zone_record_distribution(account_id, zone_id, record_id)
expect(response).to be_a(Dnsimple::Response)

result = response.data
expect(result).to be_a(Dnsimple::Struct::ZoneDistribution)
expect(result.distributed).to be(false)
end

it "raises an error when the server wasn't able to complete the check" do
stub_request(:get, %r{/v2/#{account_id}/zones/#{zone_id}/records/#{record_id}/distribution$})
.to_return(read_http_fixture("checkZoneRecordDistribution/error.http"))

expect {
subject.zone_record_distribution(account_id, zone_id, record_id)
}.to raise_error(Dnsimple::RequestError, "Could not query zone, connection timed out")
end

context "when the zone does not exist" do
it "raises NotFoundError" do
stub_request(:get, %r{/v2})
.to_return(read_http_fixture("notfound-zone.http"))

expect {
subject.zone_record_distribution(account_id, zone_id, "0")
}.to raise_error(Dnsimple::NotFoundError)
end
end

context "when the record does not exist" do
it "raises NotFoundError" do
stub_request(:get, %r{/v2})
.to_return(read_http_fixture("notfound-record.http"))

expect {
subject.zone_record_distribution(account_id, zone_id, "0")
}.to raise_error(Dnsimple::NotFoundError)
end
end
end

end
21 changes: 21 additions & 0 deletions spec/fixtures.http/checkZoneDistribution/error.http
@@ -0,0 +1,21 @@
HTTP/1.1 504 Gateway Timeout
Server: nginx
Date: Mon, 30 Oct 2017 09:09:41 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-RateLimit-Limit: 2400
X-RateLimit-Remaining: 2399
X-RateLimit-Reset: 1509358181
ETag: W/"10fc650d019e6bffa876f08bce8f3380"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 91f124fc-671d-40fa-877b-0b222692f623
X-Runtime: 0.471005
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: DENY
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000

{"message":"Could not query zone, connection timed out"}
21 changes: 21 additions & 0 deletions spec/fixtures.http/checkZoneDistribution/failure.http
@@ -0,0 +1,21 @@
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 30 Oct 2017 09:09:41 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-RateLimit-Limit: 2400
X-RateLimit-Remaining: 2399
X-RateLimit-Reset: 1509358181
ETag: W/"10fc650d019e6bffa876f08bce8f3380"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 91f124fc-671d-40fa-877b-0b222692f623
X-Runtime: 0.471005
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: DENY
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000

{"data":{"distributed":false}}
21 changes: 21 additions & 0 deletions spec/fixtures.http/checkZoneDistribution/success.http
@@ -0,0 +1,21 @@
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 30 Oct 2017 09:09:41 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-RateLimit-Limit: 2400
X-RateLimit-Remaining: 2399
X-RateLimit-Reset: 1509358181
ETag: W/"10fc650d019e6bffa876f08bce8f3380"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 91f124fc-671d-40fa-877b-0b222692f623
X-Runtime: 0.471005
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: DENY
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000

{"data":{"distributed":true}}
21 changes: 21 additions & 0 deletions spec/fixtures.http/checkZoneRecordDistribution/error.http
@@ -0,0 +1,21 @@
HTTP/1.1 504 Gateway Timeout
Server: nginx
Date: Mon, 18 Dec 2017 10:54:48 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-RateLimit-Limit: 2400
X-RateLimit-Remaining: 2397
X-RateLimit-Reset: 1513597686
ETag: W/"10fc650d019e6bffa876f08bce8f3380"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 74059b13-9262-4e2d-b8ff-a833376dce19
X-Runtime: 0.408180
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: DENY
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000

{"message":"Could not query zone, connection timed out"}
21 changes: 21 additions & 0 deletions spec/fixtures.http/checkZoneRecordDistribution/failure.http
@@ -0,0 +1,21 @@
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 18 Dec 2017 10:54:13 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-RateLimit-Limit: 2400
X-RateLimit-Remaining: 2398
X-RateLimit-Reset: 1513597686
ETag: W/"10fc650d019e6bffa876f08bce8f3380"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: f5a86610-0e22-4047-a27c-350769eaa6d5
X-Runtime: 0.425440
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: DENY
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000

{"data":{"distributed":false}}
21 changes: 21 additions & 0 deletions spec/fixtures.http/checkZoneRecordDistribution/success.http
@@ -0,0 +1,21 @@
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 18 Dec 2017 10:48:06 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-RateLimit-Limit: 2400
X-RateLimit-Remaining: 2399
X-RateLimit-Reset: 1513597686
ETag: W/"10fc650d019e6bffa876f08bce8f3380"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 34c69751-ffee-4856-ac28-ead4f3a66e18
X-Runtime: 0.438473
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: DENY
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000

{"data":{"distributed":true}}

0 comments on commit 5874b68

Please sign in to comment.