api-transformer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.overcommit.yml +27 -0
- data/.rubocop.yml +9 -0
- data/.rubocop_todo.yml +15 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +358 -0
- data/Rakefile +9 -0
- data/api-transformer.gemspec +31 -0
- data/examples/ip_server.rb +19 -0
- data/lib/api/transformer.rb +1 -0
- data/lib/api_transformer/backend_request.rb +79 -0
- data/lib/api_transformer/backend_request_sender.rb +56 -0
- data/lib/api_transformer/backend_response.rb +62 -0
- data/lib/api_transformer/endpoint.rb +120 -0
- data/lib/api_transformer/errors.rb +4 -0
- data/lib/api_transformer/frontend_response.rb +52 -0
- data/lib/api_transformer/frontend_response_builder.rb +138 -0
- data/lib/api_transformer/params.rb +8 -0
- data/lib/api_transformer/rack/cookie_params.rb +38 -0
- data/lib/api_transformer/routes.rb +71 -0
- data/lib/api_transformer/version.rb +4 -0
- data/lib/api_transformer.rb +147 -0
- data/spec/server_spec.rb +746 -0
- data/spec/spec_helper.rb +3 -0
- metadata +199 -0
data/spec/server_spec.rb
ADDED
@@ -0,0 +1,746 @@
|
|
1
|
+
require "goliath/test_helper"
|
2
|
+
require "goliath/test_helper_streaming"
|
3
|
+
|
4
|
+
require_relative "./spec_helper"
|
5
|
+
require_relative "../lib/api_transformer"
|
6
|
+
|
7
|
+
def create_server(&block)
|
8
|
+
server = Class.new(ApiTransformer::Server) do
|
9
|
+
base_url "http://localhost:9900"
|
10
|
+
end
|
11
|
+
|
12
|
+
server.instance_eval(&block)
|
13
|
+
|
14
|
+
server
|
15
|
+
end
|
16
|
+
|
17
|
+
def extend_server(server, &block)
|
18
|
+
server.instance_eval(&block)
|
19
|
+
server
|
20
|
+
end
|
21
|
+
|
22
|
+
def echo_greeting_server
|
23
|
+
create_server do
|
24
|
+
get "/echo_greeting" do |params|
|
25
|
+
response do
|
26
|
+
attribute :greeting, params[:greeting]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe ApiTransformer::Server do
|
33
|
+
include Goliath::TestHelper
|
34
|
+
|
35
|
+
let(:err) { proc { |c| fail "HTTP Request failed #{c.response}" } }
|
36
|
+
|
37
|
+
before do
|
38
|
+
ApiTransformer::Server.reset_routes
|
39
|
+
end
|
40
|
+
|
41
|
+
it "works without any backend requests" do
|
42
|
+
no_backend = create_server do
|
43
|
+
get "/ping" do
|
44
|
+
response do
|
45
|
+
success { attribute :result, "pong" }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
with_api(no_backend) do
|
51
|
+
get_request(path: "/ping") do |c|
|
52
|
+
c.response.must_equal '{"result":"pong"}'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it "works with a backend request" do
|
58
|
+
backend = create_server do
|
59
|
+
get "/one" do
|
60
|
+
request :two do
|
61
|
+
path "/two"
|
62
|
+
method :get
|
63
|
+
end
|
64
|
+
|
65
|
+
response do |data|
|
66
|
+
success { attribute :two, data[:two].json }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
get "/two" do
|
71
|
+
response do
|
72
|
+
success { attribute :result, "OK" }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
with_api(backend) do
|
78
|
+
get_request(path: "/one") do |c|
|
79
|
+
c.response.must_equal '{"two":{"result":"OK"}}'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it "fails without a method on backend requests" do
|
85
|
+
server = create_server do
|
86
|
+
get "/nomethod" do
|
87
|
+
request :somewhere do
|
88
|
+
path "/somewhere"
|
89
|
+
end
|
90
|
+
|
91
|
+
response do
|
92
|
+
success 204
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
with_api(server) do
|
98
|
+
get_request(path: "/nomethod") do |c|
|
99
|
+
c.response.must_equal "Missing method for backend request: somewhere"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
it "works with a namespace" do
|
105
|
+
namspaced = create_server do
|
106
|
+
namespace "/first" do
|
107
|
+
get "/second" do
|
108
|
+
response do
|
109
|
+
success { attribute :result, "Found me!" }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
with_api(namspaced) do
|
116
|
+
get_request(path: "/first/second") do |c|
|
117
|
+
c.response.must_equal '{"result":"Found me!"}'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it "accepts path params from incoming requests" do
|
123
|
+
server = create_server do
|
124
|
+
get "/echo_greeting/:greeting" do |params|
|
125
|
+
response do
|
126
|
+
attribute :greeting, params[:greeting]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
with_api(server) do
|
132
|
+
get_request(path: "/echo_greeting/hola") do |c|
|
133
|
+
c.response.must_equal '{"greeting":"hola"}'
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
it "accepts query params from incoming requests" do
|
139
|
+
with_api(echo_greeting_server) do
|
140
|
+
get_request(path: "/echo_greeting", query: { greeting: "yo" }) do |c|
|
141
|
+
c.response.must_equal '{"greeting":"yo"}'
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
it "accepts form params from incoming requests" do
|
147
|
+
with_api(echo_greeting_server) do
|
148
|
+
get_request(path: "/echo_greeting", body: { greeting: "hullo" }) do |c|
|
149
|
+
c.response.must_equal '{"greeting":"hullo"}'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
it "accepts json params from incoming requests" do
|
155
|
+
with_api(echo_greeting_server) do
|
156
|
+
get_request(
|
157
|
+
path: "/echo_greeting",
|
158
|
+
body: '{"greeting":"howdy"}',
|
159
|
+
head: { "Content-Type" => "application/json" }
|
160
|
+
) do |c|
|
161
|
+
c.response.must_equal '{"greeting":"howdy"}'
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
it "sends query params in backend requests" do
|
167
|
+
proxy_query = extend_server echo_greeting_server do
|
168
|
+
get "/proxy_query_param" do
|
169
|
+
request :echo do
|
170
|
+
path "/echo_greeting"
|
171
|
+
method :get
|
172
|
+
|
173
|
+
query_param :greeting, "hello"
|
174
|
+
end
|
175
|
+
|
176
|
+
response do |data|
|
177
|
+
attribute :greeting, data[:echo][:greeting]
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
with_api(proxy_query) do
|
183
|
+
get_request(path: "/proxy_query_param") do |c|
|
184
|
+
c.response.must_equal '{"greeting":"hello"}'
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
it "sends form params in backend requests" do
|
190
|
+
proxy_form = extend_server echo_greeting_server do
|
191
|
+
get "/proxy_form_param" do
|
192
|
+
request :echo do
|
193
|
+
path "/echo_greeting"
|
194
|
+
method :get
|
195
|
+
|
196
|
+
form_param :greeting, "hello"
|
197
|
+
end
|
198
|
+
|
199
|
+
response do |data|
|
200
|
+
attribute :greeting, data[:echo][:greeting]
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
with_api(proxy_form) do
|
206
|
+
get_request(path: "/proxy_form_param") do |c|
|
207
|
+
c.response.must_equal '{"greeting":"hello"}'
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe "json params" do
|
213
|
+
it "sends json params in backend requests" do
|
214
|
+
proxy_json = extend_server echo_greeting_server do
|
215
|
+
get "/proxy_json_param" do
|
216
|
+
request :echo do
|
217
|
+
path "/echo_greeting"
|
218
|
+
method :get
|
219
|
+
|
220
|
+
json_param :greeting, "hello"
|
221
|
+
end
|
222
|
+
|
223
|
+
response do |data|
|
224
|
+
attribute :greeting, data[:echo][:greeting]
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
with_api(proxy_json) do
|
230
|
+
get_request(path: "/proxy_json_param") do |c|
|
231
|
+
c.response.must_equal '{"greeting":"hello"}'
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
it "does not allow both json and form params together" do
|
237
|
+
conflicting_params = create_server do
|
238
|
+
get "/conflicting_params" do
|
239
|
+
request :echo do
|
240
|
+
path "/echo_greeting"
|
241
|
+
method :get
|
242
|
+
|
243
|
+
json_param :greeting, "hello"
|
244
|
+
form_param :name, "Bob"
|
245
|
+
end
|
246
|
+
|
247
|
+
response do |data|
|
248
|
+
attribute :greeting, data[:echo][:greeting]
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
with_api(conflicting_params) do
|
254
|
+
get_request(path: "/conflicting_params") do |c|
|
255
|
+
c.response.must_equal "A request cannot have both json and form " \
|
256
|
+
"parameters"
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
# TODO: make this test work
|
263
|
+
# It works if the /proxy_cookie_param and /echo_greeting endpoints are run
|
264
|
+
# in an actual server instance, but not here in the test.
|
265
|
+
#
|
266
|
+
# it "sends cookie params in backend requests" do
|
267
|
+
# proxy_cookie = extend_server echo_greeting_server do
|
268
|
+
# get "/proxy_cookie_param" do
|
269
|
+
# request :echo do
|
270
|
+
# path "/echo_greeting"
|
271
|
+
# method :get
|
272
|
+
|
273
|
+
# cookie_param :greeting, "hello"
|
274
|
+
# end
|
275
|
+
|
276
|
+
# response do |data|
|
277
|
+
# attribute :greeting, data[:echo][:greeting]
|
278
|
+
# end
|
279
|
+
# end
|
280
|
+
# end
|
281
|
+
|
282
|
+
# with_api(proxy_cookie) do
|
283
|
+
# get_request(path: "/proxy_cookie_param") do |c|
|
284
|
+
# c.response.must_equal '{"greeting":"hello"}'
|
285
|
+
# end
|
286
|
+
# end
|
287
|
+
# end
|
288
|
+
|
289
|
+
it "handles frontend post requests" do
|
290
|
+
frontend_post = create_server do
|
291
|
+
post "/ping" do
|
292
|
+
response do
|
293
|
+
success { attribute :result, "pong" }
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
with_api(frontend_post) do
|
299
|
+
post_request(path: "/ping") do |c|
|
300
|
+
c.response.must_equal '{"result":"pong"}'
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
it "handles frontend put requests" do
|
306
|
+
frontend_post = create_server do
|
307
|
+
put "/ping" do
|
308
|
+
response do
|
309
|
+
success { attribute :result, "pong" }
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
with_api(frontend_post) do
|
315
|
+
put_request(path: "/ping") do |c|
|
316
|
+
c.response.must_equal '{"result":"pong"}'
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
it "handles frontend delete requests" do
|
322
|
+
frontend_post = create_server do
|
323
|
+
delete "/ping" do
|
324
|
+
response do
|
325
|
+
success { attribute :result, "pong" }
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
with_api(frontend_post) do
|
331
|
+
delete_request(path: "/ping") do |c|
|
332
|
+
c.response.must_equal '{"result":"pong"}'
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
it "passes frontend request headers through to backend requests" do
|
338
|
+
echo_header = create_server do
|
339
|
+
get "/proxy" do
|
340
|
+
request :echo do
|
341
|
+
path "/echo"
|
342
|
+
method :get
|
343
|
+
end
|
344
|
+
|
345
|
+
response do |data|
|
346
|
+
success { attribute :result, data[:echo][:header] }
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
get "/echo" do |_, headers|
|
351
|
+
response do
|
352
|
+
success { attribute :header, headers["Bob-Content"] }
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
with_api(echo_header) do
|
358
|
+
get_request(
|
359
|
+
path: "/proxy",
|
360
|
+
head: { "Bob-Content" => "bob/classic" }
|
361
|
+
) do |c|
|
362
|
+
c.response.must_equal '{"result":"bob/classic"}'
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
it "can set the entire body of the reponse" do
|
368
|
+
server = create_server do
|
369
|
+
get "/endpoint" do
|
370
|
+
response do
|
371
|
+
success { body "free form text!" }
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
with_api(server) do
|
377
|
+
get_request(path: "/endpoint") do |c|
|
378
|
+
c.response.must_equal "free form text!"
|
379
|
+
end
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
it "can respond with objects" do
|
384
|
+
class Bob
|
385
|
+
def initialize(last_name)
|
386
|
+
@last_name = last_name
|
387
|
+
end
|
388
|
+
|
389
|
+
def to_hash
|
390
|
+
{ first_name: "Bob", last_name: @last_name }
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
object_response = create_server do
|
395
|
+
get "/object" do
|
396
|
+
response do
|
397
|
+
success { object :bob, Bob, "Saget" }
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
with_api(object_response) do
|
403
|
+
get_request(path: "/object") do |c|
|
404
|
+
c.response.must_equal '{"bob":{"first_name":"Bob","last_name":"Saget"}}'
|
405
|
+
end
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
it "can respond with arrays" do
|
410
|
+
# Example serialization class
|
411
|
+
class Bob
|
412
|
+
def initialize(last_name)
|
413
|
+
@last_name = last_name
|
414
|
+
end
|
415
|
+
|
416
|
+
def to_hash
|
417
|
+
{ first_name: "Bob", last_name: @last_name }
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
object_response = create_server do
|
422
|
+
get "/object" do
|
423
|
+
response do
|
424
|
+
success { array :bobs, Bob, %w(Ross Marley) }
|
425
|
+
end
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
with_api(object_response) do
|
430
|
+
get_request(path: "/object") do |c|
|
431
|
+
c.response.must_equal '{"bobs":[' \
|
432
|
+
'{"first_name":"Bob","last_name":"Ross"},' \
|
433
|
+
'{"first_name":"Bob","last_name":"Marley"}' \
|
434
|
+
"]}"
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
it "can respond with cookies" do
|
440
|
+
server = create_server do
|
441
|
+
get "/cookie" do
|
442
|
+
response do
|
443
|
+
success { cookie "cookie-monster", "mmm... cookie" }
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
with_api(server) do
|
449
|
+
get_request(path: "/cookie") do |c|
|
450
|
+
expected = "cookie-monster=mmm... cookie"
|
451
|
+
c.response_header["Set-Cookie"].must_equal expected
|
452
|
+
end
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
it "can respond with a specified content type" do
|
457
|
+
server = create_server do
|
458
|
+
get "/endpoint" do
|
459
|
+
response do
|
460
|
+
success { content_type "image/jpeg" }
|
461
|
+
end
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
with_api(server) do
|
466
|
+
get_request(path: "/endpoint") do |c|
|
467
|
+
c.response_header["CONTENT_TYPE"].must_equal "image/jpeg"
|
468
|
+
end
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
it "makes the results of requests available to subsequent requests" do
|
473
|
+
multiple_requests = create_server do
|
474
|
+
get "/multi" do
|
475
|
+
request :one do
|
476
|
+
path "/one"
|
477
|
+
method :get
|
478
|
+
end
|
479
|
+
|
480
|
+
request :two do |data|
|
481
|
+
path "/two"
|
482
|
+
method :get
|
483
|
+
|
484
|
+
query_param :name, data[:one][:name]
|
485
|
+
end
|
486
|
+
|
487
|
+
response do |data|
|
488
|
+
success do
|
489
|
+
attribute :name, data[:two][:result]
|
490
|
+
cookie "type", data[:two].cookies[:type]
|
491
|
+
end
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
get "/one" do
|
496
|
+
response do
|
497
|
+
success { attribute :name, "Bob" }
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
get "/two" do |params|
|
502
|
+
response do
|
503
|
+
success do
|
504
|
+
attribute :result, params[:name]
|
505
|
+
cookie "type", "delicious"
|
506
|
+
end
|
507
|
+
end
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
with_api(multiple_requests) do
|
512
|
+
get_request(path: "/multi") do |c|
|
513
|
+
c.response.must_equal '{"name":"Bob"}'
|
514
|
+
c.response_header["Set-Cookie"].must_equal "type=delicious"
|
515
|
+
end
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
it "allows conditional requests" do
|
520
|
+
server = create_server do
|
521
|
+
get "/conditional" do
|
522
|
+
request :nonexistent, when: false do
|
523
|
+
path "/nonexistent"
|
524
|
+
method :get
|
525
|
+
end
|
526
|
+
|
527
|
+
response do
|
528
|
+
success { attribute :result, "OK" }
|
529
|
+
end
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
with_api(server) do
|
534
|
+
get_request(path: "/conditional") do |c|
|
535
|
+
c.response.must_equal '{"result":"OK"}'
|
536
|
+
end
|
537
|
+
end
|
538
|
+
end
|
539
|
+
|
540
|
+
it "streams downloads" do
|
541
|
+
server = create_server do
|
542
|
+
get "/one" do
|
543
|
+
stream true
|
544
|
+
|
545
|
+
request :two do
|
546
|
+
path "/two"
|
547
|
+
method :get
|
548
|
+
end
|
549
|
+
|
550
|
+
response do |data|
|
551
|
+
success do
|
552
|
+
stream do
|
553
|
+
data[:two].stream do |chunk|
|
554
|
+
stream_write chunk
|
555
|
+
end
|
556
|
+
end
|
557
|
+
end
|
558
|
+
end
|
559
|
+
end
|
560
|
+
|
561
|
+
get "/two" do
|
562
|
+
stream true
|
563
|
+
|
564
|
+
response do
|
565
|
+
success do
|
566
|
+
stream do
|
567
|
+
(1..9).each { |n| stream_write n }
|
568
|
+
end
|
569
|
+
end
|
570
|
+
end
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
with_api(server) do
|
575
|
+
get_request(path: "/one") do |c|
|
576
|
+
c.response.must_equal "123456789"
|
577
|
+
end
|
578
|
+
end
|
579
|
+
end
|
580
|
+
|
581
|
+
it "supports failure handlers in the response declaration" do
|
582
|
+
server = create_server do
|
583
|
+
get "/fail" do
|
584
|
+
response do
|
585
|
+
failure true do
|
586
|
+
status 422
|
587
|
+
attribute :result, "fail"
|
588
|
+
end
|
589
|
+
end
|
590
|
+
end
|
591
|
+
end
|
592
|
+
|
593
|
+
with_api(server) do
|
594
|
+
get_request(path: "/fail") do |c|
|
595
|
+
c.response.must_equal '{"result":"fail"}'
|
596
|
+
end
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
it "responds with the first matching failure handler" do
|
601
|
+
server = create_server do
|
602
|
+
get "/doublefail" do
|
603
|
+
response do
|
604
|
+
failure true do
|
605
|
+
attribute :fail, "one"
|
606
|
+
end
|
607
|
+
|
608
|
+
failure true do
|
609
|
+
attribute :fail, "two"
|
610
|
+
end
|
611
|
+
end
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
with_api(server) do
|
616
|
+
get_request(path: "/doublefail") do |c|
|
617
|
+
c.response.must_equal '{"fail":"one"}'
|
618
|
+
end
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
622
|
+
it "checks unhandled failures" do
|
623
|
+
server = create_server do
|
624
|
+
unhandled_failures do |data|
|
625
|
+
failure data.status == 400 do
|
626
|
+
status 422
|
627
|
+
attribute :fail, "yep"
|
628
|
+
end
|
629
|
+
end
|
630
|
+
|
631
|
+
get "/unhandled" do
|
632
|
+
request :fail do
|
633
|
+
path "/fail"
|
634
|
+
method :get
|
635
|
+
end
|
636
|
+
|
637
|
+
response do
|
638
|
+
success { attribute :result, "win" }
|
639
|
+
end
|
640
|
+
end
|
641
|
+
|
642
|
+
get "/fail" do
|
643
|
+
response do
|
644
|
+
success do
|
645
|
+
status 400
|
646
|
+
end
|
647
|
+
end
|
648
|
+
end
|
649
|
+
end
|
650
|
+
|
651
|
+
with_api(server) do
|
652
|
+
get_request(path: "/unhandled") do |c|
|
653
|
+
c.response.must_equal '{"fail":"yep"}'
|
654
|
+
end
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
658
|
+
it "passes through completely unhandled failures" do
|
659
|
+
server = create_server do
|
660
|
+
get "/completely_unhandled" do
|
661
|
+
request :fail do
|
662
|
+
path "/fail"
|
663
|
+
method :get
|
664
|
+
end
|
665
|
+
|
666
|
+
response do
|
667
|
+
success { attribute :result, "win" }
|
668
|
+
end
|
669
|
+
end
|
670
|
+
|
671
|
+
get "/fail" do
|
672
|
+
response do
|
673
|
+
success do
|
674
|
+
status 400
|
675
|
+
attribute :oh, "no"
|
676
|
+
end
|
677
|
+
end
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
681
|
+
with_api(server) do
|
682
|
+
get_request(path: "/completely_unhandled") do |c|
|
683
|
+
c.response.must_equal '{"oh":"no"}'
|
684
|
+
end
|
685
|
+
end
|
686
|
+
end
|
687
|
+
|
688
|
+
it "does not crash when there are no routes for an HTTP verb" do
|
689
|
+
server = create_server do
|
690
|
+
get "/ping" do
|
691
|
+
response do
|
692
|
+
success { attribute :result, "pong" }
|
693
|
+
end
|
694
|
+
end
|
695
|
+
end
|
696
|
+
|
697
|
+
with_api(server) do
|
698
|
+
post_request(path: "/whatever") do |c|
|
699
|
+
c.response.must_equal "nope"
|
700
|
+
end
|
701
|
+
end
|
702
|
+
end
|
703
|
+
|
704
|
+
it "allows a shorthand for setting success response status" do
|
705
|
+
server = create_server do
|
706
|
+
get "/no_body" do
|
707
|
+
response do
|
708
|
+
success 204
|
709
|
+
end
|
710
|
+
end
|
711
|
+
end
|
712
|
+
|
713
|
+
with_api(server) do
|
714
|
+
get_request(path: "/no_body") do |c|
|
715
|
+
c.response_header.http_status.must_equal 204
|
716
|
+
c.response.must_equal ""
|
717
|
+
end
|
718
|
+
end
|
719
|
+
end
|
720
|
+
|
721
|
+
it "provides a way to add helper methods" do
|
722
|
+
server = create_server do
|
723
|
+
helpers do
|
724
|
+
def victory_attribute
|
725
|
+
attribute :result, "VICTORY"
|
726
|
+
end
|
727
|
+
|
728
|
+
def victory!
|
729
|
+
response do
|
730
|
+
success { victory_attribute }
|
731
|
+
end
|
732
|
+
end
|
733
|
+
end
|
734
|
+
|
735
|
+
get "/status" do
|
736
|
+
victory!
|
737
|
+
end
|
738
|
+
end
|
739
|
+
|
740
|
+
with_api(server) do
|
741
|
+
get_request(path: "/status") do |c|
|
742
|
+
c.response.must_equal '{"result":"VICTORY"}'
|
743
|
+
end
|
744
|
+
end
|
745
|
+
end
|
746
|
+
end
|