diff options
author | Joshua Peek <josh@joshpeek.com> | 2009-08-31 23:08:20 -0500 |
---|---|---|
committer | Joshua Peek <josh@joshpeek.com> | 2009-08-31 23:08:20 -0500 |
commit | a79790e1a5733694baef3d03d8d79b76948a9d69 (patch) | |
tree | 9c6df0ceaf39700bcfa906d54c64b1621f9fb245 /actionpack | |
parent | 426e76ad85c060ef2fa87bc2bebfc906ea7b090e (diff) | |
download | rails-a79790e1a5733694baef3d03d8d79b76948a9d69.tar.gz rails-a79790e1a5733694baef3d03d8d79b76948a9d69.tar.bz2 rails-a79790e1a5733694baef3d03d8d79b76948a9d69.zip |
rack-test 0.4.2 has rack 1.1.pre goodies, we'll use it instead
Diffstat (limited to 'actionpack')
4 files changed, 11 insertions, 308 deletions
diff --git a/actionpack/lib/action_controller/testing/integration.rb b/actionpack/lib/action_controller/testing/integration.rb index fb82f866fe..e7104e5c3d 100644 --- a/actionpack/lib/action_controller/testing/integration.rb +++ b/actionpack/lib/action_controller/testing/integration.rb @@ -2,9 +2,7 @@ require 'stringio' require 'uri' require 'active_support/test_case' require 'active_support/core_ext/object/metaclass' - -require 'rack/mock_session' -require 'rack/test/cookie_jar' +require 'rack/test' module ActionController module Integration #:nodoc: @@ -251,7 +249,7 @@ module ActionController end end - opts = { + env = { :method => method, :params => parameters, @@ -268,18 +266,18 @@ module ActionController "HTTP_ACCEPT" => accept } - env = ActionDispatch::TestRequest.env_for(path, opts) - (rack_environment || {}).each do |key, value| env[key] = value end + session = Rack::Test::Session.new(@mock_session) + @controller = ActionController::Base.capture_instantiation do - @mock_session.request(URI.parse(path), env) + session.request(path, env) end @request_count += 1 - @request = ActionDispatch::Request.new(env) + @request = ActionDispatch::Request.new(session.last_request.env) @response = ActionDispatch::TestResponse.from_response(@mock_session.last_response) @html_document = nil diff --git a/actionpack/lib/action_controller/testing/process.rb b/actionpack/lib/action_controller/testing/process.rb index a58b2de379..5fb244e3eb 100644 --- a/actionpack/lib/action_controller/testing/process.rb +++ b/actionpack/lib/action_controller/testing/process.rb @@ -84,7 +84,7 @@ module ActionController #:nodoc: # # Pass a true third parameter to ensure the uploaded file is opened in binary mode (only required for Windows): # post :change_avatar, :avatar => ActionController::TestUploadedFile.new(ActionController::TestCase.fixture_path + '/files/spongebob.png', 'image/png', :binary) - TestUploadedFile = ActionDispatch::TestRequest::Multipart::UploadedFile + TestUploadedFile = Rack::Test::UploadedFile module TestProcess def self.included(base) diff --git a/actionpack/lib/action_dispatch/testing/test_request.rb b/actionpack/lib/action_dispatch/testing/test_request.rb index 8242ea4ef6..20288aa7a5 100644 --- a/actionpack/lib/action_dispatch/testing/test_request.rb +++ b/actionpack/lib/action_dispatch/testing/test_request.rb @@ -1,308 +1,13 @@ module ActionDispatch class TestRequest < Request - # Improve version of Multipart thats in rack/master - module Multipart #:nodoc: - class UploadedFile - # The filename, *not* including the path, of the "uploaded" file - attr_reader :original_filename - - # The content type of the "uploaded" file - attr_accessor :content_type - - def initialize(path, content_type = "text/plain", binary = false) - raise "#{path} file does not exist" unless ::File.exist?(path) - @content_type = content_type - @original_filename = ::File.basename(path) - @tempfile = Tempfile.new(@original_filename) - @tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding) - @tempfile.binmode if binary - FileUtils.copy_file(path, @tempfile.path) - end - - def path - @tempfile.path - end - alias_method :local_path, :path - - def method_missing(method_name, *args, &block) #:nodoc: - @tempfile.__send__(method_name, *args, &block) - end - end - - EOL = "\r\n" - MULTIPART_BOUNDARY = "AaB03x" - - def self.parse_multipart(env) - unless env['CONTENT_TYPE'] =~ - %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|n - nil - else - boundary = "--#{$1}" - - params = {} - buf = "" - content_length = env['CONTENT_LENGTH'].to_i - input = env['rack.input'] - input.rewind - - boundary_size = Utils.bytesize(boundary) + EOL.size - bufsize = 16384 - - content_length -= boundary_size - - read_buffer = '' - - status = input.read(boundary_size, read_buffer) - raise EOFError, "bad content body" unless status == boundary + EOL - - rx = /(?:#{EOL})?#{Regexp.quote boundary}(#{EOL}|--)/n - - loop { - head = nil - body = '' - filename = content_type = name = nil - - until head && buf =~ rx - if !head && i = buf.index(EOL+EOL) - head = buf.slice!(0, i+2) # First \r\n - buf.slice!(0, 2) # Second \r\n - - filename = head[/Content-Disposition:.* filename="?([^\";]*)"?/ni, 1] - content_type = head[/Content-Type: (.*)#{EOL}/ni, 1] - name = head[/Content-Disposition:.*\s+name="?([^\";]*)"?/ni, 1] || head[/Content-ID:\s*([^#{EOL}]*)/ni, 1] - - if content_type || filename - body = Tempfile.new("RackMultipart") - body.binmode if body.respond_to?(:binmode) - end - - next - end - - # Save the read body part. - if head && (boundary_size+4 < buf.size) - body << buf.slice!(0, buf.size - (boundary_size+4)) - end - - c = input.read(bufsize < content_length ? bufsize : content_length, read_buffer) - raise EOFError, "bad content body" if c.nil? || c.empty? - buf << c - content_length -= c.size - end - - # Save the rest. - if i = buf.index(rx) - body << buf.slice!(0, i) - buf.slice!(0, boundary_size+2) - - content_length = -1 if $1 == "--" - end - - if filename == "" - # filename is blank which means no file has been selected - data = nil - elsif filename - body.rewind - - # Take the basename of the upload's original filename. - # This handles the full Windows paths given by Internet Explorer - # (and perhaps other broken user agents) without affecting - # those which give the lone filename. - filename =~ /^(?:.*[:\\\/])?(.*)/m - filename = $1 - - data = {:filename => filename, :type => content_type, - :name => name, :tempfile => body, :head => head} - elsif !filename && content_type - body.rewind - - # Generic multipart cases, not coming from a form - data = {:type => content_type, - :name => name, :tempfile => body, :head => head} - else - data = body - end - - Utils.normalize_params(params, name, data) unless data.nil? - - break if buf.empty? || content_length == -1 - } - - input.rewind - - params - end - end - - def self.build_multipart(params, first = true) - if first - unless params.is_a?(Hash) - raise ArgumentError, "value must be a Hash" - end - - multipart = false - query = lambda { |value| - case value - when Array - value.each(&query) - when Hash - value.values.each(&query) - when UploadedFile - multipart = true - end - } - params.values.each(&query) - return nil unless multipart - end - - flattened_params = Hash.new - - params.each do |key, value| - k = first ? key.to_s : "[#{key}]" - - case value - when Array - value.map { |v| - build_multipart(v, false).each { |subkey, subvalue| - flattened_params["#{k}[]#{subkey}"] = subvalue - } - } - when Hash - build_multipart(value, false).each { |subkey, subvalue| - flattened_params[k + subkey] = subvalue - } - else - flattened_params[k] = value - end - end - - if first - flattened_params.map { |name, file| - if file.respond_to?(:original_filename) - ::File.open(file.path, "rb") do |f| - f.set_encoding(Encoding::BINARY) if f.respond_to?(:set_encoding) -<<-EOF ---#{MULTIPART_BOUNDARY}\r -Content-Disposition: form-data; name="#{name}"; filename="#{Rack::Utils.escape(file.original_filename)}"\r -Content-Type: #{file.content_type}\r -Content-Length: #{::File.stat(file.path).size}\r -\r -#{f.read}\r -EOF - end - else -<<-EOF ---#{MULTIPART_BOUNDARY}\r -Content-Disposition: form-data; name="#{name}"\r -\r -#{file}\r -EOF - end - }.join + "--#{MULTIPART_BOUNDARY}--\r" - else - flattened_params - end - end - end - - DEFAULT_ENV = { - "rack.version" => [1,0], - "rack.input" => StringIO.new, - "rack.errors" => StringIO.new, - "rack.multithread" => true, - "rack.multiprocess" => true, - "rack.run_once" => false, - } - - # Improve version of env_for thats in rack/master - def self.env_for(uri="", opts={}) #:nodoc: - uri = URI(uri) - uri.path = "/#{uri.path}" unless uri.path[0] == ?/ - - env = DEFAULT_ENV.dup - - env["REQUEST_METHOD"] = opts[:method] ? opts[:method].to_s.upcase : "GET" - env["SERVER_NAME"] = uri.host || "example.org" - env["SERVER_PORT"] = uri.port ? uri.port.to_s : "80" - env["QUERY_STRING"] = uri.query.to_s - env["PATH_INFO"] = (!uri.path || uri.path.empty?) ? "/" : uri.path - env["rack.url_scheme"] = uri.scheme || "http" - env["HTTPS"] = env["rack.url_scheme"] == "https" ? "on" : "off" - - env["SCRIPT_NAME"] = opts[:script_name] || "" - - if opts[:fatal] - env["rack.errors"] = FatalWarner.new - else - env["rack.errors"] = StringIO.new - end - - if params = opts[:params] - if env["REQUEST_METHOD"] == "GET" - params = Rack::Utils.parse_nested_query(params) if params.is_a?(String) - params.update(Rack::Utils.parse_nested_query(env["QUERY_STRING"])) - env["QUERY_STRING"] = build_nested_query(params) - elsif !opts.has_key?(:input) - opts["CONTENT_TYPE"] = "application/x-www-form-urlencoded" - if params.is_a?(Hash) - if data = Multipart.build_multipart(params) - opts[:input] = data - opts["CONTENT_LENGTH"] ||= data.length.to_s - opts["CONTENT_TYPE"] = "multipart/form-data; boundary=#{Multipart::MULTIPART_BOUNDARY}" - else - opts[:input] = build_nested_query(params) - end - else - opts[:input] = params - end - end - end - - empty_str = "" - empty_str.force_encoding("ASCII-8BIT") if empty_str.respond_to? :force_encoding - opts[:input] ||= empty_str - if String === opts[:input] - rack_input = StringIO.new(opts[:input]) - else - rack_input = opts[:input] - end - - rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding) - env['rack.input'] = rack_input - - env["CONTENT_LENGTH"] ||= env["rack.input"].length.to_s - - opts.each { |field, value| - env[field] = value if String === field - } - - env - end - - def self.build_nested_query(value, prefix = nil) - case value - when Array - value.map { |v| - build_nested_query(v, "#{prefix}[]") - }.join("&") - when Hash - value.map { |k, v| - build_nested_query(v, prefix ? "#{prefix}[#{Rack::Utils.escape(k)}]" : Rack::Utils.escape(k)) - }.join("&") - when String - raise ArgumentError, "value must be a Hash" if prefix.nil? - "#{prefix}=#{Rack::Utils.escape(value)}" - else - prefix - end - end + DEFAULT_ENV = Rack::MockRequest.env_for('/') def self.new(env = {}) super end def initialize(env = {}) - super(self.class.env_for('/').merge(env)) + super(DEFAULT_ENV.merge(env)) self.host = 'test.host' self.remote_addr = '0.0.0.0' diff --git a/actionpack/test/dispatch/test_request_test.rb b/actionpack/test/dispatch/test_request_test.rb index 5da02b2ea6..b8e340e055 100644 --- a/actionpack/test/dispatch/test_request_test.rb +++ b/actionpack/test/dispatch/test_request_test.rb @@ -5,7 +5,7 @@ class TestRequestTest < ActiveSupport::TestCase env = ActionDispatch::TestRequest.new.env assert_equal "GET", env.delete("REQUEST_METHOD") - assert_equal "off", env.delete("HTTPS") + assert_equal nil, env.delete("HTTPS") assert_equal "http", env.delete("rack.url_scheme") assert_equal "example.org", env.delete("SERVER_NAME") assert_equal "80", env.delete("SERVER_PORT") @@ -18,7 +18,7 @@ class TestRequestTest < ActiveSupport::TestCase assert_equal "0.0.0.0", env.delete("REMOTE_ADDR") assert_equal "Rails Testing", env.delete("HTTP_USER_AGENT") - assert_equal [1, 0], env.delete("rack.version") + assert_equal [0, 1], env.delete("rack.version") assert_equal "", env.delete("rack.input").string assert_kind_of StringIO, env.delete("rack.errors") assert_equal true, env.delete("rack.multithread") |