Skip to content

Commit ac27525

Browse files
author
Dhruv Paranjape
committed
restrict validator.
1 parent dea3e2e commit ac27525

File tree

3 files changed

+82
-8
lines changed

3 files changed

+82
-8
lines changed

README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1713,15 +1713,14 @@ end
17131713

17141714
#### `length`
17151715

1716-
Parameters can be restricted from having a specific length or size with the `:length` option.
1716+
Parameters of type `String` or `Array` can be restricted to have a specific length or size with the `:length` option.
17171717

1718-
the validator accepts `:min` or `:max` or both options to validate that they parameter is within
1719-
the given limits.
1718+
The validator accepts `:min` or `:max` or both options to validate that the value of the parameter is within the given limits.
17201719

17211720
```ruby
17221721
params do
1723-
requires :str, length: { min: 3 }
1724-
requires :list, length: { min: 3, max: 5}
1722+
requires :str, type: String, length: { min: 3 }
1723+
requires :list, type: [Integer], length: { min: 3, max: 5 }
17251724
end
17261725
```
17271726

lib/grape/validations/validators/length_validator.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@ def initialize(attrs, options, required, scope, **opts)
1010

1111
super
1212

13+
raise ArgumentError, 'min must be an integer greater than or equal to zero' if !@min.nil? && (!@min.is_a?(Integer) || @min.negative?)
14+
raise ArgumentError, 'max must be an integer greater than or equal to zero' if !@max.nil? && (!@max.is_a?(Integer) || @max.negative?)
1315
raise ArgumentError, "min #{@min} cannot be greater than max #{@max}" if !@min.nil? && !@max.nil? && @min > @max
1416
end
1517

1618
def validate_param!(attr_name, params)
1719
param = params[attr_name]
1820
param = param.compact if param.respond_to?(:compact)
1921

20-
return unless param.respond_to?(:length)
22+
raise ArgumentError, "parameter #{param} has an unsupported type. Only strings & arrays are supported" unless params.is_a?(String) || param.is_a?(Array)
23+
2124
return unless (!@min.nil? && param.length < @min) || (!@max.nil? && param.length > @max)
2225

2326
raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: build_message)

spec/grape/validations/validators/length_spec.rb

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,36 @@
2727
post 'type_is_not_array' do
2828
end
2929

30+
params do
31+
requires :list, type: Hash, length: { max: 3 }
32+
end
33+
post 'type_supports_length' do
34+
end
35+
36+
params do
37+
requires :list, type: [Integer], length: { min: -3 }
38+
end
39+
post 'negative_min' do
40+
end
41+
42+
params do
43+
requires :list, type: [Integer], length: { max: -3 }
44+
end
45+
post 'negative_max' do
46+
end
47+
48+
params do
49+
requires :list, type: [Integer], length: { min: 2.5 }
50+
end
51+
post 'float_min' do
52+
end
53+
54+
params do
55+
requires :list, type: [Integer], length: { max: 2.5 }
56+
end
57+
post 'float_max' do
58+
end
59+
3060
params do
3161
requires :list, type: [Integer], length: { min: 15, max: 3 }
3262
end
@@ -160,9 +190,51 @@
160190
describe '/type_is_not_array' do
161191
context 'is no op' do
162192
it do
193+
expect do
163194
post 'type_is_not_array', list: 12
164-
expect(last_response.status).to eq(201)
165-
expect(last_response.body).to eq('')
195+
end.to raise_error(ArgumentError, 'parameter 12 has an unsupported type. Only strings & arrays are supported')
196+
end
197+
end
198+
end
199+
200+
describe '/type_supports_length' do
201+
context 'raises an error' do
202+
it do
203+
expect do
204+
post 'type_supports_length', list: { key: 'value' }
205+
end.to raise_error(ArgumentError, 'parameter {"key"=>"value"} has an unsupported type. Only strings & arrays are supported')
206+
end
207+
end
208+
end
209+
210+
describe '/negative_min' do
211+
context 'when min is negative' do
212+
it do
213+
expect { post 'negative_min', list: [12] }.to raise_error(ArgumentError, 'min must be an integer greater than or equal to zero')
214+
end
215+
end
216+
end
217+
218+
describe '/negative_max' do
219+
context 'it raises an error' do
220+
it do
221+
expect { post 'negative_max', list: [12] }.to raise_error(ArgumentError, 'max must be an integer greater than or equal to zero')
222+
end
223+
end
224+
end
225+
226+
describe '/float_min' do
227+
context 'when min is not an integer' do
228+
it do
229+
expect { post 'float_min', list: [12] }.to raise_error(ArgumentError, 'min must be an integer greater than or equal to zero')
230+
end
231+
end
232+
end
233+
234+
describe '/float_max' do
235+
context 'when max is not an integer' do
236+
it do
237+
expect { post 'float_max', list: [12] }.to raise_error(ArgumentError, 'max must be an integer greater than or equal to zero')
166238
end
167239
end
168240
end

0 commit comments

Comments
 (0)