dnsimple 2.0.0.alpha2 → 2.0.0.alpha3

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 (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