aboutsummaryrefslogblamecommitdiffstats
path: root/actionpack/test/controller/params_wrapper_test.rb
blob: d74e24437a291914f13629f951694cb991e95294 (plain) (tree)
1
2
3
4
5
6
7
                       


                                  

                                          
                                                                








                                                                      
                                                    

                               
                                                






                                                                              
       
     
 










                            


                       



                                         

                                   


                                                                                                                                                                                     


       
                                       
                                   


                                                                                          






                                             


                                                                                            






                                            


                                                                                            


       
                                 
                                   
                                                           
 


                                                                                                                  


       
                                 
                                   
                                                        
 


                                                                                                                  


       
                                                       
                                   
                                                                    
 


                                                                                                                    




                                   


                                                                              


       


                                           


                                                                              


       



                                                     


                                                                                                                                          




                                       


                                                                                                                                                                    




                                       


                                                                   




                                   


                                                                                                                        



                                                   

                                                                             


                                                                                                                    
         




                                                    

                                                                                 
 


                                                                                                                      
         


       
                                      
                                   


                                                                                                                                          

       


                                        

                                                                 
                        
                                              





                                   
                                                       
                             
                        
                        


       


                                                              

                               
              









                                                                                  

         
     
 
                 
                            

                  
     
 
                 
                            




                                     
 
              
                                                       

     
                                       
                                   


                                                                                         


       
                                      
                                                

                                     


                                                                                                                    


                                     


       
                                                
                                                 

                                     


                                                                                                                   


                                      


       







                                                                       
       
 


                                                                              
       



                                          


                                                       





                                                         


                                                                                           

       
   





                                                                       
                   
















                                                                              

                                                       
                                                                       
         
 
                                     


                                                                                                                                               
         

       









                                                                                                 
   
require "abstract_unit"

module Admin; class User; end; end

module ParamsWrapperTestHelp
  def with_default_wrapper_options(&block)
    @controller.class._set_wrapper_options({:format => [:json]})
    @controller.class.inherited(@controller.class)
    yield
  end

  def assert_parameters(expected)
    assert_equal expected, self.class.controller_class.last_parameters
  end
end

class ParamsWrapperTest < ActionController::TestCase
  include ParamsWrapperTestHelp

  class UsersController < ActionController::Base
    class << self
      attr_accessor :last_parameters
    end

    def parse
      self.class.last_parameters = request.params.except(:controller, :action)
      head :ok
    end
  end

  class User
    def self.attribute_names
      []
    end
  end

  class Person
    def self.attribute_names
      []
    end
  end

  tests UsersController

  def teardown
    UsersController.last_parameters = nil
  end

  def test_filtered_parameters
    with_default_wrapper_options do
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu" }
      assert_equal @request.filtered_parameters, { "controller" => "params_wrapper_test/users", "action" => "parse", "username" => "sikachu", "user" => { "username" => "sikachu" } }
    end
  end

  def test_derived_name_from_controller
    with_default_wrapper_options do
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu" }
      assert_parameters({ "username" => "sikachu", "user" => { "username" => "sikachu" }})
    end
  end

  def test_specify_wrapper_name
    with_default_wrapper_options do
      UsersController.wrap_parameters :person

      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu" }
      assert_parameters({ "username" => "sikachu", "person" => { "username" => "sikachu" }})
    end
  end

  def test_specify_wrapper_model
    with_default_wrapper_options do
      UsersController.wrap_parameters Person

      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu" }
      assert_parameters({ "username" => "sikachu", "person" => { "username" => "sikachu" }})
    end
  end

  def test_specify_include_option
    with_default_wrapper_options do
      UsersController.wrap_parameters :include => :username

      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu", "title" => "Developer" }
      assert_parameters({ "username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu" }})
    end
  end

  def test_specify_exclude_option
    with_default_wrapper_options do
      UsersController.wrap_parameters :exclude => :title

      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu", "title" => "Developer" }
      assert_parameters({ "username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu" }})
    end
  end

  def test_specify_both_wrapper_name_and_include_option
    with_default_wrapper_options do
      UsersController.wrap_parameters :person, :include => :username

      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu", "title" => "Developer" }
      assert_parameters({ "username" => "sikachu", "title" => "Developer", "person" => { "username" => "sikachu" }})
    end
  end

  def test_not_enabled_format
    with_default_wrapper_options do
      @request.env["CONTENT_TYPE"] = "application/xml"
      post :parse, params: { "username" => "sikachu", "title" => "Developer" }
      assert_parameters({ "username" => "sikachu", "title" => "Developer" })
    end
  end

  def test_wrap_parameters_false
    with_default_wrapper_options do
      UsersController.wrap_parameters false
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu", "title" => "Developer" }
      assert_parameters({ "username" => "sikachu", "title" => "Developer" })
    end
  end

  def test_specify_format
    with_default_wrapper_options do
      UsersController.wrap_parameters :format => :xml

      @request.env["CONTENT_TYPE"] = "application/xml"
      post :parse, params: { "username" => "sikachu", "title" => "Developer" }
      assert_parameters({ "username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu", "title" => "Developer" }})
    end
  end

  def test_not_wrap_reserved_parameters
    with_default_wrapper_options do
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "authenticity_token" => "pwned", "_method" => "put", "utf8" => "&#9731;", "username" => "sikachu" }
      assert_parameters({ "authenticity_token" => "pwned", "_method" => "put", "utf8" => "&#9731;", "username" => "sikachu", "user" => { "username" => "sikachu" }})
    end
  end

  def test_no_double_wrap_if_key_exists
    with_default_wrapper_options do
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "user" => { "username" => "sikachu" }}
      assert_parameters({ "user" => { "username" => "sikachu" }})
    end
  end

  def test_nested_params
    with_default_wrapper_options do
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "person" => { "username" => "sikachu" }}
      assert_parameters({ "person" => { "username" => "sikachu" }, "user" => {"person" => { "username" => "sikachu" }}})
    end
  end

  def test_derived_wrapped_keys_from_matching_model
    assert_called(User, :attribute_names, times: 2, returns: ["username"]) do
      with_default_wrapper_options do
        @request.env["CONTENT_TYPE"] = "application/json"
        post :parse, params: { "username" => "sikachu", "title" => "Developer" }
        assert_parameters({ "username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu" }})
      end
    end
  end

  def test_derived_wrapped_keys_from_specified_model
    with_default_wrapper_options do
      assert_called(Person, :attribute_names, times: 2, returns: ["username"]) do
        UsersController.wrap_parameters Person

        @request.env["CONTENT_TYPE"] = "application/json"
        post :parse, params: { "username" => "sikachu", "title" => "Developer" }
        assert_parameters({ "username" => "sikachu", "title" => "Developer", "person" => { "username" => "sikachu" }})
      end
    end
  end

  def test_not_wrapping_abstract_model
    with_default_wrapper_options do
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu", "title" => "Developer" }
      assert_parameters({ "username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu", "title" => "Developer" }})
    end
  end

  def test_preserves_query_string_params
    with_default_wrapper_options do
      @request.env["CONTENT_TYPE"] = "application/json"
      get :parse, params: { "user" => { "username" => "nixon" } }
      assert_parameters(
        {"user" => { "username" => "nixon" } }
      )
    end
  end

  def test_empty_parameter_set
    with_default_wrapper_options do
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: {}
      assert_parameters(
        {"user" => { } }
      )
    end
  end
end

class NamespacedParamsWrapperTest < ActionController::TestCase
  include ParamsWrapperTestHelp

  module Admin
    module Users
      class UsersController < ActionController::Base;
        class << self
          attr_accessor :last_parameters
        end

        def parse
          self.class.last_parameters = request.params.except(:controller, :action)
          head :ok
        end
      end
    end
  end

  class SampleOne
    def self.attribute_names
      ["username"]
    end
  end

  class SampleTwo
    def self.attribute_names
      ["title"]
    end
  end

  tests Admin::Users::UsersController

  def teardown
    Admin::Users::UsersController.last_parameters = nil
  end

  def test_derived_name_from_controller
    with_default_wrapper_options do
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu" }
      assert_parameters({"username" => "sikachu", "user" => { "username" => "sikachu" }})
    end
  end

  def test_namespace_lookup_from_model
    Admin.const_set(:User, Class.new(SampleOne))
    begin
      with_default_wrapper_options do
        @request.env["CONTENT_TYPE"] = "application/json"
        post :parse, params: { "username" => "sikachu", "title" => "Developer" }
        assert_parameters({ "username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu" }})
      end
    ensure
      Admin.send :remove_const, :User
    end
  end

  def test_hierarchy_namespace_lookup_from_model
    Object.const_set(:User, Class.new(SampleTwo))
    begin
      with_default_wrapper_options do
        @request.env["CONTENT_TYPE"] = "application/json"
        post :parse, params: { "username" => "sikachu", "title" => "Developer" }
        assert_parameters({ "username" => "sikachu", "title" => "Developer", "user" => { "title" => "Developer" }})
      end
    ensure
      Object.send :remove_const, :User
    end
  end

end

class AnonymousControllerParamsWrapperTest < ActionController::TestCase
  include ParamsWrapperTestHelp

  tests(Class.new(ActionController::Base) do
    class << self
      attr_accessor :last_parameters
    end

    def parse
      self.class.last_parameters = request.params.except(:controller, :action)
      head :ok
    end
  end)

  def test_does_not_implicitly_wrap_params
    with_default_wrapper_options do
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu" }
      assert_parameters({ "username" => "sikachu" })
    end
  end

  def test_does_wrap_params_if_name_provided
    with_default_wrapper_options do
      @controller.class.wrap_parameters(:name => "guest")
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu" }
      assert_parameters({ "username" => "sikachu", "guest" => { "username" => "sikachu" }})
    end
  end
end

class IrregularInflectionParamsWrapperTest < ActionController::TestCase
  include ParamsWrapperTestHelp

  class ParamswrappernewsItem
    def self.attribute_names
      ["test_attr"]
    end
  end

  class ParamswrappernewsController < ActionController::Base
    class << self
      attr_accessor :last_parameters
    end

    def parse
      self.class.last_parameters = request.params.except(:controller, :action)
      head :ok
    end
  end

  tests ParamswrappernewsController

  def test_uses_model_attribute_names_with_irregular_inflection
    with_dup do
      ActiveSupport::Inflector.inflections do |inflect|
        inflect.irregular "paramswrappernews_item", "paramswrappernews"
      end

      with_default_wrapper_options do
        @request.env["CONTENT_TYPE"] = "application/json"
        post :parse, params: { "username" => "sikachu", "test_attr" => "test_value" }
        assert_parameters({ "username" => "sikachu", "test_attr" => "test_value", "paramswrappernews_item" => { "test_attr" => "test_value" }})
      end
    end
  end

  private

  def with_dup
    original = ActiveSupport::Inflector::Inflections.instance_variable_get(:@__instance__)[:en]
    ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, en: original.dup)
    yield
  ensure
    ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, en: original)
  end
end