gandi_v5 0.1.0 → 0.2.0

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