<commit_before>require 'spec_helper'

describe Grape::Validations do
  subject { Class.new(Grape::API) }
  def app; subject end

  describe 'params' do
    context 'optional' do
      it 'validates when params is present' do
        subject.params { optional :a_number, :regexp => /^[0-9]+$/ }
        subject.get '/optional' do 'optional works!'; end

        get '/optional', { :a_number => 'string' }
        last_response.status.should == 400
        last_response.body.should == 'invalid parameter: a_number'

        get '/optional', { :a_number => 45 }
        last_response.status.should == 200
        last_response.body.should == 'optional works!'
      end

      it "doesn't validate when param not present" do
        subject.params { optional :a_number, :regexp => /^[0-9]+$/ }
        subject.get '/optional' do 'optional works!'; end

        get '/optional'
        last_response.status.should == 200
        last_response.body.should == 'optional works!'
      end

      it 'adds to declared parameters' do
        subject.params { optional :some_param }
        subject.settings[:declared_params].should == [:some_param]
      end
    end

    context 'required' do
      before do
        subject.params { requires :key }
        subject.get '/required' do 'required works'; end
      end

      it 'errors when param not present' do
        get '/required'
        last_response.status.should == 400
        last_response.body.should == 'missing parameter: key'
      end

      it "doesn't throw a missing param when param is present" do
        get '/required', { :key => 'cool' }
        last_response.status.should == 200
        last_response.body.should == 'required works'
      end

      it 'adds to declared parameters' do
        subject.params { requires :some_param }
        subject.settings[:declared_params].should == [:some_param]
      end
    end

    context 'group' do
      before do
        subject.params {
          group :items do
            requires :key
          end
        }
        subject.get '/required' do 'required works'; end
      end

      it 'errors when param not present' do
        get '/required'
        last_response.status.should == 400
        last_response.body.should == 'missing parameter: items[key]'
      end

      it "doesn't throw a missing param when param is present" do
        get '/required', { :items => [:key => 'hello', :key => 'world'] }
        last_response.status.should == 200
        last_response.body.should == 'required works'
      end

      it 'adds to declared parameters' do
        subject.params {
          group :items do
            requires :key
          end
        }
        subject.settings[:declared_params].should == [:items => [:key]]
      end
    end

    context 'custom validation' do
      module CustomValidations
        class Customvalidator < Grape::Validations::Validator
          def validate_param!(attr_name, params)
            unless params[attr_name] == 'im custom'
              throw :error, :status => 400, :message => "#{attr_name}: is not custom!"
            end
          end
        end
      end

      context 'when using optional with a custom validator' do
        before do
          subject.params { optional :custom, :customvalidator => true }
          subject.get '/optional_custom' do 'optional with custom works!'; end
        end

        it 'validates when param is present' do
          get '/optional_custom', { :custom => 'im custom' }
          last_response.status.should == 200
          last_response.body.should == 'optional with custom works!'
<commit_msg>specs for issue #319 (optional groups)<commit_after>require 'spec_helper'

describe Grape::Validations do
  subject { Class.new(Grape::API) }
  def app; subject end

  describe 'params' do
    context 'optional' do
      it 'validates when params is present' do
        subject.params { optional :a_number, :regexp => /^[0-9]+$/ }
        subject.get '/optional' do 'optional works!'; end

        get '/optional', { :a_number => 'string' }
        last_response.status.should == 400
        last_response.body.should == 'invalid parameter: a_number'

        get '/optional', { :a_number => 45 }
        last_response.status.should == 200
        last_response.body.should == 'optional works!'
      end

      it "doesn't validate when param not present" do
        subject.params { optional :a_number, :regexp => /^[0-9]+$/ }
        subject.get '/optional' do 'optional works!'; end

        get '/optional'
        last_response.status.should == 200
        last_response.body.should == 'optional works!'
      end

      it 'adds to declared parameters' do
        subject.params { optional :some_param }
        subject.settings[:declared_params].should == [:some_param]
      end
    end

    context 'required' do
      before do
        subject.params { requires :key }
        subject.get '/required' do 'required works'; end
      end

      it 'errors when param not present' do
        get '/required'
        last_response.status.should == 400
        last_response.body.should == 'missing parameter: key'
      end

      it "doesn't throw a missing param when param is present" do
        get '/required', { :key => 'cool' }
        last_response.status.should == 200
        last_response.body.should == 'required works'
      end

      it 'adds to declared parameters' do
        subject.params { requires :some_param }
        subject.settings[:declared_params].should == [:some_param]
      end
    end

    context 'group' do
      before do
        subject.params {
          group :items do
            requires :key
          end
        }
        subject.get '/required' do 'required works'; end
      end

      it 'errors when param not present' do
        get '/required'
        last_response.status.should == 400
        last_response.body.should == 'missing parameter: items[key]'
      end

      it "doesn't throw a missing param when param is present" do
        get '/required', { :items => [:key => 'hello', :key => 'world'] }
        last_response.status.should == 200
        last_response.body.should == 'required works'
      end

      it 'adds to declared parameters' do
        subject.params {
          group :items do
            requires :key
          end
        }
        subject.settings[:declared_params].should == [:items => [:key]]
      end
    end

    context 'optional group' do
      before do
        subject.params {
          group(:items, required: false) do
            requires :key
          end
        }
        subject.get '/optional_group' do 'optional group works'; end
      end

      it "doesn't throw a missing param when the group isn't present" do
        get '/optional_group'
        last_response.status.should == 200
        last_response.body.should == 'optional group works'
      end

      it "doesn't throw a missing param when both group and param are given" do
        get '/optional_group', { :items => {:key => 'foo'} }
        last_response.status.should == 200
        last_response.body.should == 'optional group works'
      end

      it "errors when group is present, but required param is not" do
        get '/optional_group', { :items => {:NOT_key => 'foo'} }
        last_response.status.should == 400
        last_response.body.should == 'missing parameter: items[key]'
      end

      it 'adds to declared parameters' do
        subject.params {
          group(:items, required: false) do
            requires :key
          end
        }
        subject.settings[:declared_params].should == [:items => [:key]]
      end
    end

    context 'nested optional groups' do
      before do
        subject.params {
          group(:items, required: false) do
            requires :key
            group(:optional_subitems, required: false) { requires :value }
            group(:required_subitems) { requires :value }
          end
        }
        subject.get('/nested_optional_group') { 'nested optional group works' }
      end

      it 'does no internal validations if the outer group is blank' do
        get '/nested_optional_group'
        last_response.status.should == 200
        last_response.body.should == 'nested optional group works'
      end

      it 'does internal validations if the outer group is present' do
        get '/nested_optional_group', { :items => {:key => 'foo' }}
        last_response.status.should == 400
        last_response.body.should == 'missing parameter: items[required_subitems][value]'

        get '/nested_optional_group', { :items => { :key => 'foo', :required_subitems => {:value => 'bar'}}}
        last_response.status.should == 200
        last_response.body.should == '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'}}}
        last_response.status.should == 400
        last_response.body.should == 'missing parameter: items[optional_subitems][value]'

        get '/nested_optional_group', { :items => { :key => 'foo', :required_subitems => {:value => 'bar'}, :optional_subitems => {:value => 'baz'}}}
        last_response.status.should == 200
        last_response.body.should == 'nested optional group works'
      end

      it 'adds to declared parameters' do
        subject.params {
          group(:items, required: false) do
            requires :key
            group(:optional_subitems, required: false) { requires :value }
            group(:required_subitems) { requires :value }
          end
        }
        subject.settings[:declared_params].should == [:items => [:key, {:optional_subitems => [:value]}, {:required_subitems => [:value]}]]
      end
    end

    context 'custom validation' do
      module CustomValidations
        class Customvalidator < Grape::Validations::Validator
          def validate_param!(attr_name, params)
            unless params[attr_name] == 'im custom'
              throw :error, :status => 400, :message => "#{attr_name}: is not custom!"
            end
          end
        end
      end

      context 'when using optional with a custom validator' do
        before do
          subject.params { optional :custom, :customvalidator => true }
          subject.get '/optional_custom' do 'optional with custom works!'; end
        end

        it 'validates when param is present' do
          get '/optional_custom', { :custom => 'im custom' }
          last_response.status.should == 200
          last_response.body.should == 'optional with custom works!'

{'fraction_non_alphanumeric': 0.10872621614021932, 'fraction_numerical': 0.008716843190552067, 'mean_word_length': 2.210953957267529, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6621571', 'n_tokens_mistral': 2993, 'n_tokens_neox': 2812, 'n_words': 898}