gandi_v5 0.9.1 → 0.10.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/README.md +10 -6
  4. data/lib/gandi_v5.rb +2 -0
  5. data/lib/gandi_v5/domain.rb +39 -1
  6. data/lib/gandi_v5/domain/transfer_in.rb +2 -0
  7. data/lib/gandi_v5/domain/web_forwarding.rb +182 -0
  8. data/lib/gandi_v5/email.rb +2 -0
  9. data/lib/gandi_v5/email/forward.rb +1 -1
  10. data/lib/gandi_v5/email/mailbox.rb +1 -1
  11. data/lib/gandi_v5/live_dns/domain/snapshot.rb +1 -1
  12. data/lib/gandi_v5/live_dns/domain/tsig_key.rb +1 -1
  13. data/lib/gandi_v5/simple_hosting/instance.rb +6 -0
  14. data/lib/gandi_v5/simple_hosting/instance/virtual_host.rb +87 -2
  15. data/lib/gandi_v5/simple_hosting/instance/virtual_host/linked_dns_zone.rb +1 -1
  16. data/lib/gandi_v5/template.rb +271 -0
  17. data/lib/gandi_v5/template/dispatch.rb +109 -0
  18. data/lib/gandi_v5/template/payload.rb +64 -0
  19. data/lib/gandi_v5/template/payload/dns_record.rb +23 -0
  20. data/lib/gandi_v5/template/payload/web_forwarding.rb +82 -0
  21. data/lib/gandi_v5/version.rb +1 -1
  22. data/spec/fixtures/bodies/GandiV5_Domain_WebForwarding/fetch.yml +9 -0
  23. data/spec/fixtures/bodies/GandiV5_Domain_WebForwarding/list.yml +9 -0
  24. data/spec/fixtures/bodies/GandiV5_Template/fetch.yml +41 -0
  25. data/spec/fixtures/bodies/GandiV5_Template/list.yml +20 -0
  26. data/spec/fixtures/bodies/GandiV5_Template_Dispatch/fetch.yml +49 -0
  27. data/spec/spec_helper.rb +8 -7
  28. data/spec/units/gandi_v5/domain/web_forwarding_spec.rb +150 -0
  29. data/spec/units/gandi_v5/domain_spec.rb +50 -0
  30. data/spec/units/gandi_v5/simple_hosting/instance/virtual_host_spec.rb +125 -0
  31. data/spec/units/gandi_v5/simple_hosting/instance_spec.rb +8 -0
  32. data/spec/units/gandi_v5/template/dispatch_spec.rb +70 -0
  33. data/spec/units/gandi_v5/template/payload/web_forwarding_spec.rb +44 -0
  34. data/spec/units/gandi_v5/template_spec.rb +341 -0
  35. data/spec/units/gandi_v5_spec.rb +1 -1
  36. metadata +73 -47
  37. data/spec/units/gandi_v5/billing/info_spec.rb +0 -4
  38. data/spec/units/gandi_v5/domain/availability/product/period_spec.rb +0 -4
  39. data/spec/units/gandi_v5/domain/availability/product/price_spec.rb +0 -4
  40. data/spec/units/gandi_v5/domain/availability/product_spec.rb +0 -4
  41. data/spec/units/gandi_v5/domain/availability/tax_spec.rb +0 -4
  42. data/spec/units/gandi_v5/domain/contract_spec.rb +0 -4
  43. data/spec/units/gandi_v5/domain/dates_spec.rb +0 -4
  44. data/spec/units/gandi_v5/domain/restore_information_spec.rb +0 -4
  45. data/spec/units/gandi_v5/error_spec.rb +0 -4
  46. data/spec/units/gandi_v5/sharing_space_spec.rb +0 -4
  47. data/spec/units/gandi_v5/simple_hosting/instance/database_spec.rb +0 -4
  48. data/spec/units/gandi_v5/simple_hosting/instance/language_spec.rb +0 -4
  49. data/spec/units/gandi_v5/simple_hosting/instance/upgrade_spec.rb +0 -4
@@ -28,6 +28,85 @@ describe GandiV5::SimpleHosting::Instance::VirtualHost do
28
28
  expect(subject.linked_dns_zone.cname).to_not be nil
29
29
  end
30
30
 
31
+ describe '#update' do
32
+ describe 'application' do
33
+ it 'Given a GandiV5::SimpleHosting::Instance::Application' do
34
+ application = GandiV5::SimpleHosting::Instance::Application.new(
35
+ name: 'app-name',
36
+ parameters: {}
37
+ )
38
+
39
+ expect(GandiV5).to receive(:put).with(
40
+ 'https://api.gandi.net/v5/simplehosting/instances/instance-uuid/vhosts/vh.example.com',
41
+ '{"application":{"name":"app-name","parameters":{}}}'
42
+ ).and_return([nil, body_fetch])
43
+ subject.update(application: application)
44
+
45
+ expect(subject.application.name).to eq 'app-name'
46
+ expect(subject.application.parameters).to eq({})
47
+ end
48
+
49
+ it 'Given a Hash' do
50
+ expect(GandiV5).to receive(:put).with(
51
+ 'https://api.gandi.net/v5/simplehosting/instances/instance-uuid/vhosts/vh.example.com',
52
+ '{"application":{"name":"app-name"}}'
53
+ ).and_return([nil, body_fetch])
54
+ subject.update(application: { name: 'app-name' })
55
+ end
56
+ end
57
+
58
+ describe 'https_strategy' do
59
+ it ':redirect_http_to_https' do
60
+ expect(GandiV5).to receive(:put).with(
61
+ 'https://api.gandi.net/v5/simplehosting/instances/instance-uuid/vhosts/vh.example.com',
62
+ '{"https_strategy":"redirect_HTTP_to_HTTPS"}'
63
+ ).and_return([nil, body_fetch])
64
+ subject.update(https_strategy: :redirect_http_to_https)
65
+ expect(subject.https_strategy).to be :redirect_http_to_https
66
+ end
67
+
68
+ it ':allow_http_and_https' do
69
+ expect(GandiV5).to receive(:put).with(
70
+ 'https://api.gandi.net/v5/simplehosting/instances/instance-uuid/vhosts/vh.example.com',
71
+ '{"https_strategy":"allow_HTTP_and_HTTPS"}'
72
+ ).and_return([nil, body_fetch])
73
+ subject.update(https_strategy: :allow_http_and_https)
74
+ expect(subject.https_strategy).to be :redirect_http_to_https
75
+ end
76
+
77
+ it ':http_only' do
78
+ expect(GandiV5).to receive(:put).with(
79
+ 'https://api.gandi.net/v5/simplehosting/instances/instance-uuid/vhosts/vh.example.com',
80
+ '{"https_strategy":"HTTP_only"}'
81
+ ).and_return([nil, body_fetch])
82
+ subject.update(https_strategy: :http_only)
83
+ expect(subject.https_strategy).to be :redirect_http_to_https
84
+ end
85
+
86
+ it 'invalid' do
87
+ expect(GandiV5).not_to receive(:put)
88
+ expect { subject.update(https_strategy: :invalid) }.to \
89
+ raise_error ArgumentError, 'https_strategy :invalid is invalid'
90
+ end
91
+ end
92
+
93
+ it 'linked_dns_zone' do
94
+ expect(GandiV5).to receive(:put).with(
95
+ 'https://api.gandi.net/v5/simplehosting/instances/instance-uuid/vhosts/vh.example.com',
96
+ '{"linked_dns_zone":{"allow_alteration":false,"allow_alteration_override":true}}'
97
+ ).and_return([nil, body_fetch])
98
+ subject.update(linked_dns_zone_allow_alteration: false, linked_dns_zone_allow_alteration_override: true)
99
+ expect(subject.linked_dns_zone.allow_alteration).to be true
100
+ end
101
+ end
102
+
103
+ it '#delete' do
104
+ expect(GandiV5).to receive(:delete).with(
105
+ 'https://api.gandi.net/v5/simplehosting/instances/instance-uuid/vhosts/vh.example.com'
106
+ ).and_return([nil, { 'message' => 'Confirmation message.' }])
107
+ expect(subject.delete).to eq 'Confirmation message.'
108
+ end
109
+
31
110
  describe 'Helper methods' do
32
111
  describe 'Status' do
33
112
  context 'being_created' do
@@ -130,6 +209,52 @@ describe GandiV5::SimpleHosting::Instance::VirtualHost do
130
209
  end
131
210
  end
132
211
 
212
+ describe '.create' do
213
+ it 'With just fqdn' do
214
+ expect(GandiV5).to receive(:post).with(
215
+ 'https://api.gandi.net/v5/simplehosting/instances/instance-uuid/vhosts',
216
+ '{"fqdn":"vh.example.com"}'
217
+ ).and_return([nil, nil])
218
+
219
+ url = 'https://api.gandi.net/v5/simplehosting/instances/instance-uuid/vhosts/vh.example.com'
220
+ expect(GandiV5).to receive(:get).with(url).and_return([nil, body_fetch])
221
+
222
+ subject = described_class.create('instance-uuid', 'vh.example.com')
223
+ expect(subject.created_at).to eq Time.new(2020, 1, 2, 12, 34, 56, 0)
224
+ end
225
+
226
+ it 'Also with application' do
227
+ expect(GandiV5).to receive(:post).with(
228
+ 'https://api.gandi.net/v5/simplehosting/instances/instance-uuid/vhosts',
229
+ '{"fqdn":"vh.example.com","application":{"name":"app-name"}}'
230
+ ).and_return([nil, nil])
231
+
232
+ url = 'https://api.gandi.net/v5/simplehosting/instances/instance-uuid/vhosts/vh.example.com'
233
+ expect(GandiV5).to receive(:get).with(url).and_return([nil, body_fetch])
234
+
235
+ subject = described_class.create('instance-uuid', 'vh.example.com', application: { name: 'app-name' })
236
+ expect(subject.created_at).to eq Time.new(2020, 1, 2, 12, 34, 56, 0)
237
+ end
238
+
239
+ it 'Also with linked_dns_zone' do
240
+ expect(GandiV5).to receive(:post).with(
241
+ 'https://api.gandi.net/v5/simplehosting/instances/instance-uuid/vhosts',
242
+ '{"fqdn":"vh.example.com","linked_dns_zone":{"allow_alteration":false,"allow_alteration_override":true}}'
243
+ ).and_return([nil, nil])
244
+
245
+ url = 'https://api.gandi.net/v5/simplehosting/instances/instance-uuid/vhosts/vh.example.com'
246
+ expect(GandiV5).to receive(:get).with(url).and_return([nil, body_fetch])
247
+
248
+ subject = described_class.create(
249
+ 'instance-uuid',
250
+ 'vh.example.com',
251
+ linked_dns_zone_allow_alteration: false,
252
+ linked_dns_zone_allow_alteration_override: true
253
+ )
254
+ expect(subject.created_at).to eq Time.new(2020, 1, 2, 12, 34, 56, 0)
255
+ end
256
+ end
257
+
133
258
  describe '.list' do
134
259
  subject { described_class.list('instance-uuid') }
135
260
  let(:url) { 'https://api.gandi.net/v5/simplehosting/instances/instance-uuid/vhosts' }
@@ -179,4 +179,12 @@ describe GandiV5::SimpleHosting::Instance do
179
179
  its('upgrade_to.first.type') { should eq 'database' }
180
180
  its('upgrade_to.first.version') { should eq 'upgrade to version' }
181
181
  end
182
+
183
+ it '.create_virtual_host' do
184
+ returns = double Object
185
+ expect(GandiV5::SimpleHosting::Instance::VirtualHost).to receive(:create).with('instance-uuid', 'fqdn', key: :value)
186
+ .and_return(returns)
187
+ expect(subject).to receive(:refresh)
188
+ subject.create_virtual_host 'fqdn', key: :value
189
+ end
182
190
  end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GandiV5::Template::Dispatch do
4
+ subject do
5
+ described_class.new uuid: 'dispatch-uuid'
6
+ end
7
+
8
+ describe '.fetch' do
9
+ subject { described_class.fetch('dispatch-uuid') }
10
+
11
+ before :each do
12
+ expect(GandiV5).to receive(:get).with(url).and_return([nil, YAML.load_file(body_fixture)])
13
+ end
14
+
15
+ let(:url) { 'https://api.gandi.net/v5/template/dispatch/dispatch-uuid' }
16
+ let(:body_fixture) do
17
+ File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Template_Dispatch', 'fetch.yml'))
18
+ end
19
+
20
+ its('attempt') { should eq 1 }
21
+ its('created_at') { should eq Time.new(2020, 11, 29, 14, 57, 14) }
22
+ its('uuid') { should eq 'dispatch-uuid' }
23
+ its('created_by') { should eq 'sharing-uuid' }
24
+ its('state') { should be :running }
25
+ its('state_message') { should eq 'state message' }
26
+ its('updated_at') { should eq Time.new(2020, 11, 29, 14, 57, 15) }
27
+ its('template_uuid') { should eq 'template-uuid' }
28
+ its('template_name') { should eq 'template' }
29
+ its('target_uuid') { should eq 'target-uuid' }
30
+ its('task_history') do
31
+ should eq(
32
+ [
33
+ {
34
+ at: Time.new(2020, 11, 29, 16, 57, 47),
35
+ what: :name_servers,
36
+ status: :done,
37
+ message: ''
38
+ }
39
+ ]
40
+ )
41
+ end
42
+ its('task_statuses') do
43
+ should eq(
44
+ {
45
+ dns_records: :pending,
46
+ mailboxes: :running,
47
+ name_servers: :done,
48
+ web_forwardings: :error
49
+ }
50
+ )
51
+ end
52
+
53
+ its('payload.dns_records.count') { should eq 1 }
54
+ its('payload.dns_records.first.name') { should eq 'record-name' }
55
+ its('payload.dns_records.first.type') { should eq 'TXT' }
56
+ its('payload.dns_records.first.values') { should eq ['record-value'] }
57
+ its('payload.dns_records.first.ttl') { should eq 600 }
58
+
59
+ its('payload.mailboxes') { should eq ['user-name'] }
60
+
61
+ its('payload.name_servers') { should eq ['1.1.1.1'] }
62
+
63
+ its('payload.web_forwardings.count') { should eq 1 }
64
+ its('payload.web_forwardings.first.type') { should eq :http301 }
65
+ its('payload.web_forwardings.first.target') { should eq 'https://example.com/here' }
66
+ its('payload.web_forwardings.first.fqdn') { should eq 'here.example.com' }
67
+ its('payload.web_forwardings.first.override') { should be true }
68
+ its('payload.web_forwardings.first.protocol') { should eq :https }
69
+ end
70
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GandiV5::Template::Payload::WebForwarding do
4
+ describe 'helper methods' do
5
+ context 'an HTTP 301 redirect' do
6
+ subject { described_class.new type: :http301 }
7
+ it('#permanent?') { expect(subject.permanent?).to be true }
8
+ it('#http301?') { expect(subject.http301?).to be true }
9
+ it('#temporary?') { expect(subject.temporary?).to be false }
10
+ it('#http302?') { expect(subject.http302?).to be false }
11
+ it('#found?') { expect(subject.found?).to be false }
12
+ end
13
+
14
+ context 'an HTTP 302 redirect' do
15
+ subject { described_class.new type: :http302 }
16
+ it('#permanent?') { expect(subject.permanent?).to be false }
17
+ it('#http301?') { expect(subject.http301?).to be false }
18
+ it('#temporary?') { expect(subject.temporary?).to be true }
19
+ it('#http302?') { expect(subject.http302?).to be true }
20
+ it('#found?') { expect(subject.found?).to be true }
21
+ end
22
+
23
+ context 'an http endpoint' do
24
+ subject { described_class.new protocol: :http }
25
+ it('#http?') { expect(subject.http?).to be true }
26
+ it('#https?') { expect(subject.https?).to be false }
27
+ it('#https_only?') { expect(subject.https_only?).to be false }
28
+ end
29
+
30
+ context 'an https endpoint' do
31
+ subject { described_class.new protocol: :https }
32
+ it('#http?') { expect(subject.http?).to be true }
33
+ it('#https?') { expect(subject.https?).to be true }
34
+ it('#https_only?') { expect(subject.https_only?).to be false }
35
+ end
36
+
37
+ context 'an https_only endpoint' do
38
+ subject { described_class.new protocol: :https_only }
39
+ it('#http?') { expect(subject.http?).to be false }
40
+ it('#https?') { expect(subject.https?).to be true }
41
+ it('#https_only?') { expect(subject.https_only?).to be true }
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,341 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GandiV5::Template do
4
+ subject do
5
+ described_class.new uuid: 'template-uuid'
6
+ end
7
+
8
+ describe '#refresh' do
9
+ before :each do
10
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Template', 'fetch.yml'))
11
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/template/templates/template-uuid')
12
+ .and_return([nil, YAML.load_file(body_fixture)])
13
+ subject.refresh
14
+ end
15
+
16
+ its('description') { should eq 'description of template' }
17
+ its('editable') { should be true }
18
+ its('uuid') { should eq 'template-uuid' }
19
+ its('name') { should eq 'template name' }
20
+ its('organisation_name') { should eq 'org-name' }
21
+ its('sharing_space.uuid') { should eq 'sharing-space-uuid' }
22
+ its('sharing_space.name') { should eq 'sharing-space-name' }
23
+ its('sharing_space.reseller') { should be true }
24
+ its('sharing_space.type') { should eq 'user' }
25
+ its('sharing_space.reseller_details.uuid') { should eq 'reseller-uuid' }
26
+ its('sharing_space.reseller_details.name') { should eq 'reseller-name' }
27
+ its('variables') { should eq [] }
28
+
29
+ its('payload.dns_records.count') { should eq 1 }
30
+ its('payload.dns_records.first.name') { should eq 'record-name' }
31
+ its('payload.dns_records.first.type') { should eq 'TXT' }
32
+ its('payload.dns_records.first.values') { should eq ['record-value'] }
33
+ its('payload.dns_records.first.ttl') { should eq 600 }
34
+
35
+ its('payload.mailboxes') { should eq ['user-name'] }
36
+
37
+ its('payload.name_servers') { should eq ['1.1.1.1'] }
38
+
39
+ its('payload.web_forwardings.count') { should eq 1 }
40
+ its('payload.web_forwardings.first.type') { should eq :http301 }
41
+ its('payload.web_forwardings.first.target') { should eq 'https://example.com/here' }
42
+ its('payload.web_forwardings.first.fqdn') { should eq 'here.example.com' }
43
+ its('payload.web_forwardings.first.override') { should be true }
44
+ its('payload.web_forwardings.first.protocol') { should eq :https }
45
+ end
46
+
47
+ describe '#update' do
48
+ let(:url) { 'https://api.gandi.net/v5/template/templates/template-uuid' }
49
+ let(:updated_template) { double GandiV5::Template }
50
+
51
+ before :each do
52
+ expect(subject).to receive(:refresh).and_return(updated_template)
53
+ end
54
+
55
+ it 'nothing' do
56
+ expect(GandiV5).to receive(:patch).with(url, '{}')
57
+ expect(subject.update).to be updated_template
58
+ end
59
+
60
+ it 'name' do
61
+ expect(GandiV5).to receive(:patch).with(url, '{"name":"new"}')
62
+ expect(subject.update(name: 'new')).to be updated_template
63
+ end
64
+
65
+ it 'description' do
66
+ expect(GandiV5).to receive(:patch).with(url, '{"description":"new"}')
67
+ expect(subject.update(description: 'new')).to be updated_template
68
+ end
69
+
70
+ it 'dns_records' do
71
+ expect(GandiV5).to receive(:patch).with(url, '{"payload":{"dns:records":{"default":true}}}')
72
+ expect(subject.update(dns_records: :default)).to be updated_template
73
+ end
74
+
75
+ it 'mailboxes' do
76
+ expect(GandiV5).to receive(:patch).with(url, '{"payload":{"domain:mailboxes":{"values":[{"login":"user"}]}}}')
77
+ expect(subject.update(mailboxes: ['user'])).to be updated_template
78
+ end
79
+
80
+ it 'name servers' do
81
+ expect(GandiV5).to receive(:patch).with(url, '{"payload":{"domain:nameservers":{"service":"livedns"}}}')
82
+ expect(subject.update(name_servers: :livedns)).to be updated_template
83
+ end
84
+
85
+ it 'web forwardings' do
86
+ expect(GandiV5).to receive(:patch).with(url, '{"payload":{"domain:webredirs":{"values":[]}}}')
87
+ expect(subject.update(web_forwardings: [])).to be updated_template
88
+ end
89
+ end
90
+
91
+ it '#delete' do
92
+ url = 'https://api.gandi.net/v5/template/templates/template-uuid'
93
+ expect(GandiV5).to receive(:delete).with(url)
94
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
95
+ expect(subject.delete).to be nil
96
+ end
97
+
98
+ it '#apply' do
99
+ url = 'https://api.gandi.net/v5/template/templates/template-uuid'
100
+ body = { 'dispatch_href' => 'https://api.gandi.net/v5/template/dispatch/dispatch-uuid' }
101
+ expect(GandiV5).to receive(:post).with(url, '{"object_type":"domain","object_id":"domain-uuid"}')
102
+ .and_return([nil, body])
103
+ expect(subject.apply('domain-uuid')).to eq 'dispatch-uuid'
104
+ end
105
+
106
+ describe '.list' do
107
+ subject { described_class.list }
108
+
109
+ before :each do
110
+ expect(GandiV5).to receive(:paginated_get).with(url, (1..), 100)
111
+ .and_yield(YAML.load_file(body_fixture))
112
+ end
113
+
114
+ let(:body_fixture) { File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Template', 'list.yml')) }
115
+ let(:url) { 'https://api.gandi.net/v5/template/templates' }
116
+
117
+ its('count') { should eq 1 }
118
+
119
+ its('first.description') { should eq 'description of template' }
120
+ its('first.editable') { should be true }
121
+ its('first.uuid') { should eq 'template-uuid' }
122
+ its('first.name') { should eq 'template name' }
123
+ its('first.organisation_name') { should eq 'org-name' }
124
+ its('first.sharing_space.uuid') { should eq 'sharing-space-uuid' }
125
+ its('first.sharing_space.name') { should eq 'sharing-space-name' }
126
+ its('first.sharing_space.reseller') { should be true }
127
+ its('first.sharing_space.type') { should eq 'user' }
128
+ its('first.sharing_space.reseller_details.uuid') { should eq 'reseller-uuid' }
129
+ its('first.sharing_space.reseller_details.name') { should eq 'reseller-name' }
130
+ end
131
+
132
+ describe '.fetch' do
133
+ subject { described_class.fetch 'template-uuid' }
134
+
135
+ before :each do
136
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Template', 'fetch.yml'))
137
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/template/templates/template-uuid')
138
+ .and_return([nil, YAML.load_file(body_fixture)])
139
+ end
140
+
141
+ its('description') { should eq 'description of template' }
142
+ its('editable') { should be true }
143
+ its('uuid') { should eq 'template-uuid' }
144
+ its('name') { should eq 'template name' }
145
+ its('organisation_name') { should eq 'org-name' }
146
+ its('sharing_space.uuid') { should eq 'sharing-space-uuid' }
147
+ its('sharing_space.name') { should eq 'sharing-space-name' }
148
+ its('sharing_space.reseller') { should be true }
149
+ its('sharing_space.type') { should eq 'user' }
150
+ its('sharing_space.reseller_details.uuid') { should eq 'reseller-uuid' }
151
+ its('sharing_space.reseller_details.name') { should eq 'reseller-name' }
152
+ its('variables') { should eq [] }
153
+
154
+ its('payload.dns_records.count') { should eq 1 }
155
+ its('payload.dns_records.first.name') { should eq 'record-name' }
156
+ its('payload.dns_records.first.type') { should eq 'TXT' }
157
+ its('payload.dns_records.first.values') { should eq ['record-value'] }
158
+ its('payload.dns_records.first.ttl') { should eq 600 }
159
+
160
+ its('payload.mailboxes') { should eq ['user-name'] }
161
+
162
+ its('payload.name_servers') { should eq ['1.1.1.1'] }
163
+
164
+ its('payload.web_forwardings.count') { should eq 1 }
165
+ its('payload.web_forwardings.first.type') { should eq :http301 }
166
+ its('payload.web_forwardings.first.target') { should eq 'https://example.com/here' }
167
+ its('payload.web_forwardings.first.fqdn') { should eq 'here.example.com' }
168
+ its('payload.web_forwardings.first.override') { should be true }
169
+ its('payload.web_forwardings.first.protocol') { should eq :https }
170
+ end
171
+
172
+ describe '.fetch' do
173
+ it 'With default dns records' do
174
+ body = { 'payload' => { 'dns:records' => { 'default' => true, 'records' => [] } } }
175
+ expect(GandiV5).to receive(:get).and_return([nil, body])
176
+ expect(described_class.fetch('template-uuid').payload.dns_records).to be :default
177
+ end
178
+
179
+ it 'With livedns name servers' do
180
+ body = { 'payload' => { 'domain:nameservers' => { 'service' => 'livedns', 'addresses' => [] } } }
181
+ expect(GandiV5).to receive(:get).and_return([nil, body])
182
+ expect(described_class.fetch('template-uuid').payload.name_servers).to be :livedns
183
+ end
184
+ end
185
+
186
+ describe '.create' do
187
+ let(:url) { 'https://api.gandi.net/v5/template/templates' }
188
+
189
+ it 'Without sharing_id' do
190
+ body = {
191
+ 'name' => 'template name',
192
+ 'description' => 'description of template',
193
+ 'payload' => {
194
+ 'dns:records' => {
195
+ 'default' => false,
196
+ 'records' => [{ 'name' => 'host', 'ttl' => 600, 'type' => 'TXT', 'values' => ['value'] }]
197
+ },
198
+ 'domain:mailboxes' => { 'values' => [{ 'login' => 'user1' }, { 'login' => 'user2' }] },
199
+ 'domain:nameservers' => {
200
+ 'service' => 'custom',
201
+ 'addresses' => ['1.1.1.1', '2.2.2.2']
202
+ },
203
+ 'domain:webredirs' => {
204
+ 'values' => [
205
+ {
206
+ 'type' => 'http302',
207
+ 'url' => 'example.com',
208
+ 'host' => 'here',
209
+ 'override' => true,
210
+ 'protocol' => 'httpsonly'
211
+ }
212
+ ]
213
+ }
214
+ }
215
+ }.to_json
216
+ response = double(
217
+ RestClient::Response,
218
+ headers: { location: 'https://api.gandi.net/v5/template/templates/template-uuid' }
219
+ )
220
+ created_template = double GandiV5::Template
221
+ expect(GandiV5).to receive(:post).with(url, body).and_return([response, 'Confirmation message'])
222
+ expect(described_class).to receive(:fetch).with('template-uuid').and_return(created_template)
223
+
224
+ create = {
225
+ name: 'template name',
226
+ description: 'description of template',
227
+ 'dns_records': [{ name: 'host', ttl: 600, type: 'TXT', values: ['value'] }],
228
+ 'mailboxes': %w[user1 user2],
229
+ 'name_servers': ['1.1.1.1', '2.2.2.2'],
230
+ 'web_forwardings': [
231
+ { type: :http302, target: 'example.com', host: 'here', override: true, protocol: :https_only }
232
+ ]
233
+ }
234
+ expect(described_class.create(**create)).to be created_template
235
+ end
236
+
237
+ it 'With a :permanent web forwarding' do
238
+ url = 'https://api.gandi.net/v5/template/templates'
239
+ body = '{"name":"n","description":"d","payload":{"domain:webredirs":{"values":[{"type":"http301","url":""}]}}}'
240
+ response = double(
241
+ RestClient::Response,
242
+ headers: { location: 'https://api.gandi.net/v5/template/templates/template-uuid' }
243
+ )
244
+ expect(GandiV5).to receive(:post).with(url, body).and_return([response, 'Confirmation message'])
245
+ expect(described_class).to receive(:fetch).with('template-uuid').and_return(double(GandiV5::Template))
246
+
247
+ described_class.create(
248
+ name: 'n',
249
+ description: 'd',
250
+ web_forwardings: [{ type: :permanent, target: '' }]
251
+ )
252
+ end
253
+
254
+ it 'With a :temporary web forwarding' do
255
+ url = 'https://api.gandi.net/v5/template/templates'
256
+ body = '{"name":"n","description":"d","payload":{"domain:webredirs":{"values":[{"type":"http302","url":""}]}}}'
257
+ response = double(
258
+ RestClient::Response,
259
+ headers: { location: 'https://api.gandi.net/v5/template/templates/template-uuid' }
260
+ )
261
+ expect(GandiV5).to receive(:post).with(url, body).and_return([response, 'Confirmation message'])
262
+ expect(described_class).to receive(:fetch).with('template-uuid').and_return(double(GandiV5::Template))
263
+
264
+ described_class.create(
265
+ name: 'n',
266
+ description: 'd',
267
+ web_forwardings: [{ type: :temporary, target: '' }]
268
+ )
269
+ end
270
+
271
+ it 'With a :found web forwarding' do
272
+ url = 'https://api.gandi.net/v5/template/templates'
273
+ body = '{"name":"n","description":"d","payload":{"domain:webredirs":{"values":[{"type":"http302","url":""}]}}}'
274
+ response = double(
275
+ RestClient::Response,
276
+ headers: { location: 'https://api.gandi.net/v5/template/templates/template-uuid' }
277
+ )
278
+ expect(GandiV5).to receive(:post).with(url, body).and_return([response, 'Confirmation message'])
279
+ expect(described_class).to receive(:fetch).with('template-uuid').and_return(double(GandiV5::Template))
280
+
281
+ described_class.create(
282
+ name: 'n',
283
+ description: 'd',
284
+ web_forwardings: [{ type: :found, target: '' }]
285
+ )
286
+ end
287
+
288
+ it 'With sharing_id' do
289
+ url = 'https://api.gandi.net/v5/template/templates?sharing_id=sharing-uuid'
290
+ body = '{"name":"n","description":"d","payload":{}}'
291
+ response = double(
292
+ RestClient::Response,
293
+ headers: { location: 'https://api.gandi.net/v5/template/templates/template-uuid' }
294
+ )
295
+ expect(GandiV5).to receive(:post).with(url, body).and_return([response, 'Confirmation message'])
296
+ expect(described_class).to receive(:fetch).with('template-uuid').and_return(double(GandiV5::Template))
297
+
298
+ described_class.create name: 'n', description: 'd', sharing_id: 'sharing-uuid'
299
+ end
300
+
301
+ it 'Use livedns name servers' do
302
+ body = '{"name":"n","description":"d","payload":{"domain:nameservers":{"service":"livedns"}}}'
303
+ response = double(
304
+ RestClient::Response,
305
+ headers: { location: 'https://api.gandi.net/v5/template/templates/template-uuid' }
306
+ )
307
+ expect(GandiV5).to receive(:post).with(url, body).and_return([response, 'Confirmation message'])
308
+ expect(described_class).to receive(:fetch).with('template-uuid').and_return(double(GandiV5::Template))
309
+
310
+ described_class.create name: 'n', description: 'd', name_servers: :livedns
311
+ end
312
+
313
+ it 'Use default DNS records' do
314
+ body = '{"name":"n","description":"d","payload":{"dns:records":{"default":true}}}'
315
+ response = double(
316
+ RestClient::Response,
317
+ headers: { location: 'https://api.gandi.net/v5/template/templates/template-uuid' }
318
+ )
319
+ expect(GandiV5).to receive(:post).with(url, body).and_return([response, 'Confirmation message'])
320
+ expect(described_class).to receive(:fetch).with('template-uuid').and_return(double(GandiV5::Template))
321
+
322
+ described_class.create name: 'n', description: 'd', dns_records: :default
323
+ end
324
+
325
+ it 'With empty payload' do
326
+ body = {
327
+ 'name' => 'n',
328
+ 'description' => 'd',
329
+ 'payload' => {}
330
+ }.to_json
331
+ response = double(
332
+ RestClient::Response,
333
+ headers: { location: 'https://api.gandi.net/v5/template/templates/template-uuid' }
334
+ )
335
+ expect(GandiV5).to receive(:post).with(url, body).and_return([response, 'Confirmation message'])
336
+ expect(described_class).to receive(:fetch).with('template-uuid').and_return(double(GandiV5::Template))
337
+
338
+ described_class.create name: 'n', description: 'd'
339
+ end
340
+ end
341
+ end