Skip to content

Commit

Permalink
Fix parameter validation with an empty optional nested Array. Closes #…
Browse files Browse the repository at this point in the history
  • Loading branch information
ipkes authored and dblock committed May 6, 2016
1 parent a711cab commit 9a08358
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

* [#1365](https://github.com/ruby-grape/grape/pull/1365): Fix finding exception handler in error middleware - [@ktimothy](https://github.com/ktimothy).
* [#1380](https://github.com/ruby-grape/grape/pull/1380): Fix `allow_blank: false` for `Time` attributes with valid values causes `NoMethodError` - [@ipkes](https://github.com/ipkes).
* [#1384](https://github.com/ruby-grape/grape/pull/1384): Fix parameter validation with an empty optional nested `Array` - [@ipkes](https://github.com/ipkes).

0.16.2 (4/12/2016)
==================
Expand Down
9 changes: 8 additions & 1 deletion lib/grape/validations/params_scope.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ def initialize(opts, &block)
# @return [Boolean] whether or not this entire scope needs to be
# validated
def should_validate?(parameters)
return false if @optional && params(parameters).respond_to?(:all?) && params(parameters).all?(&:blank?)
return false if @optional && (params(parameters).blank? ||
any_element_blank?(parameters))

@dependent_on.each do |dependency|
return false if params(parameters).try(:[], dependency).blank?
end if @dependent_on

return true if parent.nil?
parent.should_validate?(parameters)
end
Expand Down Expand Up @@ -357,6 +360,10 @@ def extract_message_option(attrs)
def options_key?(type, key, validations)
validations[type].respond_to?(:key?) && validations[type].key?(key) && !validations[type][key].nil?
end

def any_element_blank?(parameters)
params(parameters).respond_to?(:any?) && params(parameters).any?(&:blank?)
end
end
end
end
44 changes: 44 additions & 0 deletions spec/grape/validations/validators/default_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,32 @@ class API < Grape::API
get '/array' do
{ array: params[:array] }
end

params do
requires :thing1
optional :more_things, type: Array do
requires :nested_thing
requires :other_thing, default: 1
end
end
get '/optional_array' do
{ thing1: params[:thing1] }
end

params do
requires :root, type: Hash do
optional :some_things, type: Array do
requires :foo
optional :options, type: Array do
requires :name, type: String
requires :value, type: String
end
end
end
end
get '/nested_optional_array' do
{ root: params[:root] }
end
end
end
end
Expand All @@ -57,6 +83,24 @@ def app
ValidationsSpec::DefaultValidatorSpec::API
end

it 'lets you leave required values nested inside an optional blank' do
get '/optional_array', thing1: 'stuff'
expect(last_response.status).to eq(200)
expect(last_response.body).to eq({ thing1: 'stuff' }.to_json)
end

it 'allows optional arrays to be omitted' do
params = { some_things:
[{ foo: 'one', options: [{ name: 'wat', value: 'nope' }] },
{ foo: 'two' },
{ foo: 'three', options: [{ name: 'wooop', value: 'yap' }] }
]
}
get '/nested_optional_array', root: params
expect(last_response.status).to eq(200)
expect(last_response.body).to eq({ root: params }.to_json)
end

it 'set default value for optional param' do
get('/')
expect(last_response.status).to eq(200)
Expand Down

0 comments on commit 9a08358

Please sign in to comment.