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#{::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#{::Base64.encode64('ABC')}"
post "/parse", xml, default_headers.merge('action_dispatch.show_exceptions' => true, 'action_dispatch.logger' => ActiveSupport::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"
exception = assert_raise(ActionDispatch::ParamsParser::ParseError) { post "/parse", xml, default_headers.merge('action_dispatch.show_exceptions' => false) }
assert_equal REXML::ParseException, exception.original_exception.class
assert_equal exception.original_exception.message, exception.message
ensure
$stderr = STDERR
end
end
end
test "parses multiple files" do
xml = <<-end_body
David
#{::Base64.encode64('ABC')}
#{::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
post ':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
post ':action', :to => ::RootLessXmlParamsParsingTest::TestController
end
yield
end
end
end