gandi_v5 0.1.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +14 -4
  4. data/.travis.yml +16 -1
  5. data/CHANGELOG.md +80 -2
  6. data/FUNDING.yml +10 -0
  7. data/Guardfile +5 -6
  8. data/LICENSE.md +2 -6
  9. data/README.md +17 -23
  10. data/gandi_v5.gemspec +4 -3
  11. data/lib/gandi_v5.rb +54 -15
  12. data/lib/gandi_v5/billing.rb +2 -4
  13. data/lib/gandi_v5/billing/info.rb +0 -2
  14. data/lib/gandi_v5/data.rb +1 -2
  15. data/lib/gandi_v5/data/converter.rb +0 -4
  16. data/lib/gandi_v5/data/converter/integer.rb +26 -0
  17. data/lib/gandi_v5/domain.rb +201 -101
  18. data/lib/gandi_v5/domain/auto_renew.rb +4 -4
  19. data/lib/gandi_v5/domain/availability.rb +46 -0
  20. data/lib/gandi_v5/domain/availability/product.rb +49 -0
  21. data/lib/gandi_v5/domain/availability/product/period.rb +24 -0
  22. data/lib/gandi_v5/domain/availability/product/price.rb +36 -0
  23. data/lib/gandi_v5/domain/availability/tax.rb +20 -0
  24. data/lib/gandi_v5/domain/live_dns.rb +42 -0
  25. data/lib/gandi_v5/domain/renewal_information.rb +0 -3
  26. data/lib/gandi_v5/domain/sharing_space.rb +10 -2
  27. data/lib/gandi_v5/domain/tld.rb +57 -0
  28. data/lib/gandi_v5/email.rb +0 -4
  29. data/lib/gandi_v5/email/forward.rb +108 -0
  30. data/lib/gandi_v5/email/mailbox.rb +85 -24
  31. data/lib/gandi_v5/email/mailbox/responder.rb +43 -2
  32. data/lib/gandi_v5/email/offer.rb +2 -2
  33. data/lib/gandi_v5/email/slot.rb +52 -18
  34. data/lib/gandi_v5/error.rb +0 -2
  35. data/lib/gandi_v5/error/gandi_error.rb +2 -2
  36. data/lib/gandi_v5/live_dns.rb +20 -4
  37. data/lib/gandi_v5/live_dns/domain.rb +21 -150
  38. data/lib/gandi_v5/live_dns/has_zone_records.rb +153 -0
  39. data/lib/gandi_v5/live_dns/record_set.rb +1 -1
  40. data/lib/gandi_v5/live_dns/zone.rb +24 -165
  41. data/lib/gandi_v5/live_dns/zone/snapshot.rb +27 -8
  42. data/lib/gandi_v5/organization.rb +39 -6
  43. data/lib/gandi_v5/organization/customer.rb +90 -0
  44. data/lib/gandi_v5/version.rb +1 -1
  45. data/spec/.rubocop.yml +9 -2
  46. data/spec/features/domain_spec.rb +2 -2
  47. data/spec/features/livedns_zone_spec.rb +12 -13
  48. data/spec/fixtures/bodies/GandiV5_Billing/{info.yaml → info.yml} +0 -0
  49. data/spec/fixtures/bodies/GandiV5_Domain/{get.yaml → fetch.yml} +8 -0
  50. data/spec/fixtures/bodies/GandiV5_Domain/{fetch_contacts.yaml → fetch_contacts.yml} +0 -0
  51. data/spec/fixtures/bodies/GandiV5_Domain/fetch_glue_records.yml +7 -0
  52. data/spec/fixtures/bodies/GandiV5_Domain/fetch_livedns.yml +6 -0
  53. data/spec/fixtures/bodies/GandiV5_Domain/fetch_name_servers.yml +2 -0
  54. data/spec/fixtures/bodies/GandiV5_Domain/{renewal_info.yaml → fetch_renewal_info.yml} +0 -3
  55. data/spec/fixtures/bodies/GandiV5_Domain/{restore_info.yaml → fetch_restore_info.yml} +0 -0
  56. data/spec/fixtures/bodies/GandiV5_Domain/{list.yaml → list.yml} +1 -0
  57. data/spec/fixtures/bodies/{GandiV5_Domain/availability.yaml → GandiV5_Domain_Availability/fetch.yml} +0 -0
  58. data/spec/fixtures/bodies/{GandiV5_Domain/tld.yaml → GandiV5_Domain_TLD/fetch.yml} +0 -0
  59. data/spec/fixtures/bodies/{GandiV5_Domain/tlds.yaml → GandiV5_Domain_TLD/list.yml} +0 -0
  60. data/spec/fixtures/bodies/GandiV5_Email_Forward/list.yml +6 -0
  61. data/spec/fixtures/bodies/GandiV5_Email_Mailbox/{get.yaml → fetch.yml} +0 -0
  62. data/spec/fixtures/bodies/GandiV5_Email_Mailbox/{list.yaml → list.yml} +0 -0
  63. data/spec/fixtures/bodies/GandiV5_Email_Slot/{get.yaml → fetch.yml} +0 -0
  64. data/spec/fixtures/bodies/GandiV5_Email_Slot/{list.yaml → list.yml} +0 -0
  65. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/{get.yaml → fetch.yml} +0 -0
  66. data/spec/fixtures/bodies/GandiV5_LiveDNS_Domain/{list.yaml → list.yml} +0 -0
  67. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/{get.yaml → fetch.yml} +0 -0
  68. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone/{list.yaml → list.yml} +0 -0
  69. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/{get.yaml → fetch.yml} +0 -0
  70. data/spec/fixtures/bodies/GandiV5_LiveDNS_Zone_Snapshot/list.yml +3 -0
  71. data/spec/fixtures/bodies/GandiV5_Organization/{get.yaml → fetch.yml} +0 -0
  72. data/spec/fixtures/bodies/GandiV5_Organization/list.yml +7 -0
  73. data/spec/fixtures/bodies/GandiV5_Organization_Customer/list.yml +8 -0
  74. data/spec/fixtures/vcr/Domain_features/List_domains.yml +2 -1
  75. data/spec/spec_helper.rb +2 -2
  76. data/spec/units/gandi_v5/billing_spec.rb +4 -4
  77. data/spec/units/gandi_v5/data/converter/integer_spec.rb +16 -0
  78. data/spec/units/gandi_v5/domain/auto_renew_spec.rb +5 -5
  79. data/spec/units/gandi_v5/domain/availability/product/period_spec.rb +4 -0
  80. data/spec/units/gandi_v5/domain/availability/product/price_spec.rb +4 -0
  81. data/spec/units/gandi_v5/domain/availability/product_spec.rb +4 -0
  82. data/spec/units/gandi_v5/domain/availability/tax_spec.rb +4 -0
  83. data/spec/units/gandi_v5/domain/availability_spec.rb +43 -0
  84. data/spec/units/gandi_v5/domain/live_dns_spec.rb +45 -0
  85. data/spec/units/gandi_v5/domain/tld_spec.rb +29 -0
  86. data/spec/units/gandi_v5/domain_spec.rb +359 -91
  87. data/spec/units/gandi_v5/email/forward_spec.rb +121 -0
  88. data/spec/units/gandi_v5/email/mailbox/responder_spec.rb +52 -0
  89. data/spec/units/gandi_v5/email/mailbox_spec.rb +174 -33
  90. data/spec/units/gandi_v5/email/offer_spec.rb +1 -1
  91. data/spec/units/gandi_v5/email/slot_spec.rb +113 -17
  92. data/spec/units/gandi_v5/live_dns/domain_spec.rb +73 -43
  93. data/spec/units/gandi_v5/live_dns/zone/snapshot_spec.rb +32 -3
  94. data/spec/units/gandi_v5/live_dns/zone_spec.rb +70 -52
  95. data/spec/units/gandi_v5/live_dns_spec.rb +24 -0
  96. data/spec/units/gandi_v5/organization/customer_spec.rb +81 -0
  97. data/spec/units/gandi_v5/organization_spec.rb +52 -1
  98. data/spec/units/gandi_v5_spec.rb +56 -19
  99. metadata +71 -29
  100. data/TODO.md +0 -29
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GandiV5::Data::Converter::Integer do
4
+ it '.from_gandi' do
5
+ expect(described_class.from_gandi('123')).to eq 123
6
+ end
7
+
8
+ it '.to_gandi' do
9
+ expect(described_class.to_gandi(123)).to eq '123'
10
+ end
11
+
12
+ it 'nil value' do
13
+ expect(described_class.from_gandi(nil)).to be nil
14
+ expect(described_class.to_gandi(nil)).to be nil
15
+ end
16
+ end
@@ -6,7 +6,7 @@ describe GandiV5::Domain::AutoRenew do
6
6
 
7
7
  it '#disable' do
8
8
  expect(GandiV5).to receive(:patch).with(url, '{"enabled":false}')
9
- .and_return('message' => 'Confirmation message.')
9
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
10
10
  expect(subject.disable).to eq 'Confirmation message.'
11
11
  expect(subject.enabled).to be false
12
12
  end
@@ -14,7 +14,7 @@ describe GandiV5::Domain::AutoRenew do
14
14
  describe '#enable' do
15
15
  it 'Success' do
16
16
  expect(GandiV5).to receive(:patch).with(url, '{"enabled":true,"duration":1,"org_id":"org-uuid"}')
17
- .and_return('message' => 'Confirmation message.')
17
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
18
18
  expect(subject.enable(org_id: 'org-uuid', duration: 1)).to eq 'Confirmation message.'
19
19
  expect(subject.enabled).to be true
20
20
  end
@@ -36,7 +36,7 @@ describe GandiV5::Domain::AutoRenew do
36
36
  describe 'Missing duration' do
37
37
  it 'Uses #duration if present' do
38
38
  expect(GandiV5).to receive(:patch).with(url, '{"enabled":true,"duration":5,"org_id":"org-uuid"}')
39
- .and_return('message' => 'Confirmation message.')
39
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
40
40
  expect(subject).to receive(:duration).and_return(5)
41
41
  expect(subject.enable(org_id: 'org-uuid')).to eq 'Confirmation message.'
42
42
  expect(subject.enabled).to be true
@@ -44,7 +44,7 @@ describe GandiV5::Domain::AutoRenew do
44
44
 
45
45
  it 'Uses 1 if #duration not present' do
46
46
  expect(GandiV5).to receive(:patch).with(url, '{"enabled":true,"duration":1,"org_id":"org-uuid"}')
47
- .and_return('message' => 'Confirmation message.')
47
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
48
48
  expect(subject.enable(org_id: 'org-uuid')).to eq 'Confirmation message.'
49
49
  expect(subject.enabled).to be true
50
50
  end
@@ -53,7 +53,7 @@ describe GandiV5::Domain::AutoRenew do
53
53
  describe 'Missing org_id' do
54
54
  it 'Uses #org_id if present' do
55
55
  expect(GandiV5).to receive(:patch).with(url, '{"enabled":true,"duration":1,"org_id":"org-uuid"}')
56
- .and_return('message' => 'Confirmation message.')
56
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
57
57
  expect(subject).to receive(:org_id).and_return('org-uuid')
58
58
  expect(subject.enable).to eq 'Confirmation message.'
59
59
  expect(subject.enabled).to be true
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GandiV5::Domain::Availability::Product::Period do
4
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GandiV5::Domain::Availability::Product::Price do
4
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GandiV5::Domain::Availability::Product do
4
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GandiV5::Domain::Availability::Tax do
4
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GandiV5::Domain::Availability do
4
+ describe '.fetch' do
5
+ let(:body_fixture) do
6
+ File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain_Availability', 'fetch.yml'))
7
+ end
8
+
9
+ describe 'With default values' do
10
+ subject { described_class.fetch 'example.com' }
11
+
12
+ before(:each) do
13
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/check', params: { name: 'example.com' })
14
+ .and_return([nil, YAML.load_file(body_fixture)])
15
+ end
16
+
17
+ its('currency') { should eq 'GBP' }
18
+ its('grid') { should eq 'A' }
19
+ its('products.size') { should eq 1 }
20
+ its('products.first.status') { should eq :unavailable }
21
+ its('products.first.name') { should eq 'example.com' }
22
+ its('products.first.process') { should eq :create }
23
+ its('products.first.taxes.size') { should eq 1 }
24
+ its('products.first.taxes.first.type') { should eq 'service' }
25
+ its('products.first.taxes.first.rate') { should eq 0 }
26
+ its('products.first.taxes.first.name') { should eq 'vat' }
27
+ its('taxes.size') { should eq 1 }
28
+ its('taxes.first.type') { should eq 'service' }
29
+ its('taxes.first.rate') { should eq 0 }
30
+ its('taxes.first.name') { should eq 'vat' }
31
+ end
32
+
33
+ describe 'Passes optional query params' do
34
+ %i[country currency duration_unit extension grid lang max_duration period processes sharing_uuid].each do |param|
35
+ it param.to_s do
36
+ url = 'https://api.gandi.net/v5/domain/check'
37
+ expect(GandiV5).to receive(:get).with(url, params: { name: 'example.com', param => 5 }).and_return([nil, {}])
38
+ described_class.fetch('example.com', param => 5)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GandiV5::Domain::LiveDNS do
4
+ describe '#classic?' do
5
+ it 'Is using classic DNS' do
6
+ expect(described_class.new(current: :classic).classic?).to be true
7
+ end
8
+
9
+ it 'Is using LiveDNS' do
10
+ expect(described_class.new(current: :livedns).classic?).to be false
11
+ end
12
+
13
+ it 'Is using custom DNS' do
14
+ expect(described_class.new(current: :custom).classic?).to be false
15
+ end
16
+ end
17
+
18
+ describe '#livedns?' do
19
+ it 'Is using classic DNS' do
20
+ expect(described_class.new(current: :classic).livedns?).to be false
21
+ end
22
+
23
+ it 'Is using LiveDNS' do
24
+ expect(described_class.new(current: :livedns).livedns?).to be true
25
+ end
26
+
27
+ it 'Is using custom DNS' do
28
+ expect(described_class.new(current: :custom).livedns?).to be false
29
+ end
30
+ end
31
+
32
+ describe '#custom?' do
33
+ it 'Is using classic DNS' do
34
+ expect(described_class.new(current: :classic).custom?).to be false
35
+ end
36
+
37
+ it 'Is using LiveDNS' do
38
+ expect(described_class.new(current: :livedns).custom?).to be false
39
+ end
40
+
41
+ it 'Is using custom DNS' do
42
+ expect(described_class.new(current: :custom).custom?).to be true
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GandiV5::Domain::TLD do
4
+ it '.list' do
5
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain_TLD', 'list.yml'))
6
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/tlds')
7
+ .and_return([nil, YAML.load_file(body_fixture)])
8
+ expect(described_class.list.map(&:name)).to match_array %w[a b c]
9
+ end
10
+
11
+ describe '.fetch' do
12
+ subject { described_class.fetch 'name' }
13
+
14
+ before(:each) do
15
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain_TLD', 'fetch.yml'))
16
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/tlds/name')
17
+ .and_return([nil, YAML.load_file(body_fixture)])
18
+ end
19
+
20
+ its('category') { should eq :ccTLD }
21
+ its('name') { should eq 'eu' }
22
+ its('lock') { should be false }
23
+ its('change_owner') { should be true }
24
+ its('authinfo_for_transfer') { should be true }
25
+ its('full_tld') { should eq 'eu' }
26
+ its('corporate') { should be false }
27
+ its('ext_trade') { should be true }
28
+ end
29
+ end
@@ -4,7 +4,7 @@ describe GandiV5::Domain do
4
4
  subject { described_class.new fqdn: 'example.com' }
5
5
 
6
6
  describe '.list' do
7
- let(:body_fixture) { File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'list.yaml')) }
7
+ let(:body_fixture) { File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'list.yml')) }
8
8
 
9
9
  describe 'With default values' do
10
10
  subject { described_class.list }
@@ -12,14 +12,14 @@ 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 }
19
19
  its('first.uuid') { should eq 'domain-uuid' }
20
20
  its('first.fqdn') { should eq 'example.com' }
21
21
  its('first.fqdn_unicode') { should eq 'example.com' }
22
- its('first.name_servers') { should be_nil }
22
+ its('first.name_servers') { should eq [] }
23
23
  its('first.services') { should be_nil }
24
24
  its('first.status') { should eq [] }
25
25
  its('first.tld') { should eq 'com' }
@@ -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
@@ -93,9 +89,9 @@ describe GandiV5::Domain do
93
89
  subject { described_class.fetch 'example.com' }
94
90
 
95
91
  before :each do
96
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'get.yaml'))
92
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch.yml'))
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' }
@@ -112,7 +108,12 @@ describe GandiV5::Domain do
112
108
  its('domain_owner') { should be_nil }
113
109
  its('name_servers') { should match_array %w[192.168.0.1 192.168.0.2] }
114
110
  its('services') { should match_array %i[gandilivedns dnssec] }
115
- its('sharing_space') { should be_nil }
111
+ its('sharing_space.uuid') { should eq 'SHARING-UUID' }
112
+ its('sharing_space.name') { should eq 'User' }
113
+ its('sharing_space.type') { should eq 'user' }
114
+ its('sharing_space.reseller') { should be true }
115
+ its('sharing_space.reseller_details.uuid') { should eq 'RESELLER-UUID' }
116
+ its('sharing_space.reseller_details.name') { should eq 'Reseller' }
116
117
  its('dates.created_at') { should eq Time.new(2011, 2, 21, 10, 39, 0) }
117
118
  its('dates.registry_created_at') { should eq Time.new(2003, 3, 12, 12, 2, 11) }
118
119
  its('dates.registry_ends_at') { should eq Time.new(2020, 3, 12, 12, 2, 11) }
@@ -132,29 +133,33 @@ describe GandiV5::Domain do
132
133
 
133
134
  describe '.create' do
134
135
  let(:url) { 'https://api.gandi.net/v5/domain/domains' }
136
+ let(:returns) { double described_class }
137
+ let(:response) { double RestClient::Response, headers: { location: 'https://api.gandi.net/v5/domains/example.com' } }
135
138
 
136
139
  describe 'Sets dry-run header' do
137
140
  let(:body) { '{"owner":{},"fqdn":"example.com"}' }
138
141
 
139
142
  it 'False by default' do
140
- expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
143
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0).and_return([response, nil])
144
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
141
145
  described_class.create 'example.com', owner: {}
142
146
  end
143
147
 
144
148
  it 'True' do
145
- expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 1)
149
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 1).and_return([nil, nil])
146
150
  described_class.create 'example.com', owner: {}, dry_run: true
147
151
  end
148
152
 
149
153
  it 'False' do
150
- expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
154
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0).and_return([response, nil])
155
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
151
156
  described_class.create 'example.com', owner: {}, dry_run: false
152
157
  end
153
158
 
154
159
  it 'Dry run was successful' do
155
160
  returns = { 'status' => 'success' }
156
161
  expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 1)
157
- .and_return(returns)
162
+ .and_return([nil, returns])
158
163
  expect(described_class.create('example.com', owner: {}, dry_run: true)).to be returns
159
164
  end
160
165
 
@@ -164,16 +169,35 @@ describe GandiV5::Domain do
164
169
  'errors' => [{ 'description' => 'd', 'location' => 'l', 'name' => 'n' }]
165
170
  }
166
171
  expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 1)
167
- .and_return(returns)
172
+ .and_return([nil, returns])
168
173
  expect(described_class.create('example.com', owner: {}, dry_run: true)).to be returns
169
174
  end
170
175
  end
171
176
 
177
+ describe 'Sets sharing_id' do
178
+ it 'Absent by default' do
179
+ expect(GandiV5).to receive(:post).with(url, any_args).and_return([response, nil])
180
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
181
+ described_class.create('example.com', owner: {})
182
+ end
183
+
184
+ it 'Paying as another organization' do
185
+ expect(GandiV5).to receive(:post).with("#{url}?sharing_id=organization_id", any_args).and_return([response, nil])
186
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
187
+ described_class.create('example.com', sharing_id: 'organization_id', owner: {})
188
+ end
189
+
190
+ it 'Buy as a reseller' do
191
+ expect(GandiV5).to receive(:post).with("#{url}?sharing_id=reseller_id", any_args).and_return([response, nil])
192
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
193
+ described_class.create('example.com', sharing_id: 'reseller_id', owner: {})
194
+ end
195
+ end
196
+
172
197
  it 'Success' do
173
- returns = { 'message' => 'Confirmation message.' }
174
198
  body = '{"owner":{},"fqdn":"example.com"}'
175
- expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
176
- .and_return(returns)
199
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0).and_return([response, nil])
200
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
177
201
  expect(described_class.create('example.com', owner: {})).to be returns
178
202
  end
179
203
 
@@ -183,71 +207,36 @@ describe GandiV5::Domain do
183
207
 
184
208
  it 'Given contact as hash' do
185
209
  body = '{"owner":{"email":"owner@example.com"},"fqdn":"example.com"}'
186
- expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
210
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0).and_return([response, nil])
211
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
187
212
  described_class.create 'example.com', owner: { email: 'owner@example.com' }
188
213
  end
189
214
 
190
215
  it 'Given contact as GandiV5::Domain::Contact' do
191
216
  body = '{"owner":{"email":"owner@example.com"},"fqdn":"example.com"}'
192
- expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
217
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0).and_return([response, nil])
218
+ expect(described_class).to receive(:fetch).with('example.com').and_return(returns)
193
219
  owner = double GandiV5::Domain::Contact, to_gandi: { 'email' => 'owner@example.com' }
194
220
  described_class.create 'example.com', owner: owner
195
221
  end
196
222
  end
197
223
 
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
224
+ it '.mailboxes' do
225
+ returns = double Array
226
+ expect(GandiV5::Email::Mailbox).to receive(:list).with(param: :value, fqdn: 'example.com').and_return(returns)
227
+ expect(subject.mailboxes(param: :value)).to be returns
227
228
  end
228
229
 
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]
230
+ it '.mailbox_slots' do
231
+ returns = double Array
232
+ expect(GandiV5::Email::Slot).to receive(:list).with(param: :value, fqdn: 'example.com').and_return(returns)
233
+ expect(subject.mailbox_slots(param: :value)).to be returns
234
234
  end
235
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
- )
236
+ it '.email_forwards' do
237
+ returns = double Array
238
+ expect(GandiV5::Email::Forward).to receive(:list).with(param: :value, fqdn: 'example.com').and_return(returns)
239
+ expect(subject.email_forwards(param: :value)).to be returns
251
240
  end
252
241
 
253
242
  describe '#to_s' do
@@ -264,9 +253,9 @@ describe GandiV5::Domain do
264
253
 
265
254
  describe '#refresh' do
266
255
  before :each do
267
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'get.yaml'))
256
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch.yml'))
268
257
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com')
269
- .and_return(YAML.load_file(body_fixture))
258
+ .and_return([nil, YAML.load_file(body_fixture)])
270
259
  subject.refresh
271
260
  end
272
261
 
@@ -284,7 +273,7 @@ describe GandiV5::Domain do
284
273
  its('domain_owner') { should be_nil }
285
274
  its('name_servers') { should match_array %w[192.168.0.1 192.168.0.2] }
286
275
  its('services') { should match_array %i[gandilivedns dnssec] }
287
- its('sharing_space') { should be_nil }
276
+ its('sharing_space') { should_not be_nil }
288
277
  its('dates.created_at') { should eq Time.new(2011, 2, 21, 10, 39, 0) }
289
278
  its('dates.registry_created_at') { should eq Time.new(2003, 3, 12, 12, 2, 11) }
290
279
  its('dates.registry_ends_at') { should eq Time.new(2020, 3, 12, 12, 2, 11) }
@@ -320,9 +309,9 @@ describe GandiV5::Domain do
320
309
  subject { described_class.new(fqdn: 'example.com').fetch_contacts }
321
310
 
322
311
  before(:each) do
323
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_contacts.yaml'))
312
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_contacts.yml'))
324
313
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/contacts')
325
- .and_return(YAML.load_file(body_fixture))
314
+ .and_return([nil, YAML.load_file(body_fixture)])
326
315
  end
327
316
 
328
317
  its('owner.country') { should eq 'GB' }
@@ -377,9 +366,9 @@ describe GandiV5::Domain do
377
366
  subject { described_class.new(fqdn: 'example.com').fetch_renewal_information }
378
367
 
379
368
  before(:each) do
380
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'renewal_info.yaml'))
369
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_renewal_info.yml'))
381
370
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/renew')
382
- .and_return(YAML.load_file(body_fixture))
371
+ .and_return([nil, YAML.load_file(body_fixture)])
383
372
  end
384
373
 
385
374
  its('begins_at') { should eq Time.new(2012, 1, 1, 0, 0, 0) }
@@ -387,15 +376,101 @@ describe GandiV5::Domain do
387
376
  its('minimum') { should eq 1 }
388
377
  its('maximum') { should eq 2 }
389
378
  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
379
  end
394
380
 
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.'
381
+ describe '#renew_for' do
382
+ it 'Defaults to 1 year and current user' do
383
+ expect(GandiV5).to receive(:post).with(
384
+ 'https://api.gandi.net/v5/domain/domains/example.com/renew',
385
+ '{"duration":1}',
386
+ 'Dry-Run': 0
387
+ )
388
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
389
+ expect(subject.renew_for).to eq 'Confirmation message.'
390
+ end
391
+
392
+ it 'With provided duration' do
393
+ expect(GandiV5).to receive(:post).with(
394
+ 'https://api.gandi.net/v5/domain/domains/example.com/renew',
395
+ '{"duration":2}',
396
+ 'Dry-Run': 0
397
+ )
398
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
399
+ expect(subject.renew_for(2)).to eq 'Confirmation message.'
400
+ end
401
+
402
+ it 'With provided sharing_id' do
403
+ expect(GandiV5).to receive(:post).with(
404
+ 'https://api.gandi.net/v5/domain/domains/example.com/renew?sharing_id=def',
405
+ '{"duration":1}',
406
+ 'Dry-Run': 0
407
+ )
408
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
409
+ expect(subject.renew_for(sharing_id: 'def')).to eq 'Confirmation message.'
410
+ end
411
+
412
+ it 'Does a dry run' do
413
+ expect(GandiV5).to receive(:post).with(
414
+ 'https://api.gandi.net/v5/domain/domains/example.com/renew',
415
+ '{"duration":1}',
416
+ 'Dry-Run': 1
417
+ )
418
+ .and_return([nil, { 'status' => 'success' }])
419
+ expect(subject.renew_for(dry_run: true)).to eq('status' => 'success')
420
+ end
421
+ end
422
+
423
+ describe '#renewal_price' do
424
+ it 'Default values' do
425
+ price = double GandiV5::Domain::Availability::Product::Price
426
+ arguments = { processes: [:renew], currency: 'GBP', period: 1 }
427
+ expect(GandiV5::Domain::Availability).to receive(:fetch).with('example.com', **arguments).and_return(
428
+ double(
429
+ GandiV5::Domain::Availability,
430
+ products: [
431
+ double(
432
+ GandiV5::Domain::Availability::Product,
433
+ prices: [price]
434
+ )
435
+ ]
436
+ )
437
+ )
438
+ expect(subject.renewal_price).to be price
439
+ end
440
+
441
+ it 'Passed currency' do
442
+ price = double GandiV5::Domain::Availability::Product::Price
443
+ arguments = { processes: [:renew], currency: 'EUR', period: 1 }
444
+ expect(GandiV5::Domain::Availability).to receive(:fetch).with('example.com', **arguments).and_return(
445
+ double(
446
+ GandiV5::Domain::Availability,
447
+ products: [
448
+ double(
449
+ GandiV5::Domain::Availability::Product,
450
+ prices: [price]
451
+ )
452
+ ]
453
+ )
454
+ )
455
+ expect(subject.renewal_price(currency: 'EUR')).to be price
456
+ end
457
+
458
+ it 'Passed period' do
459
+ price = double GandiV5::Domain::Availability::Product::Price
460
+ arguments = { processes: [:renew], currency: 'GBP', period: 2 }
461
+ expect(GandiV5::Domain::Availability).to receive(:fetch).with('example.com', **arguments).and_return(
462
+ double(
463
+ GandiV5::Domain::Availability,
464
+ products: [
465
+ double(
466
+ GandiV5::Domain::Availability::Product,
467
+ prices: [price]
468
+ )
469
+ ]
470
+ )
471
+ )
472
+ expect(subject.renewal_price(period: 2)).to be price
473
+ end
399
474
  end
400
475
  end
401
476
 
@@ -420,9 +495,10 @@ describe GandiV5::Domain do
420
495
 
421
496
  describe 'Information is available' do
422
497
  before(:each) do
423
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'restore_info.yaml'))
498
+ body_fixture = File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_restore_info.yml')
499
+ body_fixture = File.expand_path(body_fixture)
424
500
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/restore')
425
- .and_return(YAML.load_file(body_fixture))
501
+ .and_return([nil, YAML.load_file(body_fixture)])
426
502
  end
427
503
 
428
504
  its('restorable') { should be true }
@@ -444,8 +520,200 @@ describe GandiV5::Domain do
444
520
 
445
521
  it '#restore' do
446
522
  expect(GandiV5).to receive(:post).with('https://api.gandi.net/v5/domain/domains/example.com/restore', '{}')
447
- .and_return('message' => 'Confirmation message.')
523
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
448
524
  expect(subject.restore).to eq 'Confirmation message.'
449
525
  end
450
526
  end
527
+
528
+ describe '#glue_records' do
529
+ let(:glue_records) { double Hash }
530
+
531
+ it 'Already fetched' do
532
+ subject.instance_exec(glue_records) { |glue_records| @glue_records = glue_records }
533
+ expect(subject).to_not receive(:fetch_glue_records)
534
+ expect(subject.glue_records).to be glue_records
535
+ end
536
+
537
+ it 'Not already fetched' do
538
+ expect(subject).to receive(:fetch_glue_records).and_return(glue_records)
539
+ expect(subject.glue_records).to be glue_records
540
+ end
541
+ end
542
+
543
+ it '#fetch_glue_records' do
544
+ body_fixture = File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_glue_records.yml')
545
+ body_fixture = File.expand_path(body_fixture)
546
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/hosts')
547
+ .and_return([nil, YAML.load_file(body_fixture)])
548
+ expect(subject.fetch_glue_records).to eq(
549
+ 'ns1' => ['1.2.3.4']
550
+ )
551
+ end
552
+
553
+ describe '#add_glue_record' do
554
+ before(:each) { described_class.instance_exec { @glue_records = {} } }
555
+
556
+ it 'Make API request' do
557
+ expect(GandiV5).to receive(:post).with(
558
+ 'https://api.gandi.net/v5/domain/domains/example.com/hosts',
559
+ '{"name":"ns1","ips":["1.2.3.4"]}'
560
+ )
561
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
562
+ expect(subject.add_glue_record('ns1', '1.2.3.4')).to eq 'Confirmation message.'
563
+ end
564
+
565
+ it 'Updates glue records' do
566
+ expect(GandiV5).to receive(:post).and_return([nil, { 'message' => 'Confirmation message.' }])
567
+ subject.add_glue_record 'ns1', '1.2.3.4'
568
+ expect(subject.glue_records).to eq('ns1' => ['1.2.3.4'])
569
+ end
570
+ end
571
+
572
+ describe '#glue_record' do
573
+ before(:each) { subject.instance_exec { @glue_records = { 'ns1' => ['1.2.3.4'] } } }
574
+
575
+ it 'Already fetched' do
576
+ expect(subject).to_not receive(:fetch_glue_records)
577
+ expect(subject.glue_record('ns1')).to eq('ns1' => ['1.2.3.4'])
578
+ end
579
+
580
+ it 'Not already fetched' do
581
+ expect(subject).to receive(:fetch_glue_records).and_return('ns2' => ['2.3.4.5'])
582
+ expect(subject.glue_record('ns2')).to eq('ns2' => ['2.3.4.5'])
583
+ end
584
+
585
+ it 'Not present' do
586
+ expect(subject).to receive(:fetch_glue_records).and_return({})
587
+ expect(subject.glue_record('ns3')).to be nil
588
+ end
589
+ end
590
+
591
+ describe '#update_glue_record' do
592
+ it 'Make API request' do
593
+ expect(GandiV5).to receive(:put).with(
594
+ 'https://api.gandi.net/v5/domain/domains/example.com/hosts/name',
595
+ '{"ips":["1.2.3.4"]}'
596
+ )
597
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
598
+ expect(subject.update_glue_record('name', '1.2.3.4')).to eq 'Confirmation message.'
599
+ end
600
+
601
+ it 'Update name_servers' do
602
+ expect(GandiV5).to receive(:put).and_return([nil, { 'message' => 'Confirmation message.' }])
603
+ subject.update_glue_record 'name', '1.2.3.4'
604
+ expect(subject.glue_records).to eq('name' => ['1.2.3.4'])
605
+ end
606
+ end
607
+
608
+ describe '#delete_glue_record' do
609
+ before(:each) { subject.instance_exec { @glue_records = { 'ns1' => ['1.2.3.4'], 'ns2' => [] } } }
610
+
611
+ it 'Make API request' do
612
+ expect(GandiV5).to receive(:delete).with(
613
+ 'https://api.gandi.net/v5/domain/domains/example.com/hosts/ns2'
614
+ )
615
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
616
+ expect(subject.delete_glue_record('ns2')).to eq 'Confirmation message.'
617
+ end
618
+
619
+ it 'Update name_servers' do
620
+ expect(GandiV5).to receive(:delete).and_return([nil, { 'message' => 'Confirmation message.' }])
621
+ subject.delete_glue_record 'ns2'
622
+ expect(subject.glue_records).to eq('ns1' => ['1.2.3.4'])
623
+ end
624
+ end
625
+
626
+ describe '#livedns' do
627
+ let(:live_dns) { double GandiV5::Domain::LiveDNS }
628
+
629
+ it 'Already fetched' do
630
+ subject.instance_exec(live_dns) { |live_dns| @livedns = live_dns }
631
+ expect(subject).to_not receive(:fetch_livedns)
632
+ expect(subject.livedns).to be live_dns
633
+ end
634
+
635
+ it 'Not already fetched' do
636
+ expect(subject).to receive(:fetch_livedns).and_return(live_dns)
637
+ expect(subject.livedns).to be live_dns
638
+ end
639
+ end
640
+
641
+ describe '#fetch_livedns' do
642
+ before(:each) do
643
+ body_fixture = File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_livedns.yml')
644
+ body_fixture = File.expand_path(body_fixture)
645
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/livedns')
646
+ .and_return([nil, YAML.load_file(body_fixture)])
647
+ end
648
+
649
+ describe 'Returned live_dns' do
650
+ subject { described_class.new(fqdn: 'example.com').fetch_livedns }
651
+
652
+ its('current') { should be :livedns }
653
+ its('name_servers') { should match_array ['1.2.3.4'] }
654
+ its('dnssec_available') { should be true }
655
+ its('livednssec_available') { should be true }
656
+ end
657
+
658
+ it 'Updates name_server' do
659
+ expect(subject.name_server).to be nil
660
+ subject.fetch_livedns
661
+ expect(subject.name_server).to be :livedns
662
+ end
663
+
664
+ it 'Updates name_servers' do
665
+ subject.instance_exec { @name_servers = [] }
666
+ subject.fetch_livedns
667
+ expect(subject.name_servers).to match_array ['1.2.3.4']
668
+ end
669
+ end
670
+
671
+ it '#enable_livedns' do
672
+ expect(GandiV5).to receive(:post).with('https://api.gandi.net/v5/domain/domains/example.com/livedns')
673
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
674
+ expect(subject.enable_livedns).to eq 'Confirmation message.'
675
+ end
676
+
677
+ describe '#name_servers' do
678
+ let(:nameservers) { double Array }
679
+
680
+ it 'Already fetched' do
681
+ subject.instance_exec(nameservers) { |nameservers| @name_servers = nameservers }
682
+ expect(subject).to_not receive(:fetch_name_servers)
683
+ expect(subject.name_servers).to be nameservers
684
+ end
685
+
686
+ it 'Not already fetched' do
687
+ expect(subject).to receive(:fetch_name_servers).and_return(nameservers)
688
+ expect(subject.name_servers).to be nameservers
689
+ end
690
+ end
691
+
692
+ it '#fetch_name_servers' do
693
+ body_fixture = File.join('spec', 'fixtures', 'bodies', 'GandiV5_Domain', 'fetch_name_servers.yml')
694
+ body_fixture = File.expand_path(body_fixture)
695
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/domain/domains/example.com/nameservers')
696
+ .and_return([nil, YAML.load_file(body_fixture)])
697
+ expect(subject.fetch_name_servers).to match_array ['1.2.3.4']
698
+ end
699
+
700
+ describe '#update_name_servers' do
701
+ subject { described_class.new fqdn: 'example.com', name_servers: [] }
702
+ let(:new_name_servers) { ['a.examle.com', 'b.example.net'] }
703
+
704
+ it 'Make API request' do
705
+ expect(GandiV5).to receive(:put).with(
706
+ 'https://api.gandi.net/v5/domain/domains/example.com/nameservers',
707
+ '{"nameservers":["a.examle.com","b.example.net"]}'
708
+ )
709
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
710
+ expect(subject.update_name_servers(new_name_servers)).to eq 'Confirmation message.'
711
+ end
712
+
713
+ it 'Update name_servers' do
714
+ expect(GandiV5).to receive(:put).and_return([nil, { 'message' => 'Confirmation message.' }])
715
+ subject.update_name_servers new_name_servers
716
+ expect(subject.name_servers).to be new_name_servers
717
+ end
718
+ end
451
719
  end