gandi_v5 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +24 -0
- data/.rspec +3 -0
- data/.rubocop.yml +20 -0
- data/.travis.yml +23 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +6 -0
- data/Guardfile +40 -0
- data/LICENSE.md +32 -0
- data/README.md +94 -0
- data/Rakefile +3 -0
- data/TODO.md +29 -0
- data/bin/console +13 -0
- data/gandi_v5.gemspec +41 -0
- data/lib/gandi_v5/billing/info/prepaid.rb +33 -0
- data/lib/gandi_v5/billing/info.rb +26 -0
- data/lib/gandi_v5/billing.rb +28 -0
- data/lib/gandi_v5/data/converter/array_of.rb +35 -0
- data/lib/gandi_v5/data/converter/symbol.rb +26 -0
- data/lib/gandi_v5/data/converter/time.rb +28 -0
- data/lib/gandi_v5/data/converter.rb +41 -0
- data/lib/gandi_v5/data.rb +244 -0
- data/lib/gandi_v5/domain/auto_renew.rb +64 -0
- data/lib/gandi_v5/domain/contact.rb +102 -0
- data/lib/gandi_v5/domain/contract.rb +22 -0
- data/lib/gandi_v5/domain/dates.rb +44 -0
- data/lib/gandi_v5/domain/renewal_information.rb +41 -0
- data/lib/gandi_v5/domain/restore_information.rb +18 -0
- data/lib/gandi_v5/domain/sharing_space.rb +21 -0
- data/lib/gandi_v5/domain.rb +431 -0
- data/lib/gandi_v5/email/mailbox/responder.rb +36 -0
- data/lib/gandi_v5/email/mailbox.rb +236 -0
- data/lib/gandi_v5/email/offer.rb +27 -0
- data/lib/gandi_v5/email/slot.rb +134 -0
- data/lib/gandi_v5/email.rb +11 -0
- data/lib/gandi_v5/error/gandi_error.rb +21 -0
- data/lib/gandi_v5/error.rb +9 -0
- data/lib/gandi_v5/live_dns/domain.rb +211 -0
- data/lib/gandi_v5/live_dns/record_set.rb +79 -0
- data/lib/gandi_v5/live_dns/zone/snapshot.rb +62 -0
- data/lib/gandi_v5/live_dns/zone.rb +301 -0
- data/lib/gandi_v5/live_dns.rb +30 -0
- data/lib/gandi_v5/organization.rb +66 -0
- data/lib/gandi_v5/version.rb +5 -0
- data/lib/gandi_v5.rb +178 -0
- data/spec/.rubocop.yml +4 -0
- data/spec/features/domain_spec.rb +45 -0
- data/spec/features/livedns_domain_spec.rb +8 -0
- data/spec/features/livedns_zone_spec.rb +45 -0
- data/spec/features/mailbox_spec.rb +18 -0
- data/spec/fixtures/bodies/GandiV5_Billing/info.yaml +10 -0
- data/spec/fixtures/bodies/GandiV5_Domain/availability.yaml +15 -0
- data/spec/fixtures/bodies/GandiV5_Domain/fetch_contacts.yaml +8 -0
- data/spec/fixtures/bodies/GandiV5_Domain/get.yaml +37 -0
- data/spec/fixtures/bodies/GandiV5_Domain/list.yaml +20 -0
- data/spec/fixtures/bodies/GandiV5_Domain/renewal_info.yaml +12 -0
- data/spec/fixtures/bodies/GandiV5_Domain/restore_info.yaml +5 -0
- data/spec/fixtures/bodies/GandiV5_Domain/tld.yaml +10 -0
- data/spec/fixtures/bodies/GandiV5_Domain/tlds.yaml +7 -0
- data/spec/fixtures/bodies/GandiV5_Email_Mailbox/get.yaml +16 -0
- data/spec/fixtures/bodies/GandiV5_Email_Mailbox/list.yaml +8 -0
- data/spec/fixtures/bodies/GandiV5_Email_Slot/get.yaml +10 -0
- data/spec/fixtures/bodies/GandiV5_Email_Slot/list.yaml +8 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/get.yaml +4 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/list.yaml +2 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/get.yaml +11 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/list.yaml +11 -0
- data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/get.yaml +9 -0
- data/spec/fixtures/bodies/GandiV5_Organization/get.yaml +17 -0
- data/spec/fixtures/vcr/Domain_features/List_domains.yml +54 -0
- data/spec/fixtures/vcr/Domain_features/Renew_domain.yml +133 -0
- data/spec/fixtures/vcr/LiveDNS_Domain_features/List_domains.yml +32 -0
- data/spec/fixtures/vcr/LiveDNS_Zone_features/List_zones.yml +42 -0
- data/spec/fixtures/vcr/LiveDNS_Zone_features/Make_and_save_snapshot.yml +72 -0
- data/spec/fixtures/vcr/LiveDNS_Zone_features/Save_zone_to_file.yml +28 -0
- data/spec/fixtures/vcr/Mailbox_features/List_mailboxes.yml +39 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/test.env +1 -0
- data/spec/units/gandi_v5/billing/info/prepaid_spec.rb +20 -0
- data/spec/units/gandi_v5/billing/info_spec.rb +4 -0
- data/spec/units/gandi_v5/billing_spec.rb +41 -0
- data/spec/units/gandi_v5/data/converter/array_of_spec.rb +18 -0
- data/spec/units/gandi_v5/data/converter/symbol_spec.rb +16 -0
- data/spec/units/gandi_v5/data/converter/time_spec.rb +16 -0
- data/spec/units/gandi_v5/data/converter_spec.rb +31 -0
- data/spec/units/gandi_v5/data_spec.rb +340 -0
- data/spec/units/gandi_v5/domain/auto_renew_spec.rb +70 -0
- data/spec/units/gandi_v5/domain/contact_spec.rb +36 -0
- data/spec/units/gandi_v5/domain/contract_spec.rb +4 -0
- data/spec/units/gandi_v5/domain/dates_spec.rb +4 -0
- data/spec/units/gandi_v5/domain/renewal_information_spec.rb +81 -0
- data/spec/units/gandi_v5/domain/restore_information_spec.rb +4 -0
- data/spec/units/gandi_v5/domain/sharing_space_spec.rb +4 -0
- data/spec/units/gandi_v5/domain_spec.rb +451 -0
- data/spec/units/gandi_v5/email/mailbox/responder_spec.rb +131 -0
- data/spec/units/gandi_v5/email/mailbox_spec.rb +384 -0
- data/spec/units/gandi_v5/email/offer_spec.rb +17 -0
- data/spec/units/gandi_v5/email/slot_spec.rb +102 -0
- data/spec/units/gandi_v5/error/gandi_error_spec.rb +30 -0
- data/spec/units/gandi_v5/error_spec.rb +4 -0
- data/spec/units/gandi_v5/live_dns/domain_spec.rb +247 -0
- data/spec/units/gandi_v5/live_dns/record_set_spec.rb +74 -0
- data/spec/units/gandi_v5/live_dns/zone/snapshot_spec.rb +37 -0
- data/spec/units/gandi_v5/live_dns/zone_spec.rb +329 -0
- data/spec/units/gandi_v5/live_dns_spec.rb +17 -0
- data/spec/units/gandi_v5/organization_spec.rb +30 -0
- data/spec/units/gandi_v5_spec.rb +204 -0
- metadata +406 -0
@@ -0,0 +1,451 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe GandiV5::Domain do
|
4
|
+
subject { described_class.new fqdn: 'example.com' }
|
5
|
+
|
6
|
+
describe '.list' do
|
7
|
+
let(:body_fixture) { File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'list.yaml')) }
|
8
|
+
|
9
|
+
describe 'With default values' do
|
10
|
+
subject { described_class.list }
|
11
|
+
|
12
|
+
before :each do
|
13
|
+
headers = { params: { page: 1, per_page: 100 } }
|
14
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains', headers)
|
15
|
+
.and_return(YAML.load_file(body_fixture))
|
16
|
+
end
|
17
|
+
|
18
|
+
its('count') { should eq 1 }
|
19
|
+
its('first.uuid') { should eq 'domain-uuid' }
|
20
|
+
its('first.fqdn') { should eq 'example.com' }
|
21
|
+
its('first.fqdn_unicode') { should eq 'example.com' }
|
22
|
+
its('first.name_servers') { should be_nil }
|
23
|
+
its('first.services') { should be_nil }
|
24
|
+
its('first.status') { should eq [] }
|
25
|
+
its('first.tld') { should eq 'com' }
|
26
|
+
its('first.can_tld_lock') { should be_nil }
|
27
|
+
its('first.auth_info') { should be_nil }
|
28
|
+
its('first.sharing_uuid') { should be_nil }
|
29
|
+
its('first.tags') { should match_array ['Tag'] }
|
30
|
+
its('first.trustee_roles') { should be_nil }
|
31
|
+
its('first.owner') { should eq 'Example Owner' }
|
32
|
+
its('first.organisation_owner') { should eq 'Example Organisation' }
|
33
|
+
its('first.domain_owner') { should eq 'Example Owner' }
|
34
|
+
its('first.name_server') { should be :livedns }
|
35
|
+
its('first.sharing_space') { should be_nil }
|
36
|
+
its('first.dates.created_at') { should eq Time.new(2011, 2, 21, 10, 39, 0) }
|
37
|
+
its('first.dates.registry_created_at') { should eq Time.new(2003, 3, 12, 12, 2, 11) }
|
38
|
+
its('first.dates.registry_ends_at') { should eq Time.new(2020, 3, 12, 12, 2, 11) }
|
39
|
+
its('first.dates.updated_at') { should eq Time.new(2019, 2, 6, 9, 49, 37) }
|
40
|
+
its('first.auto_renew.dates') { should be_nil }
|
41
|
+
its('first.auto_renew.duration') { should be_nil }
|
42
|
+
its('first.auto_renew.enabled') { should eq false }
|
43
|
+
its('first.auto_renew.org_id') { should be_nil }
|
44
|
+
its('first.contacts?') { should be false }
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'Keeps fetching until no more to get' do
|
48
|
+
headers1 = { params: { page: 1, per_page: 1 } }
|
49
|
+
headers2 = { params: { page: 2, per_page: 1 } }
|
50
|
+
# rubocop:disable Layout/MultilineMethodCallIndentation
|
51
|
+
# https://github.com/rubocop-hq/rubocop/issues/7088
|
52
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains', headers1)
|
53
|
+
.ordered
|
54
|
+
.and_return(YAML.load_file(body_fixture))
|
55
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains', headers2)
|
56
|
+
.ordered
|
57
|
+
.and_return([])
|
58
|
+
# rubocop:enable Layout/MultilineMethodCallIndentation
|
59
|
+
|
60
|
+
expect(described_class.list(per_page: 1).count).to eq 1
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'Given a range as page number' do
|
64
|
+
headers1 = { params: { page: 1, per_page: 1 } }
|
65
|
+
headers2 = { params: { page: 2, per_page: 1 } }
|
66
|
+
# rubocop:disable Layout/MultilineMethodCallIndentation
|
67
|
+
# https://github.com/rubocop-hq/rubocop/issues/7088
|
68
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains', headers1)
|
69
|
+
.ordered
|
70
|
+
.and_return(YAML.load_file(body_fixture))
|
71
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains', headers2)
|
72
|
+
.ordered
|
73
|
+
.and_return([])
|
74
|
+
# rubocop:enable Layout/MultilineMethodCallIndentation
|
75
|
+
|
76
|
+
expect(described_class.list(page: (1..2), per_page: 1).count).to eq 1
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'Passes optional query params' do
|
80
|
+
%i[fqdn page per_page sort_by tld].each do |param|
|
81
|
+
it param.to_s do
|
82
|
+
param = { param => 5 }
|
83
|
+
headers = { params: { page: 1, per_page: 100 }.merge(param) }
|
84
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains', headers)
|
85
|
+
.and_return([])
|
86
|
+
expect(described_class.list(**param)).to eq []
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '.fetch' do
|
93
|
+
subject { described_class.fetch 'example.com' }
|
94
|
+
|
95
|
+
before :each do
|
96
|
+
body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'get.yaml'))
|
97
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com')
|
98
|
+
.and_return(YAML.load_file(body_fixture))
|
99
|
+
end
|
100
|
+
|
101
|
+
its('uuid') { should eq 'domain-uuid' }
|
102
|
+
its('fqdn') { should eq 'example.com' }
|
103
|
+
its('fqdn_unicode') { should eq 'example.com' }
|
104
|
+
its('status') { should eq [] }
|
105
|
+
its('tld') { should eq 'com' }
|
106
|
+
its('auth_info') { should be_nil }
|
107
|
+
its('sharing_uuid') { should be_nil }
|
108
|
+
its('tags') { should match_array ['Tag'] }
|
109
|
+
its('trustee_roles') { should be_nil }
|
110
|
+
its('owner') { should be_nil }
|
111
|
+
its('organisation_owner') { should be_nil }
|
112
|
+
its('domain_owner') { should be_nil }
|
113
|
+
its('name_servers') { should match_array %w[192.168.0.1 192.168.0.2] }
|
114
|
+
its('services') { should match_array %i[gandilivedns dnssec] }
|
115
|
+
its('sharing_space') { should be_nil }
|
116
|
+
its('dates.created_at') { should eq Time.new(2011, 2, 21, 10, 39, 0) }
|
117
|
+
its('dates.registry_created_at') { should eq Time.new(2003, 3, 12, 12, 2, 11) }
|
118
|
+
its('dates.registry_ends_at') { should eq Time.new(2020, 3, 12, 12, 2, 11) }
|
119
|
+
its('dates.updated_at') { should eq Time.new(2019, 2, 6, 9, 49, 37) }
|
120
|
+
its('auto_renew.dates') { should match_array [Time.new(2021, 1, 13, 9, 4, 18), Time.new(2021, 1, 29, 10, 4, 18)] }
|
121
|
+
its('auto_renew.duration') { should eq 1 }
|
122
|
+
its('auto_renew.enabled') { should eq true }
|
123
|
+
its('auto_renew.org_id') { should eq 'org-uuid' }
|
124
|
+
its('contacts?') { should be true }
|
125
|
+
its('contacts.owner.country') { should eq 'GB' }
|
126
|
+
its('contacts.owner.email') { should eq 'owner@example.com' }
|
127
|
+
its('contacts.owner.family') { should eq 'Fam' }
|
128
|
+
its('contacts.owner.given') { should eq 'Giv' }
|
129
|
+
its('contacts.owner.address') { should eq 'Somestreet' }
|
130
|
+
its('contacts.owner.type') { should be :company }
|
131
|
+
end
|
132
|
+
|
133
|
+
describe '.create' do
|
134
|
+
let(:url) { 'https://api.gandi.net/v5/domain/domains' }
|
135
|
+
|
136
|
+
describe 'Sets dry-run header' do
|
137
|
+
let(:body) { '{"owner":{},"fqdn":"example.com"}' }
|
138
|
+
|
139
|
+
it 'False by default' do
|
140
|
+
expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
|
141
|
+
described_class.create 'example.com', owner: {}
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'True' do
|
145
|
+
expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 1)
|
146
|
+
described_class.create 'example.com', owner: {}, dry_run: true
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'False' do
|
150
|
+
expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
|
151
|
+
described_class.create 'example.com', owner: {}, dry_run: false
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'Dry run was successful' do
|
155
|
+
returns = { 'status' => 'success' }
|
156
|
+
expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 1)
|
157
|
+
.and_return(returns)
|
158
|
+
expect(described_class.create('example.com', owner: {}, dry_run: true)).to be returns
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'Dry run has errors' do
|
162
|
+
returns = {
|
163
|
+
'status' => 'error',
|
164
|
+
'errors' => [{ 'description' => 'd', 'location' => 'l', 'name' => 'n' }]
|
165
|
+
}
|
166
|
+
expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 1)
|
167
|
+
.and_return(returns)
|
168
|
+
expect(described_class.create('example.com', owner: {}, dry_run: true)).to be returns
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'Success' do
|
173
|
+
returns = { 'message' => 'Confirmation message.' }
|
174
|
+
body = '{"owner":{},"fqdn":"example.com"}'
|
175
|
+
expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
|
176
|
+
.and_return(returns)
|
177
|
+
expect(described_class.create('example.com', owner: {})).to be returns
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'Errors on missing owner' do
|
181
|
+
expect { described_class.create 'example.com' }.to raise_error ArgumentError, 'missing keyword: owner'
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'Given contact as hash' do
|
185
|
+
body = '{"owner":{"email":"owner@example.com"},"fqdn":"example.com"}'
|
186
|
+
expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
|
187
|
+
described_class.create 'example.com', owner: { email: 'owner@example.com' }
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'Given contact as GandiV5::Domain::Contact' do
|
191
|
+
body = '{"owner":{"email":"owner@example.com"},"fqdn":"example.com"}'
|
192
|
+
expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
|
193
|
+
owner = double GandiV5::Domain::Contact, to_gandi: { 'email' => 'owner@example.com' }
|
194
|
+
described_class.create 'example.com', owner: owner
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe '.availability' do
|
199
|
+
it 'With default values' do
|
200
|
+
body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'availability.yaml'))
|
201
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/check', params: { name: 'example.com' })
|
202
|
+
.and_return(YAML.load_file(body_fixture))
|
203
|
+
expect(described_class.availability('example.com')).to eq(
|
204
|
+
'currency' => 'GBP',
|
205
|
+
'grid' => 'A',
|
206
|
+
'products' => [
|
207
|
+
{
|
208
|
+
'status' => 'unavailable',
|
209
|
+
'name' => 'example.com',
|
210
|
+
'process' => 'create',
|
211
|
+
'taxes' => [{ 'type' => 'service', 'rate' => 0, 'name' => 'vat' }]
|
212
|
+
}
|
213
|
+
],
|
214
|
+
'taxes' => [{ 'type' => 'service', 'rate' => 0, 'name' => 'vat' }]
|
215
|
+
)
|
216
|
+
end
|
217
|
+
|
218
|
+
describe 'Passes optional query params' do
|
219
|
+
%i[country currency duration_unit extension grid lang max_duration period processes sharing_uuid].each do |param|
|
220
|
+
it param.to_s do
|
221
|
+
url = 'https://api.gandi.net/v5/domain/check'
|
222
|
+
expect(GandiV5).to receive(:get).with(url, params: { name: 'example.com', param => 5 }).and_return([])
|
223
|
+
expect(described_class.availability('example.com', param => 5)).to eq []
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
it '.tlds' do
|
230
|
+
body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'tlds.yaml'))
|
231
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/tlds')
|
232
|
+
.and_return(YAML.load_file(body_fixture))
|
233
|
+
expect(described_class.tlds).to match_array %w[a b c]
|
234
|
+
end
|
235
|
+
|
236
|
+
it '.tld' do
|
237
|
+
body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'tld.yaml'))
|
238
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/tlds/name')
|
239
|
+
.and_return(YAML.load_file(body_fixture))
|
240
|
+
expect(described_class.tld('name')).to eq(
|
241
|
+
category: 'ccTLD',
|
242
|
+
name: 'eu',
|
243
|
+
lock: false,
|
244
|
+
change_owner: true,
|
245
|
+
authinfo_for_transfer: true,
|
246
|
+
full_tld: 'eu',
|
247
|
+
corporate: false,
|
248
|
+
ext_trade: true,
|
249
|
+
href: 'https://api.test/v5/domain/tlds/eu'
|
250
|
+
)
|
251
|
+
end
|
252
|
+
|
253
|
+
describe '#to_s' do
|
254
|
+
it 'Has identical fqdn and fqdn_unicode' do
|
255
|
+
domain = described_class.new fqdn: 'example.com', fqdn_unicode: 'example.com'
|
256
|
+
expect(domain.to_s).to eq 'example.com'
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'Has differing fqdn and fqdn_unicode' do
|
260
|
+
domain = described_class.new fqdn: 'example.com', fqdn_unicode: 'unicode.example.com'
|
261
|
+
expect(domain.to_s).to eq 'unicode.example.com (example.com)'
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
describe '#refresh' do
|
266
|
+
before :each do
|
267
|
+
body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'get.yaml'))
|
268
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com')
|
269
|
+
.and_return(YAML.load_file(body_fixture))
|
270
|
+
subject.refresh
|
271
|
+
end
|
272
|
+
|
273
|
+
its('uuid') { should eq 'domain-uuid' }
|
274
|
+
its('fqdn') { should eq 'example.com' }
|
275
|
+
its('fqdn_unicode') { should eq 'example.com' }
|
276
|
+
its('status') { should eq [] }
|
277
|
+
its('tld') { should eq 'com' }
|
278
|
+
its('auth_info') { should be_nil }
|
279
|
+
its('sharing_uuid') { should be_nil }
|
280
|
+
its('tags') { should match_array ['Tag'] }
|
281
|
+
its('trustee_roles') { should be_nil }
|
282
|
+
its('owner') { should be_nil }
|
283
|
+
its('organisation_owner') { should be_nil }
|
284
|
+
its('domain_owner') { should be_nil }
|
285
|
+
its('name_servers') { should match_array %w[192.168.0.1 192.168.0.2] }
|
286
|
+
its('services') { should match_array %i[gandilivedns dnssec] }
|
287
|
+
its('sharing_space') { should be_nil }
|
288
|
+
its('dates.created_at') { should eq Time.new(2011, 2, 21, 10, 39, 0) }
|
289
|
+
its('dates.registry_created_at') { should eq Time.new(2003, 3, 12, 12, 2, 11) }
|
290
|
+
its('dates.registry_ends_at') { should eq Time.new(2020, 3, 12, 12, 2, 11) }
|
291
|
+
its('dates.updated_at') { should eq Time.new(2019, 2, 6, 9, 49, 37) }
|
292
|
+
its('auto_renew.dates') { should match_array [Time.new(2021, 1, 13, 9, 4, 18), Time.new(2021, 1, 29, 10, 4, 18)] }
|
293
|
+
its('auto_renew.duration') { should eq 1 }
|
294
|
+
its('auto_renew.enabled') { should eq true }
|
295
|
+
its('auto_renew.org_id') { should eq 'org-uuid' }
|
296
|
+
its('contacts.owner.country') { should eq 'GB' }
|
297
|
+
its('contacts.owner.email') { should eq 'owner@example.com' }
|
298
|
+
its('contacts.owner.family') { should eq 'Fam' }
|
299
|
+
its('contacts.owner.given') { should eq 'Giv' }
|
300
|
+
its('contacts.owner.address') { should eq 'Somestreet' }
|
301
|
+
its('contacts.owner.type') { should be :company }
|
302
|
+
end
|
303
|
+
|
304
|
+
describe 'Domain contacts' do
|
305
|
+
describe '#contacts' do
|
306
|
+
it 'Already fetched' do
|
307
|
+
domain = described_class.new fqdn: 'example.com', contacts: {}
|
308
|
+
expect(domain).to_not receive(:fetch_contacts)
|
309
|
+
expect(domain.contacts).to eq({})
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'Not already fetched' do
|
313
|
+
contacts = {}
|
314
|
+
expect(subject).to receive(:fetch_contacts).and_return(contacts)
|
315
|
+
expect(subject.contacts).to be contacts
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
describe '#fetch_contacts' do
|
320
|
+
subject { described_class.new(fqdn: 'example.com').fetch_contacts }
|
321
|
+
|
322
|
+
before(:each) do
|
323
|
+
body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_contacts.yaml'))
|
324
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/contacts')
|
325
|
+
.and_return(YAML.load_file(body_fixture))
|
326
|
+
end
|
327
|
+
|
328
|
+
its('owner.country') { should eq 'GB' }
|
329
|
+
its('owner.email') { should eq 'owner@example.com' }
|
330
|
+
its('owner.family') { should eq 'Fam' }
|
331
|
+
its('owner.given') { should eq 'Giv' }
|
332
|
+
its('owner.address') { should eq 'Somestreet' }
|
333
|
+
its('owner.type') { should be :company }
|
334
|
+
end
|
335
|
+
|
336
|
+
describe '#update_contacts' do
|
337
|
+
let(:fetched_contacts) { { admin: double(GandiV5::Domain::Contact) } }
|
338
|
+
|
339
|
+
before(:each) do
|
340
|
+
url = 'https://api.gandi.net/v5/domain/domains/example.com/contacts'
|
341
|
+
body = '{"admin":{"email":"admin@example.com"}}'
|
342
|
+
expect(GandiV5).to receive(:patch).with(url, body)
|
343
|
+
.and_return('message' => 'Confirmation message.')
|
344
|
+
|
345
|
+
expect(subject).to receive(:fetch_contacts).and_return(fetched_contacts)
|
346
|
+
end
|
347
|
+
|
348
|
+
it 'Given a Hash' do
|
349
|
+
new_contacts = { admin: { email: 'admin@example.com' } }
|
350
|
+
expect(subject.update_contacts(**new_contacts)).to be fetched_contacts
|
351
|
+
end
|
352
|
+
|
353
|
+
it 'Given a GandiV5::Domain::Contact' do
|
354
|
+
new_contacts = { admin: double(GandiV5::Domain::Contact, to_gandi: { 'email' => 'admin@example.com' }) }
|
355
|
+
expect(subject.update_contacts(**new_contacts)).to be fetched_contacts
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
describe 'Domain renewal' do
|
361
|
+
describe '#renewal_information' do
|
362
|
+
let(:renewal_info) { double GandiV5::Domain::RenewalInformation }
|
363
|
+
|
364
|
+
it 'Already fetched' do
|
365
|
+
subject.instance_exec(renewal_info) { |renewal_info| @renewal_information = renewal_info }
|
366
|
+
expect(subject).to_not receive(:fetch_renewal_information)
|
367
|
+
expect(subject.renewal_information).to be renewal_info
|
368
|
+
end
|
369
|
+
|
370
|
+
it 'Not already fetched' do
|
371
|
+
expect(subject).to receive(:fetch_renewal_information).and_return(renewal_info)
|
372
|
+
expect(subject.renewal_information).to be renewal_info
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
describe '#fetch_renewal_information' do
|
377
|
+
subject { described_class.new(fqdn: 'example.com').fetch_renewal_information }
|
378
|
+
|
379
|
+
before(:each) do
|
380
|
+
body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'renewal_info.yaml'))
|
381
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/renew')
|
382
|
+
.and_return(YAML.load_file(body_fixture))
|
383
|
+
end
|
384
|
+
|
385
|
+
its('begins_at') { should eq Time.new(2012, 1, 1, 0, 0, 0) }
|
386
|
+
its('prohibited') { should be false }
|
387
|
+
its('minimum') { should eq 1 }
|
388
|
+
its('maximum') { should eq 2 }
|
389
|
+
its('durations') { should match_array [1, 2] }
|
390
|
+
its('contracts.count') { should eq 1 }
|
391
|
+
its('contracts.first.id') { should eq 'uuid' }
|
392
|
+
its('contracts.first.name') { should eq 'Name' }
|
393
|
+
end
|
394
|
+
|
395
|
+
it '#renew_for' do
|
396
|
+
expect(GandiV5).to receive(:post).with('https://api.gandi.net/v5/domain/domains/example.com/renew', '{"duration":2}')
|
397
|
+
.and_return('message' => 'Confirmation message.')
|
398
|
+
expect(subject.renew_for(2)).to eq 'Confirmation message.'
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
describe 'Domain restoration' do
|
403
|
+
describe '#restore_information' do
|
404
|
+
let(:restore_info) { double GandiV5::Domain::RestoreInformation }
|
405
|
+
|
406
|
+
it 'Already fetched' do
|
407
|
+
subject.instance_exec(restore_info) { |restore_info| @restore_information = restore_info }
|
408
|
+
expect(subject).to_not receive(:fetch_restore_information)
|
409
|
+
expect(subject.restore_information).to be restore_info
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'Not already fetched' do
|
413
|
+
expect(subject).to receive(:fetch_restore_information).and_return(restore_info)
|
414
|
+
expect(subject.restore_information).to be restore_info
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
describe '#fetch_restore_information' do
|
419
|
+
subject { described_class.new(fqdn: 'example.com').fetch_restore_information }
|
420
|
+
|
421
|
+
describe 'Information is available' do
|
422
|
+
before(:each) do
|
423
|
+
body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'restore_info.yaml'))
|
424
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/restore')
|
425
|
+
.and_return(YAML.load_file(body_fixture))
|
426
|
+
end
|
427
|
+
|
428
|
+
its('restorable') { should be true }
|
429
|
+
its('contracts.count') { should eq 1 }
|
430
|
+
its('contracts.first.id') { should eq 'uuid' }
|
431
|
+
its('contracts.first.name') { should eq 'Name' }
|
432
|
+
end
|
433
|
+
|
434
|
+
describe 'Information is unavailable' do
|
435
|
+
before(:each) do
|
436
|
+
expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/restore')
|
437
|
+
.and_raise(RestClient::NotFound)
|
438
|
+
end
|
439
|
+
|
440
|
+
its('restorable') { should be false }
|
441
|
+
its('contracts') { should be_nil }
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
it '#restore' do
|
446
|
+
expect(GandiV5).to receive(:post).with('https://api.gandi.net/v5/domain/domains/example.com/restore', '{}')
|
447
|
+
.and_return('message' => 'Confirmation message.')
|
448
|
+
expect(subject.restore).to eq 'Confirmation message.'
|
449
|
+
end
|
450
|
+
end
|
451
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe GandiV5::Email::Mailbox::Responder do
|
4
|
+
describe '#active?' do
|
5
|
+
before(:each) { Timecop.travel Time.new(2000, 1, 2, 12, 0, 0) }
|
6
|
+
let(:future) { Time.new 2000, 1, 3, 0, 0, 0, 0 }
|
7
|
+
let(:past) { Time.new 2000, 1, 1, 0, 0, 0, 0 }
|
8
|
+
|
9
|
+
describe 'Is enabled' do
|
10
|
+
describe 'Starts at' do
|
11
|
+
describe 'Missing' do
|
12
|
+
describe 'Ends at' do
|
13
|
+
it 'Missing' do
|
14
|
+
responder = described_class.new enabled: true
|
15
|
+
expect(responder.active?).to be true
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'In the past' do
|
19
|
+
responder = described_class.new enabled: true, ends_at: past
|
20
|
+
expect(responder.active?).to be false
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'In the future' do
|
24
|
+
responder = described_class.new enabled: true, ends_at: future
|
25
|
+
expect(responder.active?).to be true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'In the past' do
|
31
|
+
describe 'Ends at' do
|
32
|
+
it 'Missing' do
|
33
|
+
responder = described_class.new enabled: true, starts_at: past
|
34
|
+
expect(responder.active?).to be true
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'In the past' do
|
38
|
+
responder = described_class.new enabled: true, starts_at: past, ends_at: past
|
39
|
+
expect(responder.active?).to be false
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'In the future' do
|
43
|
+
responder = described_class.new enabled: true, starts_at: past, ends_at: future
|
44
|
+
expect(responder.active?).to be true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'In the future' do
|
50
|
+
describe 'Ends at' do
|
51
|
+
it 'Missing' do
|
52
|
+
responder = described_class.new enabled: true, starts_at: future
|
53
|
+
expect(responder.active?).to be false
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'In the past' do
|
57
|
+
responder = described_class.new enabled: true, starts_at: future, ends_at: past
|
58
|
+
expect(responder.active?).to be false
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'In the future' do
|
62
|
+
responder = described_class.new enabled: true, starts_at: future, ends_at: future
|
63
|
+
expect(responder.active?).to be false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'Is disabled' do
|
71
|
+
describe 'Starts at' do
|
72
|
+
describe 'Missing' do
|
73
|
+
describe 'Ends at' do
|
74
|
+
it 'Missing' do
|
75
|
+
responder = described_class.new enabled: false
|
76
|
+
expect(responder.active?).to be false
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'In the past' do
|
80
|
+
responder = described_class.new enabled: false, ends_at: past
|
81
|
+
expect(responder.active?).to be false
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'In the future' do
|
85
|
+
responder = described_class.new enabled: false, ends_at: future
|
86
|
+
expect(responder.active?).to be false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe 'In the past' do
|
92
|
+
describe 'Ends at' do
|
93
|
+
it 'Missing' do
|
94
|
+
responder = described_class.new enabled: false, starts_at: past
|
95
|
+
expect(responder.active?).to be false
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'In the past' do
|
99
|
+
responder = described_class.new enabled: false, starts_at: past, ends_at: past
|
100
|
+
expect(responder.active?).to be false
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'In the future' do
|
104
|
+
responder = described_class.new enabled: false, starts_at: past, ends_at: future
|
105
|
+
expect(responder.active?).to be false
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe 'In the future' do
|
111
|
+
describe 'Ends at' do
|
112
|
+
it 'Missing' do
|
113
|
+
responder = described_class.new enabled: false, starts_at: future
|
114
|
+
expect(responder.active?).to be false
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'In the past' do
|
118
|
+
responder = described_class.new enabled: false, starts_at: future, ends_at: past
|
119
|
+
expect(responder.active?).to be false
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'In the future' do
|
123
|
+
responder = described_class.new enabled: false, starts_at: future, ends_at: future
|
124
|
+
expect(responder.active?).to be false
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|