From 312ebee743820004b22c73d253673172e56e05f6 Mon Sep 17 00:00:00 2001 From: Luca Guidi Date: Mon, 18 Jul 2016 10:06:39 +0200 Subject: [PATCH 1/3] Added support for `appliedServices` --- lib/dnsimple/client/clients.rb | 12 ++++ lib/dnsimple/client/domain_services.rb | 35 +++++++++++ spec/dnsimple/client/domain_services_spec.rb | 60 +++++++++++++++++++ .../appliedServices/success.http | 21 +++++++ 4 files changed, 128 insertions(+) create mode 100644 lib/dnsimple/client/domain_services.rb create mode 100644 spec/dnsimple/client/domain_services_spec.rb create mode 100644 spec/fixtures.http/appliedServices/success.http diff --git a/lib/dnsimple/client/clients.rb b/lib/dnsimple/client/clients.rb index e56b4cb0..a9473a1a 100644 --- a/lib/dnsimple/client/clients.rb +++ b/lib/dnsimple/client/clients.rb @@ -16,6 +16,11 @@ def domains @services[:domains] ||= Client::DomainsService.new(self) end + # @return [Dnsimple::Client::DomainServicesService] The domain-services-related API proxy. + def domain_services + @services[:domains] ||= Client::DomainServicesService.new(self) + end + # @return [Dnsimple::Client::IdentityService] The identity-related API proxy. def identity @services[:auth] ||= Client::IdentityService.new(self) @@ -119,6 +124,13 @@ class DomainsService < ClientService end + require_relative 'domain_services' + + class DomainServicesService < ClientService + include Client::DomainServices + end + + require_relative 'identity' class IdentityService < ClientService diff --git a/lib/dnsimple/client/domain_services.rb b/lib/dnsimple/client/domain_services.rb new file mode 100644 index 00000000..fd2190eb --- /dev/null +++ b/lib/dnsimple/client/domain_services.rb @@ -0,0 +1,35 @@ +module Dnsimple + class Client + module DomainServices + + # Lists the one-click services applied to the domain. + # + # @see https://developer.dnsimple.com/v2/services/domains/#applied + # + # @example List one-click applied services for example.com: + # client.domain_services.applied_services(1010, "example.com") + # + # @example List one-click applied services for example.com, provide a specific page: + # client.services.list_services(1010, "example.com", page: 2) + # + # @example List one-click applied services for example.com, provide a sorting policy: + # client.services.list_services(1010, "example.com", sort: "short_name:asc") + # + # @param [Fixnum] account_id the account ID + # @param [#to_s] domain_name the domain name + # @param [Hash] options the filtering and sorting options + # @option options [Integer] :page current page (pagination) + # @option options [Integer] :per_page number of entries to return (pagination) + # @option options [String] :sort sorting policy + # @return [Dnsimple::PaginatedResponse] + # + # @raise [RequestError] When the request fails. + def applied_services(account_id, domain_name, options = {}) + endpoint = Client.versioned("/%s/domains/%s/services" % [account_id, domain_name]) + response = client.get(endpoint, Options::ListOptions.new(options)) + + Dnsimple::PaginatedResponse.new(response, response["data"].map { |r| Struct::Service.new(r) }) + end + end + end +end diff --git a/spec/dnsimple/client/domain_services_spec.rb b/spec/dnsimple/client/domain_services_spec.rb new file mode 100644 index 00000000..6f5d0f18 --- /dev/null +++ b/spec/dnsimple/client/domain_services_spec.rb @@ -0,0 +1,60 @@ +require 'spec_helper' + +describe Dnsimple::Client, ".domain_services" do + + subject { described_class.new(base_url: "https://api.dnsimple.test", access_token: "a1b2c3").domain_services } + + + describe "#applied_services" do + let(:account_id) { 1010 } + let(:domain_id) { 'example.com' } + + before do + stub_request(:get, %r{/v2/#{account_id}/domains/#{domain_id}/services}). + to_return(read_http_fixture("appliedServices/success.http")) + end + + it "builds the correct request" do + subject.applied_services(account_id, domain_id) + + expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/services"). + with(headers: { "Accept" => "application/json" }) + end + + it "supports pagination" do + subject.applied_services(account_id, domain_id, page: 2) + + expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/services?page=2") + end + + it "supports extra request options" do + subject.applied_services(account_id, domain_id, query: { foo: "bar" }) + + expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/services?foo=bar") + end + + it "supports sorting" do + subject.applied_services(account_id, domain_id, sort: "short_name:asc") + + expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/services?sort=short_name:asc") + end + + it "returns the list of available services" do + response = subject.applied_services(account_id, domain_id) + expect(response).to be_a(Dnsimple::CollectionResponse) + + response.data.each do |service| + expect(service).to be_a(Dnsimple::Struct::Service) + expect(service.id).to be_a(Fixnum) + expect(service.name).to be_a(String) + expect(service.short_name).to be_a(String) + expect(service.description).to be_a(String) + + service.settings.each do |service_setting| + expect(service_setting).to be_a(Dnsimple::Struct::Service::Setting) + end + end + end + end + +end diff --git a/spec/fixtures.http/appliedServices/success.http b/spec/fixtures.http/appliedServices/success.http new file mode 100644 index 00000000..4b9fdf17 --- /dev/null +++ b/spec/fixtures.http/appliedServices/success.http @@ -0,0 +1,21 @@ +HTTP/1.1 200 OK +Server: nginx +Date: Wed, 15 Jun 2016 11:09:44 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: 1465992405 +ETag: W/"f3fb525524e0a0eab452025850afb062" +Cache-Control: max-age=0, private, must-revalidate +X-Request-Id: 03bcc2ff-d1f1-4fc2-bb3f-9218a21c04b7 +X-Runtime: 0.065526 +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":[{"id":1,"name":"WordPress","short_name":"wordpress","description":"Share with the world, your community, or your closest friends.","setup_description":null,"requires_setup":true,"default_subdomain":"blog","created_at":"2013-11-05T18:06:50.968Z","updated_at":"2016-03-04T09:23:27.885Z","settings":[{"name":"site","label":"Site","append":null,"description":"Your Wordpress.com subdomain","example":null,"password":false}]}],"pagination":{"current_page":1,"per_page":30,"total_entries":1,"total_pages":1}} From 2b4629c53fa5ad9bd04b0638b3afbca77ee2301c Mon Sep 17 00:00:00 2001 From: Luca Guidi Date: Mon, 18 Jul 2016 10:28:13 +0200 Subject: [PATCH 2/3] Added support for `applyService` --- lib/dnsimple/client/domain_services.rb | 24 ++++++++++++++++ spec/dnsimple/client/domain_services_spec.rb | 29 ++++++++++++++++++++ spec/fixtures.http/applyService/created.http | 17 ++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 spec/fixtures.http/applyService/created.http diff --git a/lib/dnsimple/client/domain_services.rb b/lib/dnsimple/client/domain_services.rb index fd2190eb..f79ae292 100644 --- a/lib/dnsimple/client/domain_services.rb +++ b/lib/dnsimple/client/domain_services.rb @@ -30,6 +30,30 @@ def applied_services(account_id, domain_name, options = {}) Dnsimple::PaginatedResponse.new(response, response["data"].map { |r| Struct::Service.new(r) }) end + + # Apply a given one-click service to the domain. + # + # @see https://developer.dnsimple.com/v2/services/domains/#apply + # + # @example Apply one-click service service1 to example.com: + # client.domain_services.applied_services(1010, "example.com", "service1") + # + # @example Apply one-click service service1 to example.com, provide optional settings: + # client.domain_services.applied_services(1010, "example.com", "service1", app: "foo") + # + # @param [Fixnum] account_id the account ID + # @param [#to_s] domain_name the domain name + # @param [#to_s] service_name the service name (or ID) + # @param [Hash] options + # @return [Dnsimple::Response] + # + # @raise [RequestError] When the request fails. + def apply_service(account_id, domain_name, service_name, settings = {}, options = {}) + response = client.post(Client.versioned("/%s/domains/%s/services/%s" % [account_id, domain_name, service_name]), settings, options) + + Dnsimple::Response.new(response, response["data"]) + end + end end end diff --git a/spec/dnsimple/client/domain_services_spec.rb b/spec/dnsimple/client/domain_services_spec.rb index 6f5d0f18..f39bde09 100644 --- a/spec/dnsimple/client/domain_services_spec.rb +++ b/spec/dnsimple/client/domain_services_spec.rb @@ -57,4 +57,33 @@ end end + describe "#apply_service" do + let(:account_id) { 1010 } + let(:domain_id) { "example.com" } + let(:service_id) { "service1" } + + before do + stub_request(:post, %r{/v2/#{account_id}/domains/#{domain_id}/services/#{service_id}$}). + to_return(read_http_fixture("applyService/created.http")) + end + + let(:settings) { { app: "foo" } } + + it "builds the correct request" do + subject.apply_service(account_id, domain_id, service_id, settings) + + expect(WebMock).to have_requested(:post, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/services/#{service_id}"). + with(body: settings). + with(headers: { 'Accept' => 'application/json' }) + end + + it "returns empty response" do + response = subject.apply_service(account_id, domain_id, service_id, settings) + expect(response).to be_a(Dnsimple::Response) + + result = response.data + expect(result).to be_nil + end + end + end diff --git a/spec/fixtures.http/applyService/created.http b/spec/fixtures.http/applyService/created.http new file mode 100644 index 00000000..4c290234 --- /dev/null +++ b/spec/fixtures.http/applyService/created.http @@ -0,0 +1,17 @@ +HTTP/1.1 204 No Content +Server: nginx +Date: Sat, 09 Jul 2016 11:12:42 GMT +Connection: keep-alive +X-RateLimit-Limit: 2400 +X-RateLimit-Remaining: 2398 +X-RateLimit-Reset: 1468066326 +Cache-Control: no-cache +X-Request-Id: 30a3a44b-5792-4114-a355-a866603311ce +X-Runtime: 0.087254 +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 + From 3baf076227fd8325baad3d7fe9b380284eb1ddc4 Mon Sep 17 00:00:00 2001 From: Luca Guidi Date: Mon, 18 Jul 2016 10:31:55 +0200 Subject: [PATCH 3/3] Added support for `unapplyService` --- lib/dnsimple/client/domain_services.rb | 22 ++++++++++++++++ spec/dnsimple/client/domain_services_spec.rb | 26 +++++++++++++++++++ .../fixtures.http/unapplyService/success.http | 17 ++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 spec/fixtures.http/unapplyService/success.http diff --git a/lib/dnsimple/client/domain_services.rb b/lib/dnsimple/client/domain_services.rb index f79ae292..426b3680 100644 --- a/lib/dnsimple/client/domain_services.rb +++ b/lib/dnsimple/client/domain_services.rb @@ -44,6 +44,7 @@ def applied_services(account_id, domain_name, options = {}) # @param [Fixnum] account_id the account ID # @param [#to_s] domain_name the domain name # @param [#to_s] service_name the service name (or ID) + # @param [Hash] settings optional settings to apply the one-click service # @param [Hash] options # @return [Dnsimple::Response] # @@ -54,6 +55,27 @@ def apply_service(account_id, domain_name, service_name, settings = {}, options Dnsimple::Response.new(response, response["data"]) end + # Unapply a given one-click service from the domain. + # + # @see https://developer.dnsimple.com/v2/services/domains/#unapply + # + # @example Unapply one-click service service1 from example.com: + # client.domain_services.applied_services(1010, "example.com", "service1") + # + # @param [Fixnum] account_id the account ID + # @param [#to_s] domain_name the domain name + # @param [#to_s] service_name the service name (or ID) + # @param [Hash] options + # @return [Dnsimple::Response] + # + # @raise [RequestError] When the request fails. + def unapply_service(account_id, domain_name, service_name, options = {}) + endpoint = Client.versioned("/%s/domains/%s/services/%s" % [account_id, domain_name, service_name]) + response = client.delete(endpoint, options) + + Dnsimple::Response.new(response, response["data"]) + end + end end end diff --git a/spec/dnsimple/client/domain_services_spec.rb b/spec/dnsimple/client/domain_services_spec.rb index f39bde09..e758f02c 100644 --- a/spec/dnsimple/client/domain_services_spec.rb +++ b/spec/dnsimple/client/domain_services_spec.rb @@ -86,4 +86,30 @@ end end + describe "#unapply_service" do + let(:account_id) { 1010 } + let(:domain_id) { "example.com" } + let(:service_id) { "service1" } + + before do + stub_request(:delete, %r{/v2/#{account_id}/domains/#{domain_id}/services/#{service_id}$}). + to_return(read_http_fixture("unapplyService/success.http")) + end + + it "builds the correct request" do + subject.unapply_service(account_id, domain_id, service_id) + + expect(WebMock).to have_requested(:delete, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/services/#{service_id}"). + with(headers: { 'Accept' => 'application/json' }) + end + + it "returns empty response" do + response = subject.unapply_service(account_id, domain_id, service_id) + expect(response).to be_a(Dnsimple::Response) + + result = response.data + expect(result).to be_nil + end + end + end diff --git a/spec/fixtures.http/unapplyService/success.http b/spec/fixtures.http/unapplyService/success.http new file mode 100644 index 00000000..0f1b9a3c --- /dev/null +++ b/spec/fixtures.http/unapplyService/success.http @@ -0,0 +1,17 @@ +HTTP/1.1 204 No Content +Server: nginx +Date: Sat, 09 Jul 2016 11:13:48 GMT +Connection: keep-alive +X-RateLimit-Limit: 2400 +X-RateLimit-Remaining: 2397 +X-RateLimit-Reset: 1468066326 +Cache-Control: no-cache +X-Request-Id: bb164b01-636a-4d02-acb5-a829afc5ea8c +X-Runtime: 0.070508 +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 +