gandi_v5 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +1 -0
  4. data/CHANGELOG.md +44 -2
  5. data/Guardfile +5 -6
  6. data/README.md +5 -5
  7. data/doc/GandiV5/Billing/Info/Prepaid.html +817 -0
  8. data/doc/GandiV5/Billing/Info.html +641 -0
  9. data/doc/GandiV5/Billing.html +293 -0
  10. data/doc/GandiV5/Data/ClassMethods.html +223 -0
  11. data/doc/GandiV5/Data/Converter/ArrayOf.html +413 -0
  12. data/doc/GandiV5/Data/Converter/Symbol.html +322 -0
  13. data/doc/GandiV5/Data/Converter/Time.html +330 -0
  14. data/doc/GandiV5/Data/Converter.html +433 -0
  15. data/doc/GandiV5/Data.html +785 -0
  16. data/doc/GandiV5/Domain/AutoRenew.html +1237 -0
  17. data/doc/GandiV5/Domain/Availability/Product/Period.html +220 -0
  18. data/doc/GandiV5/Domain/Availability/Product/Price.html +1031 -0
  19. data/doc/GandiV5/Domain/Availability/Product.html +988 -0
  20. data/doc/GandiV5/Domain/Availability/Tax.html +440 -0
  21. data/doc/GandiV5/Domain/Availability.html +1020 -0
  22. data/doc/GandiV5/Domain/Contact.html +4459 -0
  23. data/doc/GandiV5/Domain/Contract.html +520 -0
  24. data/doc/GandiV5/Domain/Dates.html +1313 -0
  25. data/doc/GandiV5/Domain/RenewalInformation.html +1147 -0
  26. data/doc/GandiV5/Domain/RestoreInformation.html +339 -0
  27. data/doc/GandiV5/Domain/SharingSpace.html +437 -0
  28. data/doc/GandiV5/Domain/TLD.html +1565 -0
  29. data/doc/GandiV5/Domain.html +16847 -0
  30. data/doc/GandiV5/Email/Mailbox/Responder.html +1560 -0
  31. data/doc/GandiV5/Email/Mailbox.html +6307 -0
  32. data/doc/GandiV5/Email/Offer.html +514 -0
  33. data/doc/GandiV5/Email/Slot.html +4244 -0
  34. data/doc/GandiV5/Email.html +144 -0
  35. data/doc/GandiV5/Error/GandiError.html +270 -0
  36. data/doc/GandiV5/Error.html +151 -0
  37. data/doc/GandiV5/LiveDNS/Domain.html +2984 -0
  38. data/doc/GandiV5/LiveDNS/RecordSet.html +1593 -0
  39. data/doc/GandiV5/LiveDNS/Zone/Snapshot.html +1556 -0
  40. data/doc/GandiV5/LiveDNS/Zone.html +8891 -0
  41. data/doc/GandiV5/LiveDNS.html +300 -0
  42. data/doc/GandiV5/Organization.html +2341 -0
  43. data/doc/GandiV5.html +1183 -0
  44. data/doc/_index.html +474 -0
  45. data/doc/class_list.html +51 -0
  46. data/doc/css/common.css +1 -0
  47. data/doc/css/full_list.css +58 -0
  48. data/doc/css/style.css +496 -0
  49. data/doc/file.README.html +175 -0
  50. data/doc/file_list.html +56 -0
  51. data/doc/frames.html +17 -0
  52. data/doc/index.html +175 -0
  53. data/doc/js/app.js +303 -0
  54. data/doc/js/full_list.js +216 -0
  55. data/doc/js/jquery.js +4 -0
  56. data/doc/method_list.html +2427 -0
  57. data/doc/top-level-namespace.html +110 -0
  58. data/gandi_v5.gemspec +1 -1
  59. data/lib/gandi_v5/billing.rb +2 -2
  60. data/lib/gandi_v5/data.rb +2 -0
  61. data/lib/gandi_v5/domain/auto_renew.rb +4 -4
  62. data/lib/gandi_v5/domain/availability/product/period.rb +24 -0
  63. data/lib/gandi_v5/domain/availability/product/price.rb +36 -0
  64. data/lib/gandi_v5/domain/availability/product.rb +52 -0
  65. data/lib/gandi_v5/domain/availability/tax.rb +20 -0
  66. data/lib/gandi_v5/domain/availability.rb +49 -0
  67. data/lib/gandi_v5/domain/tld.rb +57 -0
  68. data/lib/gandi_v5/domain.rb +41 -86
  69. data/lib/gandi_v5/email/mailbox/responder.rb +43 -2
  70. data/lib/gandi_v5/email/mailbox.rb +32 -21
  71. data/lib/gandi_v5/email/offer.rb +2 -2
  72. data/lib/gandi_v5/email/slot.rb +42 -16
  73. data/lib/gandi_v5/error/gandi_error.rb +2 -2
  74. data/lib/gandi_v5/live_dns/domain.rb +59 -45
  75. data/lib/gandi_v5/live_dns/zone/snapshot.rb +27 -8
  76. data/lib/gandi_v5/live_dns/zone.rb +63 -59
  77. data/lib/gandi_v5/live_dns.rb +20 -0
  78. data/lib/gandi_v5/organization.rb +2 -2
  79. data/lib/gandi_v5/version.rb +1 -1
  80. data/lib/gandi_v5.rb +25 -5
  81. data/spec/features/domain_spec.rb +1 -1
  82. data/spec/fixtures/bodies/{GandiV5_Domain/availability.yaml → GandiV5_Domain_Availability/fetch.yaml} +0 -0
  83. data/spec/fixtures/bodies/{GandiV5_Domain/tld.yaml → GandiV5_Domain_TLD/fetch.yaml} +0 -0
  84. data/spec/fixtures/bodies/{GandiV5_Domain/tlds.yaml → GandiV5_Domain_TLD/list.yaml} +0 -0
  85. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/{get.yaml → fetch.yaml} +0 -0
  86. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/list.yaml +3 -0
  87. data/spec/units/gandi_v5/billing_spec.rb +2 -2
  88. data/spec/units/gandi_v5/domain/auto_renew_spec.rb +5 -5
  89. data/spec/units/gandi_v5/domain/availability/product/period_spec.rb +4 -0
  90. data/spec/units/gandi_v5/domain/availability/product/price_spec.rb +4 -0
  91. data/spec/units/gandi_v5/domain/availability/product_spec.rb +4 -0
  92. data/spec/units/gandi_v5/domain/availability/tax_spec.rb +4 -0
  93. data/spec/units/gandi_v5/domain/availability_spec.rb +43 -0
  94. data/spec/units/gandi_v5/domain/tld_spec.rb +29 -0
  95. data/spec/units/gandi_v5/domain_spec.rb +89 -81
  96. data/spec/units/gandi_v5/email/mailbox/responder_spec.rb +52 -0
  97. data/spec/units/gandi_v5/email/mailbox_spec.rb +56 -27
  98. data/spec/units/gandi_v5/email/offer_spec.rb +1 -1
  99. data/spec/units/gandi_v5/email/slot_spec.rb +101 -13
  100. data/spec/units/gandi_v5/live_dns/domain_spec.rb +70 -40
  101. data/spec/units/gandi_v5/live_dns/zone/snapshot_spec.rb +32 -3
  102. data/spec/units/gandi_v5/live_dns/zone_spec.rb +68 -50
  103. data/spec/units/gandi_v5/live_dns_spec.rb +24 -0
  104. data/spec/units/gandi_v5/organization_spec.rb +1 -1
  105. data/spec/units/gandi_v5_spec.rb +37 -12
  106. metadata +72 -9
  107. data/TODO.md +0 -29
@@ -12,7 +12,7 @@ describe GandiV5::Domain do
12
12
  before :each do
13
13
  headers = { params: { page: 1, per_page: 100 } }
14
14
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains', headers)
15
- .and_return(YAML.load_file(body_fixture))
15
+ .and_return([nil, YAML.load_file(body_fixture)])
16
16
  end
17
17
 
18
18
  its('count') { should eq 1 }
@@ -47,15 +47,13 @@ describe GandiV5::Domain do
47
47
  it 'Keeps fetching until no more to get' do
48
48
  headers1 = { params: { page: 1, per_page: 1 } }
49
49
  headers2 = { params: { page: 2, per_page: 1 } }
50
- # rubocop:disable Layout/MultilineMethodCallIndentation
51
50
  # https://github.com/rubocop-hq/rubocop/issues/7088
52
51
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains', headers1)
53
52
  .ordered
54
- .and_return(YAML.load_file(body_fixture))
53
+ .and_return([nil, YAML.load_file(body_fixture)])
55
54
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains', headers2)
56
55
  .ordered
57
- .and_return([])
58
- # rubocop:enable Layout/MultilineMethodCallIndentation
56
+ .and_return([nil, []])
59
57
 
60
58
  expect(described_class.list(per_page: 1).count).to eq 1
61
59
  end
@@ -63,15 +61,13 @@ describe GandiV5::Domain do
63
61
  it 'Given a range as page number' do
64
62
  headers1 = { params: { page: 1, per_page: 1 } }
65
63
  headers2 = { params: { page: 2, per_page: 1 } }
66
- # rubocop:disable Layout/MultilineMethodCallIndentation
67
64
  # https://github.com/rubocop-hq/rubocop/issues/7088
68
65
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains', headers1)
69
66
  .ordered
70
- .and_return(YAML.load_file(body_fixture))
67
+ .and_return([nil, YAML.load_file(body_fixture)])
71
68
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains', headers2)
72
69
  .ordered
73
- .and_return([])
74
- # rubocop:enable Layout/MultilineMethodCallIndentation
70
+ .and_return([nil, []])
75
71
 
76
72
  expect(described_class.list(page: (1..2), per_page: 1).count).to eq 1
77
73
  end
@@ -82,7 +78,7 @@ describe GandiV5::Domain do
82
78
  param = { param => 5 }
83
79
  headers = { params: { page: 1, per_page: 100 }.merge(param) }
84
80
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains', headers)
85
- .and_return([])
81
+ .and_return([nil, []])
86
82
  expect(described_class.list(**param)).to eq []
87
83
  end
88
84
  end
@@ -95,7 +91,7 @@ describe GandiV5::Domain do
95
91
  before :each do
96
92
  body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'get.yaml'))
97
93
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com')
98
- .and_return(YAML.load_file(body_fixture))
94
+ .and_return([nil, YAML.load_file(body_fixture)])
99
95
  end
100
96
 
101
97
  its('uuid') { should eq 'domain-uuid' }
@@ -137,24 +133,30 @@ describe GandiV5::Domain do
137
133
  let(:body) { '{"owner":{},"fqdn":"example.com"}' }
138
134
 
139
135
  it 'False by default' do
140
- expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
136
+ returns = double described_class
137
+ response = double RestClient::Response, headers: { location: 'https://api.gandi.net/v5/domains/example.com' }
138
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0).and_return([response, nil])
139
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
141
140
  described_class.create 'example.com', owner: {}
142
141
  end
143
142
 
144
143
  it 'True' do
145
- expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 1)
144
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 1).and_return([nil, nil])
146
145
  described_class.create 'example.com', owner: {}, dry_run: true
147
146
  end
148
147
 
149
148
  it 'False' do
150
- expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
149
+ returns = double described_class
150
+ response = double RestClient::Response, headers: { location: 'https://api.gandi.net/v5/domains/example.com' }
151
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0).and_return([response, nil])
152
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
151
153
  described_class.create 'example.com', owner: {}, dry_run: false
152
154
  end
153
155
 
154
156
  it 'Dry run was successful' do
155
157
  returns = { 'status' => 'success' }
156
158
  expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 1)
157
- .and_return(returns)
159
+ .and_return([nil, returns])
158
160
  expect(described_class.create('example.com', owner: {}, dry_run: true)).to be returns
159
161
  end
160
162
 
@@ -164,16 +166,18 @@ describe GandiV5::Domain do
164
166
  'errors' => [{ 'description' => 'd', 'location' => 'l', 'name' => 'n' }]
165
167
  }
166
168
  expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 1)
167
- .and_return(returns)
169
+ .and_return([nil, returns])
168
170
  expect(described_class.create('example.com', owner: {}, dry_run: true)).to be returns
169
171
  end
170
172
  end
171
173
 
172
174
  it 'Success' do
173
- returns = { 'message' => 'Confirmation message.' }
175
+ returns = double described_class
176
+ response = double RestClient::Response, headers: { location: 'https://api.gandi.net/v5/domains/example.com' }
174
177
  body = '{"owner":{},"fqdn":"example.com"}'
175
178
  expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
176
- .and_return(returns)
179
+ .and_return([response, nil])
180
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
177
181
  expect(described_class.create('example.com', owner: {})).to be returns
178
182
  end
179
183
 
@@ -182,74 +186,25 @@ describe GandiV5::Domain do
182
186
  end
183
187
 
184
188
  it 'Given contact as hash' do
189
+ returns = double described_class
185
190
  body = '{"owner":{"email":"owner@example.com"},"fqdn":"example.com"}'
186
- expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
191
+ response = double RestClient::Response, headers: { location: 'https://api.gandi.net/v5/domains/example.com' }
192
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0).and_return([response, nil])
193
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
187
194
  described_class.create 'example.com', owner: { email: 'owner@example.com' }
188
195
  end
189
196
 
190
197
  it 'Given contact as GandiV5::Domain::Contact' do
198
+ returns = double described_class
191
199
  body = '{"owner":{"email":"owner@example.com"},"fqdn":"example.com"}'
192
- expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
200
+ response = double RestClient::Response, headers: { location: 'https://api.gandi.net/v5/domains/example.com' }
201
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0).and_return([response, nil])
202
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
193
203
  owner = double GandiV5::Domain::Contact, to_gandi: { 'email' => 'owner@example.com' }
194
204
  described_class.create 'example.com', owner: owner
195
205
  end
196
206
  end
197
207
 
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
208
  describe '#to_s' do
254
209
  it 'Has identical fqdn and fqdn_unicode' do
255
210
  domain = described_class.new fqdn: 'example.com', fqdn_unicode: 'example.com'
@@ -266,7 +221,7 @@ describe GandiV5::Domain do
266
221
  before :each do
267
222
  body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'get.yaml'))
268
223
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com')
269
- .and_return(YAML.load_file(body_fixture))
224
+ .and_return([nil, YAML.load_file(body_fixture)])
270
225
  subject.refresh
271
226
  end
272
227
 
@@ -322,7 +277,7 @@ describe GandiV5::Domain do
322
277
  before(:each) do
323
278
  body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_contacts.yaml'))
324
279
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/contacts')
325
- .and_return(YAML.load_file(body_fixture))
280
+ .and_return([nil, YAML.load_file(body_fixture)])
326
281
  end
327
282
 
328
283
  its('owner.country') { should eq 'GB' }
@@ -379,7 +334,7 @@ describe GandiV5::Domain do
379
334
  before(:each) do
380
335
  body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'renewal_info.yaml'))
381
336
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/renew')
382
- .and_return(YAML.load_file(body_fixture))
337
+ .and_return([nil, YAML.load_file(body_fixture)])
383
338
  end
384
339
 
385
340
  its('begins_at') { should eq Time.new(2012, 1, 1, 0, 0, 0) }
@@ -394,9 +349,62 @@ describe GandiV5::Domain do
394
349
 
395
350
  it '#renew_for' do
396
351
  expect(GandiV5).to receive(:post).with('https://api.gandi.net/v5/domain/domains/example.com/renew', '{"duration":2}')
397
- .and_return('message' => 'Confirmation message.')
352
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
398
353
  expect(subject.renew_for(2)).to eq 'Confirmation message.'
399
354
  end
355
+
356
+ describe '#renewal_price' do
357
+ it 'Default values' do
358
+ price = double GandiV5::Domain::Availability::Product::Price
359
+ arguments = { processes: [:renew], currency: 'GBP', period: 1 }
360
+ expect(GandiV5::Domain::Availability).to receive(:fetch).with('example.com', **arguments).and_return(
361
+ double(
362
+ GandiV5::Domain::Availability,
363
+ products: [
364
+ double(
365
+ GandiV5::Domain::Availability::Product,
366
+ prices: [price]
367
+ )
368
+ ]
369
+ )
370
+ )
371
+ expect(subject.renewal_price).to be price
372
+ end
373
+
374
+ it 'Passed currency' do
375
+ price = double GandiV5::Domain::Availability::Product::Price
376
+ arguments = { processes: [:renew], currency: 'EUR', period: 1 }
377
+ expect(GandiV5::Domain::Availability).to receive(:fetch).with('example.com', **arguments).and_return(
378
+ double(
379
+ GandiV5::Domain::Availability,
380
+ products: [
381
+ double(
382
+ GandiV5::Domain::Availability::Product,
383
+ prices: [price]
384
+ )
385
+ ]
386
+ )
387
+ )
388
+ expect(subject.renewal_price(currency: 'EUR')).to be price
389
+ end
390
+
391
+ it 'Passed period' do
392
+ price = double GandiV5::Domain::Availability::Product::Price
393
+ arguments = { processes: [:renew], currency: 'GBP', period: 2 }
394
+ expect(GandiV5::Domain::Availability).to receive(:fetch).with('example.com', **arguments).and_return(
395
+ double(
396
+ GandiV5::Domain::Availability,
397
+ products: [
398
+ double(
399
+ GandiV5::Domain::Availability::Product,
400
+ prices: [price]
401
+ )
402
+ ]
403
+ )
404
+ )
405
+ expect(subject.renewal_price(period: 2)).to be price
406
+ end
407
+ end
400
408
  end
401
409
 
402
410
  describe 'Domain restoration' do
@@ -422,7 +430,7 @@ describe GandiV5::Domain do
422
430
  before(:each) do
423
431
  body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'restore_info.yaml'))
424
432
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/restore')
425
- .and_return(YAML.load_file(body_fixture))
433
+ .and_return([nil, YAML.load_file(body_fixture)])
426
434
  end
427
435
 
428
436
  its('restorable') { should be true }
@@ -444,7 +452,7 @@ describe GandiV5::Domain do
444
452
 
445
453
  it '#restore' do
446
454
  expect(GandiV5).to receive(:post).with('https://api.gandi.net/v5/domain/domains/example.com/restore', '{}')
447
- .and_return('message' => 'Confirmation message.')
455
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
448
456
  expect(subject.restore).to eq 'Confirmation message.'
449
457
  end
450
458
  end
@@ -128,4 +128,56 @@ describe GandiV5::Email::Mailbox::Responder do
128
128
  end
129
129
  end
130
130
  end
131
+
132
+ describe '#enable' do
133
+ let(:mailbox) { double GandiV5::Email::Mailbox }
134
+ let(:update) do
135
+ {
136
+ starts_at: '2019-01-01T00:00:00Z',
137
+ ends_at: '2020-01-01T00:00:00Z',
138
+ message: 'Auto response message.',
139
+ enabled: true
140
+ }
141
+ end
142
+
143
+ it 'Uses now as default starts_at' do
144
+ starts_at = Time.new(2019, 1, 1, 0, 0, 0, 0)
145
+ Timecop.freeze(starts_at) do
146
+ ends_at = Time.new(2020, 1, 1, 0, 0, 0, 0)
147
+ subject = described_class.new mailbox: mailbox
148
+ expect(mailbox).to receive(:update).with(responder: update)
149
+
150
+ subject.enable message: 'Auto response message.', ends_at: ends_at
151
+ expect(subject.enabled).to be true
152
+ expect(subject.message).to eq 'Auto response message.'
153
+ expect(subject.starts_at).to eq starts_at
154
+ expect(subject.ends_at).to eq ends_at
155
+ end
156
+ end
157
+
158
+ it 'Uses passed starts_at' do
159
+ starts_at = Time.new(2019, 1, 1, 0, 0, 0, 0)
160
+ ends_at = Time.new(2020, 1, 1, 0, 0, 0, 0)
161
+ subject = described_class.new mailbox: mailbox
162
+ expect(mailbox).to receive(:update).with(responder: update)
163
+
164
+ subject.enable message: 'Auto response message.', starts_at: starts_at, ends_at: ends_at
165
+ expect(subject.enabled).to be true
166
+ expect(subject.message).to eq 'Auto response message.'
167
+ expect(subject.starts_at).to eq starts_at
168
+ expect(subject.ends_at).to eq ends_at
169
+ end
170
+ end
171
+
172
+ it '#disable' do
173
+ mailbox = double GandiV5::Email::Mailbox
174
+ subject = described_class.new mailbox: mailbox
175
+ expect(mailbox).to receive(:update).with(responder: { enabled: false })
176
+
177
+ subject.disable
178
+ expect(subject.enabled).to be false
179
+ expect(subject.message).to be nil
180
+ expect(subject.starts_at).to be nil
181
+ expect(subject.ends_at).to be nil
182
+ end
131
183
  end
@@ -11,7 +11,7 @@ describe GandiV5::Email::Mailbox do
11
11
  before :each do
12
12
  body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Email_Mailbox', 'get.yaml'))
13
13
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com/mailbox-uuid')
14
- .and_return(YAML.load_file(body_fixture))
14
+ .and_return([nil, YAML.load_file(body_fixture)])
15
15
  subject.refresh
16
16
  end
17
17
 
@@ -22,6 +22,7 @@ describe GandiV5::Email::Mailbox do
22
22
  its('login') { should eq 'address' }
23
23
  its('type') { should eq :standard }
24
24
  its('quota_used') { should eq 1_000_000 }
25
+ its('responder.mailbox') { should be subject }
25
26
  its('responder.enabled') { should be false }
26
27
  its('responder.starts_at') { should eq Time.new(2000, 1, 1, 0, 0, 0) }
27
28
  its('responder.ends_at') { should eq Time.new(2000, 1, 2, 0, 0, 0) }
@@ -33,14 +34,14 @@ describe GandiV5::Email::Mailbox do
33
34
 
34
35
  it 'Aliases' do
35
36
  expect(GandiV5).to receive(:patch).with(url, '{"aliases":["alias-1"]}')
36
- .and_return('message' => 'Confirmation message.')
37
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
37
38
  expect(subject).to receive(:refresh)
38
39
  expect(subject.update(aliases: ['alias-1'])).to eq 'Confirmation message.'
39
40
  end
40
41
 
41
42
  it 'Login' do
42
43
  expect(GandiV5).to receive(:patch).with(url, '{"login":"new-login"}')
43
- .and_return('message' => 'Confirmation message.')
44
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
44
45
  expect(subject).to receive(:refresh)
45
46
  expect(subject.update(login: 'new-login')).to eq 'Confirmation message.'
46
47
  end
@@ -48,7 +49,7 @@ describe GandiV5::Email::Mailbox do
48
49
  describe 'Password' do
49
50
  it 'Password is good' do
50
51
  expect(GandiV5).to receive(:patch).with(url, '{"password":"crypted_password"}')
51
- .and_return('message' => 'Confirmation message.')
52
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
52
53
  expect(subject).to receive(:refresh)
53
54
  expect(subject).to receive(:crypt_password).with(good_password).and_return('crypted_password')
54
55
  expect(subject.update(password: good_password)).to eq 'Confirmation message.'
@@ -63,7 +64,7 @@ describe GandiV5::Email::Mailbox do
63
64
  describe 'Responder' do
64
65
  before(:each) do
65
66
  expect(GandiV5).to receive(:patch).with(url, '{"responder":{"enabled":false}}')
66
- .and_return('message' => 'Confirmation message.')
67
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
67
68
 
68
69
  expect(subject).to receive(:refresh)
69
70
  end
@@ -89,14 +90,14 @@ describe GandiV5::Email::Mailbox do
89
90
  it '#delete' do
90
91
  url = 'https://api.gandi.net/v5/email/mailboxes/example.com/mailbox-uuid'
91
92
  expect(GandiV5).to receive(:delete).with(url)
92
- .and_return('message' => 'Confirmation message.')
93
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
93
94
  expect(subject.delete).to eq 'Confirmation message.'
94
95
  end
95
96
 
96
97
  it '#purge' do
97
98
  url = 'https://api.gandi.net/v5/email/mailboxes/example.com/mailbox-uuid/contents'
98
99
  expect(GandiV5).to receive(:delete).with(url)
99
- .and_return('message' => 'Confirmation message.')
100
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
100
101
  expect(subject.purge).to eq 'Confirmation message.'
101
102
  end
102
103
 
@@ -186,33 +187,49 @@ describe GandiV5::Email::Mailbox do
186
187
 
187
188
  describe '.create' do
188
189
  let(:url) { 'https://api.gandi.net/v5/email/mailboxes/example.com' }
190
+ let(:created_response) do
191
+ double(
192
+ RestClient::Response,
193
+ headers: { location: 'https://api.gandi.net/v5/email/mailboxes/example.com/created-mailbox-uuid' }
194
+ )
195
+ end
196
+ let(:created_mailbox) { double GandiV5::Email::Mailbox }
197
+
198
+ before :each do
199
+ allow(GandiV5::Email::Slot).to receive(:list).and_return [
200
+ GandiV5::Email::Slot.new(mailbox_type: :standard, status: :inactive),
201
+ GandiV5::Email::Slot.new(mailbox_type: :premium, status: :inactive)
202
+ ]
203
+ end
189
204
 
190
205
  it 'No aliases and :standard type' do
191
206
  body = '{"mailbox_type":"standard","login":"login","password":"crypted_password","aliases":[]}'
192
207
  expect(GandiV5).to receive(:post).with(url, body)
193
- .and_return('message' => 'Confirmation message.')
208
+ .and_return([created_response, { 'message' => 'Confirmation message.' }])
194
209
  expect(described_class).to receive(:crypt_password).with(good_password).and_return('crypted_password')
210
+ expect(described_class).to receive(:fetch).with('example.com', 'created-mailbox-uuid').and_return(created_mailbox)
195
211
 
196
- expect(described_class.create('example.com', 'login', good_password)).to eq 'Confirmation message.'
212
+ expect(described_class.create('example.com', 'login', good_password)).to be created_mailbox
197
213
  end
198
214
 
199
215
  it 'With aliases' do
200
216
  body = '{"mailbox_type":"standard","login":"login","password":"crypted_password","aliases":["alias-1"]}'
201
217
  expect(GandiV5).to receive(:post).with(url, body)
202
- .and_return('message' => 'Confirmation message.')
218
+ .and_return([created_response, { 'message' => 'Confirmation message.' }])
203
219
  expect(described_class).to receive(:crypt_password).with(good_password).and_return('crypted_password')
220
+ expect(described_class).to receive(:fetch).with('example.com', 'created-mailbox-uuid').and_return(created_mailbox)
204
221
 
205
- expect(described_class.create('example.com', 'login', good_password, aliases: ['alias-1']))
206
- .to eq 'Confirmation message.'
222
+ expect(described_class.create('example.com', 'login', good_password, aliases: ['alias-1'])).to be created_mailbox
207
223
  end
208
224
 
209
225
  it 'With different type' do
210
226
  body = '{"mailbox_type":"premium","login":"login","password":"crypted_password","aliases":[]}'
211
227
  expect(GandiV5).to receive(:post).with(url, body)
212
- .and_return('message' => 'Confirmation message.')
228
+ .and_return([created_response, { 'message' => 'Confirmation message.' }])
213
229
  expect(described_class).to receive(:crypt_password).with(good_password).and_return('crypted_password')
230
+ expect(described_class).to receive(:fetch).with('example.com', 'created-mailbox-uuid').and_return(created_mailbox)
214
231
 
215
- expect(described_class.create('example.com', 'login', good_password, type: :premium)).to eq 'Confirmation message.'
232
+ expect(described_class.create('example.com', 'login', good_password, type: :premium)).to be created_mailbox
216
233
  end
217
234
 
218
235
  it 'Bad password' do
@@ -220,8 +237,23 @@ describe GandiV5::Email::Mailbox do
220
237
  expect { described_class.create 'example.com', 'login', 'password' }.to raise_error ArgumentError, 'message'
221
238
  end
222
239
 
223
- # TODO: pending 'Bad type'
224
- # TODO: pending 'No available slots'
240
+ it 'Bad type' do
241
+ expect { described_class.create 'example.com', 'login', good_password, type: :invalid }.to raise_error(
242
+ ArgumentError,
243
+ ':invalid is not a valid type'
244
+ )
245
+ end
246
+
247
+ it 'No free slot' do
248
+ expect(GandiV5::Email::Slot).to receive(:list).and_return [
249
+ GandiV5::Email::Slot.new(mailbox_type: :standard, status: :active),
250
+ GandiV5::Email::Slot.new(mailbox_type: :premium, status: :inactive)
251
+ ]
252
+ expect { described_class.create 'example.com', 'login', good_password }.to raise_error(
253
+ GandiV5::Error,
254
+ 'no available standard slots'
255
+ )
256
+ end
225
257
  end
226
258
 
227
259
  describe '.fetch' do
@@ -230,7 +262,7 @@ describe GandiV5::Email::Mailbox do
230
262
  before :each do
231
263
  body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Email_Mailbox', 'get.yaml'))
232
264
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com/mailbox-uuid')
233
- .and_return(YAML.load_file(body_fixture))
265
+ .and_return([nil, YAML.load_file(body_fixture)])
234
266
  end
235
267
 
236
268
  its('address') { should eq 'address@example.com' }
@@ -240,6 +272,7 @@ describe GandiV5::Email::Mailbox do
240
272
  its('login') { should eq 'address' }
241
273
  its('type') { should eq :standard }
242
274
  its('quota_used') { should eq 1_000_000 }
275
+ its('responder.mailbox') { should be subject }
243
276
  its('responder.enabled') { should be false }
244
277
  its('responder.starts_at') { should eq Time.new(2000, 1, 1, 0, 0, 0) }
245
278
  its('responder.ends_at') { should eq Time.new(2000, 1, 2, 0, 0, 0) }
@@ -257,7 +290,7 @@ describe GandiV5::Email::Mailbox do
257
290
  before :each do
258
291
  headers = { params: { page: 1 } }
259
292
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com', headers)
260
- .and_return(YAML.load_file(body_fixture))
293
+ .and_return([nil, YAML.load_file(body_fixture)])
261
294
  end
262
295
 
263
296
  its('count') { should eq 1 }
@@ -272,15 +305,13 @@ describe GandiV5::Email::Mailbox do
272
305
  it 'Keeps fetching until no more to get' do
273
306
  headers1 = { params: { page: 1, per_page: 1 } }
274
307
  headers2 = { params: { page: 2, per_page: 1 } }
275
- # rubocop:disable Layout/MultilineMethodCallIndentation
276
308
  # https://github.com/rubocop-hq/rubocop/issues/7088
277
309
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com', headers1)
278
310
  .ordered
279
- .and_return(YAML.load_file(body_fixture))
311
+ .and_return([nil, YAML.load_file(body_fixture)])
280
312
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com', headers2)
281
313
  .ordered
282
- .and_return([])
283
- # rubocop:enable Layout/MultilineMethodCallIndentation
314
+ .and_return([nil, []])
284
315
 
285
316
  expect(described_class.list('example.com', per_page: 1).count).to eq 1
286
317
  end
@@ -288,15 +319,13 @@ describe GandiV5::Email::Mailbox do
288
319
  it 'Given a range as page number' do
289
320
  headers1 = { params: { page: 1, per_page: 1 } }
290
321
  headers2 = { params: { page: 2, per_page: 1 } }
291
- # rubocop:disable Layout/MultilineMethodCallIndentation
292
322
  # https://github.com/rubocop-hq/rubocop/issues/7088
293
323
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com', headers1)
294
324
  .ordered
295
- .and_return(YAML.load_file(body_fixture))
325
+ .and_return([nil, YAML.load_file(body_fixture)])
296
326
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com', headers2)
297
327
  .ordered
298
- .and_return([])
299
- # rubocop:enable Layout/MultilineMethodCallIndentation
328
+ .and_return([nil, []])
300
329
 
301
330
  expect(described_class.list('example.com', page: (1..2), per_page: 1).count).to eq 1
302
331
  end
@@ -309,7 +338,7 @@ describe GandiV5::Email::Mailbox do
309
338
  it param.to_s do
310
339
  headers = { params: { page: 1 }.merge(query_param => 'value') }
311
340
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com', headers)
312
- .and_return([])
341
+ .and_return([nil, []])
313
342
  expect(described_class.list('example.com', param => 'value')).to eq []
314
343
  end
315
344
  end
@@ -8,7 +8,7 @@ describe GandiV5::Email::Offer do
8
8
 
9
9
  before :each do
10
10
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/offers/example.com')
11
- .and_return('status' => 'active', 'version' => 2)
11
+ .and_return([nil, { 'status' => 'active', 'version' => 2 }])
12
12
  end
13
13
 
14
14
  its('status') { should be :active }