diff --git a/CHANGELOG.md b/CHANGELOG.md index 89bcd3d6..7a1d7343 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ This project uses [Semantic Versioning 2.0.0](http://semver.org/). +## main + +- NEW: Added `registrar.get_domain_prices` to retrieve whether a domain is premium and the prices to register, transfer, and renew. (dnsimple/dnsimple-ruby#230) + ## 5.2.0 - CHANGED: `Certificate#expires_on` (date only) is deprecated in favor of `Certificate#expires_at` (timestamp). (dnsimple/dnsimple-ruby#190) diff --git a/lib/dnsimple/client/registrar.rb b/lib/dnsimple/client/registrar.rb index 4be1546f..94b9d43e 100644 --- a/lib/dnsimple/client/registrar.rb +++ b/lib/dnsimple/client/registrar.rb @@ -50,6 +50,26 @@ def domain_premium_price(account_id, domain_name, options = {}) Dnsimple::Response.new(response, Struct::DomainPremiumPrice.new(response["data"])) end + # Get prices for a domain. + # @see https://developer.dnsimple.com/v2/registrar/#getDomainPrices + # + # @example Check prices for example.com: + # client.registrar.get_domain_prices(1010, "example.com") + # + # @param [Integer] account_id the Account id + # @param [#to_s] domain_name the domain name to find the prices + # @param [Hash] options + # + # @return [Struct::DomainPrice] + # + # @raise [RequestError] When the request fails. + def get_domain_prices(account_id, domain_name, options = {}) + endpoint = Client.versioned("/%s/registrar/domains/%s/prices" % [account_id, domain_name]) + response = client.get(endpoint, options) + + Dnsimple::Response.new(response, Struct::DomainPrice.new(response["data"])) + end + # Registers a domain. # # @see https://developer.dnsimple.com/v2/registrar/#register diff --git a/lib/dnsimple/struct.rb b/lib/dnsimple/struct.rb index be026c59..26eac577 100644 --- a/lib/dnsimple/struct.rb +++ b/lib/dnsimple/struct.rb @@ -27,6 +27,7 @@ def initialize(attributes = {}) require_relative 'struct/domain' require_relative 'struct/domain_check' require_relative 'struct/domain_premium_price' +require_relative 'struct/domain_price' require_relative 'struct/domain_push' require_relative 'struct/domain_registration' require_relative 'struct/domain_transfer' diff --git a/lib/dnsimple/struct/domain_price.rb b/lib/dnsimple/struct/domain_price.rb new file mode 100644 index 00000000..9df8f66a --- /dev/null +++ b/lib/dnsimple/struct/domain_price.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Dnsimple + module Struct + + class DomainPrice < Base + # @return [String] The domain name + attr_accessor :domain + + # @return [Boolean] Whether the domain is premium. + attr_accessor :premium + + # @return [Float] The price for registration + attr_accessor :registration_price + + # @return [Float] The price for renewal + attr_accessor :renewal_price + + # @return [Float] The price for transfer + attr_accessor :transfer_price + end + + end +end diff --git a/spec/dnsimple/client/registrar_spec.rb b/spec/dnsimple/client/registrar_spec.rb index 24e754cc..26404f1f 100644 --- a/spec/dnsimple/client/registrar_spec.rb +++ b/spec/dnsimple/client/registrar_spec.rb @@ -82,6 +82,49 @@ end end + describe "#get_domain_prices" do + let(:account_id) { 1010 } + + before do + stub_request(:get, %r{/v2/#{account_id}/registrar/domains/bingo.pizza/prices$}) + .to_return(read_http_fixture("getDomainPrices/success.http")) + end + + it "builds the correct request" do + subject.get_domain_prices(account_id, "bingo.pizza") + + expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/registrar/domains/bingo.pizza/prices") + .with(headers: { "Accept" => "application/json" }) + end + + it "returns the prices" do + response = subject.get_domain_prices(account_id, "bingo.pizza") + expect(response).to be_a(Dnsimple::Response) + + result = response.data + + expect(result).to be_a(Dnsimple::Struct::DomainPrice) + expect(result.domain).to eq("bingo.pizza") + expect(result.premium).to be(true) + expect(result.registration_price).to eq(20.0) + expect(result.renewal_price).to eq(20.0) + expect(result.transfer_price).to eq(20.0) + end + + context "when the TLD is not supported" do + before do + stub_request(:get, %r{/v2/#{account_id}/registrar/domains/bingo.pineapple/prices$}) + .to_return(read_http_fixture("getDomainPrices/failure.http")) + end + + it "raises error" do + expect { + subject.get_domain_prices(account_id, "bingo.pineapple") + }.to raise_error(Dnsimple::RequestError, "TLD .PINEAPPLE is not supported") + end + end + end + describe "#register_domain" do let(:account_id) { 1010 } let(:attributes) { { registrant_id: "10" } } diff --git a/spec/fixtures.http/getDomainPrices/failure.http b/spec/fixtures.http/getDomainPrices/failure.http new file mode 100644 index 00000000..cdc1bbea --- /dev/null +++ b/spec/fixtures.http/getDomainPrices/failure.http @@ -0,0 +1,20 @@ +HTTP/1.1 400 Bad Request +Server: nginx +Date: Mon, 08 Mar 2021 14:35:58 GMT +Content-Type: application/json; charset=utf-8 +Transfer-Encoding: identity +Connection: keep-alive +X-RateLimit-Limit: 2400 +X-RateLimit-Remaining: 2396 +X-RateLimit-Reset: 1615217645 +Cache-Control: no-cache +X-Request-Id: e414a674-63bb-4e54-b714-db5b516bb190 +X-Runtime: 0.009579 +X-Frame-Options: DENY +X-Content-Type-Options: nosniff +X-XSS-Protection: 1; mode=block +X-Download-Options: noopen +X-Permitted-Cross-Domain-Policies: none +Content-Security-Policy: frame-ancestors 'none' + +{"message":"TLD .PINEAPPLE is not supported"} \ No newline at end of file diff --git a/spec/fixtures.http/getDomainPrices/success.http b/spec/fixtures.http/getDomainPrices/success.http new file mode 100644 index 00000000..15b7f96c --- /dev/null +++ b/spec/fixtures.http/getDomainPrices/success.http @@ -0,0 +1,22 @@ +HTTP/1.1 200 OK +Server: nginx +Date: Mon, 08 Mar 2021 14:35:26 GMT +Content-Type: application/json; charset=utf-8 +Transfer-Encoding: identity +Connection: keep-alive +X-RateLimit-Limit: 2400 +X-RateLimit-Remaining: 2397 +X-RateLimit-Reset: 1615217645 +ETag: W/"2104f27f2877f429295359cfc409f9f7" +Cache-Control: max-age=0, private, must-revalidate +X-Request-Id: b0d9e000-58a6-4254-af43-8735d26e12d9 +X-Runtime: 9.129301 +X-Frame-Options: DENY +X-Content-Type-Options: nosniff +X-XSS-Protection: 1; mode=block +X-Download-Options: noopen +X-Permitted-Cross-Domain-Policies: none +Content-Security-Policy: frame-ancestors 'none' +Strict-Transport-Security: max-age=31536000 + +{"data":{"domain":"bingo.pizza","premium":true,"registration_price":20.0,"renewal_price":20.0,"transfer_price":20.0}}