spec/grape/validations_spec.rb in grape-0.13.0 vs spec/grape/validations_spec.rb in grape-0.14.0
- old
+ new
@@ -316,10 +316,39 @@
end
expect(subject.route_setting(:declared_params)).to eq([items: [:key]])
end
end
+ context 'hash with a required param with validation' do
+ before do
+ subject.params do
+ requires :items, type: Hash do
+ requires :key, type: String, values: %w(a b)
+ end
+ end
+ subject.get '/required' do
+ 'required works'
+ end
+ end
+
+ it 'errors when param is not a Hash' do
+ get '/required', items: 'not a hash'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items is invalid, items[key] is missing, items[key] is invalid')
+
+ get '/required', items: [{ key: 'hash in array' }]
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items is invalid, items[0][key] does not have a valid value')
+ end
+
+ it 'works when all params match' do
+ get '/required', items: { key: 'a' }
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('required works')
+ end
+ end
+
context 'group' do
before do
subject.params do
group :items, type: Array do
requires :key
@@ -372,14 +401,15 @@
expect(last_response.status).to eq(400)
end
end
context 'custom validator for a Hash' do
- module DateRangeValidations
- class DateRangeValidator < Grape::Validations::Base
- def validate_param!(attr_name, params)
- unless params[attr_name][:from] <= params[attr_name][:to]
+ module ValuesSpec
+ module DateRangeValidations
+ class DateRangeValidator < Grape::Validations::Base
+ def validate_param!(attr_name, params)
+ return if params[attr_name][:from] <= params[attr_name][:to]
fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: "'from' must be lower or equal to 'to'"
end
end
end
end
@@ -460,22 +490,22 @@
{ name: 'Job', parents: [{ name: 'Joy' }] }
]
# NOTE: with body parameters in json or XML or similar this
# should actually fail with: children[parents][name] is missing.
expect(last_response.status).to eq(400)
- expect(last_response.body).to eq('children[parents] is missing')
+ expect(last_response.body).to eq('children[0][parents] is missing')
end
it 'safely handles empty arrays and blank parameters' do
# NOTE: with body parameters in json or XML or similar this
# should actually return 200, since an empty array is valid.
get '/within_array', children: []
expect(last_response.status).to eq(400)
expect(last_response.body).to eq('children is missing')
get '/within_array', children: [name: 'Jay']
expect(last_response.status).to eq(400)
- expect(last_response.body).to eq('children[parents] is missing')
+ expect(last_response.body).to eq('children[0][parents] is missing')
end
it 'errors when param is not an Array' do
# NOTE: would be nicer if these just returned 'children is invalid'
get '/within_array', children: 'hello'
@@ -486,11 +516,11 @@
expect(last_response.status).to eq(400)
expect(last_response.body).to eq('children is invalid, children[parents] is missing')
get '/within_array', children: [name: 'Jay', parents: { name: 'Fred' }]
expect(last_response.status).to eq(400)
- expect(last_response.body).to eq('children[parents] is invalid')
+ expect(last_response.body).to eq('children[0][parents] is invalid')
end
end
context 'with block param' do
before do
@@ -612,19 +642,19 @@
put_with_json '/within_array', children: [
{ name: 'Jim', parents: [{}] },
{ name: 'Job', parents: [{ name: 'Joy' }] }
]
expect(last_response.status).to eq(400)
- expect(last_response.body).to eq('children[parents][name] is missing')
+ expect(last_response.body).to eq('children[0][parents][0][name] is missing')
end
it 'safely handles empty arrays and blank parameters' do
put_with_json '/within_array', children: []
expect(last_response.status).to eq(200)
put_with_json '/within_array', children: [name: 'Jay']
expect(last_response.status).to eq(400)
- expect(last_response.body).to eq('children[parents] is missing')
+ expect(last_response.body).to eq('children[0][parents] is missing')
end
end
context 'optional with an Array block' do
before do
@@ -651,11 +681,11 @@
end
it 'errors when group is present, but required param is not' do
get '/optional_group', items: [{ not_key: 'foo' }]
expect(last_response.status).to eq(400)
- expect(last_response.body).to eq('items[key] is missing')
+ expect(last_response.body).to eq('items[0][key] is missing')
end
it "errors when param is present but isn't an Array" do
get '/optional_group', items: 'hello'
expect(last_response.status).to eq(400)
@@ -695,39 +725,39 @@
end
it 'does internal validations if the outer group is present' do
get '/nested_optional_group', items: [{ key: 'foo' }]
expect(last_response.status).to eq(400)
- expect(last_response.body).to eq('items[required_subitems] is missing')
+ expect(last_response.body).to eq('items[0][required_subitems] is missing')
get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }] }]
expect(last_response.status).to eq(200)
expect(last_response.body).to eq('nested optional group works')
end
it 'handles deep nesting' do
get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }], optional_subitems: [{ not_value: 'baz' }] }]
expect(last_response.status).to eq(400)
- expect(last_response.body).to eq('items[optional_subitems][value] is missing')
+ expect(last_response.body).to eq('items[0][optional_subitems][0][value] is missing')
get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }], optional_subitems: [{ value: 'baz' }] }]
expect(last_response.status).to eq(200)
expect(last_response.body).to eq('nested optional group works')
end
it 'handles validation within arrays' do
get '/nested_optional_group', items: [{ key: 'foo' }]
expect(last_response.status).to eq(400)
- expect(last_response.body).to eq('items[required_subitems] is missing')
+ expect(last_response.body).to eq('items[0][required_subitems] is missing')
get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }] }]
expect(last_response.status).to eq(200)
expect(last_response.body).to eq('nested optional group works')
get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }], optional_subitems: [{ not_value: 'baz' }] }]
expect(last_response.status).to eq(400)
- expect(last_response.body).to eq('items[optional_subitems][value] is missing')
+ expect(last_response.body).to eq('items[0][optional_subitems][0][value] is missing')
end
it 'adds to declared parameters' do
subject.params do
optional :items, type: Array do
@@ -761,13 +791,12 @@
context 'custom validation' do
module CustomValidations
class Customvalidator < Grape::Validations::Base
def validate_param!(attr_name, params)
- unless params[attr_name] == 'im custom'
- fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: 'is not custom!'
- end
+ return if params[attr_name] == 'im custom'
+ fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: 'is not custom!'
end
end
end
context 'when using optional with a custom validator' do
@@ -910,13 +939,12 @@
context 'when using options on param' do
module CustomValidations
class CustomvalidatorWithOptions < Grape::Validations::Base
def validate_param!(attr_name, params)
- unless params[attr_name] == @option[:text]
- fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: @option[:error_message]
- end
+ return if params[attr_name] == @option[:text]
+ fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: @option[:error_message]
end
end
end
before do
@@ -948,28 +976,29 @@
end
end
end
it 'in helper module which kind of Grape::DSL::Helpers::BaseHelper' do
- module SharedParams
+ shared_params = Module.new do
extend Grape::DSL::Helpers::BaseHelper
params :pagination do
end
end
- subject.helpers SharedParams
+ subject.helpers shared_params
end
end
context 'can be included in usual params' do
before do
- module SharedParams
+ shared_params = Module.new do
extend Grape::DSL::Helpers::BaseHelper
params :period do
optional :start_date
optional :end_date
end
end
- subject.helpers SharedParams
+
+ subject.helpers shared_params
subject.helpers do
params :pagination do
optional :page, type: Integer
optional :per_page, type: Integer