spec/grape/api/custom_validations_spec.rb in grape-0.14.0 vs spec/grape/api/custom_validations_spec.rb in grape-0.15.0
- old
+ new
@@ -1,36 +1,35 @@
require 'spec_helper'
describe Grape::Validations do
- before do
- module CustomValidationsSpec
- class DefaultLength < Grape::Validations::Base
- def validate_param!(attr_name, params)
- @option = params[:max].to_i if params.key?(:max)
- return if params[attr_name].length <= @option
- fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: "must be at the most #{@option} characters long"
+ context 'using a custom length validator' do
+ before do
+ module CustomValidationsSpec
+ class DefaultLength < Grape::Validations::Base
+ def validate_param!(attr_name, params)
+ @option = params[:max].to_i if params.key?(:max)
+ return if params[attr_name].length <= @option
+ fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: "must be at the most #{@option} characters long"
+ end
end
end
end
- end
-
- subject do
- Class.new(Grape::API) do
- params do
- requires :text, default_length: 140
+ subject do
+ Class.new(Grape::API) do
+ params do
+ requires :text, default_length: 140
+ end
+ get do
+ 'bacon'
+ end
end
- get do
- 'bacon'
- end
end
- end
- def app
- subject
- end
+ def app
+ subject
+ end
- context 'using a custom length validator' do
it 'under 140 characters' do
get '/', text: 'abc'
expect(last_response.status).to eq 200
expect(last_response.body).to eq 'bacon'
end
@@ -41,8 +40,144 @@
end
it 'specified in the query string' do
get '/', text: 'a' * 141, max: 141
expect(last_response.status).to eq 200
expect(last_response.body).to eq 'bacon'
+ end
+ end
+
+ context 'using a custom body-only validator' do
+ before do
+ module CustomValidationsSpec
+ class InBody < Grape::Validations::PresenceValidator
+ def validate(request)
+ validate!(request.env['api.request.body'])
+ end
+ end
+ end
+ end
+ subject do
+ Class.new(Grape::API) do
+ params do
+ requires :text, in_body: true
+ end
+ get do
+ 'bacon'
+ end
+ end
+ end
+
+ def app
+ subject
+ end
+
+ it 'allows field in body' do
+ get '/', text: 'abc'
+ expect(last_response.status).to eq 200
+ expect(last_response.body).to eq 'bacon'
+ end
+ it 'ignores field in query' do
+ get '/', nil, text: 'abc'
+ expect(last_response.status).to eq 400
+ expect(last_response.body).to eq 'text is missing'
+ end
+ end
+
+ context 'using a custom validator with message_key' do
+ before do
+ module CustomValidationsSpec
+ class WithMessageKey < Grape::Validations::PresenceValidator
+ def validate_param!(attr_name, _params)
+ fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: :presence
+ end
+ end
+ end
+ end
+ subject do
+ Class.new(Grape::API) do
+ params do
+ requires :text, with_message_key: true
+ end
+ get do
+ 'bacon'
+ end
+ end
+ end
+
+ def app
+ subject
+ end
+
+ it 'fails with message' do
+ get '/', text: 'foobar'
+ expect(last_response.status).to eq 400
+ expect(last_response.body).to eq 'text is missing'
+ end
+ end
+
+ context 'using a custom request/param validator' do
+ before do
+ module CustomValidationsSpec
+ class Admin < Grape::Validations::Base
+ def validate(request)
+ # return if the param we are checking was not in request
+ # @attrs is a list containing the attribute we are currently validating
+ return unless request.params.key? @attrs.first
+ # check if admin flag is set to true
+ return unless @option
+ # check if user is admin or not
+ # as an example get a token from request and check if it's admin or not
+ fail Grape::Exceptions::Validation, params: @attrs, message: 'Can not set Admin only field.' unless request.headers['X-Access-Token'] == 'admin'
+ end
+ end
+ end
+ end
+ subject do
+ Class.new(Grape::API) do
+ params do
+ optional :admin_field, type: String, admin: true
+ optional :non_admin_field, type: String
+ optional :admin_false_field, type: String, admin: false
+ end
+ get do
+ 'bacon'
+ end
+ end
+ end
+
+ def app
+ subject
+ end
+
+ it 'fail when non-admin user sets an admin field' do
+ get '/', admin_field: 'tester', non_admin_field: 'toaster'
+ expect(last_response.status).to eq 400
+ expect(last_response.body).to include 'Can not set Admin only field.'
+ end
+
+ it 'does not fail when we send non-admin fields only' do
+ get '/', non_admin_field: 'toaster'
+ expect(last_response.status).to eq 200
+ expect(last_response.body).to eq 'bacon'
+ end
+
+ it 'does not fail when we send non-admin and admin=false fields only' do
+ get '/', non_admin_field: 'toaster', admin_false_field: 'test'
+ expect(last_response.status).to eq 200
+ expect(last_response.body).to eq 'bacon'
+ end
+
+ it 'does not fail when we send admin fields and we are admin' do
+ header 'X-Access-Token', 'admin'
+ get '/', admin_field: 'tester', non_admin_field: 'toaster', admin_false_field: 'test'
+ expect(last_response.status).to eq 200
+ expect(last_response.body).to eq 'bacon'
+ end
+
+ it 'fails when we send admin fields and we are not admin' do
+ header 'X-Access-Token', 'user'
+ get '/', admin_field: 'tester', non_admin_field: 'toaster', admin_false_field: 'test'
+ expect(last_response.status).to eq 400
+ expect(last_response.body).to include 'Can not set Admin only field.'
end
end
end