dnsimple 2.0.0.alpha2 → 2.0.0.alpha3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.markdown +6 -2
  3. data/README.markdown +32 -30
  4. data/dnsimple.gemspec +1 -2
  5. data/lib/dnsimple.rb +2 -13
  6. data/lib/dnsimple/client.rb +164 -53
  7. data/lib/dnsimple/client/certificates_service.rb +98 -0
  8. data/lib/dnsimple/client/client_service.rb +8 -0
  9. data/lib/dnsimple/client/contacts_service.rb +82 -0
  10. data/lib/dnsimple/client/domains_service.rb +333 -0
  11. data/lib/dnsimple/client/name_servers_service.rb +69 -0
  12. data/lib/dnsimple/client/registrars_service.rb +105 -0
  13. data/lib/dnsimple/client/services_service.rb +95 -0
  14. data/lib/dnsimple/client/templates_service.rb +180 -0
  15. data/lib/dnsimple/client/users_service.rb +37 -0
  16. data/lib/dnsimple/compatibility.rb +46 -0
  17. data/lib/dnsimple/default.rb +86 -0
  18. data/lib/dnsimple/error.rb +7 -11
  19. data/lib/dnsimple/extra.rb +54 -0
  20. data/lib/dnsimple/struct.rb +29 -0
  21. data/lib/dnsimple/struct/certificate.rb +56 -0
  22. data/lib/dnsimple/struct/contact.rb +61 -0
  23. data/lib/dnsimple/struct/domain.rb +40 -0
  24. data/lib/dnsimple/struct/email_forward.rb +14 -0
  25. data/lib/dnsimple/struct/extended_attribute.rb +39 -0
  26. data/lib/dnsimple/struct/membership.rb +22 -0
  27. data/lib/dnsimple/struct/price.rb +16 -0
  28. data/lib/dnsimple/struct/record.rb +22 -0
  29. data/lib/dnsimple/struct/service.rb +19 -0
  30. data/lib/dnsimple/struct/template.rb +19 -0
  31. data/lib/dnsimple/struct/template_record.rb +24 -0
  32. data/lib/dnsimple/struct/transfer_order.rb +10 -0
  33. data/lib/dnsimple/struct/user.rb +17 -0
  34. data/lib/dnsimple/struct/whois_privacy.rb +19 -0
  35. data/lib/dnsimple/version.rb +1 -1
  36. data/spec/dnsimple/client/certificates_service_spec.rb +196 -0
  37. data/spec/dnsimple/client/contacts_service_spec.rb +179 -0
  38. data/spec/dnsimple/client/domains_service_spec.rb +662 -0
  39. data/spec/dnsimple/client/name_servers_service_spec.rb +131 -0
  40. data/spec/dnsimple/client/registrars_service_spec.rb +160 -0
  41. data/spec/dnsimple/client/services_service_spec.rb +162 -0
  42. data/spec/dnsimple/client/templates_service_spec.rb +371 -0
  43. data/spec/dnsimple/client/users_service_spec.rb +70 -0
  44. data/spec/dnsimple/client_spec.rb +108 -99
  45. data/spec/dnsimple/compatibility_spec.rb +57 -0
  46. data/spec/files/2fa/exchange-token.http +8 -11
  47. data/spec/files/badgateway.http +14 -0
  48. data/spec/files/certificates/configure/success.http +19 -0
  49. data/spec/files/certificates/index/success.http +1 -1
  50. data/spec/files/certificates/notfound.http +19 -0
  51. data/spec/files/certificates/purchase/success.http +19 -0
  52. data/spec/files/certificates/show/success.http +1 -1
  53. data/spec/files/certificates/submit/success.http +19 -0
  54. data/spec/files/contacts/create/badrequest-missingcontact.http +19 -0
  55. data/spec/files/contacts/create/badrequest-validationerror.http +19 -0
  56. data/spec/files/contacts/create/created.http +22 -0
  57. data/spec/files/contacts/delete/success-204.http +18 -0
  58. data/spec/files/{extended_attributes/com.http → contacts/delete/success.http} +5 -5
  59. data/spec/files/{domains/auto_renewal_enable → contacts/index}/success.http +6 -6
  60. data/spec/files/contacts/notfound.http +19 -0
  61. data/spec/files/contacts/update/success.http +21 -0
  62. data/spec/files/domains/create/created.http +21 -0
  63. data/spec/files/domains/index/success.http +11 -9
  64. data/spec/files/domains/notfound.http +11 -9
  65. data/spec/files/domains/show/success.http +12 -10
  66. data/spec/files/domains_autorenewal/disable/success.http +21 -0
  67. data/spec/files/domains_autorenewal/enable/success.http +21 -0
  68. data/spec/files/domains_autorenewal/notfound-domain.http +19 -0
  69. data/spec/files/domains_forwards/create/created.http +22 -0
  70. data/spec/files/domains_forwards/delete/success.http +17 -0
  71. data/spec/files/domains_forwards/get/success.http +21 -0
  72. data/spec/files/domains_forwards/list/success.http +21 -0
  73. data/spec/files/domains_forwards/notfound-domain.http +19 -0
  74. data/spec/files/domains_forwards/notfound.http +19 -0
  75. data/spec/files/domains_records/create/created.http +21 -0
  76. data/spec/files/domains_records/delete/success-204.http +18 -0
  77. data/spec/files/{contacts/show/notfound.http → domains_records/delete/success.http} +9 -7
  78. data/spec/files/{records → domains_records}/index/success.http +0 -0
  79. data/spec/files/{records/show → domains_records}/notfound.http +1 -1
  80. data/spec/files/{records → domains_records}/show/success.http +0 -0
  81. data/spec/files/domains_records/update/success.http +21 -0
  82. data/spec/files/domains_sharing/create/success.http +21 -0
  83. data/spec/files/domains_sharing/delete/success.http +17 -0
  84. data/spec/files/domains_sharing/list/success.http +21 -0
  85. data/spec/files/domains_sharing/notfound-domain.http +19 -0
  86. data/spec/files/domains_sharing/notfound.http +19 -0
  87. data/spec/files/domains_whois_privacy/disable/success.http +21 -0
  88. data/spec/files/domains_whois_privacy/enable/success.http +22 -0
  89. data/spec/files/domains_zones/get/success.http +21 -0
  90. data/spec/files/domains_zones/notfound-domain.http +19 -0
  91. data/spec/files/{domains/auto_renewal_disable/notfound.http → nameservers/change/success.http} +23 -21
  92. data/spec/files/nameservers/deregister/success.http +17 -0
  93. data/spec/files/{domains/auto_renewal_enable/notfound.http → nameservers/list/success.http} +23 -21
  94. data/spec/files/nameservers/notfound-domain.http +19 -0
  95. data/spec/files/nameservers/register/badrequest-valueerror.http +19 -0
  96. data/spec/files/nameservers/register/success.http +21 -0
  97. data/spec/files/registrars/check/available.http +19 -0
  98. data/spec/files/registrars/check/registered.http +21 -0
  99. data/spec/files/registrars/register/badrequest-missingdomain.http +19 -0
  100. data/spec/files/registrars/register/badrequest-missingregistrant.http +19 -0
  101. data/spec/files/registrars/register/success.http +21 -0
  102. data/spec/files/registrars/renew/badrequest-missingrenewal.http +19 -0
  103. data/spec/files/registrars/renew/badrequest-unable.http +19 -0
  104. data/spec/files/registrars/renew/success.http +21 -0
  105. data/spec/files/registrars/transfer/success.http +21 -0
  106. data/spec/files/registrars_extended_attributes/list/success.http +21 -0
  107. data/spec/files/registrars_prices/list/success.http +21 -0
  108. data/spec/files/services/applied/success.http +21 -0
  109. data/spec/files/services/apply/success.http +21 -0
  110. data/spec/files/services/available/success.http +21 -0
  111. data/spec/files/services/index/success.http +21 -0
  112. data/spec/files/services/notfound.http +19 -0
  113. data/spec/files/services/show/success.http +21 -0
  114. data/spec/files/services/unapply/success.http +21 -0
  115. data/spec/files/subscription/show/success.http +21 -0
  116. data/spec/files/templates/apply/success.http +21 -0
  117. data/spec/files/templates/create/created.http +22 -0
  118. data/spec/files/templates/delete/success-204.http +21 -0
  119. data/spec/files/templates/delete/success.http +21 -0
  120. data/spec/files/templates/index/success.http +21 -0
  121. data/spec/files/templates/notfound.http +19 -0
  122. data/spec/files/templates/show/success.http +12 -10
  123. data/spec/files/templates/update/success.http +21 -0
  124. data/spec/files/templates_records/create/created.http +22 -0
  125. data/spec/files/templates_records/delete/success-204.http +19 -0
  126. data/spec/files/templates_records/delete/success.http +21 -0
  127. data/spec/files/templates_records/index/success.http +21 -0
  128. data/spec/files/templates_records/notfound.http +19 -0
  129. data/spec/files/templates_records/show/success.http +21 -0
  130. data/spec/files/templates_records/update/success.http +21 -0
  131. data/spec/files/users/user/success.http +21 -0
  132. data/spec/spec_helper.rb +0 -2
  133. metadata +206 -73
  134. data/lib/dnsimple/base.rb +0 -10
  135. data/lib/dnsimple/certificate.rb +0 -143
  136. data/lib/dnsimple/contact.rb +0 -157
  137. data/lib/dnsimple/domain.rb +0 -252
  138. data/lib/dnsimple/extended_attribute.rb +0 -52
  139. data/lib/dnsimple/record.rb +0 -94
  140. data/lib/dnsimple/service.rb +0 -42
  141. data/lib/dnsimple/template.rb +0 -65
  142. data/lib/dnsimple/template_record.rb +0 -80
  143. data/lib/dnsimple/transfer_order.rb +0 -34
  144. data/lib/dnsimple/user.rb +0 -50
  145. data/spec/dnsimple/certificate_spec.rb +0 -59
  146. data/spec/dnsimple/contact_spec.rb +0 -45
  147. data/spec/dnsimple/domain_spec.rb +0 -241
  148. data/spec/dnsimple/extended_attributes_spec.rb +0 -54
  149. data/spec/dnsimple/record_spec.rb +0 -51
  150. data/spec/dnsimple/template_spec.rb +0 -31
  151. data/spec/dnsimple/user_spec.rb +0 -70
  152. data/spec/files/account/user/success.http +0 -19
  153. data/spec/files/certificates/show/notfound.http +0 -17
  154. data/spec/files/domains/auto_renewal_disable/success.http +0 -23
  155. data/spec/files/domains/create/success.http +0 -19
  156. data/spec/files/extended_attributes/ca.http +0 -19
  157. data/spec/files/extended_attributes/success.http +0 -19
  158. data/spec/files/templates/show/notfound.http +0 -17
@@ -0,0 +1,371 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dnsimple::Client, ".templates" do
4
+
5
+ subject { described_class.new(api_endpoint: "https://api.zone", username: "user", api_token: "token").templates }
6
+
7
+
8
+ describe "#list" do
9
+ before do
10
+ stub_request(:get, %r[/v1/templates$]).
11
+ to_return(read_fixture("templates/index/success.http"))
12
+ end
13
+
14
+ it "builds the correct request" do
15
+ subject.list
16
+
17
+ expect(WebMock).to have_requested(:get, "https://api.zone/v1/templates").
18
+ with(headers: { 'Accept' => 'application/json' })
19
+ end
20
+
21
+ it "returns the templates" do
22
+ results = subject.list
23
+
24
+ expect(results).to be_a(Array)
25
+ expect(results.size).to eq(1)
26
+
27
+ results.each do |result|
28
+ expect(result).to be_a(Dnsimple::Struct::Template)
29
+ expect(result.id).to be_a(Fixnum)
30
+ end
31
+ end
32
+ end
33
+
34
+ describe "#create" do
35
+ before do
36
+ stub_request(:post, %r[/v1/templates]).
37
+ to_return(read_fixture("templates/create/created.http"))
38
+ end
39
+
40
+ let(:attributes) { { name: "", short_name: "" } }
41
+
42
+ it "builds the correct request" do
43
+ subject.create(attributes)
44
+
45
+ expect(WebMock).to have_requested(:post, "https://api.zone/v1/templates").
46
+ with(body: { dns_template: attributes }).
47
+ with(headers: { 'Accept' => 'application/json' })
48
+ end
49
+
50
+ it "returns the template" do
51
+ result = subject.create(attributes)
52
+
53
+ expect(result).to be_a(Dnsimple::Struct::Template)
54
+ expect(result.id).to be_a(Fixnum)
55
+ end
56
+ end
57
+
58
+ describe "#find" do
59
+ before do
60
+ stub_request(:get, %r[/v1/templates/.+$]).
61
+ to_return(read_fixture("templates/show/success.http"))
62
+ end
63
+
64
+ it "builds the correct request" do
65
+ subject.find(1)
66
+
67
+ expect(WebMock).to have_requested(:get, "https://api.zone/v1/templates/1").
68
+ with(headers: { 'Accept' => 'application/json' })
69
+ end
70
+
71
+ it "returns the template" do
72
+ result = subject.find(1)
73
+
74
+ expect(result).to be_a(Dnsimple::Struct::Template)
75
+ expect(result.id).to eq(2651)
76
+ expect(result.name).to eq("Localhost")
77
+ expect(result.short_name).to eq("localhost")
78
+ expect(result.description).to eq("This is a test.")
79
+ end
80
+
81
+ context "when something does not exist" do
82
+ it "raises RecordNotFound" do
83
+ stub_request(:get, %r[/v1]).
84
+ to_return(read_fixture("templates/notfound.http"))
85
+
86
+ expect {
87
+ subject.find(1)
88
+ }.to raise_error(Dnsimple::RecordNotFound)
89
+ end
90
+ end
91
+ end
92
+
93
+ describe "#update" do
94
+ before do
95
+ stub_request(:put, %r[/v1/templates/.+$]).
96
+ to_return(read_fixture("templates/update/success.http"))
97
+ end
98
+
99
+ it "builds the correct request" do
100
+ subject.update(1, { name: "Updated" })
101
+
102
+ expect(WebMock).to have_requested(:put, "https://api.zone/v1/templates/1").
103
+ with(body: { dns_template: { name: "Updated" } }).
104
+ with(headers: { 'Accept' => 'application/json' })
105
+ end
106
+
107
+ it "returns the template" do
108
+ result = subject.update(1, {})
109
+
110
+ expect(result).to be_a(Dnsimple::Struct::Template)
111
+ expect(result.id).to be_a(Fixnum)
112
+ end
113
+
114
+ context "when something does not exist" do
115
+ it "raises RecordNotFound" do
116
+ stub_request(:put, %r[/v1]).
117
+ to_return(read_fixture("templates/notfound.http"))
118
+
119
+ expect {
120
+ subject.update(1, {})
121
+ }.to raise_error(Dnsimple::RecordNotFound)
122
+ end
123
+ end
124
+ end
125
+
126
+ describe "#delete" do
127
+ before do
128
+ stub_request(:delete, %r[/v1/templates/.+$]).
129
+ to_return(read_fixture("templates/delete/success.http"))
130
+ end
131
+
132
+ it "builds the correct request" do
133
+ subject.delete(1)
134
+
135
+ expect(WebMock).to have_requested(:delete, "https://api.zone/v1/templates/1").
136
+ with(headers: { 'Accept' => 'application/json' })
137
+ end
138
+
139
+ it "returns nothing" do
140
+ result = subject.delete(1)
141
+
142
+ expect(result).to be_truthy
143
+ end
144
+
145
+ it "supports HTTP 204" do
146
+ stub_request(:delete, %r[/v1]).
147
+ to_return(read_fixture("templates/delete/success-204.http"))
148
+
149
+ result = subject.delete(1)
150
+
151
+ expect(result).to be_truthy
152
+ end
153
+
154
+ context "when something does not exist" do
155
+ it "raises RecordNotFound" do
156
+ stub_request(:delete, %r[/v1]).
157
+ to_return(read_fixture("templates/notfound.http"))
158
+
159
+ expect {
160
+ subject.delete(1)
161
+ }.to raise_error(Dnsimple::RecordNotFound)
162
+ end
163
+ end
164
+ end
165
+
166
+
167
+ describe "#apply" do
168
+ before do
169
+ stub_request(:post, %r[/v1/domains/.+/templates/.+/apply$]).
170
+ to_return(read_fixture("templates/apply/success.http"))
171
+ end
172
+
173
+ it "builds the correct request" do
174
+ subject.apply(1, 2)
175
+
176
+ expect(WebMock).to have_requested(:post, "https://api.zone/v1/domains/1/templates/2/apply").
177
+ with(headers: { 'Accept' => 'application/json' })
178
+ end
179
+
180
+ it "returns nothing" do
181
+ result = subject.apply(1, 2)
182
+
183
+ expect(result).to be_truthy
184
+ end
185
+
186
+ context "when something does not exist" do
187
+ it "raises RecordNotFound" do
188
+ stub_request(:post, %r[/v1]).
189
+ to_return(read_fixture("templates/notfound.http"))
190
+
191
+ expect {
192
+ subject.apply(1, 2)
193
+ }.to raise_error(Dnsimple::RecordNotFound)
194
+ end
195
+ end
196
+ end
197
+
198
+
199
+ describe "#list_records" do
200
+ before do
201
+ stub_request(:get, %r[/v1/templates/.+/records$]).
202
+ to_return(read_fixture("templates_records/index/success.http"))
203
+ end
204
+
205
+ it "builds the correct request" do
206
+ subject.list_records(1)
207
+
208
+ expect(WebMock).to have_requested(:get, "https://api.zone/v1/templates/1/records").
209
+ with(headers: { 'Accept' => 'application/json' })
210
+ end
211
+
212
+ it "returns the template records" do
213
+ results = subject.list_records(1)
214
+
215
+ expect(results).to be_a(Array)
216
+ expect(results.size).to eq(2)
217
+
218
+ results.each do |result|
219
+ expect(result).to be_a(Dnsimple::Struct::TemplateRecord)
220
+ expect(result.id).to be_a(Fixnum)
221
+ end
222
+ end
223
+ end
224
+
225
+ describe "#create_record" do
226
+ before do
227
+ stub_request(:post, %r[/v1/templates/.+/records$]).
228
+ to_return(read_fixture("templates_records/create/created.http"))
229
+ end
230
+
231
+ it "builds the correct request" do
232
+ subject.create_record(1, { name: "", record_type: "A", content: "127.0.0.1", prio: "1" })
233
+
234
+ expect(WebMock).to have_requested(:post, "https://api.zone/v1/templates/1/records").
235
+ with(body: { dns_template_record: { name: "", record_type: "A", content: "127.0.0.1", prio: "1" } }).
236
+ with(headers: { 'Accept' => 'application/json' })
237
+ end
238
+
239
+ it "returns the template record" do
240
+ result = subject.create_record(1, { name: "", record_type: "", content: "" })
241
+
242
+ expect(result).to be_a(Dnsimple::Struct::TemplateRecord)
243
+ expect(result.id).to be_a(Fixnum)
244
+ end
245
+
246
+ context "when something does not exist" do
247
+ it "raises RecordNotFound" do
248
+ stub_request(:post, %r[/v1]).
249
+ to_return(read_fixture("templates_records/notfound.http"))
250
+
251
+ expect {
252
+ subject.create_record(1, { name: "", record_type: "", content: "" })
253
+ }.to raise_error(Dnsimple::RecordNotFound)
254
+ end
255
+ end
256
+ end
257
+
258
+ describe "#find_record" do
259
+ before do
260
+ stub_request(:get, %r[/v1/templates/.+/records/.+$]).
261
+ to_return(read_fixture("templates_records/show/success.http"))
262
+ end
263
+
264
+ it "builds the correct request" do
265
+ subject.find_record(1, 2)
266
+
267
+ expect(WebMock).to have_requested(:get, "https://api.zone/v1/templates/1/records/2").
268
+ with(headers: { 'Accept' => 'application/json' })
269
+ end
270
+
271
+ it "returns the record" do
272
+ result = subject.find_record(1, 2)
273
+
274
+ expect(result).to be_a(Dnsimple::Struct::TemplateRecord)
275
+ expect(result.id).to eq(8868)
276
+ expect(result.dns_template_id).to eq(2947)
277
+ expect(result.name).to eq("ww1")
278
+ expect(result.content).to eq("127.0.0.1")
279
+ expect(result.ttl).to eq(3600)
280
+ expect(result.prio).to be_nil
281
+ expect(result.record_type).to eq("ALIAS")
282
+ expect(result.created_at).to eq("2014-12-15T17:25:20.431Z")
283
+ expect(result.updated_at).to eq("2014-12-15T17:25:20.431Z")
284
+ end
285
+
286
+ context "when something does not exist" do
287
+ it "raises RecordNotFound" do
288
+ stub_request(:get, %r[/v1]).
289
+ to_return(read_fixture("templates_records/notfound.http"))
290
+
291
+ expect {
292
+ subject.find_record(1, 2)
293
+ }.to raise_error(Dnsimple::RecordNotFound)
294
+ end
295
+ end
296
+ end
297
+
298
+ describe "#update_record" do
299
+ before do
300
+ stub_request(:put, %r[/v1/templates/.+/records/.+$]).
301
+ to_return(read_fixture("templates_records/update/success.http"))
302
+ end
303
+
304
+ it "builds the correct request" do
305
+ subject.update_record(1, 2, { name: "www" })
306
+
307
+ expect(WebMock).to have_requested(:put, "https://api.zone/v1/templates/1/records/2").
308
+ with(body: { dns_template_record: { name: "www" } }).
309
+ with(headers: { 'Accept' => 'application/json' })
310
+ end
311
+
312
+ it "returns the template record" do
313
+ result = subject.update_record(1, 2, {})
314
+
315
+ expect(result).to be_a(Dnsimple::Struct::TemplateRecord)
316
+ expect(result.id).to be_a(Fixnum)
317
+ end
318
+
319
+ context "when something does not exist" do
320
+ it "raises RecordNotFound" do
321
+ stub_request(:put, %r[/v1]).
322
+ to_return(read_fixture("templates_records/notfound.http"))
323
+
324
+ expect {
325
+ subject.update_record(1, 2, {})
326
+ }.to raise_error(Dnsimple::RecordNotFound)
327
+ end
328
+ end
329
+ end
330
+
331
+ describe "#delete_record" do
332
+ before do
333
+ stub_request(:delete, %r[/v1/templates/.+/records/.+$]).
334
+ to_return(read_fixture("templates_records/delete/success.http"))
335
+ end
336
+
337
+ it "builds the correct request" do
338
+ subject.delete_record(1, 2)
339
+
340
+ expect(WebMock).to have_requested(:delete, "https://api.zone/v1/templates/1/records/2").
341
+ with(headers: { 'Accept' => 'application/json' })
342
+ end
343
+
344
+ it "returns nothing" do
345
+ result = subject.delete_record(1, 2)
346
+
347
+ expect(result).to be_truthy
348
+ end
349
+
350
+ it "supports HTTP 204" do
351
+ stub_request(:delete, %r[/v1]).
352
+ to_return(read_fixture("templates_records/delete/success-204.http"))
353
+
354
+ result = subject.delete_record(1, 2)
355
+
356
+ expect(result).to be_truthy
357
+ end
358
+
359
+ context "when something does not exist" do
360
+ it "raises RecordNotFound" do
361
+ stub_request(:delete, %r[/v1]).
362
+ to_return(read_fixture("templates_records/notfound.http"))
363
+
364
+ expect {
365
+ subject.delete_record(1, 2)
366
+ }.to raise_error(Dnsimple::RecordNotFound)
367
+ end
368
+ end
369
+ end
370
+
371
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dnsimple::Client, ".users" do
4
+
5
+ subject { described_class.new(api_endpoint: "https://api.zone", username: "user", api_token: "token").users }
6
+
7
+
8
+ describe "#user" do
9
+ before do
10
+ stub_request(:get, %r[/v1/user]).
11
+ to_return(read_fixture("users/user/success.http"))
12
+ end
13
+
14
+ it "builds the correct request" do
15
+ subject.user
16
+
17
+ expect(WebMock).to have_requested(:get, "https://api.zone/v1/user").
18
+ with(headers: { 'Accept' => 'application/json' })
19
+ end
20
+
21
+ it "returns the user" do
22
+ result = subject.user
23
+
24
+ expect(result).to be_a(Dnsimple::Struct::User)
25
+ expect(result.id).to eq(1)
26
+ expect(result.email).to eq("example@example.com")
27
+ expect(result.api_token).to eq("api-token")
28
+ expect(result.domain_count).to eq(32)
29
+ expect(result.domain_limit).to eq(1000)
30
+ expect(result.login_count).to eq(2)
31
+ expect(result.failed_login_count).to eq(1)
32
+ expect(result.created_at).to eq("2011-03-17T21:30:25.731Z")
33
+ expect(result.updated_at).to eq("2014-12-13T13:52:08.343Z")
34
+ end
35
+ end
36
+
37
+ describe "#exchange_token" do
38
+ before do
39
+ stub_request(:get, %r[/v1/user]).
40
+ to_return(read_fixture("2fa/exchange-token.http"))
41
+ end
42
+
43
+ it "builds the correct request" do
44
+ subject.exchange_token("123456")
45
+
46
+ expect(WebMock).to have_requested(:get, "https://api.zone/v1/user").
47
+ with(headers: { "X-Dnsimple-Otp" => "123456" })
48
+ end
49
+
50
+ it "returns the exchange_token" do
51
+ result = subject.exchange_token("123456")
52
+
53
+ expect(result).to eq("0c622716aaa64124219963075bc1c870")
54
+ end
55
+
56
+ context "when the OTP token is invalid" do
57
+ before do
58
+ stub_request(:get, %r[/v1/user]).
59
+ to_return(read_fixture("2fa/error-badtoken.http"))
60
+ end
61
+
62
+ it "raises an AuthenticationFailed" do
63
+ expect {
64
+ subject.exchange_token("invalid-token")
65
+ }.to raise_error(Dnsimple::AuthenticationFailed, "Bad OTP token")
66
+ end
67
+ end
68
+ end
69
+
70
+ end
@@ -2,152 +2,161 @@ require 'spec_helper'
2
2
 
3
3
  describe Dnsimple::Client do
4
4
 
5
- let(:klass) { described_class }
6
- let(:response) { stub('response', :code => 200) }
7
-
8
- before do
9
- @_username = described_class.username
10
- @_password = described_class.password
11
- @_api_token = described_class.api_token
12
- @_base_uri = described_class.base_uri
13
- end
14
-
15
- after do
16
- described_class.username = @_username
17
- described_class.password = @_password
18
- described_class.api_token = @_api_token
19
- described_class.base_uri = @_base_uri
20
- end
5
+ describe "initialization" do
6
+ it "accepts :api_endpoint option" do
7
+ subject = described_class.new(api_endpoint: "https://api.example.com/")
8
+ expect(subject.api_endpoint).to eq("https://api.example.com/")
9
+ end
21
10
 
22
- [:get, :post, :put, :delete].each do |method|
23
- describe ".#{method}" do
24
- it "delegates to .request" do
25
- described_class.expects(:request).with(method, '/domains', { :foo => 'bar' })
26
- described_class.send(method, '/domains', { :foo => 'bar' })
27
- end
11
+ it "normalizes :api_endpoint trailing slash" do
12
+ subject = described_class.new(api_endpoint: "https://api.example.com/missing/slash")
13
+ expect(subject.api_endpoint).to eq("https://api.example.com/missing/slash/")
28
14
  end
29
- end
30
15
 
31
- describe ".request" do
32
- before do
33
- [:username, :password, :exchange_token, :api_token, :domain_api_token].each do |attribute|
34
- described_class.send("#{attribute}=", nil)
35
- end
16
+ it "defaults :api_endpoint to production API" do
17
+ subject = described_class.new
18
+ expect(subject.api_endpoint).to eq("https://api.dnsimple.com/")
36
19
  end
20
+ end
37
21
 
22
+ describe "authentication" do
38
23
  it "uses HTTP authentication if there's a password provided" do
39
- described_class.username = 'user'
40
- described_class.password = 'pass'
41
- described_class.base_uri = 'https://api.example.com/'
24
+ stub_request(:any, %r[/test])
42
25
 
43
- HTTParty.expects(:get).
44
- with('https://api.example.com/domains', has_entries(:basic_auth => { :username => 'user', :password => 'pass' })).
45
- returns(response)
26
+ subject = described_class.new(username: "user", password: "pass")
27
+ subject.request(:get, "test", {})
46
28
 
47
- described_class.request(:get, '/domains', {})
29
+ expect(WebMock).to have_requested(:get, "https://user:pass@api.dnsimple.com/test")
48
30
  end
49
31
 
50
32
  it "uses header authentication if there's a domain api token provided" do
51
- described_class.domain_api_token = 'domaintoken'
52
- described_class.base_uri = 'https://api.example.com/'
33
+ stub_request(:any, %r[/test])
53
34
 
54
- HTTParty.expects(:get).
55
- with('https://api.example.com/domains', has_entries(:headers => has_entries({ 'X-DNSimple-Domain-Token' => 'domaintoken' }))).
56
- returns(response)
35
+ subject = described_class.new(domain_api_token: "domaintoken")
36
+ subject.request(:get, "test", {})
57
37
 
58
- described_class.request(:get, '/domains', {})
38
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.com/test").
39
+ with { |req| req.headers["X-Dnsimple-Domain-Token"] == "domaintoken" }
59
40
  end
60
41
 
61
42
  it "uses header authentication if there's an api token provided" do
62
- described_class.username = 'user'
63
- described_class.api_token = 'token'
64
- described_class.base_uri = 'https://api.example.com/'
43
+ stub_request(:any, %r[/test])
65
44
 
66
- HTTParty.expects(:get).
67
- with('https://api.example.com/domains', has_entries(:headers => has_entries({ 'X-DNSimple-Token' => 'user:token' }))).
68
- returns(response)
45
+ subject = described_class.new(username: "user", api_token: "token")
46
+ subject.request(:get, "test", {})
69
47
 
70
- described_class.request(:get, '/domains', {})
48
+ expect(WebMock).to have_requested(:get, "https://api.dnsimple.com/test").
49
+ with { |req| req.headers["X-Dnsimple-Token"] == "user:token" }
71
50
  end
72
51
 
73
52
  it "uses HTTP authentication via exchange token if there's an exchange token provided" do
74
- described_class.username = 'user'
75
- described_class.password = 'pass'
76
- described_class.exchange_token = 'exchange-token'
77
- described_class.base_uri = 'https://api.example.com/'
53
+ stub_request(:any, %r[/test])
78
54
 
79
- HTTParty.expects(:get).
80
- with('https://api.example.com/domains', has_entries(:basic_auth => { :username => 'exchange-token', :password => 'x-2fa-basic' })).
81
- returns(response)
55
+ subject = described_class.new(username: "user", password: "pass", exchange_token: "exchange-token")
56
+ subject.request(:get, "test", {})
82
57
 
83
- described_class.request(:get, '/domains', {})
58
+ expect(WebMock).to have_requested(:get, "https://exchange-token:x-2fa-basic@api.dnsimple.com/test")
84
59
  end
85
60
 
86
61
  it "raises an error if there's no password or api token provided" do
87
- described_class.username = 'user'
88
- described_class.base_uri = 'https://api.example.com/'
62
+ subject = described_class.new(username: "user")
89
63
 
90
64
  expect {
91
- described_class.request(:get, '/domains', {})
65
+ subject.request(:get, "test", {})
92
66
  }.to raise_error(Dnsimple::Error, 'A password or API token is required for all API requests.')
93
67
  end
94
68
 
95
- it "adds a custom user-agent" do
96
- described_class.api_token = 'token'
69
+ context "when 2FA is required" do
70
+ subject { described_class.new(username: "user", password: "pass") }
97
71
 
98
- HTTParty.expects(:get).
99
- with(is_a(String), has_entries(:headers => has_entries({ 'User-Agent' => "dnsimple-ruby/#{Dnsimple::VERSION}" }))).
100
- returns(response)
72
+ before do
73
+ stub_request(:any, %r[/test]).
74
+ to_return(read_fixture("2fa/error-required.http"))
75
+ end
101
76
 
102
- described_class.request(:get, '/foo', {})
77
+ it "raises a TwoFactorAuthenticationRequired error" do
78
+ expect {
79
+ subject.request(:get, "test", {})
80
+ }.to raise_error(Dnsimple::TwoFactorAuthenticationRequired)
81
+ end
103
82
  end
83
+ end
104
84
 
105
- it "performs a request" do
106
- described_class.username = 'user'
107
- described_class.password = 'pass'
108
-
109
- HTTParty.expects(:get).
110
- with("#{described_class.base_uri}/foo",
111
- :format => :json,
112
- :basic_auth => { :username => described_class.username, :password => described_class.password },
113
- :headers => { 'Accept' => 'application/json', 'User-Agent' => "dnsimple-ruby/#{Dnsimple::VERSION}" }
114
- ).
115
- returns(response)
116
-
117
- described_class.request(:get, '/foo', {})
85
+ describe "#get" do
86
+ it "delegates to #request" do
87
+ expect(subject).to receive(:request).with(:get, "path", { foo: "bar" }).and_return(:returned)
88
+ expect(subject.get("path", foo: "bar")).to eq(:returned)
118
89
  end
119
90
  end
120
91
 
92
+ describe "#post" do
93
+ it "delegates to #request" do
94
+ expect(subject).to receive(:request).with(:post, "path", { foo: "bar" }).and_return(:returned)
95
+ expect(subject.post("path", foo: "bar")).to eq(:returned)
96
+ end
97
+ end
121
98
 
122
- describe ".base_uri" do
123
- it "returns the qualified API uri" do
124
- klass.base_uri = "http://api.dnsimple.com"
125
- expect(klass.base_uri).to eq("http://api.dnsimple.com")
99
+ describe "#put" do
100
+ it "delegates to #request" do
101
+ expect(subject).to receive(:request).with(:put, "path", { foo: "bar" }).and_return(:returned)
102
+ expect(subject.put("path", foo: "bar")).to eq(:returned)
126
103
  end
127
104
  end
128
105
 
129
- describe ".base_uri=" do
130
- it "sets the base_uri" do
131
- klass.base_uri = "http://api1.dnsimple.com/"
132
- expect(klass.base_uri).to eq("http://api1.dnsimple.com")
133
- klass.base_uri = "http://api2.dnsimple.com"
134
- expect(klass.base_uri).to eq("http://api2.dnsimple.com")
106
+ describe "#delete" do
107
+ it "delegates to #request" do
108
+ expect(subject).to receive(:request).with(:delete, "path", { foo: "bar" }).and_return(:returned)
109
+ expect(subject.delete("path", foo: "bar")).to eq(:returned)
135
110
  end
136
111
  end
137
112
 
113
+ describe "#request" do
114
+ subject { described_class.new(username: "user", password: "pass") }
138
115
 
139
- describe "authentication" do
140
- context "when 2FA is required" do
141
- before do
142
- stub_request(:get, %r[/foo]).
143
- to_return(read_fixture("2fa/error-required.http"))
144
- end
116
+ it "performs a request" do
117
+ stub_request(:get, %r[/foo])
145
118
 
146
- it "raises a TwoFactorAuthenticationRequired error" do
147
- expect {
148
- described_class.get('/foo', {})
149
- }.to raise_error(Dnsimple::TwoFactorAuthenticationRequired)
150
- end
119
+ subject.request(:get, 'foo', {})
120
+
121
+ expect(WebMock).to have_requested(:get, "https://user:pass@api.dnsimple.com/foo").
122
+ with(headers: { 'Accept' => 'application/json', 'User-Agent' => "dnsimple-ruby/#{Dnsimple::VERSION}" })
123
+ end
124
+
125
+ it "delegates to HTTParty" do
126
+ stub_request(:get, %r[/foo])
127
+
128
+ expect(HTTParty).to receive(:get).
129
+ with("#{subject.api_endpoint}foo",
130
+ format: :json,
131
+ basic_auth: { username: "user", password: "pass" },
132
+ headers: { 'Accept' => 'application/json', 'User-Agent' => "dnsimple-ruby/#{Dnsimple::VERSION}" }
133
+ ).
134
+ and_return(double('response', code: 200))
135
+
136
+ subject.request(:get, 'foo', {})
137
+ end
138
+
139
+ it "properly extracts options from data" do
140
+ expect(HTTParty).to receive(:put).
141
+ with("#{subject.api_endpoint}foo",
142
+ format: :json,
143
+ body: { something: "else" },
144
+ query: { foo: "bar" },
145
+ basic_auth: { username: "user", password: "pass" },
146
+ headers: { 'Accept' => 'application/json', 'User-Agent' => "dnsimple-ruby/#{Dnsimple::VERSION}", "Custom" => "Header" }
147
+ ).
148
+ and_return(double('response', code: 200))
149
+
150
+ subject.request(:put, 'foo', { something: "else", query: { foo: "bar" }, headers: { "Custom" => "Header" } })
151
+ end
152
+
153
+ it "raises RequestError in case of error" do
154
+ stub_request(:get, %r[/foo]).
155
+ to_return(status: [500, "Internal Server Error"])
156
+
157
+ expect {
158
+ subject.request(:get, "foo", {})
159
+ }.to raise_error(Dnsimple::RequestError, "500")
151
160
  end
152
161
  end
153
162