diff --git a/lib/dnsimple/client/clients.rb b/lib/dnsimple/client/clients.rb index cb65e35e..c981d90f 100644 --- a/lib/dnsimple/client/clients.rb +++ b/lib/dnsimple/client/clients.rb @@ -86,9 +86,11 @@ class RegistrarService < ClientService end + require_relative 'zones' require_relative 'zones_records' class ZonesService < ClientService + include Client::Zones include Client::ZonesRecords end diff --git a/lib/dnsimple/client/zones.rb b/lib/dnsimple/client/zones.rb new file mode 100644 index 00000000..639d7703 --- /dev/null +++ b/lib/dnsimple/client/zones.rb @@ -0,0 +1,51 @@ +module Dnsimple + class Client + module Zones + + # Lists the zones in the account. + # + # @see https://developer.dnsimple.com/v2/zones/#list + # @see #all_zones + # + # @example List zones in the first page + # client.zones.list(1010, "example.com") + # + # @example List zones, provide a specific page + # client.zones.list(1010, "example.com", query: { page: 2 }) + # + # @param [Fixnum] account_id the account ID + # @param [Hash] options the filtering and sorting option + # @return [Dnsimple::PaginatedResponse] + # + # @raise [Dnsimple::RequestError] + def zones(account_id, options = {}) + response = client.get(Client.versioned("/%s/zones" % [account_id]), options) + + Dnsimple::PaginatedResponse.new(response, response["data"].map { |r| Struct::Zone.new(r) }) + end + alias :list :zones + alias :list_zones :zones + + # Lists ALL the zones in the account. + # + # This method is similar to {#zones}, 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/#list + # @see #zones + # + # @param [Fixnum] account_id the account ID + # @param [Hash] options the filtering and sorting option + # @return [Dnsimple::CollectionResponse] + # + # @raise [Dnsimple::RequestError] + def all_zones(account_id, options = {}) + paginate(:zones, account_id, options) + end + + end + end +end diff --git a/lib/dnsimple/struct.rb b/lib/dnsimple/struct.rb index 32084a02..707e5968 100644 --- a/lib/dnsimple/struct.rb +++ b/lib/dnsimple/struct.rb @@ -18,3 +18,4 @@ def initialize(attributes = {}) require_relative 'struct/domain' require_relative 'struct/record' require_relative 'struct/user' +require_relative 'struct/zone' diff --git a/lib/dnsimple/struct/zone.rb b/lib/dnsimple/struct/zone.rb new file mode 100644 index 00000000..79bc0e1a --- /dev/null +++ b/lib/dnsimple/struct/zone.rb @@ -0,0 +1,25 @@ +module Dnsimple + module Struct + + class Zone < Base + # @return [Fixnum] The zone ID in DNSimple. + attr_accessor :id + + # @return [Fixnum] The associated account ID. + attr_accessor :account_id + + # @return [String] The zone name. + attr_accessor :name + + # @return [Boolean] True if the zone is a reverse zone. + attr_accessor :reverse + + # @return [String] When the zone was created in DNSimple. + attr_accessor :created_at + + # @return [String] When the zone was last updated in DNSimple. + attr_accessor :updated_at + end + + end +end diff --git a/spec/dnsimple/client/zones_spec.rb b/spec/dnsimple/client/zones_spec.rb new file mode 100644 index 00000000..402c0ff1 --- /dev/null +++ b/spec/dnsimple/client/zones_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' + +describe Dnsimple::Client, ".zones" do + + subject { described_class.new(base_url: "https://api.dnsimple.test", access_token: "a1b2c3").zones } + + + describe "#zones" do + let(:account_id) { 1010 } + + before do + stub_request(:get, %r[/v2/#{account_id}/zones]) + .to_return(read_http_fixture("listZones/success.http")) + end + + it "builds the correct request" do + subject.zones(account_id) + + expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/zones") + .with(headers: { 'Accept' => 'application/json' }) + end + + it "supports pagination" do + subject.zones(account_id, query: { page: 2 }) + + expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/zones?page=2") + end + + it "supports extra request options" do + subject.zones(account_id, query: { foo: "bar" }) + + expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/zones?foo=bar") + end + + it "returns the zones" do + response = subject.zones(account_id) + + expect(response).to be_a(Dnsimple::PaginatedResponse) + expect(response.data).to be_a(Array) + expect(response.data.size).to eq(2) + + response.data.each do |result| + expect(result).to be_a(Dnsimple::Struct::Zone) + expect(result.id).to be_a(Fixnum) + end + end + + it "exposes the pagination information" do + response = subject.zones(account_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_zones" do + let(:account_id) { 1010 } + + it "delegates to client.paginate" do + expect(subject).to receive(:paginate).with(:zones, account_id, { foo: "bar" }) + subject.all_zones(account_id, { foo: "bar" }) + end + end + +end diff --git a/spec/fixtures.http/listZones/success.http b/spec/fixtures.http/listZones/success.http new file mode 100644 index 00000000..fc3e227a --- /dev/null +++ b/spec/fixtures.http/listZones/success.http @@ -0,0 +1,17 @@ +HTTP/1.1 200 OK +Server: nginx +Date: Fri, 22 Jan 2016 16:54:24 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: 1453484045 +ETag: W/"485e03204e1853519bd637be743f2b25" +Cache-Control: max-age=0, private, must-revalidate +X-Request-Id: 01be9fa5-3a00-4d51-a927-f17587cb67ec +X-Runtime: 0.037083 +Strict-Transport-Security: max-age=31536000 + +{"data":[{"id":1,"account_id":1010,"name":"example-alpha.com","reverse":false,"created_at":"2015-04-23T07:40:03.045Z","updated_at":"2015-04-23T07:40:03.051Z"},{"id":2,"account_id":1010,"name":"example-beta.com","reverse":true,"created_at":"2015-04-23T07:40:03.061Z","updated_at":"2015-04-23T07:40:03.067Z"}],"pagination":{"current_page":1,"per_page":30,"total_entries":2,"total_pages":1}} \ No newline at end of file