grape 0.17.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grape might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -3
- data/Dangerfile +1 -80
- data/Gemfile +1 -1
- data/Gemfile.lock +69 -51
- data/README.md +42 -1
- data/UPGRADING.md +2 -2
- data/grape.gemspec +1 -1
- data/lib/grape/api.rb +5 -15
- data/lib/grape/cookies.rb +1 -1
- data/lib/grape/dsl/inside_route.rb +2 -3
- data/lib/grape/dsl/request_response.rb +1 -1
- data/lib/grape/endpoint.rb +19 -7
- data/lib/grape/error_formatter.rb +2 -2
- data/lib/grape/exceptions/base.rb +18 -18
- data/lib/grape/exceptions/validation.rb +6 -7
- data/lib/grape/exceptions/validation_errors.rb +5 -5
- data/lib/grape/formatter.rb +2 -2
- data/lib/grape/locale/en.yml +1 -0
- data/lib/grape/middleware/auth/base.rb +2 -2
- data/lib/grape/middleware/base.rb +2 -2
- data/lib/grape/middleware/error.rb +1 -1
- data/lib/grape/middleware/stack.rb +1 -1
- data/lib/grape/middleware/versioner/header.rb +1 -1
- data/lib/grape/namespace.rb +1 -1
- data/lib/grape/parser.rb +2 -2
- data/lib/grape/presenters/presenter.rb +1 -1
- data/lib/grape/router.rb +6 -6
- data/lib/grape/router/pattern.rb +7 -7
- data/lib/grape/router/route.rb +3 -3
- data/lib/grape/util/env.rb +1 -1
- data/lib/grape/validations/params_scope.rb +15 -7
- data/lib/grape/validations/validators/allow_blank.rb +0 -13
- data/lib/grape/validations/validators/base.rb +8 -1
- data/lib/grape/validations/validators/default.rb +1 -3
- data/lib/grape/validations/validators/presence.rb +0 -5
- data/lib/grape/validations/validators/values.rb +17 -3
- data/lib/grape/version.rb +1 -1
- data/pkg/grape-0.18.0.gem +0 -0
- data/spec/grape/api_spec.rb +41 -0
- data/spec/grape/exceptions/validation_spec.rb +1 -1
- data/spec/grape/middleware/stack_spec.rb +20 -0
- data/spec/grape/validations/params_scope_spec.rb +190 -58
- data/spec/grape/validations/validators/allow_blank_spec.rb +22 -7
- data/spec/grape/validations/validators/coerce_spec.rb +6 -6
- data/spec/grape/validations/validators/values_spec.rb +146 -0
- data/spec/grape/validations_spec.rb +28 -0
- metadata +6 -6
@@ -9,7 +9,12 @@ describe Grape::Validations::AllowBlankValidator do
|
|
9
9
|
params do
|
10
10
|
requires :name, allow_blank: false
|
11
11
|
end
|
12
|
-
get
|
12
|
+
get '/disallow_blank'
|
13
|
+
|
14
|
+
params do
|
15
|
+
optional :name, type: String, allow_blank: false
|
16
|
+
end
|
17
|
+
get '/opt_disallow_string_blank'
|
13
18
|
|
14
19
|
params do
|
15
20
|
optional :name, allow_blank: false
|
@@ -247,7 +252,7 @@ describe Grape::Validations::AllowBlankValidator do
|
|
247
252
|
|
248
253
|
context 'invalid input' do
|
249
254
|
it 'refuses empty string' do
|
250
|
-
get '/', name: ''
|
255
|
+
get '/disallow_blank', name: ''
|
251
256
|
expect(last_response.status).to eq(400)
|
252
257
|
|
253
258
|
get '/disallow_datetime_blank', val: ''
|
@@ -255,18 +260,23 @@ describe Grape::Validations::AllowBlankValidator do
|
|
255
260
|
end
|
256
261
|
|
257
262
|
it 'refuses only whitespaces' do
|
258
|
-
get '/', name: ' '
|
263
|
+
get '/disallow_blank', name: ' '
|
259
264
|
expect(last_response.status).to eq(400)
|
260
265
|
|
261
|
-
get '/', name: " \n "
|
266
|
+
get '/disallow_blank', name: " \n "
|
262
267
|
expect(last_response.status).to eq(400)
|
263
268
|
|
264
|
-
get '/', name: "\n"
|
269
|
+
get '/disallow_blank', name: "\n"
|
265
270
|
expect(last_response.status).to eq(400)
|
266
271
|
end
|
267
272
|
|
268
273
|
it 'refuses nil' do
|
269
|
-
get '/', name: nil
|
274
|
+
get '/disallow_blank', name: nil
|
275
|
+
expect(last_response.status).to eq(400)
|
276
|
+
end
|
277
|
+
|
278
|
+
it 'refuses missing' do
|
279
|
+
get '/disallow_blank'
|
270
280
|
expect(last_response.status).to eq(400)
|
271
281
|
end
|
272
282
|
end
|
@@ -432,8 +442,13 @@ describe Grape::Validations::AllowBlankValidator do
|
|
432
442
|
end
|
433
443
|
|
434
444
|
context 'valid input' do
|
445
|
+
it 'allows missing optional strings' do
|
446
|
+
get 'opt_disallow_string_blank'
|
447
|
+
expect(last_response.status).to eq(200)
|
448
|
+
end
|
449
|
+
|
435
450
|
it 'accepts valid input' do
|
436
|
-
get '/', name: 'bob'
|
451
|
+
get '/disallow_blank', name: 'bob'
|
437
452
|
expect(last_response.status).to eq(200)
|
438
453
|
end
|
439
454
|
|
@@ -625,7 +625,7 @@ describe Grape::Validations::CoerceValidator do
|
|
625
625
|
|
626
626
|
get '/', a: %w(the other)
|
627
627
|
expect(last_response.status).to eq(200)
|
628
|
-
expect(last_response.body).to eq('["the", "other"]')
|
628
|
+
expect(last_response.body).to eq('#<Hashie::Array ["the", "other"]>')
|
629
629
|
|
630
630
|
get '/', a: { a: 1, b: 2 }
|
631
631
|
expect(last_response.status).to eq(400)
|
@@ -633,27 +633,27 @@ describe Grape::Validations::CoerceValidator do
|
|
633
633
|
|
634
634
|
get '/', a: [1, 2, 3]
|
635
635
|
expect(last_response.status).to eq(200)
|
636
|
-
expect(last_response.body).to eq('["1", "2", "3"]')
|
636
|
+
expect(last_response.body).to eq('#<Hashie::Array ["1", "2", "3"]>')
|
637
637
|
end
|
638
638
|
|
639
639
|
it 'allows multiple collection types' do
|
640
640
|
get '/', b: [1, 2, 3]
|
641
641
|
expect(last_response.status).to eq(200)
|
642
|
-
expect(last_response.body).to eq('[1, 2, 3]')
|
642
|
+
expect(last_response.body).to eq('#<Hashie::Array [1, 2, 3]>')
|
643
643
|
|
644
644
|
get '/', b: %w(1 2 3)
|
645
645
|
expect(last_response.status).to eq(200)
|
646
|
-
expect(last_response.body).to eq('[1, 2, 3]')
|
646
|
+
expect(last_response.body).to eq('#<Hashie::Array [1, 2, 3]>')
|
647
647
|
|
648
648
|
get '/', b: [1, true, 'three']
|
649
649
|
expect(last_response.status).to eq(200)
|
650
|
-
expect(last_response.body).to eq('["1", "true", "three"]')
|
650
|
+
expect(last_response.body).to eq('#<Hashie::Array ["1", "true", "three"]>')
|
651
651
|
end
|
652
652
|
|
653
653
|
it 'allows collections with multiple types' do
|
654
654
|
get '/', c: [1, '2', true, 'three']
|
655
655
|
expect(last_response.status).to eq(200)
|
656
|
-
expect(last_response.body).to eq('[1, 2, "true", "three"]')
|
656
|
+
expect(last_response.body).to eq('#<Hashie::Array [1, 2, "true", "three"]>')
|
657
657
|
|
658
658
|
get '/', d: '1'
|
659
659
|
expect(last_response.status).to eq(200)
|
@@ -4,6 +4,7 @@ describe Grape::Validations::ValuesValidator do
|
|
4
4
|
module ValidationsSpec
|
5
5
|
class ValuesModel
|
6
6
|
DEFAULT_VALUES = ['valid-type1', 'valid-type2', 'valid-type3'].freeze
|
7
|
+
DEFAULT_EXCEPTS = ['invalid-type1', 'invalid-type2', 'invalid-type3'].freeze
|
7
8
|
class << self
|
8
9
|
def values
|
9
10
|
@values ||= []
|
@@ -14,6 +15,16 @@ describe Grape::Validations::ValuesValidator do
|
|
14
15
|
@values ||= []
|
15
16
|
@values << value
|
16
17
|
end
|
18
|
+
|
19
|
+
def excepts
|
20
|
+
@excepts ||= []
|
21
|
+
[DEFAULT_EXCEPTS + @excepts].flatten.uniq
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_except(except)
|
25
|
+
@excepts ||= []
|
26
|
+
@excepts << except
|
27
|
+
end
|
17
28
|
end
|
18
29
|
end
|
19
30
|
|
@@ -35,6 +46,27 @@ describe Grape::Validations::ValuesValidator do
|
|
35
46
|
get '/lambda' do
|
36
47
|
{ type: params[:type] }
|
37
48
|
end
|
49
|
+
|
50
|
+
params do
|
51
|
+
requires :type, values: { except: ValuesModel.excepts, except_message: 'value is on exclusions list', message: 'default exclude message' }
|
52
|
+
end
|
53
|
+
get '/exclude/exclude_message' do
|
54
|
+
{ type: params[:type] }
|
55
|
+
end
|
56
|
+
|
57
|
+
params do
|
58
|
+
requires :type, values: { except: -> { ValuesModel.excepts }, except_message: 'value is on exclusions list' }
|
59
|
+
end
|
60
|
+
get '/exclude/lambda/exclude_message' do
|
61
|
+
{ type: params[:type] }
|
62
|
+
end
|
63
|
+
|
64
|
+
params do
|
65
|
+
requires :type, values: { except: ValuesModel.excepts, message: 'default exclude message' }
|
66
|
+
end
|
67
|
+
get '/exclude/fallback_message' do
|
68
|
+
{ type: params[:type] }
|
69
|
+
end
|
38
70
|
end
|
39
71
|
|
40
72
|
params do
|
@@ -99,6 +131,34 @@ describe Grape::Validations::ValuesValidator do
|
|
99
131
|
end
|
100
132
|
end
|
101
133
|
get '/optional_with_required_values'
|
134
|
+
|
135
|
+
params do
|
136
|
+
requires :type, values: { except: ValuesModel.excepts }
|
137
|
+
end
|
138
|
+
get '/except/exclusive' do
|
139
|
+
{ type: params[:type] }
|
140
|
+
end
|
141
|
+
|
142
|
+
params do
|
143
|
+
requires :type, values: { except: -> { ValuesModel.excepts } }
|
144
|
+
end
|
145
|
+
get '/except/exclusive/lambda' do
|
146
|
+
{ type: params[:type] }
|
147
|
+
end
|
148
|
+
|
149
|
+
params do
|
150
|
+
requires :type, type: Integer, values: { except: -> { [3, 4, 5] } }
|
151
|
+
end
|
152
|
+
get '/except/exclusive/lambda/coercion' do
|
153
|
+
{ type: params[:type] }
|
154
|
+
end
|
155
|
+
|
156
|
+
params do
|
157
|
+
requires :type, type: Integer, values: { value: 1..5, except: [3] }
|
158
|
+
end
|
159
|
+
get '/mixed/value/except' do
|
160
|
+
{ type: params[:type] }
|
161
|
+
end
|
102
162
|
end
|
103
163
|
end
|
104
164
|
end
|
@@ -135,6 +195,30 @@ describe Grape::Validations::ValuesValidator do
|
|
135
195
|
end
|
136
196
|
end
|
137
197
|
|
198
|
+
context 'with a custom exclude validation message' do
|
199
|
+
it 'does not allow an invalid value for a parameter' do
|
200
|
+
get('/custom_message/exclude/exclude_message', type: 'invalid-type1')
|
201
|
+
expect(last_response.status).to eq 400
|
202
|
+
expect(last_response.body).to eq({ error: 'type value is on exclusions list' }.to_json)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'with a custom exclude validation message' do
|
207
|
+
it 'does not allow an invalid value for a parameter' do
|
208
|
+
get('/custom_message/exclude/lambda/exclude_message', type: 'invalid-type1')
|
209
|
+
expect(last_response.status).to eq 400
|
210
|
+
expect(last_response.body).to eq({ error: 'type value is on exclusions list' }.to_json)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context 'exclude with a standard custom validation message' do
|
215
|
+
it 'does not allow an invalid value for a parameter' do
|
216
|
+
get('/custom_message/exclude/fallback_message', type: 'invalid-type1')
|
217
|
+
expect(last_response.status).to eq 400
|
218
|
+
expect(last_response.body).to eq({ error: 'type default exclude message' }.to_json)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
138
222
|
it 'allows a valid value for a parameter' do
|
139
223
|
get('/', type: 'valid-type1')
|
140
224
|
expect(last_response.status).to eq 200
|
@@ -321,4 +405,66 @@ describe Grape::Validations::ValuesValidator do
|
|
321
405
|
expect(last_response.body).to eq('values does not have a valid value')
|
322
406
|
end
|
323
407
|
end
|
408
|
+
|
409
|
+
context 'exclusive excepts' do
|
410
|
+
it 'allows any other value outside excepts' do
|
411
|
+
get '/except/exclusive', type: 'value'
|
412
|
+
expect(last_response.status).to eq 200
|
413
|
+
expect(last_response.body).to eq({ type: 'value' }.to_json)
|
414
|
+
end
|
415
|
+
|
416
|
+
it 'rejects values that matches except' do
|
417
|
+
get '/except/exclusive', type: 'invalid-type1'
|
418
|
+
expect(last_response.status).to eq 400
|
419
|
+
expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json)
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
context 'exclusive excepts with lambda' do
|
424
|
+
it 'allows any other value outside excepts' do
|
425
|
+
get '/except/exclusive/lambda', type: 'value'
|
426
|
+
expect(last_response.status).to eq 200
|
427
|
+
expect(last_response.body).to eq({ type: 'value' }.to_json)
|
428
|
+
end
|
429
|
+
|
430
|
+
it 'rejects values that matches except' do
|
431
|
+
get '/except/exclusive/lambda', type: 'invalid-type1'
|
432
|
+
expect(last_response.status).to eq 400
|
433
|
+
expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json)
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
context 'exclusive excepts with lambda and coercion' do
|
438
|
+
it 'allows any other value outside excepts' do
|
439
|
+
get '/except/exclusive/lambda/coercion', type: '10010000'
|
440
|
+
expect(last_response.status).to eq 200
|
441
|
+
expect(last_response.body).to eq({ type: 10_010_000 }.to_json)
|
442
|
+
end
|
443
|
+
|
444
|
+
it 'rejects values that matches except' do
|
445
|
+
get '/except/exclusive/lambda/coercion', type: '3'
|
446
|
+
expect(last_response.status).to eq 400
|
447
|
+
expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json)
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
context 'with mixed values and excepts' do
|
452
|
+
it 'allows value, but not in except' do
|
453
|
+
get '/mixed/value/except', type: 2
|
454
|
+
expect(last_response.status).to eq 200
|
455
|
+
expect(last_response.body).to eq({ type: 2 }.to_json)
|
456
|
+
end
|
457
|
+
|
458
|
+
it 'rejects except' do
|
459
|
+
get '/mixed/value/except', type: 3
|
460
|
+
expect(last_response.status).to eq 400
|
461
|
+
expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json)
|
462
|
+
end
|
463
|
+
|
464
|
+
it 'rejects outside except and outside value' do
|
465
|
+
get '/mixed/value/except', type: 10
|
466
|
+
expect(last_response.status).to eq 400
|
467
|
+
expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
|
468
|
+
end
|
469
|
+
end
|
324
470
|
end
|
@@ -274,6 +274,28 @@ describe Grape::Validations do
|
|
274
274
|
end
|
275
275
|
end
|
276
276
|
|
277
|
+
# Ensure there is no leakage between declared Array types and
|
278
|
+
# subsequent Hash types
|
279
|
+
context 'required with an Array and a Hash block' do
|
280
|
+
before do
|
281
|
+
subject.params do
|
282
|
+
requires :cats, type: Array[String], default: []
|
283
|
+
requires :items, type: Hash do
|
284
|
+
requires :key
|
285
|
+
end
|
286
|
+
end
|
287
|
+
subject.get '/required' do
|
288
|
+
'required works'
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
it 'does not output index [0] for Hash types' do
|
293
|
+
get '/required', cats: ['Garfield'], items: { foo: 'bar' }
|
294
|
+
expect(last_response.status).to eq(400)
|
295
|
+
expect(last_response.body).to eq('items[key] is missing')
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
277
299
|
context 'required with a Hash block' do
|
278
300
|
before do
|
279
301
|
subject.params do
|
@@ -292,6 +314,12 @@ describe Grape::Validations do
|
|
292
314
|
expect(last_response.body).to eq('items is missing, items[key] is missing')
|
293
315
|
end
|
294
316
|
|
317
|
+
it 'errors when nested param not present' do
|
318
|
+
get '/required', items: { foo: 'bar' }
|
319
|
+
expect(last_response.status).to eq(400)
|
320
|
+
expect(last_response.body).to eq('items[key] is missing')
|
321
|
+
end
|
322
|
+
|
295
323
|
it 'errors when param is not a Hash' do
|
296
324
|
get '/required', items: 'hello'
|
297
325
|
expect(last_response.status).to eq(400)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grape
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.18.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Bleigh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -25,19 +25,19 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 1.3.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: mustermann-grape
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.4.
|
33
|
+
version: 0.4.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.4.
|
40
|
+
version: 0.4.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rack-accept
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -275,6 +275,7 @@ files:
|
|
275
275
|
- lib/grape/validations/validators/regexp.rb
|
276
276
|
- lib/grape/validations/validators/values.rb
|
277
277
|
- lib/grape/version.rb
|
278
|
+
- pkg/grape-0.18.0.gem
|
278
279
|
- spec/grape/api/custom_validations_spec.rb
|
279
280
|
- spec/grape/api/deeply_included_options_spec.rb
|
280
281
|
- spec/grape/api/invalid_format_spec.rb
|
@@ -474,4 +475,3 @@ test_files:
|
|
474
475
|
- spec/support/endpoint_faker.rb
|
475
476
|
- spec/support/file_streamer.rb
|
476
477
|
- spec/support/versioned_helpers.rb
|
477
|
-
has_rdoc:
|