1 require 'abstract_unit'
3 class MultipartParamsParsingTest
< ActionController
::IntegrationTest
4 class TestController
< ActionController
::Base
6 attr_accessor
:last_request_parameters
10 self.class.last_request_parameters
= request
.request_parameters
15 render
:text => "File: #{params[:uploaded_data].read}"
19 FIXTURE_PATH
= File
.dirname(__FILE__
) + '/../../fixtures/multipart'
22 TestController
.last_request_parameters
= nil
25 test
"parses single parameter" do
26 assert_equal({ 'foo' => 'bar' }, parse_multipart('single_parameter'))
29 test
"parses bracketed parameters" do
30 assert_equal({ 'foo' => { 'baz' => 'bar'}}, parse_multipart('bracketed_param'))
33 test
"parses text file" do
34 params
= parse_multipart('text_file')
35 assert_equal
%w(file foo
), params
.keys
.sort
36 assert_equal
'bar', params
['foo']
39 assert_kind_of Tempfile
, file
40 assert_equal
'file.txt', file
.original_filename
41 assert_equal
"text/plain", file
.content_type
42 assert_equal
'contents', file
.read
45 test
"parses boundary problem file" do
46 params
= parse_multipart('boundary_problem_file')
47 assert_equal
%w(file foo
), params
.keys
.sort
52 assert_kind_of Tempfile
, file
54 assert_equal
'file.txt', file
.original_filename
55 assert_equal
"text/plain", file
.content_type
57 assert_equal
'bar', foo
60 test
"parses large text file" do
61 params
= parse_multipart('large_text_file')
62 assert_equal
%w(file foo
), params
.keys
.sort
63 assert_equal
'bar', params
['foo']
67 assert_kind_of Tempfile
, file
69 assert_equal
'file.txt', file
.original_filename
70 assert_equal
"text/plain", file
.content_type
71 assert ('a' * 20480) == file
.read
74 test
"parses binary file" do
75 params
= parse_multipart('binary_file')
76 assert_equal
%w(file flowers foo
), params
.keys
.sort
77 assert_equal
'bar', params
['foo']
80 assert_kind_of Tempfile
, file
81 assert_equal
'file.csv', file
.original_filename
82 assert_nil file
.content_type
83 assert_equal
'contents', file
.read
85 file
= params
['flowers']
86 assert_kind_of Tempfile
, file
87 assert_equal
'flowers.jpg', file
.original_filename
88 assert_equal
"image/jpeg", file
.content_type
89 assert_equal
19512, file
.size
92 test
"parses mixed files" do
93 params
= parse_multipart('mixed_files')
94 assert_equal
%w(files foo
), params
.keys
.sort
95 assert_equal
'bar', params
['foo']
97 # Ruby CGI doesn't handle multipart/mixed for us.
98 files
= params
['files']
99 assert_kind_of String
, files
100 files
.force_encoding('ASCII-8BIT') if files
.respond_to
?(:force_encoding)
101 assert_equal
19756, files
.size
104 test
"does not create tempfile if no file has been selected" do
105 params
= parse_multipart('none')
106 assert_equal
%w(submit-name
), params
.keys
.sort
107 assert_equal
'Larry', params
['submit-name']
108 assert_equal
nil, params
['files']
111 test
"parses empty upload file" do
112 params
= parse_multipart('empty')
113 assert_equal
%w(files submit-name
), params
.keys
.sort
114 assert_equal
'Larry', params
['submit-name']
115 assert params
['files']
116 assert_equal
"", params
['files'].read
119 test
"uploads and reads binary file" do
121 fixture
= FIXTURE_PATH
+ "/mona_lisa.jpg"
122 params
= { :uploaded_data => fixture_file_upload(fixture
, "image/jpg") }
124 expected_length
= 'File: '.length
+ File
.size(fixture
)
125 assert_equal expected_length
, response
.content_length
129 test
"uploads and reads file" do
131 post
'/read', :uploaded_data => fixture_file_upload(FIXTURE_PATH
+ "/hello.txt", "text/plain")
132 assert_equal
"File: Hello", response
.body
136 # The lint wrapper is used in integration tests
137 # instead of a normal StringIO class
138 InputWrapper
= Rack
::Lint::InputWrapper
140 test
"parses unwindable stream" do
141 InputWrapper
.any_instance
.stubs(:rewind).raises(Errno
::ESPIPE)
142 params
= parse_multipart('large_text_file')
143 assert_equal
%w(file foo
), params
.keys
.sort
144 assert_equal
'bar', params
['foo']
147 test
"uploads and reads file with unwindable input" do
148 InputWrapper
.any_instance
.stubs(:rewind).raises(Errno
::ESPIPE)
151 post
'/read', :uploaded_data => fixture_file_upload(FIXTURE_PATH
+ "/hello.txt", "text/plain")
152 assert_equal
"File: Hello", response
.body
156 test
"passes through rack middleware and uploads file" do
157 with_muck_middleware
do
159 post
'/read', :uploaded_data => fixture_file_upload(FIXTURE_PATH
+ "/hello.txt", "text/plain")
160 assert_equal
"File: Hello", response
.body
165 test
"passes through rack middleware and uploads file with unwindable input" do
166 InputWrapper
.any_instance
.stubs(:rewind).raises(Errno
::ESPIPE)
168 with_muck_middleware
do
170 post
'/read', :uploaded_data => fixture_file_upload(FIXTURE_PATH
+ "/hello.txt", "text/plain")
171 assert_equal
"File: Hello", response
.body
178 File
.open(File
.join(FIXTURE_PATH
, name
), 'rb') do |file
|
179 { "rack.input" => file
.read
,
180 "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
181 "CONTENT_LENGTH" => file
.stat
.size
.to_s
}
185 def parse_multipart(name
)
187 headers
= fixture(name
)
188 post
"/parse", headers
.delete("rack.input"), headers
190 TestController
.last_request_parameters
194 def with_test_routing
195 with_routing
do |set
|
197 map
.connect
':action', :controller => "multipart_params_parsing_test/test"
209 req
= Rack
::Request.new(env)
210 req
.params
# Parse params
215 def with_muck_middleware
216 original_middleware
= ActionController
::Dispatcher.middleware
217 middleware
= original_middleware
.dup
218 middleware
.insert_after ActionController
::RewindableInput, MuckMiddleware
219 ActionController
::Dispatcher.middleware
= middleware
221 ActionController
::Dispatcher.middleware
= original_middleware