From cc5a957d2b57b1d7081abd6939396f32e7b4b204 Mon Sep 17 00:00:00 2001 From: Michael Koziarski Date: Mon, 3 Mar 2008 06:42:24 +0000 Subject: Allow file uploads in Integration Tests. Closes #11091 [RubyRedRick] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8978 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- actionpack/lib/action_controller/integration.rb | 50 ++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'actionpack/lib') diff --git a/actionpack/lib/action_controller/integration.rb b/actionpack/lib/action_controller/integration.rb index d979ca494d..6ccaa7eaa4 100644 --- a/actionpack/lib/action_controller/integration.rb +++ b/actionpack/lib/action_controller/integration.rb @@ -55,6 +55,9 @@ module ActionController # A running counter of the number of requests processed. attr_accessor :request_count + class MultiPartNeededException < Exception + end + # Create and initialize a new +Session+ instance. def initialize reset! @@ -294,6 +297,10 @@ module ActionController parse_result return status + rescue MultiPartNeededException + boundary = "----------XnJLe9ZIbbGUYtzPQJ16u1" + status = process(method, path, multipart_body(parameters, boundary), (headers || {}).merge({"CONTENT_TYPE" => "multipart/form-data; boundary=#{boundary}"})) + return status end # Parses the result of the response and extracts the various values, @@ -342,7 +349,9 @@ module ActionController # Convert the given parameters to a request string. The parameters may # be a string, +nil+, or a Hash. def requestify(parameters, prefix=nil) - if Hash === parameters + if TestUploadedFile === parameters + raise MultiPartNeededException + elsif Hash === parameters return nil if parameters.empty? parameters.map { |k,v| requestify(v, name_with_prefix(prefix, k)) }.join("&") elsif Array === parameters @@ -353,6 +362,45 @@ module ActionController "#{CGI.escape(prefix)}=#{CGI.escape(parameters.to_s)}" end end + + def multipart_requestify(params, first=true) + returning Hash.new do |p| + params.each do |key, value| + k = first ? CGI.escape(key.to_s) : "[#{CGI.escape(key.to_s)}]" + if Hash === value + multipart_requestify(value, false).each do |subkey, subvalue| + p[k + subkey] = subvalue + end + else + p[k] = value + end + end + end + end + + def multipart_body(params, boundary) + multipart_requestify(params).map do |key, value| + if value.respond_to?(:original_filename) + File.open(value.path) do |f| + <<-EOF +--#{boundary}\r +Content-Disposition: form-data; name="#{key}"; filename="#{CGI.escape(value.original_filename)}"\r +Content-Type: #{value.content_type}\r +Content-Length: #{File.stat(value.path).size}\r +\r +#{f.read}\r +EOF + end + else +<<-EOF +--#{boundary}\r +Content-Disposition: form-data; name="#{key}"\r +\r +#{value}\r +EOF + end + end.join("")+"--#{boundary}--\r" + end end # A module used to extend ActionController::Base, so that integration tests -- cgit v1.2.3