grape 1.0.1 → 1.0.2
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 +5 -5
- data/Appraisals +1 -1
- data/CHANGELOG.md +18 -0
- data/Dangerfile +1 -0
- data/Gemfile +9 -10
- data/Gemfile.lock +42 -40
- data/LICENSE +1 -1
- data/README.md +89 -40
- data/Rakefile +1 -46
- data/gemfiles/multi_json.gemfile +9 -10
- data/gemfiles/multi_xml.gemfile +9 -10
- data/gemfiles/rack_1.5.2.gemfile +9 -10
- data/gemfiles/rack_edge.gemfile +9 -10
- data/gemfiles/rails_3.gemfile +9 -10
- data/gemfiles/rails_4.gemfile +9 -10
- data/gemfiles/rails_5.gemfile +9 -10
- data/gemfiles/rails_edge.gemfile +9 -10
- data/grape.gemspec +3 -3
- data/lib/grape/api.rb +2 -2
- data/lib/grape/dsl/inside_route.rb +30 -10
- data/lib/grape/dsl/routing.rb +1 -1
- data/lib/grape/dsl/settings.rb +6 -6
- data/lib/grape/endpoint.rb +1 -1
- data/lib/grape/exceptions/incompatible_option_values.rb +0 -1
- data/lib/grape/exceptions/invalid_accept_header.rb +0 -1
- data/lib/grape/exceptions/invalid_formatter.rb +0 -1
- data/lib/grape/exceptions/invalid_message_body.rb +0 -1
- data/lib/grape/exceptions/invalid_version_header.rb +0 -1
- data/lib/grape/exceptions/invalid_versioner_option.rb +0 -1
- data/lib/grape/exceptions/invalid_with_option_for_represent.rb +0 -1
- data/lib/grape/exceptions/method_not_allowed.rb +0 -1
- data/lib/grape/exceptions/missing_group_type.rb +0 -1
- data/lib/grape/exceptions/missing_mime_type.rb +0 -1
- data/lib/grape/exceptions/missing_option.rb +0 -1
- data/lib/grape/exceptions/missing_vendor_option.rb +0 -1
- data/lib/grape/exceptions/unknown_options.rb +0 -1
- data/lib/grape/exceptions/unknown_parameter.rb +0 -1
- data/lib/grape/exceptions/unknown_validator.rb +0 -1
- data/lib/grape/exceptions/unsupported_group_type.rb +0 -1
- data/lib/grape/namespace.rb +1 -1
- data/lib/grape/router.rb +2 -0
- data/lib/grape/router/pattern.rb +1 -1
- data/lib/grape/router/route.rb +14 -14
- data/lib/grape/validations/params_scope.rb +3 -4
- data/lib/grape/validations/types.rb +14 -1
- data/lib/grape/validations/types/build_coercer.rb +8 -0
- data/lib/grape/validations/types/custom_type_coercer.rb +1 -1
- data/lib/grape/validations/types/custom_type_collection_coercer.rb +71 -0
- data/lib/grape/validations/validators/allow_blank.rb +1 -1
- data/lib/grape/validations/validators/base.rb +1 -0
- data/lib/grape/validations/validators/coerce.rb +6 -0
- data/lib/grape/version.rb +1 -1
- data/pkg/grape-1.0.1.gem +0 -0
- data/spec/grape/api_spec.rb +22 -12
- data/spec/grape/dsl/inside_route_spec.rb +1 -1
- data/spec/grape/dsl/parameters_spec.rb +5 -5
- data/spec/grape/dsl/settings_spec.rb +2 -2
- data/spec/grape/endpoint_spec.rb +25 -12
- data/spec/grape/entity_spec.rb +1 -1
- data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -1
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +0 -1
- data/spec/grape/exceptions/missing_option_spec.rb +0 -1
- data/spec/grape/exceptions/unknown_options_spec.rb +1 -2
- data/spec/grape/exceptions/unknown_validator_spec.rb +0 -1
- data/spec/grape/exceptions/validation_errors_spec.rb +1 -1
- data/spec/grape/middleware/exception_spec.rb +36 -12
- data/spec/grape/middleware/formatter_spec.rb +1 -1
- data/spec/grape/middleware/versioner/header_spec.rb +1 -1
- data/spec/grape/middleware/versioner/param_spec.rb +1 -1
- data/spec/grape/middleware/versioner/path_spec.rb +1 -1
- data/spec/grape/path_spec.rb +3 -3
- data/spec/grape/util/inheritable_setting_spec.rb +2 -2
- data/spec/grape/util/reverse_stackable_values_spec.rb +13 -13
- data/spec/grape/util/stackable_values_spec.rb +13 -13
- data/spec/grape/util/strict_hash_configuration_spec.rb +1 -1
- data/spec/grape/validations/params_scope_spec.rb +19 -7
- data/spec/grape/validations/validators/all_or_none_spec.rb +1 -1
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +1 -1
- data/spec/grape/validations/validators/coerce_spec.rb +94 -13
- data/spec/grape/validations/validators/default_spec.rb +40 -0
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +1 -1
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +1 -1
- data/spec/grape/validations/validators/values_spec.rb +3 -3
- data/spec/grape/validations_spec.rb +9 -9
- data/spec/shared/versioning_examples.rb +58 -0
- data/spec/support/content_type_helpers.rb +1 -1
- metadata +26 -24
@@ -9,7 +9,7 @@ module Grape
|
|
9
9
|
it 'returns all key' do
|
10
10
|
subject[:some_thing] = :foo_bar
|
11
11
|
subject[:some_thing_else] = :foo_bar
|
12
|
-
expect(subject.keys).to eq [
|
12
|
+
expect(subject.keys).to eq %i[some_thing some_thing_else].sort
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'returns merged keys with parent' do
|
@@ -19,7 +19,7 @@ module Grape
|
|
19
19
|
subject[:some_thing] = :foo_bar
|
20
20
|
subject[:some_thing_more] = :foo_bar
|
21
21
|
|
22
|
-
expect(subject.keys).to eq [
|
22
|
+
expect(subject.keys).to eq %i[some_thing some_thing_else some_thing_more].sort
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -52,7 +52,7 @@ module Grape
|
|
52
52
|
it 'combines parent and actual values' do
|
53
53
|
parent[:some_thing] = :foo
|
54
54
|
subject[:some_thing] = :foo_bar
|
55
|
-
expect(subject[:some_thing]).to eq [
|
55
|
+
expect(subject[:some_thing]).to eq %i[foo foo_bar]
|
56
56
|
end
|
57
57
|
|
58
58
|
it 'parent values are not changed' do
|
@@ -71,27 +71,27 @@ module Grape
|
|
71
71
|
it 'pushes further values' do
|
72
72
|
subject[:some_thing] = :foo
|
73
73
|
subject[:some_thing] = :bar
|
74
|
-
expect(subject[:some_thing]).to eq [
|
74
|
+
expect(subject[:some_thing]).to eq %i[foo bar]
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'can handle array values' do
|
78
78
|
subject[:some_thing] = :foo
|
79
|
-
subject[:some_thing] = [
|
80
|
-
expect(subject[:some_thing]).to eq [:foo, [
|
79
|
+
subject[:some_thing] = %i[bar more]
|
80
|
+
expect(subject[:some_thing]).to eq [:foo, %i[bar more]]
|
81
81
|
|
82
|
-
parent[:some_thing_else] = [
|
83
|
-
subject[:some_thing_else] = [
|
82
|
+
parent[:some_thing_else] = %i[foo bar]
|
83
|
+
subject[:some_thing_else] = %i[some bar foo]
|
84
84
|
|
85
|
-
expect(subject[:some_thing_else]).to eq [[
|
85
|
+
expect(subject[:some_thing_else]).to eq [%i[foo bar], %i[some bar foo]]
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
89
|
describe '#to_hash' do
|
90
90
|
it 'returns a Hash representation' do
|
91
91
|
parent[:some_thing] = :foo
|
92
|
-
subject[:some_thing] = [
|
92
|
+
subject[:some_thing] = %i[bar more]
|
93
93
|
subject[:some_thing_more] = :foo_bar
|
94
|
-
expect(subject.to_hash).to eq(some_thing: [:foo, [
|
94
|
+
expect(subject.to_hash).to eq(some_thing: [:foo, %i[bar more]], some_thing_more: [:foo_bar])
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
@@ -103,11 +103,11 @@ module Grape
|
|
103
103
|
grandchild = StackableValues.new child
|
104
104
|
|
105
105
|
parent[:some_thing] = :foo
|
106
|
-
child[:some_thing] = [
|
106
|
+
child[:some_thing] = %i[bar more]
|
107
107
|
grandchild[:some_thing] = :grand_foo_bar
|
108
108
|
grandchild[:some_thing_more] = :foo_bar
|
109
109
|
|
110
|
-
expect(grandchild.clone.to_hash).to eq(some_thing: [:foo, [
|
110
|
+
expect(grandchild.clone.to_hash).to eq(some_thing: [:foo, %i[bar more], :grand_foo_bar], some_thing_more: [:foo_bar])
|
111
111
|
end
|
112
112
|
|
113
113
|
context 'complex (i.e. not primitive) data types (ex. middleware, please see bug #930)' do
|
@@ -4,7 +4,7 @@ module Grape
|
|
4
4
|
describe 'StrictHashConfiguration' do
|
5
5
|
subject do
|
6
6
|
Class.new do
|
7
|
-
include Grape::Util::StrictHashConfiguration.module(:config1, :config2, config3: [:config4], config5: [config6: [
|
7
|
+
include Grape::Util::StrictHashConfiguration.module(:config1, :config2, config3: [:config4], config5: [config6: %i[config7 config8]])
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
@@ -74,7 +74,7 @@ describe Grape::Validations::ParamsScope do
|
|
74
74
|
end
|
75
75
|
|
76
76
|
context 'setting description' do
|
77
|
-
[
|
77
|
+
%i[desc description].each do |description_type|
|
78
78
|
it "allows setting #{description_type}" do
|
79
79
|
subject.params do
|
80
80
|
requires :int, type: Integer, description_type => 'My very nice integer'
|
@@ -160,18 +160,18 @@ describe Grape::Validations::ParamsScope do
|
|
160
160
|
context 'array without coerce type explicitly given' do
|
161
161
|
it 'sets the type based on first element' do
|
162
162
|
subject.params do
|
163
|
-
requires :periods, type: Array, values: -> { %w
|
163
|
+
requires :periods, type: Array, values: -> { %w[day month] }
|
164
164
|
end
|
165
165
|
subject.get('/required') { 'required works' }
|
166
166
|
|
167
|
-
get '/required', periods: %w
|
167
|
+
get '/required', periods: %w[day month]
|
168
168
|
expect(last_response.status).to eq(200)
|
169
169
|
expect(last_response.body).to eq('required works')
|
170
170
|
end
|
171
171
|
|
172
172
|
it 'fails to call API without Array type' do
|
173
173
|
subject.params do
|
174
|
-
requires :periods, type: Array, values: -> { %w
|
174
|
+
requires :periods, type: Array, values: -> { %w[day month] }
|
175
175
|
end
|
176
176
|
subject.get('/required') { 'required works' }
|
177
177
|
|
@@ -339,6 +339,18 @@ describe Grape::Validations::ParamsScope do
|
|
339
339
|
get '/optional_type_array'
|
340
340
|
end
|
341
341
|
|
342
|
+
it 'handles missing optional Array type' do
|
343
|
+
subject.params do
|
344
|
+
optional :a, type: Array do
|
345
|
+
requires :b
|
346
|
+
end
|
347
|
+
end
|
348
|
+
subject.get('/test') { declared(params).to_json }
|
349
|
+
get '/test'
|
350
|
+
expect(last_response.status).to eq(200)
|
351
|
+
expect(last_response.body).to eq('{"a":[]}')
|
352
|
+
end
|
353
|
+
|
342
354
|
it 'errors with an unsupported type' do
|
343
355
|
expect do
|
344
356
|
subject.params do
|
@@ -456,7 +468,7 @@ describe Grape::Validations::ParamsScope do
|
|
456
468
|
|
457
469
|
it 'does not validate nested requires when given is false' do
|
458
470
|
subject.params do
|
459
|
-
requires :a, type: String, allow_blank: false, values: %w
|
471
|
+
requires :a, type: String, allow_blank: false, values: %w[x y z]
|
460
472
|
given a: ->(val) { val == 'x' } do
|
461
473
|
requires :inner1, type: Hash, allow_blank: false do
|
462
474
|
requires :foo, type: Integer, allow_blank: false
|
@@ -574,8 +586,8 @@ describe Grape::Validations::ParamsScope do
|
|
574
586
|
|
575
587
|
context 'when validations are dependent on a parameter with specific value' do
|
576
588
|
# build test cases from all combinations of declarations and options
|
577
|
-
a_decls = %i
|
578
|
-
a_options = [{}, { values: %w
|
589
|
+
a_decls = %i[optional requires]
|
590
|
+
a_options = [{}, { values: %w[x y z] }]
|
579
591
|
b_options = [{}, { type: String }, { allow_blank: false }, { type: String, allow_blank: false }]
|
580
592
|
combinations = a_decls.product(a_options, b_options)
|
581
593
|
combinations.each_with_index do |combination, i|
|
@@ -11,7 +11,7 @@ describe Grape::Validations::AllOrNoneOfValidator do
|
|
11
11
|
def required?; end
|
12
12
|
end
|
13
13
|
end
|
14
|
-
let(:all_or_none_params) { [
|
14
|
+
let(:all_or_none_params) { %i[beer wine grapefruit] }
|
15
15
|
let(:validator) { described_class.new(all_or_none_params, {}, false, scope.new) }
|
16
16
|
|
17
17
|
context 'when all restricted params are present' do
|
@@ -11,7 +11,7 @@ describe Grape::Validations::AtLeastOneOfValidator do
|
|
11
11
|
def required?; end
|
12
12
|
end
|
13
13
|
end
|
14
|
-
let(:at_least_one_of_params) { [
|
14
|
+
let(:at_least_one_of_params) { %i[beer wine grapefruit] }
|
15
15
|
let(:validator) { described_class.new(at_least_one_of_params, {}, false, scope.new) }
|
16
16
|
|
17
17
|
context 'when all restricted params are present' do
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
require 'spec_helper'
|
3
2
|
|
4
3
|
describe Grape::Validations::CoerceValidator do
|
@@ -136,11 +135,11 @@ describe Grape::Validations::CoerceValidator do
|
|
136
135
|
'array int works'
|
137
136
|
end
|
138
137
|
|
139
|
-
get 'array', ids: %w
|
138
|
+
get 'array', ids: %w[1 2 az]
|
140
139
|
expect(last_response.status).to eq(400)
|
141
140
|
expect(last_response.body).to eq('ids is invalid')
|
142
141
|
|
143
|
-
get 'array', ids: %w
|
142
|
+
get 'array', ids: %w[1 2 890]
|
144
143
|
expect(last_response.status).to eq(200)
|
145
144
|
expect(last_response.body).to eq('array int works')
|
146
145
|
end
|
@@ -187,7 +186,7 @@ describe Grape::Validations::CoerceValidator do
|
|
187
186
|
params[:arry][0].class
|
188
187
|
end
|
189
188
|
|
190
|
-
get '/array', arry: %w
|
189
|
+
get '/array', arry: %w[1 2 3]
|
191
190
|
expect(last_response.status).to eq(200)
|
192
191
|
expect(last_response.body).to eq(integer_class_name)
|
193
192
|
end
|
@@ -225,6 +224,55 @@ describe Grape::Validations::CoerceValidator do
|
|
225
224
|
expect(last_response.status).to eq(200)
|
226
225
|
expect(last_response.body).to eq('1')
|
227
226
|
end
|
227
|
+
|
228
|
+
it 'Array of type implementing parse' do
|
229
|
+
subject.params do
|
230
|
+
requires :uri, type: Array[URI]
|
231
|
+
end
|
232
|
+
subject.get '/uri_array' do
|
233
|
+
params[:uri][0].class
|
234
|
+
end
|
235
|
+
get 'uri_array', uri: ['http://www.google.com']
|
236
|
+
expect(last_response.status).to eq(200)
|
237
|
+
expect(last_response.body).to eq('URI::HTTP')
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'Set of type implementing parse' do
|
241
|
+
subject.params do
|
242
|
+
requires :uri, type: Set[URI]
|
243
|
+
end
|
244
|
+
subject.get '/uri_array' do
|
245
|
+
"#{params[:uri].class},#{params[:uri].first.class},#{params[:uri].size}"
|
246
|
+
end
|
247
|
+
get 'uri_array', uri: Array.new(2) { 'http://www.example.com' }
|
248
|
+
expect(last_response.status).to eq(200)
|
249
|
+
expect(last_response.body).to eq('Set,URI::HTTP,1')
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'Array of class implementing parse and parsed?' do
|
253
|
+
class SecureURIOnly
|
254
|
+
def self.parse(value)
|
255
|
+
URI.parse(value)
|
256
|
+
end
|
257
|
+
|
258
|
+
def self.parsed?(value)
|
259
|
+
value.is_a? URI::HTTPS
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
subject.params do
|
264
|
+
requires :uri, type: Array[SecureURIOnly]
|
265
|
+
end
|
266
|
+
subject.get '/secure_uris' do
|
267
|
+
params[:uri].first.class
|
268
|
+
end
|
269
|
+
get 'secure_uris', uri: ['https://www.example.com']
|
270
|
+
expect(last_response.status).to eq(200)
|
271
|
+
expect(last_response.body).to eq('URI::HTTPS')
|
272
|
+
get 'secure_uris', uri: ['https://www.example.com', 'http://www.example.com']
|
273
|
+
expect(last_response.status).to eq(400)
|
274
|
+
expect(last_response.body).to eq('uri is invalid')
|
275
|
+
end
|
228
276
|
end
|
229
277
|
|
230
278
|
context 'Set' do
|
@@ -395,11 +443,11 @@ describe Grape::Validations::CoerceValidator do
|
|
395
443
|
|
396
444
|
get '/ints', values: '1 2 3 4'
|
397
445
|
expect(last_response.status).to eq(200)
|
398
|
-
expect(JSON.parse(last_response.body)).to eq(%w
|
446
|
+
expect(JSON.parse(last_response.body)).to eq(%w[1 2 3 4])
|
399
447
|
|
400
448
|
get '/ints', values: 'a b c d'
|
401
449
|
expect(last_response.status).to eq(200)
|
402
|
-
expect(JSON.parse(last_response.body)).to eq(%w
|
450
|
+
expect(JSON.parse(last_response.body)).to eq(%w[0 0 0 0])
|
403
451
|
end
|
404
452
|
|
405
453
|
it 'parses parameters with Array[Integer] type' do
|
@@ -419,6 +467,23 @@ describe Grape::Validations::CoerceValidator do
|
|
419
467
|
expect(JSON.parse(last_response.body)).to eq([0, 0, 0, 0])
|
420
468
|
end
|
421
469
|
|
470
|
+
it 'parses parameters even if type is valid' do
|
471
|
+
subject.params do
|
472
|
+
requires :values, type: Array, coerce_with: ->(array) { array.map { |val| val.to_i + 1 } }
|
473
|
+
end
|
474
|
+
subject.get '/ints' do
|
475
|
+
params[:values]
|
476
|
+
end
|
477
|
+
|
478
|
+
get '/ints', values: [1, 2, 3, 4]
|
479
|
+
expect(last_response.status).to eq(200)
|
480
|
+
expect(JSON.parse(last_response.body)).to eq([2, 3, 4, 5])
|
481
|
+
|
482
|
+
get '/ints', values: %w[a b c d]
|
483
|
+
expect(last_response.status).to eq(200)
|
484
|
+
expect(JSON.parse(last_response.body)).to eq([1, 1, 1, 1])
|
485
|
+
end
|
486
|
+
|
422
487
|
it 'uses parse where available' do
|
423
488
|
subject.params do
|
424
489
|
requires :ints, type: Array, coerce_with: JSON do
|
@@ -477,7 +542,7 @@ describe Grape::Validations::CoerceValidator do
|
|
477
542
|
end
|
478
543
|
|
479
544
|
context 'first-class JSON' do
|
480
|
-
it 'parses objects and arrays' do
|
545
|
+
it 'parses objects, hashes, and arrays' do
|
481
546
|
subject.params do
|
482
547
|
requires :splines, type: JSON do
|
483
548
|
requires :x, type: Integer, values: [1, 2, 3]
|
@@ -499,17 +564,33 @@ describe Grape::Validations::CoerceValidator do
|
|
499
564
|
expect(last_response.status).to eq(200)
|
500
565
|
expect(last_response.body).to eq('woof')
|
501
566
|
|
567
|
+
get '/', splines: { x: 1, ints: [1, 2, 3], obj: { y: 'woof' } }
|
568
|
+
expect(last_response.status).to eq(200)
|
569
|
+
expect(last_response.body).to eq('woof')
|
570
|
+
|
502
571
|
get '/', splines: '[{"x":2,"ints":[]},{"x":3,"ints":[4],"obj":{"y":"quack"}}]'
|
503
572
|
expect(last_response.status).to eq(200)
|
504
573
|
expect(last_response.body).to eq('arrays work')
|
505
574
|
|
575
|
+
get '/', splines: [{ x: 2, ints: [] }, { x: 3, ints: [4], obj: { y: 'quack' } }]
|
576
|
+
expect(last_response.status).to eq(200)
|
577
|
+
expect(last_response.body).to eq('arrays work')
|
578
|
+
|
506
579
|
get '/', splines: '{"x":4,"ints":[2]}'
|
507
580
|
expect(last_response.status).to eq(400)
|
508
581
|
expect(last_response.body).to eq('splines[x] does not have a valid value')
|
509
582
|
|
583
|
+
get '/', splines: { x: 4, ints: [2] }
|
584
|
+
expect(last_response.status).to eq(400)
|
585
|
+
expect(last_response.body).to eq('splines[x] does not have a valid value')
|
586
|
+
|
510
587
|
get '/', splines: '[{"x":1,"ints":[]},{"x":4,"ints":[]}]'
|
511
588
|
expect(last_response.status).to eq(400)
|
512
589
|
expect(last_response.body).to eq('splines[x] does not have a valid value')
|
590
|
+
|
591
|
+
get '/', splines: [{ x: 1, ints: [] }, { x: 4, ints: [] }]
|
592
|
+
expect(last_response.status).to eq(400)
|
593
|
+
expect(last_response.body).to eq('splines[x] does not have a valid value')
|
513
594
|
end
|
514
595
|
|
515
596
|
it 'works when declared optional' do
|
@@ -660,7 +741,7 @@ describe Grape::Validations::CoerceValidator do
|
|
660
741
|
expect(last_response.status).to eq(200)
|
661
742
|
expect(last_response.body).to eq('"one way"')
|
662
743
|
|
663
|
-
get '/', a: %w
|
744
|
+
get '/', a: %w[the other]
|
664
745
|
expect(last_response.status).to eq(200)
|
665
746
|
expect(last_response.body).to eq('["the", "other"]')
|
666
747
|
|
@@ -678,7 +759,7 @@ describe Grape::Validations::CoerceValidator do
|
|
678
759
|
expect(last_response.status).to eq(200)
|
679
760
|
expect(last_response.body).to eq('[1, 2, 3]')
|
680
761
|
|
681
|
-
get '/', b: %w
|
762
|
+
get '/', b: %w[1 2 3]
|
682
763
|
expect(last_response.status).to eq(200)
|
683
764
|
expect(last_response.body).to eq('[1, 2, 3]')
|
684
765
|
|
@@ -700,7 +781,7 @@ describe Grape::Validations::CoerceValidator do
|
|
700
781
|
expect(last_response.status).to eq(200)
|
701
782
|
expect(last_response.body).to eq('"one"')
|
702
783
|
|
703
|
-
get '/', d: %w
|
784
|
+
get '/', d: %w[1 two]
|
704
785
|
expect(last_response.status).to eq(200)
|
705
786
|
expect(last_response.body).to eq('#<Set: {1, "two"}>')
|
706
787
|
end
|
@@ -731,7 +812,7 @@ describe Grape::Validations::CoerceValidator do
|
|
731
812
|
expect(last_response.status).to eq(200)
|
732
813
|
expect(last_response.body).to eq('"one way"')
|
733
814
|
|
734
|
-
get '/', a: %w
|
815
|
+
get '/', a: %w[the other]
|
735
816
|
expect(last_response.status).to eq(200)
|
736
817
|
expect(last_response.body).to eq('#<Hashie::Array ["the", "other"]>')
|
737
818
|
|
@@ -749,7 +830,7 @@ describe Grape::Validations::CoerceValidator do
|
|
749
830
|
expect(last_response.status).to eq(200)
|
750
831
|
expect(last_response.body).to eq('#<Hashie::Array [1, 2, 3]>')
|
751
832
|
|
752
|
-
get '/', b: %w
|
833
|
+
get '/', b: %w[1 2 3]
|
753
834
|
expect(last_response.status).to eq(200)
|
754
835
|
expect(last_response.body).to eq('#<Hashie::Array [1, 2, 3]>')
|
755
836
|
|
@@ -771,7 +852,7 @@ describe Grape::Validations::CoerceValidator do
|
|
771
852
|
expect(last_response.status).to eq(200)
|
772
853
|
expect(last_response.body).to eq('"one"')
|
773
854
|
|
774
|
-
get '/', d: %w
|
855
|
+
get '/', d: %w[1 two]
|
775
856
|
expect(last_response.status).to eq(200)
|
776
857
|
expect(last_response.body).to eq('#<Set: {1, "two"}>')
|
777
858
|
end
|
@@ -75,6 +75,21 @@ describe Grape::Validations::DefaultValidator do
|
|
75
75
|
get '/nested_optional_array' do
|
76
76
|
{ root: params[:root] }
|
77
77
|
end
|
78
|
+
|
79
|
+
params do
|
80
|
+
requires :root, type: Hash do
|
81
|
+
optional :some_things, type: Array do
|
82
|
+
requires :foo
|
83
|
+
optional :options, type: Array do
|
84
|
+
optional :name, type: String
|
85
|
+
optional :value, type: String
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
get '/another_nested_optional_array' do
|
91
|
+
{ root: params[:root] }
|
92
|
+
end
|
78
93
|
end
|
79
94
|
end
|
80
95
|
end
|
@@ -99,6 +114,31 @@ describe Grape::Validations::DefaultValidator do
|
|
99
114
|
expect(last_response.body).to eq({ root: params }.to_json)
|
100
115
|
end
|
101
116
|
|
117
|
+
it 'does not allows faulty optional arrays' do
|
118
|
+
params = { some_things:
|
119
|
+
[
|
120
|
+
{ foo: 'one', options: [{ name: 'wat', value: 'nope' }] },
|
121
|
+
{ foo: 'two', options: [{ name: 'wat' }] },
|
122
|
+
{ foo: 'three' }
|
123
|
+
] }
|
124
|
+
error = { error: 'root[some_things][1][options][0][value] is missing' }
|
125
|
+
get '/nested_optional_array', root: params
|
126
|
+
expect(last_response.status).to eq(400)
|
127
|
+
expect(last_response.body).to eq(error.to_json)
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'allows optional arrays with optional params' do
|
131
|
+
params = { some_things:
|
132
|
+
[
|
133
|
+
{ foo: 'one', options: [{ value: 'nope' }] },
|
134
|
+
{ foo: 'two', options: [{ name: 'wat' }] },
|
135
|
+
{ foo: 'three' }
|
136
|
+
] }
|
137
|
+
get '/another_nested_optional_array', root: params
|
138
|
+
expect(last_response.status).to eq(200)
|
139
|
+
expect(last_response.body).to eq({ root: params }.to_json)
|
140
|
+
end
|
141
|
+
|
102
142
|
it 'set default value for optional param' do
|
103
143
|
get('/')
|
104
144
|
expect(last_response.status).to eq(200)
|
@@ -11,7 +11,7 @@ describe Grape::Validations::ExactlyOneOfValidator do
|
|
11
11
|
def required?; end
|
12
12
|
end
|
13
13
|
end
|
14
|
-
let(:exactly_one_of_params) { [
|
14
|
+
let(:exactly_one_of_params) { %i[beer wine grapefruit] }
|
15
15
|
let(:validator) { described_class.new(exactly_one_of_params, {}, false, scope.new) }
|
16
16
|
|
17
17
|
context 'when all restricted params are present' do
|