require 'abstract_unit' class XmlParamsParsingTest < ActionDispatch::IntegrationTest class TestController < ActionController::Base class << self attr_accessor :last_request_parameters end def parse self.class.last_request_parameters = request.request_parameters head :ok end end def teardown TestController.last_request_parameters = nil end test "parses a strict rack.input" do class Linted undef call if method_defined?(:call) def call(env) bar = env['action_dispatch.request.request_parameters']['foo'] result = "#{bar}" [200, {"Content-Type" => "application/xml", "Content-Length" => result.length.to_s}, [result]] end end req = Rack::MockRequest.new(ActionDispatch::ParamsParser.new(Linted.new)) resp = req.post('/', "CONTENT_TYPE" => "application/xml", :input => "bar", :lint => true) assert_equal "bar", resp.body end test "parses hash params" do with_test_routing do xml = "David" post "/parse", xml, default_headers assert_response :ok assert_equal({"person" => {"name" => "David"}}, TestController.last_request_parameters) end end test "parses single file" do with_test_routing do xml = "David#{ActiveSupport::Base64.encode64('ABC')}" post "/parse", xml, default_headers assert_response :ok person = TestController.last_request_parameters assert_equal "image/jpg", person['person']['avatar'].content_type assert_equal "me.jpg", person['person']['avatar'].original_filename assert_equal "ABC", person['person']['avatar'].read end end test "logs error if parsing unsuccessful" do with_test_routing do output = StringIO.new xml = "David#{ActiveSupport::Base64.encode64('ABC')}" post "/parse", xml, default_headers.merge('action_dispatch.show_exceptions' => true, 'action_dispatch.logger' => Logger.new(output)) assert_response :error output.rewind && err = output.read assert err =~ /Error occurred while parsing request parameters/ end end test "occurring a parse error if parsing unsuccessful" do with_test_routing do begin $stderr = StringIO.new # suppress the log xml = "David" assert_raise(REXML::ParseException) { post "/parse", xml, default_headers.merge('action_dispatch.show_exceptions' => false) } ensure $stderr = STDERR end end end test "parses multiple files" do xml = <<-end_body David #{ActiveSupport::Base64.encode64('ABC')} #{ActiveSupport::Base64.encode64('DEF')} end_body with_test_routing do post "/parse", xml, default_headers assert_response :ok end person = TestController.last_request_parameters assert_equal "image/jpg", person['person']['avatars']['avatar'].first.content_type assert_equal "me.jpg", person['person']['avatars']['avatar'].first.original_filename assert_equal "ABC", person['person']['avatars']['avatar'].first.read assert_equal "image/gif", person['person']['avatars']['avatar'].last.content_type assert_equal "you.gif", person['person']['avatars']['avatar'].last.original_filename assert_equal "DEF", person['person']['avatars']['avatar'].last.read end private def with_test_routing with_routing do |set| set.draw do match ':action', :to => ::XmlParamsParsingTest::TestController end yield end end def default_headers {'CONTENT_TYPE' => 'application/xml'} end end class LegacyXmlParamsParsingTest < XmlParamsParsingTest private def default_headers {'HTTP_X_POST_DATA_FORMAT' => 'xml'} end end class RootLessXmlParamsParsingTest < ActionDispatch::IntegrationTest class TestController < ActionController::Base wrap_parameters :person, :format => :xml class << self attr_accessor :last_request_parameters end def parse self.class.last_request_parameters = request.request_parameters head :ok end end def teardown TestController.last_request_parameters = nil end test "parses hash params" do with_test_routing do xml = "David" post "/parse", xml, {'CONTENT_TYPE' => 'application/xml'} assert_response :ok assert_equal({"name" => "David", "person" => {"name" => "David"}}, TestController.last_request_parameters) end end private def with_test_routing with_routing do |set| set.draw do match ':action', :to => ::RootLessXmlParamsParsingTest::TestController end yield end end end