Allow Merb to do file uploads

This commit is contained in:
Ryan Carver 2009-04-24 13:56:28 -07:00
parent 481bfe03c0
commit 09509025c3
4 changed files with 151 additions and 8 deletions

View File

@ -356,11 +356,17 @@ module Webrat
protected protected
def test_uploaded_file def test_uploaded_file
case Webrat.configuration.mode
when :rails
if content_type if content_type
ActionController::TestUploadedFile.new(@value, content_type) ActionController::TestUploadedFile.new(@value, content_type)
else else
ActionController::TestUploadedFile.new(@value) ActionController::TestUploadedFile.new(@value)
end end
when :merb
# TODO: support content_type
File.new(@value)
end
end end
end end

View File

@ -5,6 +5,8 @@ gem "extlib"
require "extlib" require "extlib"
require "merb-core" require "merb-core"
require "merb-core/two-oh"
# HashWithIndifferentAccess = Mash # HashWithIndifferentAccess = Mash
module Webrat module Webrat
@ -36,13 +38,36 @@ module Webrat
def response_code def response_code
@response.status @response.status
end end
include Merb::Test::MultipartRequestHelper
def do_request(url, data, headers, method) def do_request(url, data, headers, method)
if method == "POST" && has_file?(data)
@response = multipart_post(url, data, :headers => headers)
elsif method == "PUT" && has_file?(data)
@response = multipart_put(url, data, :headers => headers)
else
@response = request(url, @response = request(url,
:params => (data && data.any?) ? data : nil, :params => (data && data.any?) ? data : nil,
:headers => headers, :headers => headers,
:method => method) :method => method)
end end
end
protected
# Recursively search the data for a file attachment.
def has_file?(data)
data.each do |key, value|
if value.is_a?(Hash)
return has_file?(value)
else
return true if value.is_a?(File)
end
end
return false
end
end end
end end

View File

@ -0,0 +1,93 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
describe "attach_file with merb" do
before do
Webrat.configuration.mode = :merb
@filename = __FILE__
end
it "should fail if no file field found" do
with_html <<-HTML
<html>
<form method="post" action="/widgets">
</form>
</html>
HTML
lambda { attach_file("Doc", "/some/path") }.should raise_error(Webrat::NotFoundError)
end
it "should submit empty strings for blank file fields" do
with_html <<-HTML
<html>
<form method="post" action="/widgets">
<input type="file" id="widget_file" name="widget[file]" />
<input type="submit" />
</form>
</html>
HTML
webrat_session.should_receive(:post).with("/widgets", { "widget" => { "file" => "" } })
click_button
end
it "should submit the attached file" do
with_html <<-HTML
<html>
<form method="post" action="/widgets">
<label for="widget_file">Document</label>
<input type="file" id="widget_file" name="widget[file]" />
<input type="submit" />
</form>
</html>
HTML
webrat_session.should_receive(:post).with { |path, params|
path.should == "/widgets"
params.should have_key("widget")
params["widget"].should have_key("file")
params["widget"]["file"].should be_an_instance_of(File)
params["widget"]["file"].path.should == @filename
}
attach_file "Document", @filename
click_button
end
it "should support collections" do
with_html <<-HTML
<html>
<form method="post" action="/widgets">
<label for="widget_file1">Document</label>
<input type="file" id="widget_file1" name="widget[files][]" />
<label for="widget_file2">Spreadsheet</label>
<input type="file" id="widget_file2" name="widget[files][]" />
<input type="submit" />
</form>
</html>
HTML
webrat_session.should_receive(:post).with { |path, params|
path.should == "/widgets"
params.should have_key("widget")
params["widget"].should have_key("files")
params["widget"]["files"][0].should be_an_instance_of(File)
params["widget"]["files"][0].path.should == @filename
params["widget"]["files"][1].should be_an_instance_of(File)
params["widget"]["files"][1].path.should == @filename
}
attach_file "Document", @filename
attach_file "Spreadsheet", @filename
click_button
end
xit "should allow the content type to be specified" do
with_html <<-HTML
<html>
<form method="post" action="/widgets">
<label for="person_picture">Picture</label>
<input type="file" id="person_picture" name="person[picture]" />
<input type="submit" />
</form>
</html>
HTML
ActionController::TestUploadedFile.should_receive(:new).with(@filename, "image/png").any_number_of_times
attach_file "Picture", @filename, "image/png"
click_button
end
end

View File

@ -22,6 +22,25 @@ describe Webrat::MerbSession do
end end
end end
%w{post put}.each do |request_method|
it "should call do request with method #{request_method.upcase} with a file attachment" do
session = Webrat::MerbSession.new
response = OpenStruct.new
response.status = 200
file = File.new(__FILE__)
session.should_receive(:request).with { |path, env|
path.should == "url"
env[:method].should == request_method.upcase
env[:headers].should be_nil
env[:input].should be_an_instance_of(StringIO)
env["CONTENT_LENGTH"].should be_an_instance_of(Fixnum)
env["CONTENT_TYPE"].should match(/multipart.*boundary/)
}.and_return(response)
session.send(request_method, 'url', { :file => file }, nil)
end
end
context "a session with a response" do context "a session with a response" do
before do before do
@session = Webrat::MerbSession.new @session = Webrat::MerbSession.new