grape
grape copied to clipboard
Error when validating array items with different conditionally required properties
Hello,
If we define different properties required for array items by given condition then validation fails even if correct request is sent.
Please check the example below:
it 'test to demonstrate the validation issue' do
subject.params do
requires :a, type: String, allow_blank: false, values: %w[x y z]
given a: ->(val) { val == 'z' } do
requires :inner3, type: Array, allow_blank: false do
requires :bar, type: String, allow_blank: false
given bar: ->(val) { val == 'b' } do
requires :baz, type: Array do
requires :new_category, type: String
end
end
given bar: ->(val) { val == 'c' } do
requires :baz, type: Array do
requires :baz_category, type: String
end
end
end
end
end
subject.post('/nested-dependency') { declared(params).to_json }
test = {
a: 'z',
inner3: [
{ bar: 'b', baz: [{ new_category: 'nope' }] },
{ bar: 'c', baz: [{ baz_category: 'nope' }] }
]
}
post '/nested-dependency', **test
expect(last_response.status).to eq(200)
end
Expected behavior: 200 OK
Actual behavior: 400 Bad request, "inner3[1][baz][0][new_category] is missing, inner3[1][baz][0][baz_category] is missing"
Thank you.
Check whether this is still the behavior on HEAD and turn it into a (failing) PR/spec?
Note that your post may need a correct content-type, transforming what you post to a string, this may be a side-effect of form encoding.
I checked it on the latest commit and just have rechecked with passing Content-Type = application/json.
Validation fails.
Here is the PR with failing spec: https://github.com/ruby-grape/grape/pull/2474
params do
requires :items, type: Array, allow_blank: false do
requires :item_type, type: String, allow_blank: false
given item_type: ->(val) { val == 'type_a' } do
requires :inner_items, type: Array do
requires :prop_a, type: String
end
end
given item_type: ->(val) { val == 'type_b' } do
requires :inner_items, type: Array do
requires :prop_b, type: String
end
end
end
end
Looks like condition given item_type: ->(val) { val == 'type_a' } is ignored when validating nested array properties.
They are always validated, but it should happen when item_type meets dependency.
Looks like condition
given item_type: ->(val) { val == 'type_a' }is ignored when validating nested array properties. They are always validated, but it should happen whenitem_typemeets dependency.
And it works for nested hashes? Want to try to fix it?
No, it also doesn't work for nested hashes. Sure, will try to fix it.