grape 1.3.3 → 1.6.2
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 +4 -4
- data/CHANGELOG.md +111 -2
- data/CONTRIBUTING.md +2 -1
- data/README.md +135 -23
- data/UPGRADING.md +237 -46
- data/grape.gemspec +5 -5
- data/lib/grape/api/instance.rb +34 -42
- data/lib/grape/api.rb +21 -16
- data/lib/grape/cookies.rb +2 -0
- data/lib/grape/dsl/callbacks.rb +1 -1
- data/lib/grape/dsl/desc.rb +3 -5
- data/lib/grape/dsl/headers.rb +5 -2
- data/lib/grape/dsl/helpers.rb +8 -5
- data/lib/grape/dsl/inside_route.rb +72 -53
- data/lib/grape/dsl/middleware.rb +4 -4
- data/lib/grape/dsl/parameters.rb +11 -7
- data/lib/grape/dsl/request_response.rb +9 -6
- data/lib/grape/dsl/routing.rb +8 -9
- data/lib/grape/dsl/settings.rb +5 -5
- data/lib/grape/dsl/validations.rb +18 -1
- data/lib/grape/eager_load.rb +1 -1
- data/lib/grape/endpoint.rb +29 -42
- data/lib/grape/error_formatter/json.rb +2 -6
- data/lib/grape/error_formatter/xml.rb +2 -6
- data/lib/grape/exceptions/empty_message_body.rb +11 -0
- data/lib/grape/exceptions/validation.rb +2 -3
- data/lib/grape/exceptions/validation_errors.rb +1 -1
- data/lib/grape/formatter/json.rb +1 -0
- data/lib/grape/formatter/serializable_hash.rb +2 -1
- data/lib/grape/formatter/xml.rb +1 -0
- data/lib/grape/locale/en.yml +1 -1
- data/lib/grape/middleware/auth/base.rb +3 -3
- data/lib/grape/middleware/auth/dsl.rb +7 -1
- data/lib/grape/middleware/base.rb +6 -3
- data/lib/grape/middleware/error.rb +11 -13
- data/lib/grape/middleware/formatter.rb +7 -7
- data/lib/grape/middleware/stack.rb +10 -3
- data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
- data/lib/grape/middleware/versioner/header.rb +6 -4
- data/lib/grape/middleware/versioner/param.rb +1 -0
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
- data/lib/grape/middleware/versioner/path.rb +2 -0
- data/lib/grape/parser/json.rb +1 -1
- data/lib/grape/parser/xml.rb +1 -1
- data/lib/grape/path.rb +1 -0
- data/lib/grape/request.rb +4 -1
- data/lib/grape/router/attribute_translator.rb +3 -3
- data/lib/grape/router/pattern.rb +1 -1
- data/lib/grape/router/route.rb +2 -2
- data/lib/grape/router.rb +31 -30
- data/lib/grape/{serve_file → serve_stream}/file_body.rb +1 -1
- data/lib/grape/{serve_file → serve_stream}/sendfile_response.rb +1 -1
- data/lib/grape/{serve_file/file_response.rb → serve_stream/stream_response.rb} +8 -8
- data/lib/grape/util/base_inheritable.rb +2 -2
- data/lib/grape/util/inheritable_setting.rb +1 -3
- data/lib/grape/util/lazy_value.rb +4 -2
- data/lib/grape/util/strict_hash_configuration.rb +1 -1
- data/lib/grape/validations/attributes_iterator.rb +8 -0
- data/lib/grape/validations/multiple_attributes_iterator.rb +1 -1
- data/lib/grape/validations/params_scope.rb +97 -62
- data/lib/grape/validations/single_attribute_iterator.rb +1 -1
- data/lib/grape/validations/types/custom_type_coercer.rb +16 -3
- data/lib/grape/validations/types/dry_type_coercer.rb +1 -1
- data/lib/grape/validations/types/invalid_value.rb +24 -0
- data/lib/grape/validations/types/json.rb +2 -1
- data/lib/grape/validations/types/primitive_coercer.rb +4 -5
- data/lib/grape/validations/types.rb +1 -4
- data/lib/grape/validations/validator_factory.rb +1 -1
- data/lib/grape/validations/validators/all_or_none.rb +8 -5
- data/lib/grape/validations/validators/allow_blank.rb +9 -7
- data/lib/grape/validations/validators/as.rb +6 -8
- data/lib/grape/validations/validators/at_least_one_of.rb +7 -4
- data/lib/grape/validations/validators/base.rb +74 -69
- data/lib/grape/validations/validators/coerce.rb +63 -76
- data/lib/grape/validations/validators/default.rb +36 -34
- data/lib/grape/validations/validators/exactly_one_of.rb +9 -6
- data/lib/grape/validations/validators/except_values.rb +13 -11
- data/lib/grape/validations/validators/multiple_params_base.rb +24 -19
- data/lib/grape/validations/validators/mutual_exclusion.rb +8 -5
- data/lib/grape/validations/validators/presence.rb +7 -4
- data/lib/grape/validations/validators/regexp.rb +8 -5
- data/lib/grape/validations/validators/same_as.rb +18 -15
- data/lib/grape/validations/validators/values.rb +61 -56
- data/lib/grape/validations.rb +6 -0
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +7 -3
- data/spec/grape/api/custom_validations_spec.rb +77 -45
- data/spec/grape/api/deeply_included_options_spec.rb +3 -3
- data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -1
- data/spec/grape/api/invalid_format_spec.rb +2 -0
- data/spec/grape/api/recognize_path_spec.rb +1 -1
- data/spec/grape/api/routes_with_requirements_spec.rb +8 -8
- data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -15
- data/spec/grape/api_remount_spec.rb +25 -19
- data/spec/grape/api_spec.rb +576 -211
- data/spec/grape/dsl/callbacks_spec.rb +2 -1
- data/spec/grape/dsl/headers_spec.rb +39 -9
- data/spec/grape/dsl/helpers_spec.rb +3 -2
- data/spec/grape/dsl/inside_route_spec.rb +185 -34
- data/spec/grape/dsl/logger_spec.rb +16 -18
- data/spec/grape/dsl/middleware_spec.rb +2 -1
- data/spec/grape/dsl/parameters_spec.rb +2 -0
- data/spec/grape/dsl/request_response_spec.rb +1 -0
- data/spec/grape/dsl/routing_spec.rb +10 -7
- data/spec/grape/endpoint/declared_spec.rb +848 -0
- data/spec/grape/endpoint_spec.rb +77 -589
- data/spec/grape/entity_spec.rb +29 -23
- data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -0
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +61 -22
- data/spec/grape/exceptions/validation_errors_spec.rb +13 -10
- data/spec/grape/exceptions/validation_spec.rb +5 -3
- data/spec/grape/extensions/param_builders/hash_spec.rb +7 -7
- data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -8
- data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -8
- data/spec/grape/integration/rack_sendfile_spec.rb +13 -9
- data/spec/grape/loading_spec.rb +8 -8
- data/spec/grape/middleware/auth/dsl_spec.rb +15 -6
- data/spec/grape/middleware/auth/strategies_spec.rb +61 -21
- data/spec/grape/middleware/base_spec.rb +24 -15
- data/spec/grape/middleware/error_spec.rb +3 -3
- data/spec/grape/middleware/exception_spec.rb +111 -161
- data/spec/grape/middleware/formatter_spec.rb +28 -7
- data/spec/grape/middleware/globals_spec.rb +7 -4
- data/spec/grape/middleware/stack_spec.rb +15 -12
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -1
- data/spec/grape/middleware/versioner/header_spec.rb +14 -13
- data/spec/grape/middleware/versioner/param_spec.rb +7 -1
- data/spec/grape/middleware/versioner/path_spec.rb +5 -1
- data/spec/grape/middleware/versioner_spec.rb +1 -1
- data/spec/grape/parser_spec.rb +4 -0
- data/spec/grape/path_spec.rb +52 -52
- data/spec/grape/presenters/presenter_spec.rb +7 -6
- data/spec/grape/request_spec.rb +6 -4
- data/spec/grape/util/inheritable_setting_spec.rb +7 -7
- data/spec/grape/util/inheritable_values_spec.rb +3 -2
- data/spec/grape/util/reverse_stackable_values_spec.rb +3 -1
- data/spec/grape/util/stackable_values_spec.rb +7 -5
- data/spec/grape/validations/instance_behaivour_spec.rb +9 -10
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +14 -3
- data/spec/grape/validations/params_scope_spec.rb +72 -10
- data/spec/grape/validations/single_attribute_iterator_spec.rb +18 -6
- data/spec/grape/validations/types/primitive_coercer_spec.rb +63 -7
- data/spec/grape/validations/types_spec.rb +8 -8
- data/spec/grape/validations/validators/all_or_none_spec.rb +50 -56
- data/spec/grape/validations/validators/allow_blank_spec.rb +136 -140
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -56
- data/spec/grape/validations/validators/coerce_spec.rb +248 -33
- data/spec/grape/validations/validators/default_spec.rb +121 -78
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -77
- data/spec/grape/validations/validators/except_values_spec.rb +4 -3
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -77
- data/spec/grape/validations/validators/presence_spec.rb +16 -1
- data/spec/grape/validations/validators/regexp_spec.rb +25 -31
- data/spec/grape/validations/validators/same_as_spec.rb +14 -20
- data/spec/grape/validations/validators/values_spec.rb +183 -178
- data/spec/grape/validations_spec.rb +342 -29
- data/spec/integration/eager_load/eager_load_spec.rb +15 -0
- data/spec/integration/multi_json/json_spec.rb +1 -1
- data/spec/integration/multi_xml/xml_spec.rb +1 -1
- data/spec/shared/versioning_examples.rb +32 -29
- data/spec/spec_helper.rb +12 -12
- data/spec/support/basic_auth_encode_helpers.rb +1 -1
- data/spec/support/chunks.rb +14 -0
- data/spec/support/versioned_helpers.rb +4 -6
- metadata +110 -102
data/spec/grape/endpoint_spec.rb
CHANGED
@@ -10,32 +10,32 @@ describe Grape::Endpoint do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
describe '.before_each' do
|
13
|
-
after {
|
13
|
+
after { described_class.before_each.clear }
|
14
14
|
|
15
15
|
it 'is settable via block' do
|
16
16
|
block = ->(_endpoint) { 'noop' }
|
17
|
-
|
18
|
-
expect(
|
17
|
+
described_class.before_each(&block)
|
18
|
+
expect(described_class.before_each.first).to eq(block)
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'is settable via reference' do
|
22
22
|
block = ->(_endpoint) { 'noop' }
|
23
|
-
|
24
|
-
expect(
|
23
|
+
described_class.before_each block
|
24
|
+
expect(described_class.before_each.first).to eq(block)
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'is able to override a helper' do
|
28
28
|
subject.get('/') { current_user }
|
29
29
|
expect { get '/' }.to raise_error(NameError)
|
30
30
|
|
31
|
-
|
31
|
+
described_class.before_each do |endpoint|
|
32
32
|
allow(endpoint).to receive(:current_user).and_return('Bob')
|
33
33
|
end
|
34
34
|
|
35
35
|
get '/'
|
36
36
|
expect(last_response.body).to eq('Bob')
|
37
37
|
|
38
|
-
|
38
|
+
described_class.before_each(nil)
|
39
39
|
expect { get '/' }.to raise_error(NameError)
|
40
40
|
end
|
41
41
|
|
@@ -46,18 +46,18 @@ describe Grape::Endpoint do
|
|
46
46
|
end
|
47
47
|
expect { get '/' }.to raise_error(NameError)
|
48
48
|
|
49
|
-
|
49
|
+
described_class.before_each do |endpoint|
|
50
50
|
allow(endpoint).to receive(:current_user).and_return('Bob')
|
51
51
|
end
|
52
52
|
|
53
|
-
|
53
|
+
described_class.before_each do |endpoint|
|
54
54
|
allow(endpoint).to receive(:authenticate_user!).and_return(true)
|
55
55
|
end
|
56
56
|
|
57
57
|
get '/'
|
58
58
|
expect(last_response.body).to eq('Bob')
|
59
59
|
|
60
|
-
|
60
|
+
described_class.before_each(nil)
|
61
61
|
expect { get '/' }.to raise_error(NameError)
|
62
62
|
end
|
63
63
|
end
|
@@ -66,7 +66,7 @@ describe Grape::Endpoint do
|
|
66
66
|
it 'takes a settings stack, options, and a block' do
|
67
67
|
p = proc {}
|
68
68
|
expect do
|
69
|
-
|
69
|
+
described_class.new(Grape::Util::InheritableSetting.new, {
|
70
70
|
path: '/',
|
71
71
|
method: :get
|
72
72
|
}, &p)
|
@@ -77,7 +77,7 @@ describe Grape::Endpoint do
|
|
77
77
|
it 'sets itself in the env upon call' do
|
78
78
|
subject.get('/') { 'Hello world.' }
|
79
79
|
get '/'
|
80
|
-
expect(last_request.env['api.endpoint']).to be_kind_of(
|
80
|
+
expect(last_request.env['api.endpoint']).to be_kind_of(described_class)
|
81
81
|
end
|
82
82
|
|
83
83
|
describe '#status' do
|
@@ -137,6 +137,7 @@ describe Grape::Endpoint do
|
|
137
137
|
headers.to_json
|
138
138
|
end
|
139
139
|
end
|
140
|
+
|
140
141
|
it 'includes request headers' do
|
141
142
|
get '/headers'
|
142
143
|
expect(JSON.parse(last_response.body)).to eq(
|
@@ -144,13 +145,15 @@ describe Grape::Endpoint do
|
|
144
145
|
'Cookie' => ''
|
145
146
|
)
|
146
147
|
end
|
148
|
+
|
147
149
|
it 'includes additional request headers' do
|
148
150
|
get '/headers', nil, 'HTTP_X_GRAPE_CLIENT' => '1'
|
149
151
|
expect(JSON.parse(last_response.body)['X-Grape-Client']).to eq('1')
|
150
152
|
end
|
153
|
+
|
151
154
|
it 'includes headers passed as symbols' do
|
152
155
|
env = Rack::MockRequest.env_for('/headers')
|
153
|
-
env[
|
156
|
+
env[:HTTP_SYMBOL_HEADER] = 'Goliath passes symbols'
|
154
157
|
body = read_chunks(subject.call(env)[2]).join
|
155
158
|
expect(JSON.parse(body)['Symbol-Header']).to eq('Goliath passes symbols')
|
156
159
|
end
|
@@ -212,10 +215,10 @@ describe Grape::Endpoint do
|
|
212
215
|
end
|
213
216
|
get '/test', {}, 'HTTP_COOKIE' => 'delete_this_cookie=1; and_this=2'
|
214
217
|
expect(last_response.body).to eq('3')
|
215
|
-
cookies =
|
218
|
+
cookies = last_response.headers['Set-Cookie'].split("\n").map do |set_cookie|
|
216
219
|
cookie = CookieJar::Cookie.from_set_cookie 'http://localhost/test', set_cookie
|
217
220
|
[cookie.name, cookie]
|
218
|
-
end
|
221
|
+
end.to_h
|
219
222
|
expect(cookies.size).to eq(2)
|
220
223
|
%w[and_this delete_this_cookie].each do |cookie_name|
|
221
224
|
cookie = cookies[cookie_name]
|
@@ -236,10 +239,10 @@ describe Grape::Endpoint do
|
|
236
239
|
end
|
237
240
|
get('/test', {}, 'HTTP_COOKIE' => 'delete_this_cookie=1; and_this=2')
|
238
241
|
expect(last_response.body).to eq('3')
|
239
|
-
cookies =
|
242
|
+
cookies = last_response.headers['Set-Cookie'].split("\n").map do |set_cookie|
|
240
243
|
cookie = CookieJar::Cookie.from_set_cookie 'http://localhost/test', set_cookie
|
241
244
|
[cookie.name, cookie]
|
242
|
-
end
|
245
|
+
end.to_h
|
243
246
|
expect(cookies.size).to eq(2)
|
244
247
|
%w[and_this delete_this_cookie].each do |cookie_name|
|
245
248
|
cookie = cookies[cookie_name]
|
@@ -253,7 +256,7 @@ describe Grape::Endpoint do
|
|
253
256
|
|
254
257
|
describe '#params' do
|
255
258
|
context 'default class' do
|
256
|
-
it '
|
259
|
+
it 'is a ActiveSupport::HashWithIndifferentAccess' do
|
257
260
|
subject.get '/foo' do
|
258
261
|
params.class
|
259
262
|
end
|
@@ -280,540 +283,6 @@ describe Grape::Endpoint do
|
|
280
283
|
end
|
281
284
|
end
|
282
285
|
|
283
|
-
describe '#declared' do
|
284
|
-
before do
|
285
|
-
subject.format :json
|
286
|
-
subject.params do
|
287
|
-
requires :first
|
288
|
-
optional :second
|
289
|
-
optional :third, default: 'third-default'
|
290
|
-
optional :nested, type: Hash do
|
291
|
-
optional :fourth
|
292
|
-
optional :fifth
|
293
|
-
optional :nested_two, type: Hash do
|
294
|
-
optional :sixth
|
295
|
-
optional :nested_three, type: Hash do
|
296
|
-
optional :seventh
|
297
|
-
end
|
298
|
-
end
|
299
|
-
optional :nested_arr, type: Array do
|
300
|
-
optional :eighth
|
301
|
-
end
|
302
|
-
end
|
303
|
-
optional :arr, type: Array do
|
304
|
-
optional :nineth
|
305
|
-
end
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
context 'when params are not built with default class' do
|
310
|
-
it 'returns an object that corresponds with the params class - hash with indifferent access' do
|
311
|
-
subject.params do
|
312
|
-
build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
|
313
|
-
end
|
314
|
-
subject.get '/declared' do
|
315
|
-
d = declared(params, include_missing: true)
|
316
|
-
{ declared_class: d.class.to_s }
|
317
|
-
end
|
318
|
-
|
319
|
-
get '/declared?first=present'
|
320
|
-
expect(JSON.parse(last_response.body)['declared_class']).to eq('ActiveSupport::HashWithIndifferentAccess')
|
321
|
-
end
|
322
|
-
|
323
|
-
it 'returns an object that corresponds with the params class - hashie mash' do
|
324
|
-
subject.params do
|
325
|
-
build_with Grape::Extensions::Hashie::Mash::ParamBuilder
|
326
|
-
end
|
327
|
-
subject.get '/declared' do
|
328
|
-
d = declared(params, include_missing: true)
|
329
|
-
{ declared_class: d.class.to_s }
|
330
|
-
end
|
331
|
-
|
332
|
-
get '/declared?first=present'
|
333
|
-
expect(JSON.parse(last_response.body)['declared_class']).to eq('Hashie::Mash')
|
334
|
-
end
|
335
|
-
|
336
|
-
it 'returns an object that corresponds with the params class - hash' do
|
337
|
-
subject.params do
|
338
|
-
build_with Grape::Extensions::Hash::ParamBuilder
|
339
|
-
end
|
340
|
-
subject.get '/declared' do
|
341
|
-
d = declared(params, include_missing: true)
|
342
|
-
{ declared_class: d.class.to_s }
|
343
|
-
end
|
344
|
-
|
345
|
-
get '/declared?first=present'
|
346
|
-
expect(JSON.parse(last_response.body)['declared_class']).to eq('Hash')
|
347
|
-
end
|
348
|
-
end
|
349
|
-
|
350
|
-
it 'should show nil for nested params if include_missing is true' do
|
351
|
-
subject.get '/declared' do
|
352
|
-
declared(params, include_missing: true)
|
353
|
-
end
|
354
|
-
|
355
|
-
get '/declared?first=present'
|
356
|
-
expect(last_response.status).to eq(200)
|
357
|
-
expect(JSON.parse(last_response.body)['nested']['fourth']).to be_nil
|
358
|
-
end
|
359
|
-
|
360
|
-
it 'does not work in a before filter' do
|
361
|
-
subject.before do
|
362
|
-
declared(params)
|
363
|
-
end
|
364
|
-
subject.get('/declared') { declared(params) }
|
365
|
-
|
366
|
-
expect { get('/declared') }.to raise_error(
|
367
|
-
Grape::DSL::InsideRoute::MethodNotYetAvailable
|
368
|
-
)
|
369
|
-
end
|
370
|
-
|
371
|
-
it 'has as many keys as there are declared params' do
|
372
|
-
subject.get '/declared' do
|
373
|
-
declared(params)
|
374
|
-
end
|
375
|
-
get '/declared?first=present'
|
376
|
-
expect(last_response.status).to eq(200)
|
377
|
-
expect(JSON.parse(last_response.body).keys.size).to eq(5)
|
378
|
-
end
|
379
|
-
|
380
|
-
it 'has a optional param with default value all the time' do
|
381
|
-
subject.get '/declared' do
|
382
|
-
declared(params)
|
383
|
-
end
|
384
|
-
get '/declared?first=one'
|
385
|
-
expect(last_response.status).to eq(200)
|
386
|
-
expect(JSON.parse(last_response.body)['third']).to eql('third-default')
|
387
|
-
end
|
388
|
-
|
389
|
-
it 'builds nested params' do
|
390
|
-
subject.get '/declared' do
|
391
|
-
declared(params)
|
392
|
-
end
|
393
|
-
|
394
|
-
get '/declared?first=present&nested[fourth]=1'
|
395
|
-
expect(last_response.status).to eq(200)
|
396
|
-
expect(JSON.parse(last_response.body)['nested'].keys.size).to eq 4
|
397
|
-
end
|
398
|
-
|
399
|
-
it 'builds nested params when given array' do
|
400
|
-
subject.get '/dummy' do
|
401
|
-
end
|
402
|
-
subject.params do
|
403
|
-
requires :first
|
404
|
-
optional :second
|
405
|
-
optional :third, default: 'third-default'
|
406
|
-
optional :nested, type: Array do
|
407
|
-
optional :fourth
|
408
|
-
end
|
409
|
-
end
|
410
|
-
subject.get '/declared' do
|
411
|
-
declared(params)
|
412
|
-
end
|
413
|
-
|
414
|
-
get '/declared?first=present&nested[][fourth]=1&nested[][fourth]=2'
|
415
|
-
expect(last_response.status).to eq(200)
|
416
|
-
expect(JSON.parse(last_response.body)['nested'].size).to eq 2
|
417
|
-
end
|
418
|
-
|
419
|
-
context 'sets nested objects when the param is missing' do
|
420
|
-
it 'to be a hash when include_missing is true' do
|
421
|
-
subject.get '/declared' do
|
422
|
-
declared(params, include_missing: true)
|
423
|
-
end
|
424
|
-
|
425
|
-
get '/declared?first=present'
|
426
|
-
expect(last_response.status).to eq(200)
|
427
|
-
expect(JSON.parse(last_response.body)['nested']).to eq({})
|
428
|
-
end
|
429
|
-
|
430
|
-
it 'to be an array when include_missing is true' do
|
431
|
-
subject.get '/declared' do
|
432
|
-
declared(params, include_missing: true)
|
433
|
-
end
|
434
|
-
|
435
|
-
get '/declared?first=present'
|
436
|
-
expect(last_response.status).to eq(200)
|
437
|
-
expect(JSON.parse(last_response.body)['arr']).to be_a(Array)
|
438
|
-
end
|
439
|
-
|
440
|
-
it 'to be an array when nested and include_missing is true' do
|
441
|
-
subject.get '/declared' do
|
442
|
-
declared(params, include_missing: true)
|
443
|
-
end
|
444
|
-
|
445
|
-
get '/declared?first=present&nested[fourth]=1'
|
446
|
-
expect(last_response.status).to eq(200)
|
447
|
-
expect(JSON.parse(last_response.body)['nested']['nested_arr']).to be_a(Array)
|
448
|
-
end
|
449
|
-
|
450
|
-
it 'to be nil when include_missing is false' do
|
451
|
-
subject.get '/declared' do
|
452
|
-
declared(params, include_missing: false)
|
453
|
-
end
|
454
|
-
|
455
|
-
get '/declared?first=present'
|
456
|
-
expect(last_response.status).to eq(200)
|
457
|
-
expect(JSON.parse(last_response.body)['nested']).to be_nil
|
458
|
-
end
|
459
|
-
end
|
460
|
-
|
461
|
-
it 'filters out any additional params that are given' do
|
462
|
-
subject.get '/declared' do
|
463
|
-
declared(params)
|
464
|
-
end
|
465
|
-
get '/declared?first=one&other=two'
|
466
|
-
expect(last_response.status).to eq(200)
|
467
|
-
expect(JSON.parse(last_response.body).key?(:other)).to eq false
|
468
|
-
end
|
469
|
-
|
470
|
-
it 'stringifies if that option is passed' do
|
471
|
-
subject.get '/declared' do
|
472
|
-
declared(params, stringify: true)
|
473
|
-
end
|
474
|
-
|
475
|
-
get '/declared?first=one&other=two'
|
476
|
-
expect(last_response.status).to eq(200)
|
477
|
-
expect(JSON.parse(last_response.body)['first']).to eq 'one'
|
478
|
-
end
|
479
|
-
|
480
|
-
it 'does not include missing attributes if that option is passed' do
|
481
|
-
subject.get '/declared' do
|
482
|
-
error! 'expected nil', 400 if declared(params, include_missing: false).key?(:second)
|
483
|
-
''
|
484
|
-
end
|
485
|
-
|
486
|
-
get '/declared?first=one&other=two'
|
487
|
-
expect(last_response.status).to eq(200)
|
488
|
-
end
|
489
|
-
|
490
|
-
it 'does not include renamed missing attributes if that option is passed' do
|
491
|
-
subject.params do
|
492
|
-
optional :renamed_original, as: :renamed
|
493
|
-
end
|
494
|
-
subject.get '/declared' do
|
495
|
-
error! 'expected nil', 400 if declared(params, include_missing: false).key?(:renamed)
|
496
|
-
''
|
497
|
-
end
|
498
|
-
|
499
|
-
get '/declared?first=one&other=two'
|
500
|
-
expect(last_response.status).to eq(200)
|
501
|
-
end
|
502
|
-
|
503
|
-
it 'includes attributes with value that evaluates to false' do
|
504
|
-
subject.params do
|
505
|
-
requires :first
|
506
|
-
optional :boolean
|
507
|
-
end
|
508
|
-
|
509
|
-
subject.post '/declared' do
|
510
|
-
error!('expected false', 400) if declared(params, include_missing: false)[:boolean] != false
|
511
|
-
''
|
512
|
-
end
|
513
|
-
|
514
|
-
post '/declared', ::Grape::Json.dump(first: 'one', boolean: false), 'CONTENT_TYPE' => 'application/json'
|
515
|
-
expect(last_response.status).to eq(201)
|
516
|
-
end
|
517
|
-
|
518
|
-
it 'includes attributes with value that evaluates to nil' do
|
519
|
-
subject.params do
|
520
|
-
requires :first
|
521
|
-
optional :second
|
522
|
-
end
|
523
|
-
|
524
|
-
subject.post '/declared' do
|
525
|
-
error!('expected nil', 400) unless declared(params, include_missing: false)[:second].nil?
|
526
|
-
''
|
527
|
-
end
|
528
|
-
|
529
|
-
post '/declared', ::Grape::Json.dump(first: 'one', second: nil), 'CONTENT_TYPE' => 'application/json'
|
530
|
-
expect(last_response.status).to eq(201)
|
531
|
-
end
|
532
|
-
|
533
|
-
it 'includes missing attributes with defaults when there are nested hashes' do
|
534
|
-
subject.get '/dummy' do
|
535
|
-
end
|
536
|
-
|
537
|
-
subject.params do
|
538
|
-
requires :first
|
539
|
-
optional :second
|
540
|
-
optional :third, default: nil
|
541
|
-
optional :nested, type: Hash do
|
542
|
-
optional :fourth, default: nil
|
543
|
-
optional :fifth, default: nil
|
544
|
-
requires :nested_nested, type: Hash do
|
545
|
-
optional :sixth, default: 'sixth-default'
|
546
|
-
optional :seven, default: nil
|
547
|
-
end
|
548
|
-
end
|
549
|
-
end
|
550
|
-
|
551
|
-
subject.get '/declared' do
|
552
|
-
declared(params, include_missing: false)
|
553
|
-
end
|
554
|
-
|
555
|
-
get '/declared?first=present&nested[fourth]=&nested[nested_nested][sixth]=sixth'
|
556
|
-
json = JSON.parse(last_response.body)
|
557
|
-
expect(last_response.status).to eq(200)
|
558
|
-
expect(json['first']).to eq 'present'
|
559
|
-
expect(json['nested'].keys).to eq %w[fourth fifth nested_nested]
|
560
|
-
expect(json['nested']['fourth']).to eq ''
|
561
|
-
expect(json['nested']['nested_nested'].keys).to eq %w[sixth seven]
|
562
|
-
expect(json['nested']['nested_nested']['sixth']).to eq 'sixth'
|
563
|
-
end
|
564
|
-
|
565
|
-
it 'does not include missing attributes when there are nested hashes' do
|
566
|
-
subject.get '/dummy' do
|
567
|
-
end
|
568
|
-
|
569
|
-
subject.params do
|
570
|
-
requires :first
|
571
|
-
optional :second
|
572
|
-
optional :third
|
573
|
-
optional :nested, type: Hash do
|
574
|
-
optional :fourth
|
575
|
-
optional :fifth
|
576
|
-
end
|
577
|
-
end
|
578
|
-
|
579
|
-
subject.get '/declared' do
|
580
|
-
declared(params, include_missing: false)
|
581
|
-
end
|
582
|
-
|
583
|
-
get '/declared?first=present&nested[fourth]=4'
|
584
|
-
json = JSON.parse(last_response.body)
|
585
|
-
expect(last_response.status).to eq(200)
|
586
|
-
expect(json['first']).to eq 'present'
|
587
|
-
expect(json['nested'].keys).to eq %w[fourth]
|
588
|
-
expect(json['nested']['fourth']).to eq '4'
|
589
|
-
end
|
590
|
-
end
|
591
|
-
|
592
|
-
describe '#declared; call from child namespace' do
|
593
|
-
before do
|
594
|
-
subject.format :json
|
595
|
-
subject.namespace :parent do
|
596
|
-
params do
|
597
|
-
requires :parent_name, type: String
|
598
|
-
end
|
599
|
-
|
600
|
-
namespace ':parent_name' do
|
601
|
-
params do
|
602
|
-
requires :child_name, type: String
|
603
|
-
requires :child_age, type: Integer
|
604
|
-
end
|
605
|
-
|
606
|
-
namespace ':child_name' do
|
607
|
-
params do
|
608
|
-
requires :grandchild_name, type: String
|
609
|
-
end
|
610
|
-
|
611
|
-
get ':grandchild_name' do
|
612
|
-
{
|
613
|
-
'params' => params,
|
614
|
-
'without_parent_namespaces' => declared(params, include_parent_namespaces: false),
|
615
|
-
'with_parent_namespaces' => declared(params, include_parent_namespaces: true)
|
616
|
-
}
|
617
|
-
end
|
618
|
-
end
|
619
|
-
end
|
620
|
-
end
|
621
|
-
|
622
|
-
get '/parent/foo/bar/baz', child_age: 5, extra: 'hello'
|
623
|
-
end
|
624
|
-
|
625
|
-
let(:parsed_response) { JSON.parse(last_response.body, symbolize_names: true) }
|
626
|
-
|
627
|
-
it { expect(last_response.status).to eq 200 }
|
628
|
-
|
629
|
-
context 'with include_parent_namespaces: false' do
|
630
|
-
it 'returns declared parameters only from current namespace' do
|
631
|
-
expect(parsed_response[:without_parent_namespaces]).to eq(
|
632
|
-
grandchild_name: 'baz'
|
633
|
-
)
|
634
|
-
end
|
635
|
-
end
|
636
|
-
|
637
|
-
context 'with include_parent_namespaces: true' do
|
638
|
-
it 'returns declared parameters from every parent namespace' do
|
639
|
-
expect(parsed_response[:with_parent_namespaces]).to eq(
|
640
|
-
parent_name: 'foo',
|
641
|
-
child_name: 'bar',
|
642
|
-
grandchild_name: 'baz',
|
643
|
-
child_age: 5
|
644
|
-
)
|
645
|
-
end
|
646
|
-
end
|
647
|
-
|
648
|
-
context 'without declaration' do
|
649
|
-
it 'returns all requested parameters' do
|
650
|
-
expect(parsed_response[:params]).to eq(
|
651
|
-
parent_name: 'foo',
|
652
|
-
child_name: 'bar',
|
653
|
-
grandchild_name: 'baz',
|
654
|
-
child_age: 5,
|
655
|
-
extra: 'hello'
|
656
|
-
)
|
657
|
-
end
|
658
|
-
end
|
659
|
-
end
|
660
|
-
|
661
|
-
describe '#declared; from a nested mounted endpoint' do
|
662
|
-
before do
|
663
|
-
doubly_mounted = Class.new(Grape::API)
|
664
|
-
doubly_mounted.namespace :more do
|
665
|
-
params do
|
666
|
-
requires :y, type: Integer
|
667
|
-
end
|
668
|
-
route_param :y do
|
669
|
-
get do
|
670
|
-
{
|
671
|
-
params: params,
|
672
|
-
declared_params: declared(params)
|
673
|
-
}
|
674
|
-
end
|
675
|
-
end
|
676
|
-
end
|
677
|
-
|
678
|
-
mounted = Class.new(Grape::API)
|
679
|
-
mounted.namespace :another do
|
680
|
-
params do
|
681
|
-
requires :mount_space, type: Integer
|
682
|
-
end
|
683
|
-
route_param :mount_space do
|
684
|
-
mount doubly_mounted
|
685
|
-
end
|
686
|
-
end
|
687
|
-
|
688
|
-
subject.format :json
|
689
|
-
subject.namespace :something do
|
690
|
-
params do
|
691
|
-
requires :id, type: Integer
|
692
|
-
end
|
693
|
-
resource ':id' do
|
694
|
-
mount mounted
|
695
|
-
end
|
696
|
-
end
|
697
|
-
end
|
698
|
-
|
699
|
-
it 'can access parent attributes' do
|
700
|
-
get '/something/123/another/456/more/789'
|
701
|
-
expect(last_response.status).to eq 200
|
702
|
-
json = JSON.parse(last_response.body, symbolize_names: true)
|
703
|
-
|
704
|
-
# test all three levels of params
|
705
|
-
expect(json[:declared_params][:y]).to eq 789
|
706
|
-
expect(json[:declared_params][:mount_space]).to eq 456
|
707
|
-
expect(json[:declared_params][:id]).to eq 123
|
708
|
-
end
|
709
|
-
end
|
710
|
-
|
711
|
-
describe '#declared; mixed nesting' do
|
712
|
-
before do
|
713
|
-
subject.format :json
|
714
|
-
subject.resource :users do
|
715
|
-
route_param :id, type: Integer, desc: 'ID desc' do
|
716
|
-
# Adding this causes route_setting(:declared_params) to be nil for the
|
717
|
-
# get block in namespace 'foo' below
|
718
|
-
get do
|
719
|
-
end
|
720
|
-
|
721
|
-
namespace 'foo' do
|
722
|
-
get do
|
723
|
-
{
|
724
|
-
params: params,
|
725
|
-
declared_params: declared(params),
|
726
|
-
declared_params_no_parent: declared(params, include_parent_namespaces: false)
|
727
|
-
}
|
728
|
-
end
|
729
|
-
end
|
730
|
-
end
|
731
|
-
end
|
732
|
-
end
|
733
|
-
|
734
|
-
it 'can access parent route_param' do
|
735
|
-
get '/users/123/foo', bar: 'bar'
|
736
|
-
expect(last_response.status).to eq 200
|
737
|
-
json = JSON.parse(last_response.body, symbolize_names: true)
|
738
|
-
|
739
|
-
expect(json[:declared_params][:id]).to eq 123
|
740
|
-
expect(json[:declared_params_no_parent][:id]).to eq nil
|
741
|
-
end
|
742
|
-
end
|
743
|
-
|
744
|
-
describe '#declared; with multiple route_param' do
|
745
|
-
before do
|
746
|
-
mounted = Class.new(Grape::API)
|
747
|
-
mounted.namespace :albums do
|
748
|
-
get do
|
749
|
-
declared(params)
|
750
|
-
end
|
751
|
-
end
|
752
|
-
|
753
|
-
subject.format :json
|
754
|
-
subject.namespace :artists do
|
755
|
-
route_param :id, type: Integer do
|
756
|
-
get do
|
757
|
-
declared(params)
|
758
|
-
end
|
759
|
-
|
760
|
-
params do
|
761
|
-
requires :filter, type: String
|
762
|
-
end
|
763
|
-
get :some_route do
|
764
|
-
declared(params)
|
765
|
-
end
|
766
|
-
end
|
767
|
-
|
768
|
-
route_param :artist_id, type: Integer do
|
769
|
-
namespace :compositions do
|
770
|
-
get do
|
771
|
-
declared(params)
|
772
|
-
end
|
773
|
-
end
|
774
|
-
end
|
775
|
-
|
776
|
-
route_param :compositor_id, type: Integer do
|
777
|
-
mount mounted
|
778
|
-
end
|
779
|
-
end
|
780
|
-
end
|
781
|
-
|
782
|
-
it 'return only :id without :artist_id' do
|
783
|
-
get '/artists/1'
|
784
|
-
json = JSON.parse(last_response.body, symbolize_names: true)
|
785
|
-
|
786
|
-
expect(json.key?(:id)).to be_truthy
|
787
|
-
expect(json.key?(:artist_id)).not_to be_truthy
|
788
|
-
end
|
789
|
-
|
790
|
-
it 'return only :artist_id without :id' do
|
791
|
-
get '/artists/1/compositions'
|
792
|
-
json = JSON.parse(last_response.body, symbolize_names: true)
|
793
|
-
|
794
|
-
expect(json.key?(:artist_id)).to be_truthy
|
795
|
-
expect(json.key?(:id)).not_to be_truthy
|
796
|
-
end
|
797
|
-
|
798
|
-
it 'return :filter and :id parameters in declared for second enpoint inside route_param' do
|
799
|
-
get '/artists/1/some_route', filter: 'some_filter'
|
800
|
-
json = JSON.parse(last_response.body, symbolize_names: true)
|
801
|
-
|
802
|
-
expect(json.key?(:filter)).to be_truthy
|
803
|
-
expect(json.key?(:id)).to be_truthy
|
804
|
-
expect(json.key?(:artist_id)).not_to be_truthy
|
805
|
-
end
|
806
|
-
|
807
|
-
it 'return :compositor_id for mounter in route_param' do
|
808
|
-
get '/artists/1/albums'
|
809
|
-
json = JSON.parse(last_response.body, symbolize_names: true)
|
810
|
-
|
811
|
-
expect(json.key?(:compositor_id)).to be_truthy
|
812
|
-
expect(json.key?(:id)).not_to be_truthy
|
813
|
-
expect(json.key?(:artist_id)).not_to be_truthy
|
814
|
-
end
|
815
|
-
end
|
816
|
-
|
817
286
|
describe '#params' do
|
818
287
|
it 'is available to the caller' do
|
819
288
|
subject.get('/hey') do
|
@@ -873,7 +342,7 @@ describe Grape::Endpoint do
|
|
873
342
|
end
|
874
343
|
|
875
344
|
context 'namespace requirements' do
|
876
|
-
before
|
345
|
+
before do
|
877
346
|
subject.namespace :outer, requirements: { person_email: /abc@(.*).com/ } do
|
878
347
|
get('/:person_email') do
|
879
348
|
params[:person_email]
|
@@ -892,7 +361,7 @@ describe Grape::Endpoint do
|
|
892
361
|
expect(last_response.body).to eq('abc@example.com')
|
893
362
|
end
|
894
363
|
|
895
|
-
it "
|
364
|
+
it "overrides outer namespace's requirements" do
|
896
365
|
get '/outer/inner/someone@testing.wrong/test/1'
|
897
366
|
expect(last_response.status).to eq(404)
|
898
367
|
|
@@ -904,7 +373,7 @@ describe Grape::Endpoint do
|
|
904
373
|
end
|
905
374
|
|
906
375
|
context 'from body parameters' do
|
907
|
-
before
|
376
|
+
before do
|
908
377
|
subject.post '/request_body' do
|
909
378
|
params[:user]
|
910
379
|
end
|
@@ -954,6 +423,19 @@ describe Grape::Endpoint do
|
|
954
423
|
expect(last_response.status).to eq(201)
|
955
424
|
expect(last_response.body).to eq('Bob')
|
956
425
|
end
|
426
|
+
|
427
|
+
# Rack swallowed this error until v2.2.0
|
428
|
+
it 'returns a 400 if given an invalid multipart body', if: Gem::Version.new(Rack.release) >= Gem::Version.new('2.2.0') do
|
429
|
+
subject.params do
|
430
|
+
requires :file, type: Rack::Multipart::UploadedFile
|
431
|
+
end
|
432
|
+
subject.post '/upload' do
|
433
|
+
params[:file][:filename]
|
434
|
+
end
|
435
|
+
post '/upload', { file: '' }, 'CONTENT_TYPE' => 'multipart/form-data; boundary=foobar'
|
436
|
+
expect(last_response.status).to eq(400)
|
437
|
+
expect(last_response.body).to eq('Empty message body supplied with multipart/form-data; boundary=foobar content-type')
|
438
|
+
end
|
957
439
|
end
|
958
440
|
|
959
441
|
it 'responds with a 415 for an unsupported content-type' do
|
@@ -990,11 +472,11 @@ describe Grape::Endpoint do
|
|
990
472
|
post '/', ::Grape::Json.dump(data: { some: 'payload' }), 'CONTENT_TYPE' => 'application/json'
|
991
473
|
end
|
992
474
|
|
993
|
-
it '
|
475
|
+
it 'does not response with 406 for same type without params' do
|
994
476
|
expect(last_response.status).not_to be 406
|
995
477
|
end
|
996
478
|
|
997
|
-
it '
|
479
|
+
it 'responses with given content type in headers' do
|
998
480
|
expect(last_response.headers['Content-Type']).to eq 'application/json; charset=utf-8'
|
999
481
|
end
|
1000
482
|
end
|
@@ -1230,16 +712,18 @@ describe Grape::Endpoint do
|
|
1230
712
|
describe '.generate_api_method' do
|
1231
713
|
it 'raises NameError if the method name is already in use' do
|
1232
714
|
expect do
|
1233
|
-
|
715
|
+
described_class.generate_api_method('version', &proc {})
|
1234
716
|
end.to raise_error(NameError)
|
1235
717
|
end
|
718
|
+
|
1236
719
|
it 'raises ArgumentError if a block is not given' do
|
1237
720
|
expect do
|
1238
|
-
|
721
|
+
described_class.generate_api_method('GET without a block method')
|
1239
722
|
end.to raise_error(ArgumentError)
|
1240
723
|
end
|
724
|
+
|
1241
725
|
it 'returns a Proc' do
|
1242
|
-
expect(
|
726
|
+
expect(described_class.generate_api_method('GET test for a proc', &proc {})).to be_a Proc
|
1243
727
|
end
|
1244
728
|
end
|
1245
729
|
|
@@ -1298,7 +782,7 @@ describe Grape::Endpoint do
|
|
1298
782
|
end
|
1299
783
|
|
1300
784
|
get '/error_filters'
|
1301
|
-
expect(last_response.status).to
|
785
|
+
expect(last_response.status).to be 500
|
1302
786
|
expect(called).to match_array %w[before before_validation]
|
1303
787
|
end
|
1304
788
|
|
@@ -1307,8 +791,11 @@ describe Grape::Endpoint do
|
|
1307
791
|
subject.before { called << 'parent' }
|
1308
792
|
subject.namespace :parent do
|
1309
793
|
before { called << 'prior' }
|
794
|
+
|
1310
795
|
before { error! :oops, 500 }
|
796
|
+
|
1311
797
|
before { called << 'subsequent' }
|
798
|
+
|
1312
799
|
get :hello do
|
1313
800
|
called << :endpoint
|
1314
801
|
'Hello!'
|
@@ -1316,7 +803,7 @@ describe Grape::Endpoint do
|
|
1316
803
|
end
|
1317
804
|
|
1318
805
|
get '/parent/hello'
|
1319
|
-
expect(last_response.status).to
|
806
|
+
expect(last_response.status).to be 500
|
1320
807
|
expect(called).to match_array %w[parent prior]
|
1321
808
|
end
|
1322
809
|
end
|
@@ -1327,19 +814,19 @@ describe Grape::Endpoint do
|
|
1327
814
|
it 'allows for the anchoring option with a delete method' do
|
1328
815
|
subject.send(:delete, '/example', anchor: true) {}
|
1329
816
|
send(:delete, '/example/and/some/more')
|
1330
|
-
expect(last_response.status).to
|
817
|
+
expect(last_response.status).to be 404
|
1331
818
|
end
|
1332
819
|
|
1333
820
|
it 'anchors paths by default for the delete method' do
|
1334
821
|
subject.send(:delete, '/example') {}
|
1335
822
|
send(:delete, '/example/and/some/more')
|
1336
|
-
expect(last_response.status).to
|
823
|
+
expect(last_response.status).to be 404
|
1337
824
|
end
|
1338
825
|
|
1339
826
|
it 'responds to /example/and/some/more for the non-anchored delete method' do
|
1340
827
|
subject.send(:delete, '/example', anchor: false) {}
|
1341
828
|
send(:delete, '/example/and/some/more')
|
1342
|
-
expect(last_response.status).to
|
829
|
+
expect(last_response.status).to be 204
|
1343
830
|
expect(last_response.body).to be_empty
|
1344
831
|
end
|
1345
832
|
end
|
@@ -1351,7 +838,7 @@ describe Grape::Endpoint do
|
|
1351
838
|
body 'deleted'
|
1352
839
|
end
|
1353
840
|
send(:delete, '/example/and/some/more')
|
1354
|
-
expect(last_response.status).to
|
841
|
+
expect(last_response.status).to be 200
|
1355
842
|
expect(last_response.body).not_to be_empty
|
1356
843
|
end
|
1357
844
|
end
|
@@ -1360,7 +847,7 @@ describe Grape::Endpoint do
|
|
1360
847
|
it 'responds to /example delete method' do
|
1361
848
|
subject.delete(:example) { 'deleted' }
|
1362
849
|
delete '/example'
|
1363
|
-
expect(last_response.status).to
|
850
|
+
expect(last_response.status).to be 200
|
1364
851
|
expect(last_response.body).not_to be_empty
|
1365
852
|
end
|
1366
853
|
end
|
@@ -1369,7 +856,7 @@ describe Grape::Endpoint do
|
|
1369
856
|
it 'responds to /example delete method' do
|
1370
857
|
subject.delete(:example) { nil }
|
1371
858
|
delete '/example'
|
1372
|
-
expect(last_response.status).to
|
859
|
+
expect(last_response.status).to be 204
|
1373
860
|
expect(last_response.body).to be_empty
|
1374
861
|
end
|
1375
862
|
end
|
@@ -1378,7 +865,7 @@ describe Grape::Endpoint do
|
|
1378
865
|
it 'responds to /example delete method' do
|
1379
866
|
subject.delete(:example) { '' }
|
1380
867
|
delete '/example'
|
1381
|
-
expect(last_response.status).to
|
868
|
+
expect(last_response.status).to be 204
|
1382
869
|
expect(last_response.body).to be_empty
|
1383
870
|
end
|
1384
871
|
end
|
@@ -1390,7 +877,7 @@ describe Grape::Endpoint do
|
|
1390
877
|
verb
|
1391
878
|
end
|
1392
879
|
send(verb, '/example/and/some/more')
|
1393
|
-
expect(last_response.status).to
|
880
|
+
expect(last_response.status).to be 404
|
1394
881
|
end
|
1395
882
|
|
1396
883
|
it "anchors paths by default for the #{verb.upcase} method" do
|
@@ -1398,7 +885,7 @@ describe Grape::Endpoint do
|
|
1398
885
|
verb
|
1399
886
|
end
|
1400
887
|
send(verb, '/example/and/some/more')
|
1401
|
-
expect(last_response.status).to
|
888
|
+
expect(last_response.status).to be 404
|
1402
889
|
end
|
1403
890
|
|
1404
891
|
it "responds to /example/and/some/more for the non-anchored #{verb.upcase} method" do
|
@@ -1421,8 +908,9 @@ describe Grape::Endpoint do
|
|
1421
908
|
get '/url'
|
1422
909
|
expect(last_response.body).to eq('http://example.org/url')
|
1423
910
|
end
|
911
|
+
|
1424
912
|
['v1', :v1].each do |version|
|
1425
|
-
it "
|
913
|
+
it "includes version #{version}" do
|
1426
914
|
subject.version version, using: :path
|
1427
915
|
subject.get('/url') do
|
1428
916
|
request.url
|
@@ -1431,7 +919,7 @@ describe Grape::Endpoint do
|
|
1431
919
|
expect(last_response.body).to eq("http://example.org/#{version}/url")
|
1432
920
|
end
|
1433
921
|
end
|
1434
|
-
it '
|
922
|
+
it 'includes prefix' do
|
1435
923
|
subject.version 'v1', using: :path
|
1436
924
|
subject.prefix 'api'
|
1437
925
|
subject.get('/url') do
|
@@ -1521,26 +1009,26 @@ describe Grape::Endpoint do
|
|
1521
1009
|
|
1522
1010
|
# In order that the events finalized (time each block ended)
|
1523
1011
|
expect(@events).to contain_exactly(
|
1524
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1012
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1525
1013
|
filters: a_collection_containing_exactly(an_instance_of(Proc)),
|
1526
1014
|
type: :before }),
|
1527
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1015
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1528
1016
|
filters: [],
|
1529
1017
|
type: :before_validation }),
|
1530
|
-
have_attributes(name: 'endpoint_run_validators.grape', payload: { endpoint: a_kind_of(
|
1018
|
+
have_attributes(name: 'endpoint_run_validators.grape', payload: { endpoint: a_kind_of(described_class),
|
1531
1019
|
validators: [],
|
1532
1020
|
request: a_kind_of(Grape::Request) }),
|
1533
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1021
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1534
1022
|
filters: [],
|
1535
1023
|
type: :after_validation }),
|
1536
|
-
have_attributes(name: 'endpoint_render.grape', payload: { endpoint: a_kind_of(
|
1537
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1024
|
+
have_attributes(name: 'endpoint_render.grape', payload: { endpoint: a_kind_of(described_class) }),
|
1025
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1538
1026
|
filters: [],
|
1539
1027
|
type: :after }),
|
1540
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1028
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1541
1029
|
filters: [],
|
1542
1030
|
type: :finally }),
|
1543
|
-
have_attributes(name: 'endpoint_run.grape', payload: { endpoint: a_kind_of(
|
1031
|
+
have_attributes(name: 'endpoint_run.grape', payload: { endpoint: a_kind_of(described_class),
|
1544
1032
|
env: an_instance_of(Hash) }),
|
1545
1033
|
have_attributes(name: 'format_response.grape', payload: { env: an_instance_of(Hash),
|
1546
1034
|
formatter: a_kind_of(Module) })
|
@@ -1548,25 +1036,25 @@ describe Grape::Endpoint do
|
|
1548
1036
|
|
1549
1037
|
# In order that events were initialized
|
1550
1038
|
expect(@events.sort_by(&:time)).to contain_exactly(
|
1551
|
-
have_attributes(name: 'endpoint_run.grape', payload: { endpoint: a_kind_of(
|
1039
|
+
have_attributes(name: 'endpoint_run.grape', payload: { endpoint: a_kind_of(described_class),
|
1552
1040
|
env: an_instance_of(Hash) }),
|
1553
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1041
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1554
1042
|
filters: a_collection_containing_exactly(an_instance_of(Proc)),
|
1555
1043
|
type: :before }),
|
1556
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1044
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1557
1045
|
filters: [],
|
1558
1046
|
type: :before_validation }),
|
1559
|
-
have_attributes(name: 'endpoint_run_validators.grape', payload: { endpoint: a_kind_of(
|
1047
|
+
have_attributes(name: 'endpoint_run_validators.grape', payload: { endpoint: a_kind_of(described_class),
|
1560
1048
|
validators: [],
|
1561
1049
|
request: a_kind_of(Grape::Request) }),
|
1562
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1050
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1563
1051
|
filters: [],
|
1564
1052
|
type: :after_validation }),
|
1565
|
-
have_attributes(name: 'endpoint_render.grape', payload: { endpoint: a_kind_of(
|
1566
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1053
|
+
have_attributes(name: 'endpoint_render.grape', payload: { endpoint: a_kind_of(described_class) }),
|
1054
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1567
1055
|
filters: [],
|
1568
1056
|
type: :after }),
|
1569
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1057
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1570
1058
|
filters: [],
|
1571
1059
|
type: :finally }),
|
1572
1060
|
have_attributes(name: 'format_response.grape', payload: { env: an_instance_of(Hash),
|