spec/grape/validations/validators/values_spec.rb in grape-0.17.0 vs spec/grape/validations/validators/values_spec.rb in grape-0.18.0

- old
+ new

@@ -2,20 +2,31 @@ describe Grape::Validations::ValuesValidator do module ValidationsSpec class ValuesModel DEFAULT_VALUES = ['valid-type1', 'valid-type2', 'valid-type3'].freeze + DEFAULT_EXCEPTS = ['invalid-type1', 'invalid-type2', 'invalid-type3'].freeze class << self def values @values ||= [] [DEFAULT_VALUES + @values].flatten.uniq end def add_value(value) @values ||= [] @values << value end + + def excepts + @excepts ||= [] + [DEFAULT_EXCEPTS + @excepts].flatten.uniq + end + + def add_except(except) + @excepts ||= [] + @excepts << except + end end end module ValuesValidatorSpec class API < Grape::API @@ -33,10 +44,31 @@ optional :type, values: { value: -> { ValuesModel.values }, message: 'value does not include in values' }, default: 'valid-type2' end get '/lambda' do { type: params[:type] } end + + params do + requires :type, values: { except: ValuesModel.excepts, except_message: 'value is on exclusions list', message: 'default exclude message' } + end + get '/exclude/exclude_message' do + { type: params[:type] } + end + + params do + requires :type, values: { except: -> { ValuesModel.excepts }, except_message: 'value is on exclusions list' } + end + get '/exclude/lambda/exclude_message' do + { type: params[:type] } + end + + params do + requires :type, values: { except: ValuesModel.excepts, message: 'default exclude message' } + end + get '/exclude/fallback_message' do + { type: params[:type] } + end end params do requires :type, values: ValuesModel.values end @@ -97,10 +129,38 @@ optional :optional, type: Array do requires :type, values: %w(a b) end end get '/optional_with_required_values' + + params do + requires :type, values: { except: ValuesModel.excepts } + end + get '/except/exclusive' do + { type: params[:type] } + end + + params do + requires :type, values: { except: -> { ValuesModel.excepts } } + end + get '/except/exclusive/lambda' do + { type: params[:type] } + end + + params do + requires :type, type: Integer, values: { except: -> { [3, 4, 5] } } + end + get '/except/exclusive/lambda/coercion' do + { type: params[:type] } + end + + params do + requires :type, type: Integer, values: { value: 1..5, except: [3] } + end + get '/mixed/value/except' do + { type: params[:type] } + end end end end def app @@ -133,10 +193,34 @@ expect(last_response.status).to eq 400 expect(last_response.body).to eq({ error: 'type value does not include in values' }.to_json) end end + context 'with a custom exclude validation message' do + it 'does not allow an invalid value for a parameter' do + get('/custom_message/exclude/exclude_message', type: 'invalid-type1') + expect(last_response.status).to eq 400 + expect(last_response.body).to eq({ error: 'type value is on exclusions list' }.to_json) + end + end + + context 'with a custom exclude validation message' do + it 'does not allow an invalid value for a parameter' do + get('/custom_message/exclude/lambda/exclude_message', type: 'invalid-type1') + expect(last_response.status).to eq 400 + expect(last_response.body).to eq({ error: 'type value is on exclusions list' }.to_json) + end + end + + context 'exclude with a standard custom validation message' do + it 'does not allow an invalid value for a parameter' do + get('/custom_message/exclude/fallback_message', type: 'invalid-type1') + expect(last_response.status).to eq 400 + expect(last_response.body).to eq({ error: 'type default exclude message' }.to_json) + end + end + it 'allows a valid value for a parameter' do get('/', type: 'valid-type1') expect(last_response.status).to eq 200 expect(last_response.body).to eq({ type: 'valid-type1' }.to_json) end @@ -317,8 +401,70 @@ it 'rejects an array of values if any of them are outside the range' do get('/values', values: [8.6, 75, 3, 0.9]) expect(last_response.status).to eq 400 expect(last_response.body).to eq('values does not have a valid value') + end + end + + context 'exclusive excepts' do + it 'allows any other value outside excepts' do + get '/except/exclusive', type: 'value' + expect(last_response.status).to eq 200 + expect(last_response.body).to eq({ type: 'value' }.to_json) + end + + it 'rejects values that matches except' do + get '/except/exclusive', type: 'invalid-type1' + expect(last_response.status).to eq 400 + expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json) + end + end + + context 'exclusive excepts with lambda' do + it 'allows any other value outside excepts' do + get '/except/exclusive/lambda', type: 'value' + expect(last_response.status).to eq 200 + expect(last_response.body).to eq({ type: 'value' }.to_json) + end + + it 'rejects values that matches except' do + get '/except/exclusive/lambda', type: 'invalid-type1' + expect(last_response.status).to eq 400 + expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json) + end + end + + context 'exclusive excepts with lambda and coercion' do + it 'allows any other value outside excepts' do + get '/except/exclusive/lambda/coercion', type: '10010000' + expect(last_response.status).to eq 200 + expect(last_response.body).to eq({ type: 10_010_000 }.to_json) + end + + it 'rejects values that matches except' do + get '/except/exclusive/lambda/coercion', type: '3' + expect(last_response.status).to eq 400 + expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json) + end + end + + context 'with mixed values and excepts' do + it 'allows value, but not in except' do + get '/mixed/value/except', type: 2 + expect(last_response.status).to eq 200 + expect(last_response.body).to eq({ type: 2 }.to_json) + end + + it 'rejects except' do + get '/mixed/value/except', type: 3 + expect(last_response.status).to eq 400 + expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json) + end + + it 'rejects outside except and outside value' do + get '/mixed/value/except', type: 10 + expect(last_response.status).to eq 400 + expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json) end end end