Skip to content

Commit

Permalink
Fix #1636: optional nested array validation (#1724)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericproulx authored and dblock committed Dec 29, 2017
1 parent 63a03e5 commit 8395a41
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

* [#1710](https://github.com/ruby-grape/grape/pull/1710): Fix wrong transformation of empty Array in declared params - [@pablonahuelgomez](https://github.com/pablonahuelgomez).
* [#1722](https://github.com/ruby-grape/grape/pull/1722): Fix catch-all hiding multiple versions of an endpoint after the first definition - [@zherr](https://github.com/zherr).
* [#1724](https://github.com/ruby-grape/grape/pull/1724): Optional nested array validation - [@ericproulx](https://github.com/ericproulx).
* Your contribution here.

### 1.0.1 (9/8/2017)
Expand Down
7 changes: 3 additions & 4 deletions lib/grape/validations/params_scope.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ 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).blank? ||
any_element_blank?(parameters))
return false if @optional && (params(parameters).blank? || all_element_blank?(parameters))

return true if parent.nil?
parent.should_validate?(parameters)
Expand Down Expand Up @@ -441,8 +440,8 @@ 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?)
def all_element_blank?(parameters)
params(parameters).respond_to?(:all?) && params(parameters).all?(&:blank?)
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/grape/validations/validators/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def validate!(params)
attributes = AttributesIterator.new(self, @scope, params)
array_errors = []
attributes.each do |resource_params, attr_name|
next if !@scope.required? && resource_params.empty?
next unless @required || (resource_params.respond_to?(:key?) && resource_params.key?(attr_name))
next unless @scope.meets_dependency?(resource_params, params)

Expand Down
40 changes: 40 additions & 0 deletions spec/grape/validations/validators/default_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,21 @@ class API < Grape::API
get '/nested_optional_array' do
{ root: params[:root] }
end

params do
requires :root, type: Hash do
optional :some_things, type: Array do
requires :foo
optional :options, type: Array do
optional :name, type: String
optional :value, type: String
end
end
end
end
get '/another_nested_optional_array' do
{ root: params[:root] }
end
end
end
end
Expand All @@ -99,6 +114,31 @@ def app
expect(last_response.body).to eq({ root: params }.to_json)
end

it 'does not allows faulty optional arrays' do
params = { some_things:
[
{ foo: 'one', options: [{ name: 'wat', value: 'nope' }] },
{ foo: 'two', options: [{ name: 'wat' }] },
{ foo: 'three' }
] }
error = { error: 'root[some_things][1][options][0][value] is missing' }
get '/nested_optional_array', root: params
expect(last_response.status).to eq(400)
expect(last_response.body).to eq(error.to_json)
end

it 'allows optional arrays with optional params' do
params = { some_things:
[
{ foo: 'one', options: [{ value: 'nope' }] },
{ foo: 'two', options: [{ name: 'wat' }] },
{ foo: 'three' }
] }
get '/another_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 8395a41

Please sign in to comment.