dnsimple 3.1.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -0
  3. data/.rubocop_dnsimple.yml +24 -18
  4. data/CHANGELOG.md +17 -5
  5. data/CONTRIBUTING.md +2 -2
  6. data/Gemfile +0 -1
  7. data/README.md +14 -3
  8. data/dnsimple.gemspec +1 -1
  9. data/lib/dnsimple/client.rb +5 -5
  10. data/lib/dnsimple/client/certificates.rb +89 -0
  11. data/lib/dnsimple/client/clients.rb +37 -0
  12. data/lib/dnsimple/client/collaborators.rb +76 -0
  13. data/lib/dnsimple/client/domains_pushes.rb +97 -0
  14. data/lib/dnsimple/client/registrar.rb +2 -2
  15. data/lib/dnsimple/client/registrar_delegation.rb +42 -0
  16. data/lib/dnsimple/client/services_domains.rb +82 -0
  17. data/lib/dnsimple/client/templates.rb +0 -5
  18. data/lib/dnsimple/client/templates_domains.rb +29 -0
  19. data/lib/dnsimple/client/vanity_name_servers.rb +47 -0
  20. data/lib/dnsimple/client/zones.rb +17 -0
  21. data/lib/dnsimple/client/zones_records.rb +9 -9
  22. data/lib/dnsimple/struct.rb +6 -1
  23. data/lib/dnsimple/struct/certificate.rb +37 -0
  24. data/lib/dnsimple/struct/certificate_bundle.rb +24 -0
  25. data/lib/dnsimple/struct/collaborator.rb +34 -0
  26. data/lib/dnsimple/struct/domain_push.rb +28 -0
  27. data/lib/dnsimple/struct/tld.rb +12 -0
  28. data/lib/dnsimple/struct/zone_file.rb +10 -0
  29. data/lib/dnsimple/struct/{record.rb → zone_record.rb} +4 -1
  30. data/lib/dnsimple/version.rb +1 -1
  31. data/spec/dnsimple/client/accounts_spec.rb +1 -1
  32. data/spec/dnsimple/client/certificates_spec.rb +206 -0
  33. data/spec/dnsimple/client/collaborators_spec.rb +162 -0
  34. data/spec/dnsimple/client/contacts_spec.rb +5 -5
  35. data/spec/dnsimple/client/domains_email_forwards_spec.rb +5 -5
  36. data/spec/dnsimple/client/domains_pushes_spec.rb +162 -0
  37. data/spec/dnsimple/client/domains_spec.rb +6 -6
  38. data/spec/dnsimple/client/registrar_delegation_spec.rb +51 -0
  39. data/spec/dnsimple/client/registrar_spec.rb +6 -6
  40. data/spec/dnsimple/client/registrar_whois_privacy_spec.rb +4 -4
  41. data/spec/dnsimple/client/services_domains_spec.rb +115 -0
  42. data/spec/dnsimple/client/services_spec.rb +1 -1
  43. data/spec/dnsimple/client/templates_domains_spec.rb +32 -0
  44. data/spec/dnsimple/client/templates_records_spec.rb +1 -1
  45. data/spec/dnsimple/client/templates_spec.rb +25 -1
  46. data/spec/dnsimple/client/tlds_spec.rb +8 -4
  47. data/spec/dnsimple/client/vanity_name_servers_spec.rb +54 -0
  48. data/spec/dnsimple/client/webhooks_spec.rb +2 -2
  49. data/spec/dnsimple/client/zones_records_spec.rb +34 -23
  50. data/spec/dnsimple/client/zones_spec.rb +40 -4
  51. data/spec/fixtures.http/acceptPush/success.http +17 -0
  52. data/spec/fixtures.http/addCollaborator/invite-success.http +21 -0
  53. data/spec/fixtures.http/addCollaborator/success.http +21 -0
  54. data/spec/fixtures.http/appliedServices/success.http +21 -0
  55. data/spec/fixtures.http/applyService/created.http +17 -0
  56. data/spec/fixtures.http/applyTemplate/success.http +13 -0
  57. data/spec/fixtures.http/changeDomainDelegationFromVanity/success.http +17 -0
  58. data/spec/fixtures.http/changeDomainDelegationToVanity/success.http +21 -0
  59. data/spec/fixtures.http/createZoneRecord/created.http +13 -9
  60. data/spec/fixtures.http/disableVanityNameServers/success.http +17 -0
  61. data/spec/fixtures.http/downloadCertificate/success.http +21 -0
  62. data/spec/fixtures.http/enableVanityNameServers/success.http +21 -0
  63. data/spec/fixtures.http/getCertificate/success.http +21 -0
  64. data/spec/fixtures.http/getCertificatePrivateKey/success.http +21 -0
  65. data/spec/fixtures.http/getTld/success.http +13 -9
  66. data/spec/fixtures.http/getZoneFile/success.http +21 -0
  67. data/spec/fixtures.http/getZoneRecord/success.http +13 -9
  68. data/spec/fixtures.http/initiatePush/success.http +21 -0
  69. data/spec/fixtures.http/{accounts → listAccounts}/success-account.http +0 -0
  70. data/spec/fixtures.http/{accounts → listAccounts}/success-user.http +0 -0
  71. data/spec/fixtures.http/listCertificates/success.http +21 -0
  72. data/spec/fixtures.http/listCollaborators/success.http +21 -0
  73. data/spec/fixtures.http/listPushes/success.http +21 -0
  74. data/spec/fixtures.http/listTlds/success.http +13 -9
  75. data/spec/fixtures.http/listZoneRecords/success.http +13 -9
  76. data/spec/fixtures.http/notfound-certificate.http +16 -0
  77. data/spec/fixtures.http/notfound-collaborator.http +16 -0
  78. data/spec/fixtures.http/notfound-contact.http +1 -1
  79. data/spec/fixtures.http/notfound-domainpush.http +12 -0
  80. data/spec/fixtures.http/rejectPush/success.http +17 -0
  81. data/spec/fixtures.http/removeCollaborator/success.http +17 -0
  82. data/spec/fixtures.http/unapplyService/success.http +17 -0
  83. data/spec/fixtures.http/updateZoneRecord/success.http +13 -9
  84. metadata +80 -10
@@ -14,13 +14,17 @@ module Dnsimple
14
14
  end
15
15
 
16
16
  require_relative 'struct/account'
17
+ require_relative 'struct/collaborator'
17
18
  require_relative 'struct/contact'
19
+ require_relative 'struct/certificate'
20
+ require_relative 'struct/certificate_bundle'
18
21
  require_relative 'struct/domain'
19
22
  require_relative 'struct/domain_check'
23
+ require_relative 'struct/domain_push'
20
24
  require_relative 'struct/email_forward'
21
25
  require_relative 'struct/extended_attribute'
22
26
  require_relative 'struct/oauth_token'
23
- require_relative 'struct/record'
27
+ require_relative 'struct/zone_record'
24
28
  require_relative 'struct/service'
25
29
  require_relative 'struct/template'
26
30
  require_relative 'struct/template_record'
@@ -28,5 +32,6 @@ require_relative 'struct/tld'
28
32
  require_relative 'struct/user'
29
33
  require_relative 'struct/whois_privacy'
30
34
  require_relative 'struct/zone'
35
+ require_relative 'struct/zone_file'
31
36
  require_relative 'struct/webhook'
32
37
  require_relative 'struct/whoami'
@@ -0,0 +1,37 @@
1
+ module Dnsimple
2
+ module Struct
3
+
4
+ class Certificate < Base
5
+ # @return [Fixnum] The certificate ID in DNSimple.
6
+ attr_accessor :id
7
+
8
+ # @return [Fixnum] The associated domain ID.
9
+ attr_accessor :domain_id
10
+
11
+ # @return [String] The certificate common name.
12
+ attr_accessor :common_name
13
+
14
+ # @return [Fixnum] The years the certificate will last.
15
+ attr_accessor :years
16
+
17
+ # @return [String] The certificate CSR.
18
+ attr_accessor :csr
19
+
20
+ # @return [String] The certificate state.
21
+ attr_accessor :state
22
+
23
+ # @return [String] The Certificate Authority (CA) that issued the certificate.
24
+ attr_accessor :authority_identifier
25
+
26
+ # @return [String] When the certificate was created in DNSimple.
27
+ attr_accessor :created_at
28
+
29
+ # @return [String] When the certificate was last updated in DNSimple.
30
+ attr_accessor :updated_at
31
+
32
+ # @return [String] When the certificate will expire.
33
+ attr_accessor :expires_on
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,24 @@
1
+ module Dnsimple
2
+ module Struct
3
+
4
+ class CertificateBundle < Base
5
+
6
+ # @return [String] The certificate private key
7
+ attr_accessor :private_key
8
+
9
+ # @return [String] The server certificate
10
+ attr_accessor :server
11
+ alias server_certificate server
12
+
13
+ # @return [String] The root certificate
14
+ attr_accessor :root
15
+ alias root_certificate root
16
+
17
+ # @return [Array<String>] Intermediate certificates
18
+ attr_accessor :chain
19
+ alias intermediate_certificates chain
20
+
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ module Dnsimple
2
+ module Struct
3
+
4
+ class Collaborator < Base
5
+ # @return [Fixnum] The collaborator ID in DNSimple.
6
+ attr_accessor :id
7
+
8
+ # @return [Fixnum] The associated domain ID.
9
+ attr_accessor :domain_id
10
+
11
+ # @return [String] The associated domain name.
12
+ attr_accessor :domain_name
13
+
14
+ # @return [Fixnum,NilClass] The user ID, if the collaborator accepted the invitation.
15
+ attr_accessor :user_id
16
+
17
+ # @return [String] The user email.
18
+ attr_accessor :user_email
19
+
20
+ # @return [TrueClass,FalseClass] Invitation
21
+ attr_accessor :invitation
22
+
23
+ # @return [String] When the collaborator was created in DNSimple.
24
+ attr_accessor :created_at
25
+
26
+ # @return [String] When the collaborator was last updated in DNSimple.
27
+ attr_accessor :updated_at
28
+
29
+ # @return [String,NilClass] When the collaborator has accepted the invitation.
30
+ attr_accessor :accepted_at
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ module Dnsimple
2
+ module Struct
3
+
4
+ class DomainPush < Base
5
+ # @return [Fixnum] The domain push ID in DNSimple.
6
+ attr_accessor :id
7
+
8
+ # @return [Fixnum] The associated domain ID.
9
+ attr_accessor :domain_id
10
+
11
+ # @return [Fixnum] The associated contact ID.
12
+ attr_accessor :contact_id
13
+
14
+ # @return [Fixnum] The associated account ID.
15
+ attr_accessor :account_id
16
+
17
+ # @return [String] When the domain push was created in DNSimple.
18
+ attr_accessor :created_at
19
+
20
+ # @return [String] When the domain push was last updated in DNSimple.
21
+ attr_accessor :updated_at
22
+
23
+ # @return [String] When the domain push was accepted in DNSimple.
24
+ attr_accessor :accepted_at
25
+ end
26
+
27
+ end
28
+ end
@@ -16,6 +16,18 @@ module Dnsimple
16
16
 
17
17
  # @return [Boolean] True if IDN is available.
18
18
  attr_accessor :idn
19
+
20
+ # @return [Fixnum] The minimum registration period, in years.
21
+ attr_accessor :minimum_registration
22
+
23
+ # @return [Boolean] True if DNSimple supports registrations for this TLD.
24
+ attr_accessor :registration_enabled
25
+
26
+ # @return [Boolean] True if DNSimple supports renewals for this TLD.
27
+ attr_accessor :renewal_enabled
28
+
29
+ # @return [Boolean] True if DNSimple supports inbound transfers for this TLD.
30
+ attr_accessor :transfer_enabled
19
31
  end
20
32
 
21
33
  end
@@ -0,0 +1,10 @@
1
+ module Dnsimple
2
+ module Struct
3
+
4
+ class ZoneFile < Base
5
+ # @return [String] The zone file contents.
6
+ attr_accessor :zone
7
+ end
8
+
9
+ end
10
+ end
@@ -1,7 +1,7 @@
1
1
  module Dnsimple
2
2
  module Struct
3
3
 
4
- class Record < Base
4
+ class ZoneRecord < Base
5
5
  # @return [Fixnum] The record ID in DNSimple.
6
6
  attr_accessor :id
7
7
 
@@ -29,6 +29,9 @@ module Dnsimple
29
29
  # @return [Bool] True if this is a system record created by DNSimple. System records are read-only.
30
30
  attr_accessor :system_record
31
31
 
32
+ # @return [Array<String>] The regions where the record is propagated. This is optional.
33
+ attr_accessor :regions
34
+
32
35
  # @return [String] When the record was created in DNSimple.
33
36
  attr_accessor :created_at
34
37
 
@@ -1,3 +1,3 @@
1
1
  module Dnsimple
2
- VERSION = "3.1.0".freeze
2
+ VERSION = "4.0.0".freeze
3
3
  end
@@ -8,7 +8,7 @@ describe Dnsimple::Client, ".accounts" do
8
8
  describe "#accounts" do
9
9
  before do
10
10
  stub_request(:get, %r{/v2/accounts$}).
11
- to_return(read_http_fixture("accounts/success-user.http"))
11
+ to_return(read_http_fixture("listAccounts/success-user.http"))
12
12
  end
13
13
 
14
14
  it "builds the correct request" do
@@ -0,0 +1,206 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dnsimple::Client, ".certificates" do
4
+
5
+ subject { described_class.new(base_url: "https://api.dnsimple.test", access_token: "a1b2c3").certificates }
6
+
7
+ describe "#certificates" do
8
+ let(:account_id) { 1010 }
9
+ let(:domain_id) { "example.com" }
10
+
11
+ before do
12
+ stub_request(:get, %r{/v2/#{account_id}/domains/#{domain_id}/certificates}).
13
+ to_return(read_http_fixture("listCertificates/success.http"))
14
+ end
15
+
16
+ it "builds the correct request" do
17
+ subject.certificates(account_id, domain_id)
18
+
19
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/certificates").
20
+ with(headers: { 'Accept' => 'application/json' })
21
+ end
22
+
23
+ it "supports pagination" do
24
+ subject.certificates(account_id, domain_id, page: 2)
25
+
26
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/certificates?page=2")
27
+ end
28
+
29
+ it "supports extra request options" do
30
+ subject.certificates(account_id, domain_id, query: { foo: "bar" })
31
+
32
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/certificates?foo=bar")
33
+ end
34
+
35
+ it "returns the certificates" do
36
+ response = subject.certificates(account_id, domain_id)
37
+
38
+ expect(response).to be_a(Dnsimple::PaginatedResponse)
39
+ expect(response.data).to be_a(Array)
40
+ expect(response.data.size).to eq(2)
41
+
42
+ response.data.each do |result|
43
+ expect(result).to be_a(Dnsimple::Struct::Certificate)
44
+ expect(result.id).to be_a(Integer)
45
+ end
46
+ end
47
+
48
+ it "exposes the pagination information" do
49
+ response = subject.certificates(account_id, domain_id)
50
+
51
+ expect(response.respond_to?(:page)).to be_truthy
52
+ expect(response.page).to eq(1)
53
+ expect(response.per_page).to be_a(Integer)
54
+ expect(response.total_entries).to be_a(Integer)
55
+ expect(response.total_pages).to be_a(Integer)
56
+ end
57
+ end
58
+
59
+ describe "#certificate" do
60
+ let(:account_id) { 1010 }
61
+ let(:domain_id) { "weppos.net" }
62
+ let(:certificate_id) { 1 }
63
+
64
+ before do
65
+ stub_request(:get, %r{/v2/#{account_id}/domains/#{domain_id}/certificates/#{certificate_id}}).
66
+ to_return(read_http_fixture("getCertificate/success.http"))
67
+ end
68
+
69
+ it "builds the correct request" do
70
+ subject.certificate(account_id, domain_id, certificate_id)
71
+
72
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/certificates/#{certificate_id}").
73
+ with(headers: { 'Accept' => 'application/json' })
74
+ end
75
+
76
+ it "supports extra request options" do
77
+ subject.certificate(account_id, domain_id, certificate_id, query: { foo: "bar" })
78
+
79
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/certificates/#{certificate_id}?foo=bar")
80
+ end
81
+
82
+ it "returns the certificate" do
83
+ response = subject.certificate(account_id, domain_id, certificate_id)
84
+ expect(response).to be_a(Dnsimple::Response)
85
+
86
+ result = response.data
87
+ expect(result).to be_a(Dnsimple::Struct::Certificate)
88
+ expect(result.id).to eq(1)
89
+ expect(result.domain_id).to eq(2)
90
+ expect(result.common_name).to eq("www.weppos.net")
91
+ expect(result.years).to eq(1)
92
+ expect(result.csr).to eq("-----BEGIN CERTIFICATE REQUEST-----\nMIICljCCAX4CAQAwGTEXMBUGA1UEAwwOd3d3LndlcHBvcy5uZXQwggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3MJwx9ahBG3kAwRjQdRvYZqtovUaxY6jp\nhd09975gO+2eYPDbc1yhNftVJ4KBT0zdEqzX0CwIlxE1MsnZ2YOsC7IJO531hMBp\ndBxM4tSG07xPz70AVUi9rY6YCUoJHmxoFbclpHFbtXZocR393WyzUK8047uM2mlz\n03AZKcMdyfeuo2/9TcxpTSCkklGqwqS9wtTogckaDHJDoBunAkMioGfOSMe7Yi6E\nYRtG4yPJYsDaq2yPJWV8+i0PFR1Wi5RCnPt0YdQWstHuZrxABi45+XVkzKtz3TUc\nYxrvPBucVa6uzd953u8CixNFkiOefvb/dajsv1GIwH6/Cvc1ftz1AgMBAAGgODA2\nBgkqhkiG9w0BCQ4xKTAnMCUGA1UdEQQeMByCDnd3dy53ZXBwb3MubmV0ggp3ZXBw\nb3MubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCDnVBO9RdJX0eFeZzlv5c8yG8duhKP\nl0Vl+V88fJylb/cbNj9qFPkKTK0vTXmS2XUFBChKPtLucp8+Z754UswX+QCsdc7U\nTTSG0CkyilcSubdZUERGej1XfrVQhrokk7Fu0Jh3BdT6REP0SIDTpA8ku/aRQiAp\np+h19M37S7+w/DMGDAq2LSX8jOpJ1yIokRDyLZpmwyLxutC21DXMGoJ3xZeUFrUT\nqRNwzkn2dJzgTrPkzhaXalUBqv+nfXHqHaWljZa/O0NVCFrHCdTdd53/6EE2Yabv\nq5SFTkRCpaxrvM/7a8Tr4ixD1/VKD6rw3+WC00000000000000000000\n-----END CERTIFICATE REQUEST-----\n")
93
+ expect(result.state).to eq("issued")
94
+ expect(result.authority_identifier).to eq("letsencrypt")
95
+ expect(result.created_at).to eq("2016-06-11T18:47:08.949Z")
96
+ expect(result.updated_at).to eq("2016-06-11T18:47:37.546Z")
97
+ expect(result.expires_on).to eq("2016-09-09")
98
+ end
99
+
100
+ context "when the certificate does not exist" do
101
+ it "raises NotFoundError" do
102
+ stub_request(:get, %r{/v2}).
103
+ to_return(read_http_fixture("notfound-certificate.http"))
104
+
105
+ expect {
106
+ subject.certificate(account_id, domain_id, certificate_id)
107
+ }.to raise_error(Dnsimple::NotFoundError)
108
+ end
109
+ end
110
+ end
111
+
112
+ describe "#download_certificate" do
113
+ let(:account_id) { 1010 }
114
+ let(:domain_id) { "weppos.net" }
115
+ let(:certificate_id) { 1 }
116
+
117
+ before do
118
+ stub_request(:get, %r{/v2/#{account_id}/domains/#{domain_id}/certificates/#{certificate_id}/download}).
119
+ to_return(read_http_fixture("downloadCertificate/success.http"))
120
+ end
121
+
122
+ it "builds the correct request" do
123
+ subject.download_certificate(account_id, domain_id, certificate_id)
124
+
125
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/certificates/#{certificate_id}/download").
126
+ with(headers: { 'Accept' => 'application/json' })
127
+ end
128
+
129
+ it "supports extra request options" do
130
+ subject.download_certificate(account_id, domain_id, certificate_id, query: { foo: "bar" })
131
+
132
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/certificates/#{certificate_id}/download?foo=bar")
133
+ end
134
+
135
+ it "returns the certificate bundle" do
136
+ response = subject.download_certificate(account_id, domain_id, certificate_id)
137
+ expect(response).to be_a(Dnsimple::Response)
138
+
139
+ result = response.data
140
+ expect(result).to be_a(Dnsimple::Struct::CertificateBundle)
141
+ expect(result.private_key).to be_nil
142
+ expect(result.server_certificate).to eq("-----BEGIN CERTIFICATE-----\nMIIE7TCCA9WgAwIBAgITAPpTe4O3vjuQ9L4gLsogi/ukujANBgkqhkiG9w0BAQsF\nADAiMSAwHgYDVQQDDBdGYWtlIExFIEludGVybWVkaWF0ZSBYMTAeFw0xNjA2MTEx\nNzQ4MDBaFw0xNjA5MDkxNzQ4MDBaMBkxFzAVBgNVBAMTDnd3dy53ZXBwb3MubmV0\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtzCcMfWoQRt5AMEY0HUb\n2GaraL1GsWOo6YXdPfe+YDvtnmDw23NcoTX7VSeCgU9M3RKs19AsCJcRNTLJ2dmD\nrAuyCTud9YTAaXQcTOLUhtO8T8+9AFVIva2OmAlKCR5saBW3JaRxW7V2aHEd/d1s\ns1CvNOO7jNppc9NwGSnDHcn3rqNv/U3MaU0gpJJRqsKkvcLU6IHJGgxyQ6AbpwJD\nIqBnzkjHu2IuhGEbRuMjyWLA2qtsjyVlfPotDxUdVouUQpz7dGHUFrLR7ma8QAYu\nOfl1ZMyrc901HGMa7zwbnFWurs3fed7vAosTRZIjnn72/3Wo7L9RiMB+vwr3NX7c\n9QIDAQABo4ICIzCCAh8wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF\nBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRh9q/3Zxbk4yA/\nt7j+8xA+rkiZBTAfBgNVHSMEGDAWgBTAzANGuVggzFxycPPhLssgpvVoOjB4Bggr\nBgEFBQcBAQRsMGowMwYIKwYBBQUHMAGGJ2h0dHA6Ly9vY3NwLnN0Zy1pbnQteDEu\nbGV0c2VuY3J5cHQub3JnLzAzBggrBgEFBQcwAoYnaHR0cDovL2NlcnQuc3RnLWlu\ndC14MS5sZXRzZW5jcnlwdC5vcmcvMCUGA1UdEQQeMByCCndlcHBvcy5uZXSCDnd3\ndy53ZXBwb3MubmV0MIH+BgNVHSAEgfYwgfMwCAYGZ4EMAQIBMIHmBgsrBgEEAYLf\nEwEBATCB1jAmBggrBgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcw\ngasGCCsGAQUFBwICMIGeDIGbVGhpcyBDZXJ0aWZpY2F0ZSBtYXkgb25seSBiZSBy\nZWxpZWQgdXBvbiBieSBSZWx5aW5nIFBhcnRpZXMgYW5kIG9ubHkgaW4gYWNjb3Jk\nYW5jZSB3aXRoIHRoZSBDZXJ0aWZpY2F0ZSBQb2xpY3kgZm91bmQgYXQgaHR0cHM6\nLy9sZXRzZW5jcnlwdC5vcmcvcmVwb3NpdG9yeS8wDQYJKoZIhvcNAQELBQADggEB\nAEqMdWrmdIyQxthWsX3iHmM2h/wXwEesD0VIaA+Pq4mjwmKBkoPSmHGQ/O4v8RaK\nB6gl8v+qmvCwwqC1SkBmm+9C2yt/P6WhAiA/DD+WppYgJWfcz2lEKrgufFlHPukB\nDzE0mJDuXm09QTApWlaTZWYfWKY50T5uOT/rs+OwGFFCO/8o7v5AZRAHos6uzjvq\nAtFZj/FEnXXMjSSlQ7YKTXToVpnAYH4e3/UMsi6/O4orkVz82ZfhKwMWHV8dXlRw\ntQaemFWTjGPgSLXJAtQO30DgNJBHX/fJEaHv6Wy8TF3J0wOGpzGbOwaTX8YAmEzC\nlzzjs+clg5MN5rd1g4POJtU=\n-----END CERTIFICATE-----\n")
143
+ expect(result.root_certificate).to be_nil
144
+ expect(result.intermediate_certificates).to eq(["-----BEGIN CERTIFICATE-----\nMIIEqzCCApOgAwIBAgIRAIvhKg5ZRO08VGQx8JdhT+UwDQYJKoZIhvcNAQELBQAw\nGjEYMBYGA1UEAwwPRmFrZSBMRSBSb290IFgxMB4XDTE2MDUyMzIyMDc1OVoXDTM2\nMDUyMzIyMDc1OVowIjEgMB4GA1UEAwwXRmFrZSBMRSBJbnRlcm1lZGlhdGUgWDEw\nggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtWKySDn7rWZc5ggjz3ZB0\n8jO4xti3uzINfD5sQ7Lj7hzetUT+wQob+iXSZkhnvx+IvdbXF5/yt8aWPpUKnPym\noLxsYiI5gQBLxNDzIec0OIaflWqAr29m7J8+NNtApEN8nZFnf3bhehZW7AxmS1m0\nZnSsdHw0Fw+bgixPg2MQ9k9oefFeqa+7Kqdlz5bbrUYV2volxhDFtnI4Mh8BiWCN\nxDH1Hizq+GKCcHsinDZWurCqder/afJBnQs+SBSL6MVApHt+d35zjBD92fO2Je56\ndhMfzCgOKXeJ340WhW3TjD1zqLZXeaCyUNRnfOmWZV8nEhtHOFbUCU7r/KkjMZO9\nAgMBAAGjgeMwgeAwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw\nHQYDVR0OBBYEFMDMA0a5WCDMXHJw8+EuyyCm9Wg6MHoGCCsGAQUFBwEBBG4wbDA0\nBggrBgEFBQcwAYYoaHR0cDovL29jc3Auc3RnLXJvb3QteDEubGV0c2VuY3J5cHQu\nb3JnLzA0BggrBgEFBQcwAoYoaHR0cDovL2NlcnQuc3RnLXJvb3QteDEubGV0c2Vu\nY3J5cHQub3JnLzAfBgNVHSMEGDAWgBTBJnSkikSg5vogKNhcI5pFiBh54DANBgkq\nhkiG9w0BAQsFAAOCAgEABYSu4Il+fI0MYU42OTmEj+1HqQ5DvyAeyCA6sGuZdwjF\nUGeVOv3NnLyfofuUOjEbY5irFCDtnv+0ckukUZN9lz4Q2YjWGUpW4TTu3ieTsaC9\nAFvCSgNHJyWSVtWvB5XDxsqawl1KzHzzwr132bF2rtGtazSqVqK9E07sGHMCf+zp\nDQVDVVGtqZPHwX3KqUtefE621b8RI6VCl4oD30Olf8pjuzG4JKBFRFclzLRjo/h7\nIkkfjZ8wDa7faOjVXx6n+eUQ29cIMCzr8/rNWHS9pYGGQKJiY2xmVC9h12H99Xyf\nzWE9vb5zKP3MVG6neX1hSdo7PEAb9fqRhHkqVsqUvJlIRmvXvVKTwNCP3eCjRCCI\nPTAvjV+4ni786iXwwFYNz8l3PmPLCyQXWGohnJ8iBm+5nk7O2ynaPVW0U2W+pt2w\nSVuvdDM5zGv2f9ltNWUiYZHJ1mmO97jSY/6YfdOUH66iRtQtDkHBRdkNBsMbD+Em\n2TgBldtHNSJBfB3pm9FblgOcJ0FSWcUDWJ7vO0+NTXlgrRofRT6pVywzxVo6dND0\nWzYlTWeUVsO40xJqhgUQRER9YLOLxJ0O6C8i0xFxAMKOtSdodMB3RIwt7RFQ0uyt\nn5Z5MqkYhlMI3J1tPRTp1nEt9fyGspBOO05gi148Qasp+3N+svqKomoQglNoAxU=\n-----END CERTIFICATE-----"])
145
+ end
146
+
147
+ context "when the certificate does not exist" do
148
+ it "raises NotFoundError" do
149
+ stub_request(:get, %r{/v2}).
150
+ to_return(read_http_fixture("notfound-certificate.http"))
151
+
152
+ expect {
153
+ subject.download_certificate(account_id, domain_id, certificate_id)
154
+ }.to raise_error(Dnsimple::NotFoundError)
155
+ end
156
+ end
157
+ end
158
+
159
+ describe "#certificate_private_key" do
160
+ let(:account_id) { 1010 }
161
+ let(:domain_id) { "weppos.net" }
162
+ let(:certificate_id) { 1 }
163
+
164
+ before do
165
+ stub_request(:get, %r{/v2/#{account_id}/domains/#{domain_id}/certificates/#{certificate_id}/private_key}).
166
+ to_return(read_http_fixture("getCertificatePrivateKey/success.http"))
167
+ end
168
+
169
+ it "builds the correct request" do
170
+ subject.certificate_private_key(account_id, domain_id, certificate_id)
171
+
172
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/certificates/#{certificate_id}/private_key").
173
+ with(headers: { 'Accept' => 'application/json' })
174
+ end
175
+
176
+ it "supports extra request options" do
177
+ subject.certificate_private_key(account_id, domain_id, certificate_id, query: { foo: "bar" })
178
+
179
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/certificates/#{certificate_id}/private_key?foo=bar")
180
+ end
181
+
182
+ it "returns the certificate bundle" do
183
+ response = subject.certificate_private_key(account_id, domain_id, certificate_id)
184
+ expect(response).to be_a(Dnsimple::Response)
185
+
186
+ result = response.data
187
+ expect(result).to be_a(Dnsimple::Struct::CertificateBundle)
188
+ expect(result.private_key).to eq("-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAtzCcMfWoQRt5AMEY0HUb2GaraL1GsWOo6YXdPfe+YDvtnmDw\n23NcoTX7VSeCgU9M3RKs19AsCJcRNTLJ2dmDrAuyCTud9YTAaXQcTOLUhtO8T8+9\nAFVIva2OmAlKCR5saBW3JaRxW7V2aHEd/d1ss1CvNOO7jNppc9NwGSnDHcn3rqNv\n/U3MaU0gpJJRqsKkvcLU6IHJGgxyQ6AbpwJDIqBnzkjHu2IuhGEbRuMjyWLA2qts\njyVlfPotDxUdVouUQpz7dGHUFrLR7ma8QAYuOfl1ZMyrc901HGMa7zwbnFWurs3f\ned7vAosTRZIjnn72/3Wo7L9RiMB+vwr3NX7c9QIDAQABAoIBAEQx32OlzK34GTKT\nr7Yicmw7xEGofIGa1Q2h3Lut13whsxKLif5X0rrcyqRnoeibacS+qXXrJolIG4rP\nTl8/3wmUDQHs5J+6fJqFM+fXZUCP4AFiFzzhgsPBsVyd0KbWYYrZ0qU7s0ttoRe+\nTGjuHgIe3ip1QKNtx2Xr50YmytDydknmro79J5Gfrub1l2iA8SDm1eBrQ4SFaNQ2\nU709pHeSwX8pTihUX2Zy0ifpr0O1wYQjGLneMoG4rrNQJG/z6iUdhYczwwt1kDRQ\n4WkM2sovFOyxbBfoCQ3Gy/eem7OXfjNKUe47DAVLnPkKbqL/3Lo9FD7kcB8K87Ap\nr/vYrl0CgYEA413RAk7571w5dM+VftrdbFZ+Yi1OPhUshlPSehavro8kMGDEG5Ts\n74wEz2X3cfMxauMpMrBk/XnUCZ20AnWQClK73RB5fzPw5XNv473Tt/AFmt7eLOzl\nOcYrhpEHegtsD/ZaljlGtPqsjQAL9Ijhao03m1cGB1+uxI7FgacdckcCgYEAzkKP\n6xu9+WqOol73cnlYPS3sSZssyUF+eqWSzq2YJGRmfr1fbdtHqAS1ZbyC5fZVNZYV\nml1vfXi2LDcU0qS04JazurVyQr2rJZMTlCWVET1vhik7Y87wgCkLwKpbwamPDmlI\n9GY+fLNEa4yfAOOpvpTJpenUScxyKWH2cdYFOOMCgYBhrJnvffINC/d64Pp+BpP8\nyKN+lav5K6t3AWd4H2rVeJS5W7ijiLTIq8QdPNayUyE1o+S8695WrhGTF/aO3+ZD\nKQufikZHiQ7B43d7xL7BVBF0WK3lateGnEVyh7dIjMOdj92Wj4B6mv2pjQ2VvX/p\nAEWVLCtg24/+zL64VgxmXQKBgGosyXj1Zu2ldJcQ28AJxup3YVLilkNje4AXC2No\n6RCSvlAvm5gpcNGE2vvr9lX6YBKdl7FGt8WXBe/sysNEFfgmm45ZKOBCUn+dHk78\nqaeeQHKHdxMBy7utZWdgSqt+ZS299NgaacA3Z9kVIiSLDS4V2VeW7riujXXP/9TJ\nnxaRAoGBAMWXOfNVzfTyrKff6gvDWH+hqNICLyzvkEn2utNY9Q6WwqGuY9fvP/4Z\nXzc48AOBzUr8OeA4sHKJ79sJirOiWHNfD1swtvyVzsFZb6moiNwD3Ce/FzYCa3lQ\nU8blTH/uqpR2pSC6whzJ/lnSdqHUqhyp00000000000000000000\n-----END RSA PRIVATE KEY-----\n")
189
+ expect(result.server_certificate).to be_nil
190
+ expect(result.root_certificate).to be_nil
191
+ expect(result.intermediate_certificates).to be_nil
192
+ end
193
+
194
+ context "when the certificate does not exist" do
195
+ it "raises NotFoundError" do
196
+ stub_request(:get, %r{/v2}).
197
+ to_return(read_http_fixture("notfound-certificate.http"))
198
+
199
+ expect {
200
+ subject.certificate_private_key(account_id, domain_id, certificate_id)
201
+ }.to raise_error(Dnsimple::NotFoundError)
202
+ end
203
+ end
204
+ end
205
+
206
+ end
@@ -0,0 +1,162 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dnsimple::Client, ".domains" do
4
+
5
+ subject { described_class.new(base_url: "https://api.dnsimple.test", access_token: "a1b2c3").domains }
6
+
7
+
8
+ describe "#collaborators" do
9
+ let(:account_id) { 1010 }
10
+ let(:domain_id) { "example.com" }
11
+
12
+ before do
13
+ stub_request(:get, %r{/v2/#{account_id}/domains/#{domain_id}/collaborators}).
14
+ to_return(read_http_fixture("listCollaborators/success.http"))
15
+ end
16
+
17
+ it "builds the correct request" do
18
+ subject.collaborators(account_id, domain_id)
19
+
20
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/collaborators").
21
+ with(headers: { 'Accept' => 'application/json' })
22
+ end
23
+
24
+ it "supports pagination" do
25
+ subject.collaborators(account_id, domain_id, page: 2)
26
+
27
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/collaborators?page=2")
28
+ end
29
+
30
+ it "supports extra request options" do
31
+ subject.collaborators(account_id, domain_id, query: { foo: "bar" })
32
+
33
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/collaborators?foo=bar")
34
+ end
35
+
36
+ it "returns the collaborators" do
37
+ response = subject.collaborators(account_id, domain_id)
38
+
39
+ expect(response).to be_a(Dnsimple::PaginatedResponse)
40
+ expect(response.data).to be_a(Array)
41
+ expect(response.data.size).to eq(2)
42
+
43
+ response.data.each do |result|
44
+ expect(result).to be_a(Dnsimple::Struct::Collaborator)
45
+ expect(result.id).to be_a(Integer)
46
+ end
47
+ end
48
+
49
+ it "exposes the pagination information" do
50
+ response = subject.collaborators(account_id, domain_id)
51
+
52
+ expect(response.respond_to?(:page)).to be_truthy
53
+ expect(response.page).to eq(1)
54
+ expect(response.per_page).to be_a(Integer)
55
+ expect(response.total_entries).to be_a(Integer)
56
+ expect(response.total_pages).to be_a(Integer)
57
+ end
58
+ end
59
+
60
+ describe "#add_collaborator" do
61
+ let(:account_id) { 1010 }
62
+ let(:domain_id) { "example.com" }
63
+
64
+ context "invite user already registered on DNSimple" do
65
+ before do
66
+ stub_request(:post, %r{/v2/#{account_id}/domains/#{domain_id}/collaborators$}).
67
+ to_return(read_http_fixture("addCollaborator/success.http"))
68
+ end
69
+
70
+ let(:attributes) { { email: "existing-user@example.com" } }
71
+
72
+ it "builds the correct request" do
73
+ subject.add_collaborator(account_id, domain_id, attributes)
74
+
75
+ expect(WebMock).to have_requested(:post, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/collaborators").
76
+ with(body: attributes).
77
+ with(headers: { 'Accept' => 'application/json' })
78
+ end
79
+
80
+ it "returns the contact" do
81
+ response = subject.add_collaborator(account_id, domain_id, attributes)
82
+ expect(response).to be_a(Dnsimple::Response)
83
+
84
+ result = response.data
85
+ expect(result).to be_a(Dnsimple::Struct::Collaborator)
86
+ expect(result.id).to be_a(Integer)
87
+ expect(result.user_id).to be_a(Integer)
88
+ expect(result.accepted_at).to be_a(String)
89
+ expect(result.user_email).to eq(attributes.fetch(:email))
90
+ expect(result.invitation).to be(false)
91
+ end
92
+ end
93
+
94
+ context "invite not registered on DNSimple" do
95
+ before do
96
+ stub_request(:post, %r{/v2/#{account_id}/domains/#{domain_id}/collaborators$}).
97
+ to_return(read_http_fixture("addCollaborator/invite-success.http"))
98
+ end
99
+
100
+ let(:attributes) { { email: "invited-user@example.com" } }
101
+
102
+ it "builds the correct request" do
103
+ subject.add_collaborator(account_id, domain_id, attributes)
104
+
105
+ expect(WebMock).to have_requested(:post, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/collaborators").
106
+ with(body: attributes).
107
+ with(headers: { 'Accept' => 'application/json' })
108
+ end
109
+
110
+ it "returns the contact" do
111
+ response = subject.add_collaborator(account_id, domain_id, attributes)
112
+ expect(response).to be_a(Dnsimple::Response)
113
+
114
+ result = response.data
115
+ expect(result).to be_a(Dnsimple::Struct::Collaborator)
116
+ expect(result.id).to be_a(Integer)
117
+ expect(result.user_id).to be(nil)
118
+ expect(result.accepted_at).to be(nil)
119
+ expect(result.user_email).to eq(attributes.fetch(:email))
120
+ expect(result.invitation).to be(true)
121
+ end
122
+ end
123
+ end
124
+
125
+ describe "#remove_collaborator" do
126
+ let(:account_id) { 1010 }
127
+ let(:domain_id) { "example.com" }
128
+ let(:collaborator_id) { 100 }
129
+
130
+ before do
131
+ stub_request(:delete, %r{/v2/#{account_id}/domains/#{domain_id}/collaborators/.+$}).
132
+ to_return(read_http_fixture("removeCollaborator/success.http"))
133
+ end
134
+
135
+ it "builds the correct request" do
136
+ subject.remove_collaborator(account_id, domain_id, collaborator_id)
137
+
138
+ expect(WebMock).to have_requested(:delete, "https://api.dnsimple.test/v2/#{account_id}/domains/#{domain_id}/collaborators/#{collaborator_id}").
139
+ with(headers: { 'Accept' => 'application/json' })
140
+ end
141
+
142
+ it "returns nothing" do
143
+ response = subject.remove_collaborator(account_id, domain_id, collaborator_id)
144
+ expect(response).to be_a(Dnsimple::Response)
145
+
146
+ result = response.data
147
+ expect(result).to be_nil
148
+ end
149
+
150
+ context "when the collaborator does not exist" do
151
+ it "raises NotFoundError" do
152
+ stub_request(:delete, %r{/v2}).
153
+ to_return(read_http_fixture("notfound-collaborator.http"))
154
+
155
+ expect {
156
+ subject.remove_collaborator(account_id, domain_id, collaborator_id)
157
+ }.to raise_error(Dnsimple::NotFoundError)
158
+ end
159
+ end
160
+ end
161
+
162
+ end