From 8008ef96996b1b8fa17462c44915df015b5299ff Mon Sep 17 00:00:00 2001 From: Simone Carletti Date: Thu, 7 Jan 2016 17:47:01 +0100 Subject: [PATCH] Add listZoneRecords() and allZoneRecords() --- lib/dnsimple/client/domains.rb | 4 +- lib/dnsimple/client/zones_records.rb | 44 +++++++++++++ lib/dnsimple/struct.rb | 1 + spec/dnsimple/client/domains_spec.rb | 10 ++- spec/dnsimple/client/zones_records_spec.rb | 63 +++++++++++++++++++ spec/files/{domains => }/notfound-domain.http | 22 +++---- spec/files/notfound-zone.http | 12 ++++ spec/files/zones/records/success.http | 17 +++++ 8 files changed, 158 insertions(+), 15 deletions(-) rename spec/files/{domains => }/notfound-domain.http (96%) create mode 100644 spec/files/notfound-zone.http create mode 100644 spec/files/zones/records/success.http diff --git a/lib/dnsimple/client/domains.rb b/lib/dnsimple/client/domains.rb index 1d15ecb7..fc36c1fa 100644 --- a/lib/dnsimple/client/domains.rb +++ b/lib/dnsimple/client/domains.rb @@ -8,10 +8,10 @@ module Domains # @see #all_domains # # @example List domains in the first page - # client.domains(1010) + # client.domains.list(1010) # # @example List domains, provide a specific page - # client.domains(1010, query: { page: 2 }) + # client.domains.list(1010, query: { page: 2 }) # # @param [Fixnum] account_id the account ID # @param [Hash] options the filtering and sorting option diff --git a/lib/dnsimple/client/zones_records.rb b/lib/dnsimple/client/zones_records.rb index a78d4a50..cc20b000 100644 --- a/lib/dnsimple/client/zones_records.rb +++ b/lib/dnsimple/client/zones_records.rb @@ -1,6 +1,50 @@ module Dnsimple class Client module ZonesRecords + + # Lists the zone records in the account. + # + # @see https://developer.dnsimple.com/v2/zones/records/#list + # @see #all_records + # + # @example List records for the zone "example.com" in the first page + # client.zones.records(1010, "example.com") + # + # @example List records for the zone "example.com", provide a specific page + # client.zones.records(1010, "example.com", query: { page: 2 }) + # + # @param [Fixnum, Dnsimple::Client::WILDCARD_ACCOUNT] account_id the account ID or wildcard + # @param [String] zone_id the zone name + # @param [Hash] options the filtering and sorting option + # @return [Dnsimple::PaginatedResponse] + # @raise [Dnsimple::RequestError] + def records(account_id, zone_id, options = {}) + response = client.get(Client.versioned("/%s/zones/%s/records" % [account_id, zone_id]), options) + + Dnsimple::PaginatedResponse.new(response, response["data"].map { |r| Struct::Record.new(r) }) + end + alias :list_records :records + + # Lists ALL the zone records in the account. + # + # This method is similar to {#records}, but instead of returning the results of a specific page + # it iterates all the pages and returns the entire collection. + # + # Please use this method carefully, as fetching the entire collection will increase the number of requests + # you send to the API server and you may eventually risk to hit the throttle limit. + # + # @see https://developer.dnsimple.com/v2/zones/records/#list + # @see #records + # + # @param [Fixnum] account_id the account ID + # @param [String] zone_id the zone name + # @param [Hash] options the filtering and sorting option + # @return [Dnsimple::CollectionResponse] + # @raise [Dnsimple::RequestError] + def all_records(account_id, zone_id, options = {}) + paginate(:records, account_id, zone_id, options) + end + end end end diff --git a/lib/dnsimple/struct.rb b/lib/dnsimple/struct.rb index feb21bfe..bfa03f27 100644 --- a/lib/dnsimple/struct.rb +++ b/lib/dnsimple/struct.rb @@ -15,4 +15,5 @@ def initialize(attributes = {}) require_relative 'struct/account' require_relative 'struct/domain' +require_relative 'struct/record' require_relative 'struct/user' diff --git a/spec/dnsimple/client/domains_spec.rb b/spec/dnsimple/client/domains_spec.rb index 2d25e903..11da75f9 100644 --- a/spec/dnsimple/client/domains_spec.rb +++ b/spec/dnsimple/client/domains_spec.rb @@ -26,6 +26,12 @@ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains?page=2") end + it "supports extra request options" do + subject.domains(account_id, query: { foo: "bar" }) + + expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains?foo=bar") + end + it "returns the domains" do response = subject.domains(account_id) @@ -123,7 +129,7 @@ context "when something does not exist" do it "raises NotFoundError" do stub_request(:get, %r[/v2]) - .to_return(read_fixture("domains/notfound-domain.http")) + .to_return(read_fixture("notfound-domain.http")) expect { subject.domain(account_id, "example.com") @@ -158,7 +164,7 @@ context "when something does not exist" do it "raises NotFoundError" do stub_request(:delete, %r[/v2]) - .to_return(read_fixture("domains/notfound-domain.http")) + .to_return(read_fixture("notfound-domain.http")) expect { subject.delete_domain(account_id, "example.com") diff --git a/spec/dnsimple/client/zones_records_spec.rb b/spec/dnsimple/client/zones_records_spec.rb index 66602925..d3a33eaf 100644 --- a/spec/dnsimple/client/zones_records_spec.rb +++ b/spec/dnsimple/client/zones_records_spec.rb @@ -4,4 +4,67 @@ subject { described_class.new(api_endpoint: "https://api.dnsimple.test", access_token: "a1b2c3").zones } + + describe "#records" do + let(:account_id) { 1010 } + let(:zone_id) { "example.com" } + + before do + stub_request(:get, %r[/v2/#{account_id}/zones/#{zone_id}/records]) + .to_return(read_fixture("zones/records/success.http")) + end + + it "builds the correct request" do + subject.records(account_id, zone_id) + + expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/zones/#{zone_id}/records") + .with(headers: { 'Accept' => 'application/json' }) + end + + it "supports pagination" do + subject.records(account_id, zone_id, query: { page: 2 }) + + expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/zones/#{zone_id}/records?page=2") + end + + it "supports extra request options" do + subject.records(account_id, zone_id, query: { foo: "bar" }) + + expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/zones/#{zone_id}/records?foo=bar") + end + + it "returns the records" do + response = subject.records(account_id, zone_id) + + expect(response).to be_a(Dnsimple::PaginatedResponse) + expect(response.data).to be_a(Array) + expect(response.data.size).to eq(5) + + response.data.each do |result| + expect(result).to be_a(Dnsimple::Struct::Record) + expect(result.id).to be_a(Fixnum) + end + end + + it "exposes the pagination information" do + response = subject.records(account_id, zone_id) + + expect(response.respond_to?(:page)).to be_truthy + expect(response.page).to eq(1) + expect(response.per_page).to be_a(Fixnum) + expect(response.total_entries).to be_a(Fixnum) + expect(response.total_pages).to be_a(Fixnum) + end + end + + describe "#all_records" do + let(:account_id) { 1010 } + let(:zone_id) { "example.com" } + + it "delegates to client.paginate" do + expect(subject).to receive(:paginate).with(:records, account_id, zone_id, { foo: "bar" }) + subject.all_records(account_id, zone_id, { foo: "bar" }) + end + end + end diff --git a/spec/files/domains/notfound-domain.http b/spec/files/notfound-domain.http similarity index 96% rename from spec/files/domains/notfound-domain.http rename to spec/files/notfound-domain.http index ea415de6..5acaf7bc 100644 --- a/spec/files/domains/notfound-domain.http +++ b/spec/files/notfound-domain.http @@ -1,12 +1,12 @@ -HTTP/1.1 404 Not Found -Server: nginx -Date: Wed, 16 Dec 2015 22:07:20 GMT -Content-Type: application/json; charset=utf-8 -Transfer-Encoding: chunked -Connection: keep-alive -Strict-Transport-Security: max-age=31536000 -Cache-Control: no-cache -X-Request-Id: bc587ea7-bcd5-4c10-a940-a9b4c8339824 -X-Runtime: 0.059966 - +HTTP/1.1 404 Not Found +Server: nginx +Date: Wed, 16 Dec 2015 22:07:20 GMT +Content-Type: application/json; charset=utf-8 +Transfer-Encoding: chunked +Connection: keep-alive +Strict-Transport-Security: max-age=31536000 +Cache-Control: no-cache +X-Request-Id: bc587ea7-bcd5-4c10-a940-a9b4c8339824 +X-Runtime: 0.059966 + {"message":"Domain `0' not found"} \ No newline at end of file diff --git a/spec/files/notfound-zone.http b/spec/files/notfound-zone.http new file mode 100644 index 00000000..84dd9af1 --- /dev/null +++ b/spec/files/notfound-zone.http @@ -0,0 +1,12 @@ +HTTP/1.1 500 Internal Server Error +Server: nginx +Date: Thu, 07 Jan 2016 16:35:37 GMT +Content-Type: application/json; charset=utf-8 +Transfer-Encoding: chunked +Connection: keep-alive +Status: 500 Internal Server Error +Cache-Control: no-cache +X-Request-Id: 0de115b1-2143-44e5-b117-c7f9c51ea2ff +X-Runtime: 0.022304 + +{"message":"Internal Server Error"} \ No newline at end of file diff --git a/spec/files/zones/records/success.http b/spec/files/zones/records/success.http new file mode 100644 index 00000000..31fc420a --- /dev/null +++ b/spec/files/zones/records/success.http @@ -0,0 +1,17 @@ +HTTP/1.1 200 OK +Server: nginx +Date: Thu, 07 Jan 2016 16:33:47 GMT +Content-Type: application/json; charset=utf-8 +Transfer-Encoding: chunked +Connection: keep-alive +Status: 200 OK +X-RateLimit-Limit: 4000 +X-RateLimit-Remaining: 3994 +X-RateLimit-Reset: 1452184426 +ETag: W/"1ae3e2e65dbcc2c2a7237e3e564129dd" +Cache-Control: max-age=0, private, must-revalidate +X-Request-Id: 9b361b57-43e2-47df-9f00-e7c252bc4d41 +X-Runtime: 0.107990 +Strict-Transport-Security: max-age=31536000 + +{"data":[{"id":64779,"domain_id":5841,"parent_id":null,"name":"","content":"ns1.dnsimple.com admin.dnsimple.com 1452184205 86400 7200 604800 300","ttl":3600,"priority":null,"type":"SOA","system_record":true,"created_at":"2016-01-07T16:30:05.379Z","updated_at":"2016-01-07T16:30:05.379Z"},{"id":64780,"domain_id":5841,"parent_id":null,"name":"","content":"ns1.dnsimple.com","ttl":3600,"priority":null,"type":"NS","system_record":true,"created_at":"2016-01-07T16:30:05.422Z","updated_at":"2016-01-07T16:30:05.422Z"},{"id":64781,"domain_id":5841,"parent_id":null,"name":"","content":"ns2.dnsimple.com","ttl":3600,"priority":null,"type":"NS","system_record":true,"created_at":"2016-01-07T16:30:05.433Z","updated_at":"2016-01-07T16:30:05.433Z"},{"id":64782,"domain_id":5841,"parent_id":null,"name":"","content":"ns3.dnsimple.com","ttl":3600,"priority":null,"type":"NS","system_record":true,"created_at":"2016-01-07T16:30:05.445Z","updated_at":"2016-01-07T16:30:05.445Z"},{"id":64783,"domain_id":5841,"parent_id":null,"name":"","content":"ns4.dnsimple.com","ttl":3600,"priority":null,"type":"NS","system_record":true,"created_at":"2016-01-07T16:30:05.457Z","updated_at":"2016-01-07T16:30:05.457Z"}],"pagination":{"current_page":1,"per_page":30,"total_entries":5,"total_pages":1}} \ No newline at end of file