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,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe GandiV5::Email::Forward do
4
+ subject { described_class.new source: 'alice', destinations: ['bob@example.com'], fqdn: 'example.com' }
5
+
6
+ describe '#update' do
7
+ it 'ʘ‿ʘ' do
8
+ expect(GandiV5).to receive(:put).with(
9
+ 'https://api.gandi.net/v5/email/forwards/example.com/alice',
10
+ '{"destinations":["bob@example.com","charlie@example.com"]}'
11
+ )
12
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
13
+ expect(subject.update('bob@example.com', 'charlie@example.com')).to eq 'Confirmation message.'
14
+ expect(subject.destinations).to match_array ['bob@example.com', 'charlie@example.com']
15
+ end
16
+
17
+ it 'Empty destinations' do
18
+ expect { subject.update }.to raise_error ArgumentError, 'destinations can\'t be empty'
19
+ end
20
+ end
21
+
22
+ it '#delete' do
23
+ expect(GandiV5).to receive(:delete).with(
24
+ 'https://api.gandi.net/v5/email/forwards/example.com/alice'
25
+ )
26
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
27
+ expect(subject.delete).to eq 'Confirmation message.'
28
+ end
29
+
30
+ describe '#to_s' do
31
+ it 'With one destination' do
32
+ expect(subject.to_s).to eq 'alice@example.com -> bob@example.com'
33
+ end
34
+
35
+ it 'With many destinations' do
36
+ subject.instance_exec { @destinations = ['bob@example.com', 'charlie@example.com'] }
37
+ expect(subject.to_s).to eq 'alice@example.com -> bob@example.com, charlie@example.com'
38
+ end
39
+ end
40
+
41
+ describe '.create' do
42
+ it 'ʘ‿ʘ' do
43
+ response = double(
44
+ RestClient::Response,
45
+ headers: { location: 'https://api.gandi.net/v5/email/forwards/example.com/alice' }
46
+ )
47
+ expect(GandiV5).to receive(:post).with(
48
+ 'https://api.gandi.net/v5/email/forwards/example.com',
49
+ '{"source":"alice","destinations":["bob@example.com"]}'
50
+ )
51
+ .and_return([response, { 'message' => 'Confirmation message.' }])
52
+
53
+ forward = described_class.new fqdn: 'example.com', source: 'alice', destinations: ['bob@example.com']
54
+ expect(described_class.create('example.com', 'alice', 'bob@example.com').to_h).to eq forward.to_h
55
+ end
56
+
57
+ it 'Empty destinations' do
58
+ expect { described_class.create('example.com', 'alice') }.to raise_error ArgumentError, 'destinations can\'t be empty'
59
+ end
60
+ end
61
+
62
+ describe '.list' do
63
+ let(:body_fixture) do
64
+ File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Email_Forward', 'list.yml'))
65
+ end
66
+
67
+ describe 'With default values' do
68
+ subject { described_class.list 'example.com' }
69
+
70
+ before :each do
71
+ headers = { params: { page: 1 } }
72
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/forwards/example.com', headers)
73
+ .and_return([nil, YAML.load_file(body_fixture)])
74
+ end
75
+
76
+ its('count') { should eq 1 }
77
+ its('first.source') { should eq 'alice' }
78
+ its('first.destinations') { should match_array ['bob@example.com', 'charlie@example.com'] }
79
+ its('first.fqdn') { should eq 'example.com' }
80
+ end
81
+
82
+ it 'Keeps fetching until no more to get' do
83
+ headers1 = { params: { page: 1, per_page: 1 } }
84
+ headers2 = { params: { page: 2, per_page: 1 } }
85
+ # https://github.com/rubocop-hq/rubocop/issues/7088
86
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/forwards/example.com', headers1)
87
+ .ordered
88
+ .and_return([nil, YAML.load_file(body_fixture)])
89
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/forwards/example.com', headers2)
90
+ .ordered
91
+ .and_return([nil, []])
92
+
93
+ expect(described_class.list('example.com', per_page: 1).count).to eq 1
94
+ end
95
+
96
+ it 'Given a range as page number' do
97
+ headers1 = { params: { page: 1, per_page: 1 } }
98
+ headers2 = { params: { page: 2, per_page: 1 } }
99
+ # https://github.com/rubocop-hq/rubocop/issues/7088
100
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/forwards/example.com', headers1)
101
+ .ordered
102
+ .and_return([nil, YAML.load_file(body_fixture)])
103
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/forwards/example.com', headers2)
104
+ .ordered
105
+ .and_return([nil, []])
106
+
107
+ expect(described_class.list('example.com', page: (1..2), per_page: 1).count).to eq 1
108
+ end
109
+
110
+ describe 'Passes optional query params' do
111
+ %i[source sort_by].each do |param|
112
+ it param.to_s do
113
+ headers = { params: { page: 1 }.merge(param => 'value') }
114
+ expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/forwards/example.com', headers)
115
+ .and_return([nil, []])
116
+ expect(described_class.list('example.com', param => 'value')).to eq []
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -128,4 +128,56 @@ describe GandiV5::Email::Mailbox::Responder do
128
128
  end
129
129
  end
130
130
  end
131
+
132
+ describe '#enable' do
133
+ let(:mailbox) { double GandiV5::Email::Mailbox }
134
+ let(:update) do
135
+ {
136
+ starts_at: '2019-01-01T00:00:00Z',
137
+ ends_at: '2020-01-01T00:00:00Z',
138
+ message: 'Auto response message.',
139
+ enabled: true
140
+ }
141
+ end
142
+
143
+ it 'Uses now as default starts_at' do
144
+ starts_at = Time.new(2019, 1, 1, 0, 0, 0, 0)
145
+ Timecop.freeze(starts_at) do
146
+ ends_at = Time.new(2020, 1, 1, 0, 0, 0, 0)
147
+ subject = described_class.new mailbox: mailbox
148
+ expect(mailbox).to receive(:update).with(responder: update)
149
+
150
+ subject.enable message: 'Auto response message.', ends_at: ends_at
151
+ expect(subject.enabled).to be true
152
+ expect(subject.message).to eq 'Auto response message.'
153
+ expect(subject.starts_at).to eq starts_at
154
+ expect(subject.ends_at).to eq ends_at
155
+ end
156
+ end
157
+
158
+ it 'Uses passed starts_at' do
159
+ starts_at = Time.new(2019, 1, 1, 0, 0, 0, 0)
160
+ ends_at = Time.new(2020, 1, 1, 0, 0, 0, 0)
161
+ subject = described_class.new mailbox: mailbox
162
+ expect(mailbox).to receive(:update).with(responder: update)
163
+
164
+ subject.enable message: 'Auto response message.', starts_at: starts_at, ends_at: ends_at
165
+ expect(subject.enabled).to be true
166
+ expect(subject.message).to eq 'Auto response message.'
167
+ expect(subject.starts_at).to eq starts_at
168
+ expect(subject.ends_at).to eq ends_at
169
+ end
170
+ end
171
+
172
+ it '#disable' do
173
+ mailbox = double GandiV5::Email::Mailbox
174
+ subject = described_class.new mailbox: mailbox
175
+ expect(mailbox).to receive(:update).with(responder: { enabled: false })
176
+
177
+ subject.disable
178
+ expect(subject.enabled).to be false
179
+ expect(subject.message).to be nil
180
+ expect(subject.starts_at).to be nil
181
+ expect(subject.ends_at).to be nil
182
+ end
131
183
  end
@@ -9,9 +9,9 @@ describe GandiV5::Email::Mailbox do
9
9
 
10
10
  describe '#refresh' do
11
11
  before :each do
12
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Email_Mailbox', 'get.yaml'))
12
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Email_Mailbox', 'fetch.yml'))
13
13
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com/mailbox-uuid')
14
- .and_return(YAML.load_file(body_fixture))
14
+ .and_return([nil, YAML.load_file(body_fixture)])
15
15
  subject.refresh
16
16
  end
17
17
 
@@ -22,6 +22,7 @@ describe GandiV5::Email::Mailbox do
22
22
  its('login') { should eq 'address' }
23
23
  its('type') { should eq :standard }
24
24
  its('quota_used') { should eq 1_000_000 }
25
+ its('responder.mailbox') { should be subject }
25
26
  its('responder.enabled') { should be false }
26
27
  its('responder.starts_at') { should eq Time.new(2000, 1, 1, 0, 0, 0) }
27
28
  its('responder.ends_at') { should eq Time.new(2000, 1, 2, 0, 0, 0) }
@@ -33,14 +34,14 @@ describe GandiV5::Email::Mailbox do
33
34
 
34
35
  it 'Aliases' do
35
36
  expect(GandiV5).to receive(:patch).with(url, '{"aliases":["alias-1"]}')
36
- .and_return('message' => 'Confirmation message.')
37
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
37
38
  expect(subject).to receive(:refresh)
38
39
  expect(subject.update(aliases: ['alias-1'])).to eq 'Confirmation message.'
39
40
  end
40
41
 
41
42
  it 'Login' do
42
43
  expect(GandiV5).to receive(:patch).with(url, '{"login":"new-login"}')
43
- .and_return('message' => 'Confirmation message.')
44
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
44
45
  expect(subject).to receive(:refresh)
45
46
  expect(subject.update(login: 'new-login')).to eq 'Confirmation message.'
46
47
  end
@@ -48,7 +49,7 @@ describe GandiV5::Email::Mailbox do
48
49
  describe 'Password' do
49
50
  it 'Password is good' do
50
51
  expect(GandiV5).to receive(:patch).with(url, '{"password":"crypted_password"}')
51
- .and_return('message' => 'Confirmation message.')
52
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
52
53
  expect(subject).to receive(:refresh)
53
54
  expect(subject).to receive(:crypt_password).with(good_password).and_return('crypted_password')
54
55
  expect(subject.update(password: good_password)).to eq 'Confirmation message.'
@@ -63,7 +64,7 @@ describe GandiV5::Email::Mailbox do
63
64
  describe 'Responder' do
64
65
  before(:each) do
65
66
  expect(GandiV5).to receive(:patch).with(url, '{"responder":{"enabled":false}}')
66
- .and_return('message' => 'Confirmation message.')
67
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
67
68
 
68
69
  expect(subject).to receive(:refresh)
69
70
  end
@@ -86,17 +87,119 @@ describe GandiV5::Email::Mailbox do
86
87
  end
87
88
  end
88
89
 
90
+ describe '#upgrade' do
91
+ let(:url) { 'https://api.gandi.net/v5/email/mailboxes/example.com/mailbox-uuid/type' }
92
+
93
+ context 'No sharing_id' do
94
+ it 'Is upgraded' do
95
+ expect(GandiV5).to receive(:patch).with(url, '{"mailbox_type":"premium"}', 'Dry-Run': 0)
96
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
97
+ expect(subject.upgrade).to be true
98
+ expect(subject.type).to be :premium
99
+ end
100
+
101
+ it 'Is already premium' do
102
+ subject.instance_exec { @type = :premium }
103
+ expect(GandiV5).to_not receive(:patch)
104
+ expect(subject.upgrade).to be false
105
+ end
106
+ end
107
+
108
+ context 'With sharing_id' do
109
+ let(:url) { 'https://api.gandi.net/v5/email/mailboxes/example.com/mailbox-uuid/type?sharing_id=abc' }
110
+
111
+ it 'Is upgraded' do
112
+ expect(GandiV5).to receive(:patch).with(url, '{"mailbox_type":"premium"}', 'Dry-Run': 0)
113
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
114
+ expect(subject.upgrade(sharing_id: 'abc')).to be true
115
+ expect(subject.type).to be :premium
116
+ end
117
+
118
+ it 'Is already premium' do
119
+ subject.instance_exec { @type = :premium }
120
+ expect(GandiV5).to_not receive(:patch)
121
+ expect(subject.upgrade(sharing_id: 'abc')).to be false
122
+ end
123
+ end
124
+
125
+ context 'Dry run' do
126
+ it 'Is upgraded' do
127
+ expect(GandiV5).to receive(:patch).with(url, '{"mailbox_type":"premium"}', 'Dry-Run': 1)
128
+ .and_return([nil, { 'status' => 'success' }])
129
+ expect(subject.upgrade(dry_run: true)).to eq('status' => 'success')
130
+ expect(subject.type).to be :standard
131
+ end
132
+
133
+ it 'Is already premium' do
134
+ subject.instance_exec { @type = :premium }
135
+ expect(GandiV5).to_not receive(:patch)
136
+ expect(subject.upgrade(dry_run: true)).to be false
137
+ end
138
+ end
139
+ end
140
+
141
+ describe '#downgrade' do
142
+ let(:url) { 'https://api.gandi.net/v5/email/mailboxes/example.com/mailbox-uuid/type' }
143
+
144
+ context 'No sharing_id' do
145
+ it 'Is downgraded' do
146
+ subject.instance_exec { @type = :premium }
147
+ expect(GandiV5).to receive(:patch).with(url, '{"mailbox_type":"standard"}', 'Dry-Run': 0)
148
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
149
+ expect(subject.downgrade).to be true
150
+ expect(subject.type).to be :standard
151
+ end
152
+
153
+ it 'Is already premium' do
154
+ expect(GandiV5).to_not receive(:patch)
155
+ expect(subject.downgrade).to be false
156
+ end
157
+ end
158
+
159
+ context 'With sharing_id' do
160
+ let(:url) { 'https://api.gandi.net/v5/email/mailboxes/example.com/mailbox-uuid/type?sharing_id=abc' }
161
+
162
+ it 'Is downgraded' do
163
+ subject.instance_exec { @type = :premium }
164
+ expect(GandiV5).to receive(:patch).with(url, '{"mailbox_type":"standard"}', 'Dry-Run': 0)
165
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
166
+ expect(subject.downgrade(sharing_id: 'abc')).to be true
167
+ expect(subject.type).to be :standard
168
+ end
169
+
170
+ it 'Is already premium' do
171
+ expect(GandiV5).to_not receive(:patch)
172
+ expect(subject.downgrade(sharing_id: 'abc')).to be false
173
+ end
174
+ end
175
+
176
+ context 'Dry run' do
177
+ it 'Is downgraded' do
178
+ subject.instance_exec { @type = :premium }
179
+ expect(GandiV5).to receive(:patch).with(url, '{"mailbox_type":"standard"}', 'Dry-Run': 1)
180
+ .and_return([nil, { 'status' => 'success' }])
181
+ expect(subject.downgrade(dry_run: true)).to eq('status' => 'success')
182
+ expect(subject.type).to be :premium
183
+ end
184
+
185
+ it 'Is already premium' do
186
+ expect(GandiV5).to_not receive(:patch)
187
+ expect(subject.downgrade(dry_run: true)).to be false
188
+ end
189
+ end
190
+ end
191
+
89
192
  it '#delete' do
90
193
  url = 'https://api.gandi.net/v5/email/mailboxes/example.com/mailbox-uuid'
91
194
  expect(GandiV5).to receive(:delete).with(url)
92
- .and_return('message' => 'Confirmation message.')
195
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
93
196
  expect(subject.delete).to eq 'Confirmation message.'
94
197
  end
95
198
 
96
199
  it '#purge' do
97
200
  url = 'https://api.gandi.net/v5/email/mailboxes/example.com/mailbox-uuid/contents'
98
201
  expect(GandiV5).to receive(:delete).with(url)
99
- .and_return('message' => 'Confirmation message.')
202
+ .and_return([nil, { 'message' => 'Confirmation message.' }])
100
203
  expect(subject.purge).to eq 'Confirmation message.'
101
204
  end
102
205
 
@@ -186,33 +289,49 @@ describe GandiV5::Email::Mailbox do
186
289
 
187
290
  describe '.create' do
188
291
  let(:url) { 'https://api.gandi.net/v5/email/mailboxes/example.com' }
292
+ let(:created_response) do
293
+ double(
294
+ RestClient::Response,
295
+ headers: { location: 'https://api.gandi.net/v5/email/mailboxes/example.com/created-mailbox-uuid' }
296
+ )
297
+ end
298
+ let(:created_mailbox) { double GandiV5::Email::Mailbox }
299
+
300
+ before :each do
301
+ allow(GandiV5::Email::Slot).to receive(:list).and_return [
302
+ GandiV5::Email::Slot.new(mailbox_type: :standard, status: :inactive),
303
+ GandiV5::Email::Slot.new(mailbox_type: :premium, status: :inactive)
304
+ ]
305
+ end
189
306
 
190
307
  it 'No aliases and :standard type' do
191
308
  body = '{"mailbox_type":"standard","login":"login","password":"crypted_password","aliases":[]}'
192
- expect(GandiV5).to receive(:post).with(url, body)
193
- .and_return('message' => 'Confirmation message.')
309
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
310
+ .and_return([created_response, { 'message' => 'Confirmation message.' }])
194
311
  expect(described_class).to receive(:crypt_password).with(good_password).and_return('crypted_password')
312
+ expect(described_class).to receive(:fetch).with('example.com', 'created-mailbox-uuid').and_return(created_mailbox)
195
313
 
196
- expect(described_class.create('example.com', 'login', good_password)).to eq 'Confirmation message.'
314
+ expect(described_class.create('example.com', 'login', good_password)).to be created_mailbox
197
315
  end
198
316
 
199
317
  it 'With aliases' do
200
318
  body = '{"mailbox_type":"standard","login":"login","password":"crypted_password","aliases":["alias-1"]}'
201
- expect(GandiV5).to receive(:post).with(url, body)
202
- .and_return('message' => 'Confirmation message.')
319
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
320
+ .and_return([created_response, { 'message' => 'Confirmation message.' }])
203
321
  expect(described_class).to receive(:crypt_password).with(good_password).and_return('crypted_password')
322
+ expect(described_class).to receive(:fetch).with('example.com', 'created-mailbox-uuid').and_return(created_mailbox)
204
323
 
205
- expect(described_class.create('example.com', 'login', good_password, aliases: ['alias-1']))
206
- .to eq 'Confirmation message.'
324
+ expect(described_class.create('example.com', 'login', good_password, aliases: ['alias-1'])).to be created_mailbox
207
325
  end
208
326
 
209
327
  it 'With different type' do
210
328
  body = '{"mailbox_type":"premium","login":"login","password":"crypted_password","aliases":[]}'
211
- expect(GandiV5).to receive(:post).with(url, body)
212
- .and_return('message' => 'Confirmation message.')
329
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 0)
330
+ .and_return([created_response, { 'message' => 'Confirmation message.' }])
213
331
  expect(described_class).to receive(:crypt_password).with(good_password).and_return('crypted_password')
332
+ expect(described_class).to receive(:fetch).with('example.com', 'created-mailbox-uuid').and_return(created_mailbox)
214
333
 
215
- expect(described_class.create('example.com', 'login', good_password, type: :premium)).to eq 'Confirmation message.'
334
+ expect(described_class.create('example.com', 'login', good_password, type: :premium)).to be created_mailbox
216
335
  end
217
336
 
218
337
  it 'Bad password' do
@@ -220,17 +339,42 @@ describe GandiV5::Email::Mailbox do
220
339
  expect { described_class.create 'example.com', 'login', 'password' }.to raise_error ArgumentError, 'message'
221
340
  end
222
341
 
223
- # TODO: pending 'Bad type'
224
- # TODO: pending 'No available slots'
342
+ it 'Bad type' do
343
+ expect { described_class.create 'example.com', 'login', good_password, type: :invalid }.to raise_error(
344
+ ArgumentError,
345
+ ':invalid is not a valid type'
346
+ )
347
+ end
348
+
349
+ it 'No free slot' do
350
+ expect(GandiV5::Email::Slot).to receive(:list).and_return [
351
+ GandiV5::Email::Slot.new(mailbox_type: :standard, status: :active),
352
+ GandiV5::Email::Slot.new(mailbox_type: :premium, status: :inactive)
353
+ ]
354
+ expect { described_class.create 'example.com', 'login', good_password }.to raise_error(
355
+ GandiV5::Error,
356
+ 'no available standard slots'
357
+ )
358
+ end
359
+
360
+ it 'Doing a dry run' do
361
+ body = '{"mailbox_type":"standard","login":"login","password":"crypted_password","aliases":[]}'
362
+ expect(GandiV5).to receive(:post).with(url, body, 'Dry-Run': 1)
363
+ .and_return([nil, { 'status' => 'success' }])
364
+ expect(described_class).to receive(:crypt_password).with(good_password).and_return('crypted_password')
365
+ expect(described_class).to_not receive(:fetch)
366
+
367
+ expect(described_class.create('example.com', 'login', good_password, dry_run: true)).to eq('status' => 'success')
368
+ end
225
369
  end
226
370
 
227
371
  describe '.fetch' do
228
372
  subject { described_class.fetch 'example.com', 'mailbox-uuid' }
229
373
 
230
374
  before :each do
231
- body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Email_Mailbox', 'get.yaml'))
375
+ body_fixture = File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Email_Mailbox', 'fetch.yml'))
232
376
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com/mailbox-uuid')
233
- .and_return(YAML.load_file(body_fixture))
377
+ .and_return([nil, YAML.load_file(body_fixture)])
234
378
  end
235
379
 
236
380
  its('address') { should eq 'address@example.com' }
@@ -240,6 +384,7 @@ describe GandiV5::Email::Mailbox do
240
384
  its('login') { should eq 'address' }
241
385
  its('type') { should eq :standard }
242
386
  its('quota_used') { should eq 1_000_000 }
387
+ its('responder.mailbox') { should be subject }
243
388
  its('responder.enabled') { should be false }
244
389
  its('responder.starts_at') { should eq Time.new(2000, 1, 1, 0, 0, 0) }
245
390
  its('responder.ends_at') { should eq Time.new(2000, 1, 2, 0, 0, 0) }
@@ -248,7 +393,7 @@ describe GandiV5::Email::Mailbox do
248
393
 
249
394
  describe '.list' do
250
395
  let(:body_fixture) do
251
- File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Email_Mailbox', 'list.yaml'))
396
+ File.expand_path(File.join('spec', 'fixtures', 'bodies', 'GandiV5_Email_Mailbox', 'list.yml'))
252
397
  end
253
398
 
254
399
  describe 'With default values' do
@@ -257,7 +402,7 @@ describe GandiV5::Email::Mailbox do
257
402
  before :each do
258
403
  headers = { params: { page: 1 } }
259
404
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com', headers)
260
- .and_return(YAML.load_file(body_fixture))
405
+ .and_return([nil, YAML.load_file(body_fixture)])
261
406
  end
262
407
 
263
408
  its('count') { should eq 1 }
@@ -272,15 +417,13 @@ describe GandiV5::Email::Mailbox do
272
417
  it 'Keeps fetching until no more to get' do
273
418
  headers1 = { params: { page: 1, per_page: 1 } }
274
419
  headers2 = { params: { page: 2, per_page: 1 } }
275
- # rubocop:disable Layout/MultilineMethodCallIndentation
276
420
  # https://github.com/rubocop-hq/rubocop/issues/7088
277
421
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com', headers1)
278
422
  .ordered
279
- .and_return(YAML.load_file(body_fixture))
423
+ .and_return([nil, YAML.load_file(body_fixture)])
280
424
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com', headers2)
281
425
  .ordered
282
- .and_return([])
283
- # rubocop:enable Layout/MultilineMethodCallIndentation
426
+ .and_return([nil, []])
284
427
 
285
428
  expect(described_class.list('example.com', per_page: 1).count).to eq 1
286
429
  end
@@ -288,15 +431,13 @@ describe GandiV5::Email::Mailbox do
288
431
  it 'Given a range as page number' do
289
432
  headers1 = { params: { page: 1, per_page: 1 } }
290
433
  headers2 = { params: { page: 2, per_page: 1 } }
291
- # rubocop:disable Layout/MultilineMethodCallIndentation
292
434
  # https://github.com/rubocop-hq/rubocop/issues/7088
293
435
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com', headers1)
294
436
  .ordered
295
- .and_return(YAML.load_file(body_fixture))
437
+ .and_return([nil, YAML.load_file(body_fixture)])
296
438
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com', headers2)
297
439
  .ordered
298
- .and_return([])
299
- # rubocop:enable Layout/MultilineMethodCallIndentation
440
+ .and_return([nil, []])
300
441
 
301
442
  expect(described_class.list('example.com', page: (1..2), per_page: 1).count).to eq 1
302
443
  end
@@ -309,7 +450,7 @@ describe GandiV5::Email::Mailbox do
309
450
  it param.to_s do
310
451
  headers = { params: { page: 1 }.merge(query_param => 'value') }
311
452
  expect(GandiV5).to receive(:get).with('https://api.gandi.net/v5/email/mailboxes/example.com', headers)
312
- .and_return([])
453
+ .and_return([nil, []])
313
454
  expect(described_class.list('example.com', param => 'value')).to eq []
314
455
  end
315
456
  end