gandi_v5 0.9.1 → 0.10.0

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