gandi_v5 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +1 -1
  4. data/.travis.yml +9 -0
  5. data/CHANGELOG.md +15 -0
  6. data/FUNDING.yml +10 -0
  7. data/README.md +7 -17
  8. data/gandi_v5.gemspec +3 -2
  9. data/lib/gandi_v5.rb +24 -10
  10. data/lib/gandi_v5/billing.rb +0 -2
  11. data/lib/gandi_v5/billing/info.rb +0 -2
  12. data/lib/gandi_v5/data.rb +0 -2
  13. data/lib/gandi_v5/data/converter.rb +0 -4
  14. data/lib/gandi_v5/domain.rb +159 -17
  15. data/lib/gandi_v5/domain/availability.rb +0 -3
  16. data/lib/gandi_v5/domain/availability/product.rb +0 -3
  17. data/lib/gandi_v5/domain/live_dns.rb +42 -0
  18. data/lib/gandi_v5/domain/renewal_information.rb +0 -3
  19. data/lib/gandi_v5/email.rb +0 -4
  20. data/lib/gandi_v5/email/forward.rb +108 -0
  21. data/lib/gandi_v5/email/mailbox.rb +0 -2
  22. data/lib/gandi_v5/error.rb +0 -2
  23. data/lib/gandi_v5/live_dns.rb +0 -4
  24. data/lib/gandi_v5/live_dns/domain.rb +1 -144
  25. data/lib/gandi_v5/live_dns/has_zone_records.rb +153 -0
  26. data/lib/gandi_v5/live_dns/zone.rb +1 -146
  27. data/lib/gandi_v5/organization.rb +28 -5
  28. data/lib/gandi_v5/version.rb +1 -1
  29. data/spec/.rubocop.yml +1 -1
  30. data/spec/features/domain_spec.rb +1 -1
  31. data/spec/fixtures/bodies/GandiV5_Billing/{info.yaml → info.yml} +0 -0
  32. data/spec/fixtures/bodies/GandiV5_Domain/{get.yaml → fetch.yml} +0 -0
  33. data/spec/fixtures/bodies/GandiV5_Domain/{fetch_contacts.yaml → fetch_contacts.yml} +0 -0
  34. data/spec/fixtures/bodies/GandiV5_Domain/fetch_glue_records.yml +7 -0
  35. data/spec/fixtures/bodies/GandiV5_Domain/fetch_livedns.yml +6 -0
  36. data/spec/fixtures/bodies/GandiV5_Domain/fetch_name_servers.yml +2 -0
  37. data/spec/fixtures/bodies/GandiV5_Domain/{renewal_info.yaml → fetch_renewal_info.yml} +0 -3
  38. data/spec/fixtures/bodies/GandiV5_Domain/{restore_info.yaml → fetch_restore_info.yml} +0 -0
  39. data/spec/fixtures/bodies/GandiV5_Domain/{list.yaml → list.yml} +1 -0
  40. data/spec/fixtures/bodies/GandiV5_Domain_Availability/{fetch.yaml → fetch.yml} +0 -0
  41. data/spec/fixtures/bodies/GandiV5_Domain_TLD/{fetch.yaml → fetch.yml} +0 -0
  42. data/spec/fixtures/bodies/GandiV5_Domain_TLD/{list.yaml → list.yml} +0 -0
  43. data/spec/fixtures/bodies/GandiV5_Email_Forward/list.yml +6 -0
  44. data/spec/fixtures/bodies/GandiV5_Email_Mailbox/{get.yaml → fetch.yml} +0 -0
  45. data/spec/fixtures/bodies/GandiV5_Email_Mailbox/{list.yaml → list.yml} +0 -0
  46. data/spec/fixtures/bodies/GandiV5_Email_Slot/{get.yaml → fetch.yml} +0 -0
  47. data/spec/fixtures/bodies/GandiV5_Email_Slot/{list.yaml → list.yml} +0 -0
  48. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/{get.yaml → fetch.yml} +0 -0
  49. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/{list.yaml → list.yml} +0 -0
  50. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/{get.yaml → fetch.yml} +0 -0
  51. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/{list.yaml → list.yml} +0 -0
  52. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/{fetch.yaml → fetch.yml} +0 -0
  53. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/{list.yaml → list.yml} +0 -0
  54. data/spec/fixtures/bodies/GandiV5_Organization/{get.yaml → fetch.yml} +0 -0
  55. data/spec/fixtures/bodies/GandiV5_Organization/list.yml +7 -0
  56. data/spec/fixtures/vcr/Domain_features/List_domains.yml +2 -1
  57. data/spec/spec_helper.rb +2 -2
  58. data/spec/units/gandi_v5/billing_spec.rb +2 -2
  59. data/spec/units/gandi_v5/domain/availability_spec.rb +1 -1
  60. data/spec/units/gandi_v5/domain/live_dns_spec.rb +45 -0
  61. data/spec/units/gandi_v5/domain/tld_spec.rb +2 -2
  62. data/spec/units/gandi_v5/domain_spec.rb +241 -22
  63. data/spec/units/gandi_v5/email/forward_spec.rb +121 -0
  64. data/spec/units/gandi_v5/email/mailbox_spec.rb +3 -3
  65. data/spec/units/gandi_v5/email/slot_spec.rb +3 -3
  66. data/spec/units/gandi_v5/live_dns/domain_spec.rb +3 -3
  67. data/spec/units/gandi_v5/live_dns/zone/snapshot_spec.rb +2 -2
  68. data/spec/units/gandi_v5/live_dns/zone_spec.rb +2 -2
  69. data/spec/units/gandi_v5/organization_spec.rb +38 -1
  70. metadata +51 -77
  71. data/doc/GandiV5.html +0 -1183
  72. data/doc/GandiV5/Billing.html +0 -293
  73. data/doc/GandiV5/Billing/Info.html +0 -641
  74. data/doc/GandiV5/Billing/Info/Prepaid.html +0 -817
  75. data/doc/GandiV5/Data.html +0 -785
  76. data/doc/GandiV5/Data/ClassMethods.html +0 -223
  77. data/doc/GandiV5/Data/Converter.html +0 -433
  78. data/doc/GandiV5/Data/Converter/ArrayOf.html +0 -413
  79. data/doc/GandiV5/Data/Converter/Symbol.html +0 -322
  80. data/doc/GandiV5/Data/Converter/Time.html +0 -330
  81. data/doc/GandiV5/Domain.html +0 -16847
  82. data/doc/GandiV5/Domain/AutoRenew.html +0 -1237
  83. data/doc/GandiV5/Domain/Availability.html +0 -1020
  84. data/doc/GandiV5/Domain/Availability/Product.html +0 -988
  85. data/doc/GandiV5/Domain/Availability/Product/Period.html +0 -220
  86. data/doc/GandiV5/Domain/Availability/Product/Price.html +0 -1031
  87. data/doc/GandiV5/Domain/Availability/Tax.html +0 -440
  88. data/doc/GandiV5/Domain/Contact.html +0 -4459
  89. data/doc/GandiV5/Domain/Contract.html +0 -520
  90. data/doc/GandiV5/Domain/Dates.html +0 -1313
  91. data/doc/GandiV5/Domain/RenewalInformation.html +0 -1147
  92. data/doc/GandiV5/Domain/RestoreInformation.html +0 -339
  93. data/doc/GandiV5/Domain/SharingSpace.html +0 -437
  94. data/doc/GandiV5/Domain/TLD.html +0 -1565
  95. data/doc/GandiV5/Email.html +0 -144
  96. data/doc/GandiV5/Email/Mailbox.html +0 -6307
  97. data/doc/GandiV5/Email/Mailbox/Responder.html +0 -1560
  98. data/doc/GandiV5/Email/Offer.html +0 -514
  99. data/doc/GandiV5/Email/Slot.html +0 -4244
  100. data/doc/GandiV5/Error.html +0 -151
  101. data/doc/GandiV5/Error/GandiError.html +0 -270
  102. data/doc/GandiV5/LiveDNS.html +0 -300
  103. data/doc/GandiV5/LiveDNS/Domain.html +0 -2984
  104. data/doc/GandiV5/LiveDNS/RecordSet.html +0 -1593
  105. data/doc/GandiV5/LiveDNS/Zone.html +0 -8891
  106. data/doc/GandiV5/LiveDNS/Zone/Snapshot.html +0 -1556
  107. data/doc/GandiV5/Organization.html +0 -2341
  108. data/doc/_index.html +0 -474
  109. data/doc/class_list.html +0 -51
  110. data/doc/css/common.css +0 -1
  111. data/doc/css/full_list.css +0 -58
  112. data/doc/css/style.css +0 -496
  113. data/doc/file.README.html +0 -175
  114. data/doc/file_list.html +0 -56
  115. data/doc/frames.html +0 -17
  116. data/doc/index.html +0 -175
  117. data/doc/js/app.js +0 -303
  118. data/doc/js/full_list.js +0 -216
  119. data/doc/js/jquery.js +0 -4
  120. data/doc/method_list.html +0 -2427
  121. data/doc/top-level-namespace.html +0 -110
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'zone/snapshot'
4
-
5
3
  class GandiV5
6
4
  class LiveDNS
7
5
  # A zone within the LiveDNS system.
@@ -28,6 +26,7 @@ class GandiV5
28
26
  # @return [String] primary name server, as reported in SOA record.
29
27
  class Zone
30
28
  include GandiV5::Data
29
+ include GandiV5::LiveDNS::HasZoneRecords
31
30
 
32
31
  members :uuid, :name
33
32
  member :sharing_uuid, gandi_key: 'sharing_id'
@@ -53,150 +52,6 @@ class GandiV5
53
52
  ')'
54
53
  end
55
54
 
56
- # @overload fetch_records()
57
- # Fetch all records for this zone.
58
- # @overload fetch_records(name)
59
- # Fetch records for a name.
60
- # @param name [String] the name to fetch records for.
61
- # @overload fetch_records(name, type)
62
- # Fetch records of a type for a name.
63
- # @param name [String] the name to fetch records for.
64
- # @param type [String] the record type to fetch.
65
- # @return [Array<GandiV5::LiveDNS::RecordSet>]
66
- # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
67
- def fetch_records(name = nil, type = nil)
68
- GandiV5::LiveDNS.require_valid_record_type type if type
69
-
70
- url_ = "#{url}/records"
71
- url_ += "/#{CGI.escape name}" if name
72
- url_ += "/#{CGI.escape type}" if type
73
-
74
- _response, data = GandiV5.get url_
75
- data = [data] unless data.is_a?(Array)
76
- data.map { |item| GandiV5::LiveDNS::RecordSet.from_gandi item }
77
- end
78
-
79
- # @overload fetch_zone_lines()
80
- # Fetch all records for this zone.
81
- # @overload fetch_zone_lines(name)
82
- # Fetch records for a name.
83
- # @param name [String] the name to fetch records for.
84
- # @overload fetch_zone_lines(name, type)
85
- # Fetch records of a type for a name.
86
- # @param name [String] the name to fetch records for.
87
- # @param type [String] the record type to fetch.
88
- # @return [String]
89
- # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
90
- def fetch_zone_lines(name = nil, type = nil)
91
- GandiV5::LiveDNS.require_valid_record_type type if type
92
-
93
- url_ = "#{url}/records"
94
- url_ += "/#{CGI.escape name}" if name
95
- url_ += "/#{CGI.escape type}" if type
96
-
97
- GandiV5.get(url_, accept: 'text/plain').last
98
- end
99
-
100
- # Add record to this zone.
101
- # @param name [String]
102
- # @param type [String]
103
- # @param ttl [Integer]
104
- # @param values [Array<String>]
105
- # @return [String] The confirmation message from Gandi.
106
- # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
107
- def add_record(name, type, ttl, *values)
108
- GandiV5::LiveDNS.require_valid_record_type type
109
- fail ArgumentError, 'ttl must be positive and non-zero' unless ttl.positive?
110
- fail ArgumentError, 'there must be at least one value' if values.none?
111
-
112
- body = {
113
- rrset_name: name,
114
- rrset_type: type,
115
- rrset_ttl: ttl,
116
- rrset_values: values
117
- }.to_json
118
- _response, data = GandiV5.post "#{url}/records", body
119
- data['message']
120
- end
121
-
122
- # @overload delete_records()
123
- # Delete all records for this zone.
124
- # @overload delete_records(name)
125
- # Delete records for a name.
126
- # @param name [String] the name to delete records for.
127
- # @overload delete_records(name, type)
128
- # Delete records of a type for a name.
129
- # @param name [String] the name to delete records for.
130
- # @param type [String] the record type to delete.
131
- # @return [nil]
132
- # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
133
- def delete_records(name = nil, type = nil)
134
- GandiV5::LiveDNS.require_valid_record_type type if type
135
-
136
- url_ = "#{url}/records"
137
- url_ += "/#{CGI.escape name}" if name
138
- url_ += "/#{CGI.escape type}" if type
139
- GandiV5.delete(url_).last
140
- end
141
-
142
- # Replace all records for this zone.
143
- # @param records
144
- # [Array<Hash<:name, :type => String, :ttl => Integer, :values => Array<String>>>]
145
- # the records to add.
146
- # @param text [String] zone file lines to replace the records with.
147
- # @return [String] The confirmation message from Gandi.
148
- # @raise [ArgumentError] if neither/both of records & test are passed.
149
- # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
150
- def replace_records(records: nil, text: nil)
151
- unless [records, text].one?(&:nil?)
152
- fail ArgumentError, 'you must pass ONE of records: or text:'
153
- end
154
-
155
- if records
156
- body = {
157
- items: records.map { |r| r.transform_keys { |k| "rrset_#{k}" } }
158
- }.to_json
159
- _response, data = GandiV5.put "#{url}/records", body
160
- elsif text
161
- _response, data = GandiV5.put "#{url}/records", text, 'content-type': 'text/plain'
162
- end
163
- data['message']
164
- end
165
-
166
- # @override replace_records_for(name, records)
167
- # Replace records for a name in this zone.
168
- # @param name [String]
169
- # @param records
170
- # [Array<Hash<type: String, ttl: Integer, values: Array<String>>>]
171
- # the records to add.
172
- # @override replace_records_for(name, values, type: nil, ttl: nil)
173
- # Replace records for a name in this zone.
174
- # @param name [String]
175
- # @param type [String] the record type.
176
- # @param ttl [Integer] the TTL to set for the record.
177
- # @param values [Array<String>] the values to set for the record.
178
- # @raise [ArgumentError] if ttl is present and type is absent.
179
- # @return [String] The confirmation message from Gandi.
180
- # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
181
- def replace_records_for(name, records, type: nil, ttl: nil)
182
- fail ArgumentError, 'missing keyword: type' if ttl && type.nil?
183
-
184
- if type
185
- GandiV5::LiveDNS.require_valid_record_type type
186
- body = { rrset_values: records, rrset_ttl: ttl }
187
- # body[:rrset_ttl] = ttl if ttl
188
- _response, data = GandiV5.put "#{url}/records/#{name}/#{type}", body.to_json
189
-
190
- else
191
- body = {
192
- items: records.map { |r| r.transform_keys { |k| "rrset_#{k}" } }
193
- }
194
- _response, data = GandiV5.put "#{url}/records/#{name}", body.to_json
195
- end
196
-
197
- data['message']
198
- end
199
-
200
55
  # List the domains that use this zone.
201
56
  # @return [Array<String>] The FQDNs.
202
57
  # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'email/mailbox'
4
- require_relative 'email/offer'
5
- require_relative 'email/slot'
6
-
7
3
  class GandiV5
8
4
  # The Organization API is a read-only API.
9
5
  # All organization management must be performed via the web interface.
@@ -59,8 +55,35 @@ class GandiV5
59
55
  # @return [GandiV5::Organization]
60
56
  # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
61
57
  def self.fetch
62
- _response, data = GandiV5.get "#{BASE}organization/user-info"
58
+ _response, data = GandiV5.get "#{url}/user-info"
63
59
  from_gandi data
64
60
  end
61
+
62
+ # List organisations.
63
+ # @see https://api.gandi.net/docs/domains#get-v5-organization-organizations
64
+ # @param name [String, #to_s] (optional)
65
+ # filters the list by name, with optional patterns.
66
+ # e.g. "alice", "ali*", "*ice"
67
+ # @param type [String, #to_s] (optional)
68
+ # filters the list by type of organization.
69
+ # One of: "individual", "company", "association", "publicbody"
70
+ # @param permission [String, #to_s] (optional)
71
+ # filters the list by the permission the authenticated user
72
+ # has on that organization and products in it.
73
+ # @param sort_by [String, #to_s] (optional default "name") how to sort the list.
74
+ # @return [Array<GandiV5::Organization>]
75
+ # @raise [GandiV5::Error::GandiError] if Gandi returns an error.
76
+ def self.list(**params)
77
+ params['~name'] = params.delete(:name) if params.key?(:name)
78
+ _resp, data = GandiV5.get "#{url}/organizations", params: params
79
+ data.map { |organisation| from_gandi organisation }
80
+ end
81
+
82
+ private
83
+
84
+ def self.url
85
+ "#{BASE}organization"
86
+ end
87
+ private_class_method :url
65
88
  end
66
89
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class GandiV5
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
@@ -1,4 +1,4 @@
1
1
  Metrics/BlockLength:
2
- Max: 500
2
+ Max: 750
3
3
  Metrics/LineLength:
4
4
  Max: 125
@@ -7,7 +7,7 @@ describe 'Domain features' do
7
7
  expect(list.count).to eq 1
8
8
  expect(list.first.fqdn).to eq 'example.net'
9
9
  expect(list.first.fqdn_unicode).to eq 'example.net'
10
- expect(list.first.name_servers).to be nil
10
+ expect(list.first.name_servers).to eq []
11
11
  expect(list.first.services).to be nil
12
12
  expect(list.first.sharing_space).to be nil
13
13
  expect(list.first.status).to match_array [:clientTransferProhibited]
@@ -0,0 +1,7 @@
1
+ ---
2
+ - name: ns1
3
+ fqdn: example.com
4
+ fqdn_unicode: example.com
5
+ href: http://api.test/v5/domain/domains/example.com/hosts/ns1
6
+ ips:
7
+ - '1.2.3.4'
@@ -0,0 +1,6 @@
1
+ ---
2
+ current: livedns
3
+ nameservers:
4
+ - '1.2.3.4'
5
+ dnssec_available: true
6
+ livednssec_available: true
@@ -7,6 +7,3 @@ renew:
7
7
  maximum: 2
8
8
  minimum: 1
9
9
  prohibited: false
10
- contracts:
11
- - id: uuid
12
- name: Name
@@ -18,3 +18,4 @@
18
18
  current: livedns
19
19
  href: https://api.gandi.net/v5/domain/domains/example.com
20
20
  fqdn_unicode: example.com
21
+ nameservers: []
@@ -0,0 +1,6 @@
1
+ ---
2
+ - source: alice
3
+ href: https://api.test/api/v5/email/forwards/example.com/alice
4
+ destinations:
5
+ - bob@example.com
6
+ - charlie@example.com
@@ -0,0 +1,7 @@
1
+ ---
2
+ - id: organization-uuid
3
+ name: FirstLast
4
+ corporate: false
5
+ firstname: First
6
+ lastname: Last
7
+ reseller: false
@@ -46,7 +46,8 @@ http_interactions:
46
46
  "current": "livedns"
47
47
  },
48
48
  "href": "https://api.test/v5/domain/domains/example.net",
49
- "fqdn_unicode": "example.net"
49
+ "fqdn_unicode": "example.net",
50
+ "nameservers": []
50
51
  }
51
52
  ]
52
53
  http_version:
@@ -13,12 +13,12 @@ allow_http_connections_to = %w[localhost 127.0.0.1]
13
13
 
14
14
  Dotenv.load File.join(__dir__, 'test.env')
15
15
 
16
- SimpleCov.coverage_dir(File.join('tmp', 'coverage'))
16
+ SimpleCov.coverage_dir(File.join('tmp', 'coverage')) unless ENV.key?('TRAVIS')
17
17
  SimpleCov.start do
18
18
  add_filter 'spec/'
19
19
  end
20
20
 
21
- if ENV['TRAVIS']
21
+ if ENV.key?('TRAVIS')
22
22
  Coveralls.wear!
23
23
  allow_http_connections_to.push 'coveralls.io'
24
24
  end
@@ -4,7 +4,7 @@ describe GandiV5::Billing do
4
4
  describe '.info' do
5
5
  subject { described_class.info }
6
6
  before :each do
7
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Billing', 'info.yaml'))
7
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Billing', 'info.yml'))
8
8
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/billing/info')
9
9
  .and_return([nil, YAML.load_file(body_fixture)])
10
10
  end
@@ -23,7 +23,7 @@ describe GandiV5::Billing do
23
23
  describe '.info (for a sharing_id)' do
24
24
  subject { described_class.info('sharing-id') }
25
25
  before :each do
26
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Billing', 'info.yaml'))
26
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Billing', 'info.yml'))
27
27
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/billing/info/sharing-id')
28
28
  .and_return([nil, YAML.load_file(body_fixture)])
29
29
  end
@@ -3,7 +3,7 @@
3
3
  describe GandiV5::Domain::Availability do
4
4
  describe '.fetch' do
5
5
  let(:body_fixture) do
6
- File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain_Availability', 'fetch.yaml'))
6
+ File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain_Availability', 'fetch.yml'))
7
7
  end
8
8
 
9
9
  describe 'With default values' do
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GandiV5::Domain::LiveDNS do
4
+ describe '#classic?' do
5
+ it 'Is using classic DNS' do
6
+ expect(described_class.new(current: :classic).classic?).to be true
7
+ end
8
+
9
+ it 'Is using LiveDNS' do
10
+ expect(described_class.new(current: :livedns).classic?).to be false
11
+ end
12
+
13
+ it 'Is using custom DNS' do
14
+ expect(described_class.new(current: :custom).classic?).to be false
15
+ end
16
+ end
17
+
18
+ describe '#livedns?' do
19
+ it 'Is using classic DNS' do
20
+ expect(described_class.new(current: :classic).livedns?).to be false
21
+ end
22
+
23
+ it 'Is using LiveDNS' do
24
+ expect(described_class.new(current: :livedns).livedns?).to be true
25
+ end
26
+
27
+ it 'Is using custom DNS' do
28
+ expect(described_class.new(current: :custom).livedns?).to be false
29
+ end
30
+ end
31
+
32
+ describe '#custom?' do
33
+ it 'Is using classic DNS' do
34
+ expect(described_class.new(current: :classic).custom?).to be false
35
+ end
36
+
37
+ it 'Is using LiveDNS' do
38
+ expect(described_class.new(current: :livedns).custom?).to be false
39
+ end
40
+
41
+ it 'Is using custom DNS' do
42
+ expect(described_class.new(current: :custom).custom?).to be true
43
+ end
44
+ end
45
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  describe GandiV5::Domain::TLD do
4
4
  it '.list' do
5
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain_TLD', 'list.yaml'))
5
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain_TLD', 'list.yml'))
6
6
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/tlds')
7
7
  .and_return([nil, YAML.load_file(body_fixture)])
8
8
  expect(described_class.list.map(&:name)).to match_array %w[a b c]
@@ -12,7 +12,7 @@ describe GandiV5::Domain::TLD do
12
12
  subject { described_class.fetch 'name' }
13
13
 
14
14
  before(:each) do
15
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain_TLD', 'fetch.yaml'))
15
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain_TLD', 'fetch.yml'))
16
16
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/tlds/name')
17
17
  .and_return([nil, YAML.load_file(body_fixture)])
18
18
  end
@@ -4,7 +4,7 @@ describe GandiV5::Domain do
4
4
  subject { described_class.new fqdn: 'example.com' }
5
5
 
6
6
  describe '.list' do
7
- let(:body_fixture) { File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'list.yaml')) }
7
+ let(:body_fixture) { File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'list.yml')) }
8
8
 
9
9
  describe 'With default values' do
10
10
  subject { described_class.list }
@@ -19,7 +19,7 @@ describe GandiV5::Domain do
19
19
  its('first.uuid') { should eq 'domain-uuid' }
20
20
  its('first.fqdn') { should eq 'example.com' }
21
21
  its('first.fqdn_unicode') { should eq 'example.com' }
22
- its('first.name_servers') { should be_nil }
22
+ its('first.name_servers') { should eq [] }
23
23
  its('first.services') { should be_nil }
24
24
  its('first.status') { should eq [] }
25
25
  its('first.tld') { should eq 'com' }
@@ -89,7 +89,7 @@ describe GandiV5::Domain do
89
89
  subject { described_class.fetch 'example.com' }
90
90
 
91
91
  before :each do
92
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'get.yaml'))
92
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch.yml'))
93
93
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com')
94
94
  .and_return([nil, YAML.load_file(body_fixture)])
95
95
  end
@@ -128,13 +128,13 @@ describe GandiV5::Domain do
128
128
 
129
129
  describe '.create' do
130
130
  let(:url) { 'https://api.gandi.net/v5/domain/domains' }
131
+ let(:returns) { double described_class }
132
+ let(:response) { double RestClient::Response, headers: { location: 'https://api.gandi.net/v5/domains/example.com' } }
131
133
 
132
134
  describe 'Sets dry-run header' do
133
135
  let(:body) { '{"owner":{},"fqdn":"example.com"}' }
134
136
 
135
137
  it 'False by default' do
136
- returns = double described_class
137
- response = double RestClient::Response, headers: { location: 'https://api.gandi.net/v5/domains/example.com' }
138
138
  expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0).and_return([response, nil])
139
139
  expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
140
140
  described_class.create 'example.com', owner: {}
@@ -146,8 +146,6 @@ describe GandiV5::Domain do
146
146
  end
147
147
 
148
148
  it 'False' do
149
- returns = double described_class
150
- response = double RestClient::Response, headers: { location: 'https://api.gandi.net/v5/domains/example.com' }
151
149
  expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0).and_return([response, nil])
152
150
  expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
153
151
  described_class.create 'example.com', owner: {}, dry_run: false
@@ -171,12 +169,29 @@ describe GandiV5::Domain do
171
169
  end
172
170
  end
173
171
 
172
+ describe 'Sets sharing_id' do
173
+ it 'Absent by default' do
174
+ expect(GandiV5).to receive(:post).with(url, any_args).and_return([response, nil])
175
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
176
+ described_class.create('example.com', owner: {})
177
+ end
178
+
179
+ it 'Paying as another organization' do
180
+ expect(GandiV5).to receive(:post).with("#{url}?sharing_id=organization_id", any_args).and_return([response, nil])
181
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
182
+ described_class.create('example.com', sharing_id: 'organization_id', owner: {})
183
+ end
184
+
185
+ it 'Buy as a reseller' do
186
+ expect(GandiV5).to receive(:post).with("#{url}?sharing_id=reseller_id", any_args).and_return([response, nil])
187
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
188
+ described_class.create('example.com', sharing_id: 'reseller_id', owner: {})
189
+ end
190
+ end
191
+
174
192
  it 'Success' do
175
- returns = double described_class
176
- response = double RestClient::Response, headers: { location: 'https://api.gandi.net/v5/domains/example.com' }
177
193
  body = '{"owner":{},"fqdn":"example.com"}'
178
- expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
179
- .and_return([response, nil])
194
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0).and_return([response, nil])
180
195
  expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
181
196
  expect(described_class.create('example.com', owner: {})).to be returns
182
197
  end
@@ -186,18 +201,14 @@ describe GandiV5::Domain do
186
201
  end
187
202
 
188
203
  it 'Given contact as hash' do
189
- returns = double described_class
190
204
  body = '{"owner":{"email":"owner@example.com"},"fqdn":"example.com"}'
191
- response = double RestClient::Response, headers: { location: 'https://api.gandi.net/v5/domains/example.com' }
192
205
  expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0).and_return([response, nil])
193
206
  expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
194
207
  described_class.create 'example.com', owner: { email: 'owner@example.com' }
195
208
  end
196
209
 
197
210
  it 'Given contact as GandiV5::Domain::Contact' do
198
- returns = double described_class
199
211
  body = '{"owner":{"email":"owner@example.com"},"fqdn":"example.com"}'
200
- response = double RestClient::Response, headers: { location: 'https://api.gandi.net/v5/domains/example.com' }
201
212
  expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0).and_return([response, nil])
202
213
  expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
203
214
  owner = double GandiV5::Domain::Contact, to_gandi: { 'email' => 'owner@example.com' }
@@ -205,6 +216,24 @@ describe GandiV5::Domain do
205
216
  end
206
217
  end
207
218
 
219
+ it '.mailboxes' do
220
+ returns = double Array
221
+ expect(GandiV5::Email::Mailbox).to receive(:list).with(param: :value, fqdn: 'example.com').and_return(returns)
222
+ expect(subject.mailboxes(param: :value)).to be returns
223
+ end
224
+
225
+ it '.mailbox_slots' do
226
+ returns = double Array
227
+ expect(GandiV5::Email::Slot).to receive(:list).with(param: :value, fqdn: 'example.com').and_return(returns)
228
+ expect(subject.mailbox_slots(param: :value)).to be returns
229
+ end
230
+
231
+ it '.email_forwards' do
232
+ returns = double Array
233
+ expect(GandiV5::Email::Forward).to receive(:list).with(param: :value, fqdn: 'example.com').and_return(returns)
234
+ expect(subject.email_forwards(param: :value)).to be returns
235
+ end
236
+
208
237
  describe '#to_s' do
209
238
  it 'Has identical fqdn and fqdn_unicode' do
210
239
  domain = described_class.new fqdn: 'example.com', fqdn_unicode: 'example.com'
@@ -219,7 +248,7 @@ describe GandiV5::Domain do
219
248
 
220
249
  describe '#refresh' do
221
250
  before :each do
222
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'get.yaml'))
251
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch.yml'))
223
252
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com')
224
253
  .and_return([nil, YAML.load_file(body_fixture)])
225
254
  subject.refresh
@@ -275,7 +304,7 @@ describe GandiV5::Domain do
275
304
  subject { described_class.new(fqdn: 'example.com').fetch_contacts }
276
305
 
277
306
  before(:each) do
278
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_contacts.yaml'))
307
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_contacts.yml'))
279
308
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/contacts')
280
309
  .and_return([nil, YAML.load_file(body_fixture)])
281
310
  end
@@ -332,7 +361,7 @@ describe GandiV5::Domain do
332
361
  subject { described_class.new(fqdn: 'example.com').fetch_renewal_information }
333
362
 
334
363
  before(:each) do
335
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'renewal_info.yaml'))
364
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_renewal_info.yml'))
336
365
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/renew')
337
366
  .and_return([nil, YAML.load_file(body_fixture)])
338
367
  end
@@ -342,9 +371,6 @@ describe GandiV5::Domain do
342
371
  its('minimum') { should eq 1 }
343
372
  its('maximum') { should eq 2 }
344
373
  its('durations') { should match_array [1, 2] }
345
- its('contracts.count') { should eq 1 }
346
- its('contracts.first.id') { should eq 'uuid' }
347
- its('contracts.first.name') { should eq 'Name' }
348
374
  end
349
375
 
350
376
  it '#renew_for' do
@@ -428,7 +454,8 @@ describe GandiV5::Domain do
428
454
 
429
455
  describe 'Information is available' do
430
456
  before(:each) do
431
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'restore_info.yaml'))
457
+ body_fixture = File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_restore_info.yml')
458
+ body_fixture = File.expand_path(body_fixture)
432
459
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/restore')
433
460
  .and_return([nil, YAML.load_file(body_fixture)])
434
461
  end
@@ -456,4 +483,196 @@ describe GandiV5::Domain do
456
483
  expect(subject.restore).to eq 'Confirmation message.'
457
484
  end
458
485
  end
486
+
487
+ describe '#glue_records' do
488
+ let(:glue_records) { double Hash }
489
+
490
+ it 'Already fetched' do
491
+ subject.instance_exec(glue_records) { |glue_records| @glue_records = glue_records }
492
+ expect(subject).to_not receive(:fetch_glue_records)
493
+ expect(subject.glue_records).to be glue_records
494
+ end
495
+
496
+ it 'Not already fetched' do
497
+ expect(subject).to receive(:fetch_glue_records).and_return(glue_records)
498
+ expect(subject.glue_records).to be glue_records
499
+ end
500
+ end
501
+
502
+ it '#fetch_glue_records' do
503
+ body_fixture = File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_glue_records.yml')
504
+ body_fixture = File.expand_path(body_fixture)
505
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/hosts')
506
+ .and_return([nil, YAML.load_file(body_fixture)])
507
+ expect(subject.fetch_glue_records).to eq(
508
+ 'ns1' => ['1.2.3.4']
509
+ )
510
+ end
511
+
512
+ describe '#add_glue_record' do
513
+ before(:each) { described_class.instance_exec { @glue_records = {} } }
514
+
515
+ it 'Make API request' do
516
+ expect(GandiV5).to receive(:post).with(
517
+ 'https://api.gandi.net/v5/domain/domains/example.com/hosts',
518
+ '{"name":"ns1","ips":["1.2.3.4"]}'
519
+ )
520
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
521
+ expect(subject.add_glue_record('ns1', '1.2.3.4')).to eq 'Confirmation message.'
522
+ end
523
+
524
+ it 'Updates glue records' do
525
+ expect(GandiV5).to receive(:post).and_return([nil, { 'message' => 'Confirmation message.' }])
526
+ subject.add_glue_record 'ns1', '1.2.3.4'
527
+ expect(subject.glue_records).to eq('ns1' => ['1.2.3.4'])
528
+ end
529
+ end
530
+
531
+ describe '#glue_record' do
532
+ before(:each) { subject.instance_exec { @glue_records = { 'ns1' => ['1.2.3.4'] } } }
533
+
534
+ it 'Already fetched' do
535
+ expect(subject).to_not receive(:fetch_glue_records)
536
+ expect(subject.glue_record('ns1')).to eq('ns1' => ['1.2.3.4'])
537
+ end
538
+
539
+ it 'Not already fetched' do
540
+ expect(subject).to receive(:fetch_glue_records).and_return('ns2' => ['2.3.4.5'])
541
+ expect(subject.glue_record('ns2')).to eq('ns2' => ['2.3.4.5'])
542
+ end
543
+
544
+ it 'Not present' do
545
+ expect(subject).to receive(:fetch_glue_records).and_return({})
546
+ expect(subject.glue_record('ns3')).to be nil
547
+ end
548
+ end
549
+
550
+ describe '#update_glue_record' do
551
+ it 'Make API request' do
552
+ expect(GandiV5).to receive(:put).with(
553
+ 'https://api.gandi.net/v5/domain/domains/example.com/hosts/name',
554
+ '{"ips":["1.2.3.4"]}'
555
+ )
556
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
557
+ expect(subject.update_glue_record('name', '1.2.3.4')).to eq 'Confirmation message.'
558
+ end
559
+
560
+ it 'Update name_servers' do
561
+ expect(GandiV5).to receive(:put).and_return([nil, { 'message' => 'Confirmation message.' }])
562
+ subject.update_glue_record 'name', '1.2.3.4'
563
+ expect(subject.glue_records).to eq('name' => ['1.2.3.4'])
564
+ end
565
+ end
566
+
567
+ describe '#delete_glue_record' do
568
+ before(:each) { subject.instance_exec { @glue_records = { 'ns1' => ['1.2.3.4'], 'ns2' => [] } } }
569
+
570
+ it 'Make API request' do
571
+ expect(GandiV5).to receive(:delete).with(
572
+ 'https://api.gandi.net/v5/domain/domains/example.com/hosts/ns2'
573
+ )
574
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
575
+ expect(subject.delete_glue_record('ns2')).to eq 'Confirmation message.'
576
+ end
577
+
578
+ it 'Update name_servers' do
579
+ expect(GandiV5).to receive(:delete).and_return([nil, { 'message' => 'Confirmation message.' }])
580
+ subject.delete_glue_record 'ns2'
581
+ expect(subject.glue_records).to eq('ns1' => ['1.2.3.4'])
582
+ end
583
+ end
584
+
585
+ describe '#livedns' do
586
+ let(:live_dns) { double GandiV5::Domain::LiveDNS }
587
+
588
+ it 'Already fetched' do
589
+ subject.instance_exec(live_dns) { |live_dns| @livedns = live_dns }
590
+ expect(subject).to_not receive(:fetch_livedns)
591
+ expect(subject.livedns).to be live_dns
592
+ end
593
+
594
+ it 'Not already fetched' do
595
+ expect(subject).to receive(:fetch_livedns).and_return(live_dns)
596
+ expect(subject.livedns).to be live_dns
597
+ end
598
+ end
599
+
600
+ describe '#fetch_livedns' do
601
+ before(:each) do
602
+ body_fixture = File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_livedns.yml')
603
+ body_fixture = File.expand_path(body_fixture)
604
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/livedns')
605
+ .and_return([nil, YAML.load_file(body_fixture)])
606
+ end
607
+
608
+ describe 'Returned live_dns' do
609
+ subject { described_class.new(fqdn: 'example.com').fetch_livedns }
610
+
611
+ its('current') { should be :livedns }
612
+ its('name_servers') { should match_array ['1.2.3.4'] }
613
+ its('dnssec_available') { should be true }
614
+ its('livednssec_available') { should be true }
615
+ end
616
+
617
+ it 'Updates name_server' do
618
+ expect(subject.name_server).to be nil
619
+ subject.fetch_livedns
620
+ expect(subject.name_server).to be :livedns
621
+ end
622
+
623
+ it 'Updates name_servers' do
624
+ subject.instance_exec { @name_servers = [] }
625
+ subject.fetch_livedns
626
+ expect(subject.name_servers).to match_array ['1.2.3.4']
627
+ end
628
+ end
629
+
630
+ it '#enable_livedns' do
631
+ expect(GandiV5).to receive(:post).with('https://api.gandi.net/v5/domain/domains/example.com/livedns')
632
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
633
+ expect(subject.enable_livedns).to eq 'Confirmation message.'
634
+ end
635
+
636
+ describe '#name_servers' do
637
+ let(:nameservers) { double Array }
638
+
639
+ it 'Already fetched' do
640
+ subject.instance_exec(nameservers) { |nameservers| @name_servers = nameservers }
641
+ expect(subject).to_not receive(:fetch_name_servers)
642
+ expect(subject.name_servers).to be nameservers
643
+ end
644
+
645
+ it 'Not already fetched' do
646
+ expect(subject).to receive(:fetch_name_servers).and_return(nameservers)
647
+ expect(subject.name_servers).to be nameservers
648
+ end
649
+ end
650
+
651
+ it '#fetch_name_servers' do
652
+ body_fixture = File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_name_servers.yml')
653
+ body_fixture = File.expand_path(body_fixture)
654
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/nameservers')
655
+ .and_return([nil, YAML.load_file(body_fixture)])
656
+ expect(subject.fetch_name_servers).to match_array ['1.2.3.4']
657
+ end
658
+
659
+ describe '#update_name_servers' do
660
+ subject { described_class.new fqdn: 'example.com', name_servers: [] }
661
+ let(:new_name_servers) { ['a.examle.com', 'b.example.net'] }
662
+
663
+ it 'Make API request' do
664
+ expect(GandiV5).to receive(:put).with(
665
+ 'https://api.gandi.net/v5/domain/domains/example.com/nameservers',
666
+ '{"nameservers":["a.examle.com","b.example.net"]}'
667
+ )
668
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
669
+ expect(subject.update_name_servers(new_name_servers)).to eq 'Confirmation message.'
670
+ end
671
+
672
+ it 'Update name_servers' do
673
+ expect(GandiV5).to receive(:put).and_return([nil, { 'message' => 'Confirmation message.' }])
674
+ subject.update_name_servers new_name_servers
675
+ expect(subject.name_servers).to be new_name_servers
676
+ end
677
+ end
459
678
  end