dnsimple 3.1.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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