actionpack 1.9.1 → 1.10.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- data/CHANGELOG +237 -0
- data/README +12 -12
- data/lib/action_controller.rb +17 -12
- data/lib/action_controller/assertions.rb +119 -67
- data/lib/action_controller/base.rb +184 -102
- data/lib/action_controller/benchmarking.rb +35 -6
- data/lib/action_controller/caching.rb +115 -58
- data/lib/action_controller/cgi_ext/cgi_methods.rb +54 -21
- data/lib/action_controller/cgi_ext/cookie_performance_fix.rb +39 -35
- data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +34 -21
- data/lib/action_controller/cgi_process.rb +23 -20
- data/lib/action_controller/components.rb +11 -2
- data/lib/action_controller/dependencies.rb +0 -5
- data/lib/action_controller/deprecated_redirects.rb +17 -0
- data/lib/action_controller/filters.rb +13 -9
- data/lib/action_controller/flash.rb +7 -7
- data/lib/action_controller/helpers.rb +1 -14
- data/lib/action_controller/layout.rb +40 -29
- data/lib/action_controller/macros/auto_complete.rb +52 -0
- data/lib/action_controller/macros/in_place_editing.rb +32 -0
- data/lib/action_controller/pagination.rb +44 -28
- data/lib/action_controller/request.rb +54 -40
- data/lib/action_controller/rescue.rb +8 -6
- data/lib/action_controller/routing.rb +77 -28
- data/lib/action_controller/scaffolding.rb +10 -14
- data/lib/action_controller/session/active_record_store.rb +36 -7
- data/lib/action_controller/session_management.rb +126 -0
- data/lib/action_controller/streaming.rb +14 -5
- data/lib/action_controller/templates/rescues/_request_and_response.rhtml +1 -1
- data/lib/action_controller/templates/rescues/_trace.rhtml +24 -0
- data/lib/action_controller/templates/rescues/diagnostics.rhtml +2 -13
- data/lib/action_controller/templates/rescues/template_error.rhtml +4 -2
- data/lib/action_controller/templates/scaffolds/list.rhtml +1 -1
- data/lib/action_controller/test_process.rb +35 -17
- data/lib/action_controller/upload_progress.rb +52 -0
- data/lib/action_controller/url_rewriter.rb +21 -16
- data/lib/action_controller/vendor/html-scanner/html/document.rb +2 -2
- data/lib/action_controller/vendor/html-scanner/html/node.rb +30 -3
- data/lib/action_pack/version.rb +9 -0
- data/lib/action_view.rb +1 -1
- data/lib/action_view/base.rb +204 -60
- data/lib/action_view/compiled_templates.rb +70 -0
- data/lib/action_view/helpers/active_record_helper.rb +7 -3
- data/lib/action_view/helpers/asset_tag_helper.rb +22 -12
- data/lib/action_view/helpers/capture_helper.rb +2 -10
- data/lib/action_view/helpers/date_helper.rb +21 -13
- data/lib/action_view/helpers/form_helper.rb +14 -10
- data/lib/action_view/helpers/form_options_helper.rb +4 -4
- data/lib/action_view/helpers/form_tag_helper.rb +59 -25
- data/lib/action_view/helpers/java_script_macros_helper.rb +188 -0
- data/lib/action_view/helpers/javascript_helper.rb +68 -133
- data/lib/action_view/helpers/javascripts/controls.js +427 -165
- data/lib/action_view/helpers/javascripts/dragdrop.js +256 -277
- data/lib/action_view/helpers/javascripts/effects.js +766 -277
- data/lib/action_view/helpers/javascripts/prototype.js +906 -218
- data/lib/action_view/helpers/javascripts/slider.js +258 -0
- data/lib/action_view/helpers/number_helper.rb +4 -3
- data/lib/action_view/helpers/pagination_helper.rb +42 -27
- data/lib/action_view/helpers/tag_helper.rb +25 -11
- data/lib/action_view/helpers/text_helper.rb +119 -13
- data/lib/action_view/helpers/upload_progress_helper.rb +2 -2
- data/lib/action_view/helpers/url_helper.rb +68 -21
- data/lib/action_view/partials.rb +17 -6
- data/lib/action_view/template_error.rb +19 -24
- data/rakefile +4 -3
- data/test/abstract_unit.rb +2 -1
- data/test/controller/action_pack_assertions_test.rb +62 -2
- data/test/controller/active_record_assertions_test.rb +5 -6
- data/test/controller/active_record_store_test.rb +23 -1
- data/test/controller/addresses_render_test.rb +4 -0
- data/test/controller/{base_tests.rb → base_test.rb} +4 -3
- data/test/controller/benchmark_test.rb +36 -0
- data/test/controller/caching_filestore.rb +22 -40
- data/test/controller/capture_test.rb +10 -1
- data/test/controller/cgi_test.rb +145 -23
- data/test/controller/components_test.rb +50 -0
- data/test/controller/custom_handler_test.rb +3 -3
- data/test/controller/fake_controllers.rb +24 -0
- data/test/controller/filters_test.rb +6 -6
- data/test/controller/flash_test.rb +6 -6
- data/test/controller/fragment_store_setting_test.rb +45 -0
- data/test/controller/helper_test.rb +1 -3
- data/test/controller/new_render_test.rb +119 -7
- data/test/controller/redirect_test.rb +11 -1
- data/test/controller/render_test.rb +34 -1
- data/test/controller/request_test.rb +14 -5
- data/test/controller/routing_test.rb +238 -42
- data/test/controller/send_file_test.rb +11 -10
- data/test/controller/session_management_test.rb +94 -0
- data/test/controller/test_test.rb +194 -5
- data/test/controller/url_rewriter_test.rb +46 -0
- data/test/fixtures/layouts/talk_from_action.rhtml +2 -0
- data/test/fixtures/layouts/yield.rhtml +2 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/multipart/large_text_file +10 -0
- data/test/fixtures/multipart/mixed_files +0 -0
- data/test/fixtures/multipart/single_parameter +5 -0
- data/test/fixtures/multipart/text_file +10 -0
- data/test/fixtures/test/_customer_greeting.rhtml +1 -0
- data/test/fixtures/test/_hash_object.rhtml +1 -0
- data/test/fixtures/test/_person.rhtml +2 -0
- data/test/fixtures/test/action_talk_to_layout.rhtml +2 -0
- data/test/fixtures/test/content_for.rhtml +2 -0
- data/test/fixtures/test/potential_conflicts.rhtml +4 -0
- data/test/template/active_record_helper_test.rb +15 -8
- data/test/template/asset_tag_helper_test.rb +40 -16
- data/test/template/compiled_templates_tests.rb +63 -0
- data/test/template/date_helper_test.rb +80 -4
- data/test/template/form_helper_test.rb +48 -42
- data/test/template/form_options_helper_test.rb +40 -40
- data/test/template/form_tag_helper_test.rb +21 -15
- data/test/template/java_script_macros_helper_test.rb +56 -0
- data/test/template/javascript_helper_test.rb +70 -47
- data/test/template/number_helper_test.rb +2 -0
- data/test/template/tag_helper_test.rb +9 -0
- data/test/template/text_helper_test.rb +146 -1
- data/test/template/upload_progress_helper_testx.rb +11 -147
- data/test/template/url_helper_test.rb +90 -22
- data/test/testing_sandbox.rb +26 -0
- metadata +37 -7
- data/lib/action_controller/auto_complete.rb +0 -47
- data/lib/action_controller/deprecated_renders_and_redirects.rb +0 -76
- data/lib/action_controller/session.rb +0 -14
@@ -53,6 +53,7 @@ module CommonActiveRecordStoreTests
|
|
53
53
|
@new_session.close
|
54
54
|
end
|
55
55
|
end
|
56
|
+
|
56
57
|
end
|
57
58
|
|
58
59
|
class ActiveRecordStoreTest < Test::Unit::TestCase
|
@@ -77,6 +78,28 @@ class ActiveRecordStoreTest < Test::Unit::TestCase
|
|
77
78
|
end
|
78
79
|
end
|
79
80
|
|
81
|
+
class ColumnLimitTest < Test::Unit::TestCase
|
82
|
+
|
83
|
+
def setup
|
84
|
+
@session_class = CGI::Session::ActiveRecordStore::Session
|
85
|
+
@session_class.create_table!
|
86
|
+
end
|
87
|
+
|
88
|
+
def teardown
|
89
|
+
@session_class.drop_table!
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_protection_from_data_larger_than_column
|
93
|
+
# Can't test this unless there is a limit
|
94
|
+
return unless limit = @session_class.data_column_size_limit
|
95
|
+
too_big = ':(' * limit
|
96
|
+
s = @session_class.new(:session_id => '666', :data => {'foo' => too_big})
|
97
|
+
s.data
|
98
|
+
assert_raises(ActionController::SessionOverflowError) { s.save }
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
80
103
|
|
81
104
|
class DeprecatedActiveRecordStoreTest < ActiveRecordStoreTest
|
82
105
|
def setup
|
@@ -94,7 +117,6 @@ class DeprecatedActiveRecordStoreTest < ActiveRecordStoreTest
|
|
94
117
|
def teardown
|
95
118
|
session_class.connection.execute 'drop table old_sessions'
|
96
119
|
session_class.table_name = 'sessions'
|
97
|
-
session_class.send :setup_sessid_compatibility!
|
98
120
|
end
|
99
121
|
end
|
100
122
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../abstract_unit'
|
2
2
|
require 'test/unit'
|
3
|
+
require 'pp' # require 'pp' early to prevent hidden_methods from not picking up the pretty-print methods until too late
|
3
4
|
|
4
5
|
# This file currently contains a few controller UTs
|
5
6
|
# I couldn't find where the current base tests are, so I created this file.
|
@@ -63,10 +64,10 @@ class ControllerInstanceTests < Test::Unit::TestCase
|
|
63
64
|
|
64
65
|
@non_empty_controllers = [Controllers::NonEmptyController.new,
|
65
66
|
Controllers::Submodule::ContainedNonEmptyController.new]
|
66
|
-
|
67
67
|
end
|
68
|
+
|
68
69
|
def test_action_methods
|
69
|
-
@empty_controllers.each {|c| assert_equal
|
70
|
-
@non_empty_controllers.each {|c| assert_equal
|
70
|
+
@empty_controllers.each {|c| assert_equal({}, c.send(:action_methods), "#{c.class.controller_path} should be empty!")}
|
71
|
+
@non_empty_controllers.each {|c| assert_equal({"public_action"=>true}, c.send(:action_methods), "#{c.class.controller_path} should not be empty!")}
|
71
72
|
end
|
72
73
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../abstract_unit'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
# Provide a static version of the Controllers module instead of the auto-loading version.
|
5
|
+
# We don't want these tests to fail when dependencies are to blame.
|
6
|
+
module Controllers
|
7
|
+
class BenchmarkedController < ActionController::Base
|
8
|
+
def public_action
|
9
|
+
render :nothing => true
|
10
|
+
end
|
11
|
+
|
12
|
+
def rescue_action(e)
|
13
|
+
raise e
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class BenchmarkTest < Test::Unit::TestCase
|
19
|
+
class MockLogger
|
20
|
+
def method_missing(*args)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def setup
|
25
|
+
@controller = Controllers::BenchmarkedController.new
|
26
|
+
# benchmark doesn't do anything unless a logger is set
|
27
|
+
@controller.logger = MockLogger.new
|
28
|
+
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
|
29
|
+
@request.host = "test.actioncontroller.i"
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_with_http_1_0_request
|
33
|
+
@request.host = nil
|
34
|
+
assert_nothing_raised { get :public_action }
|
35
|
+
end
|
36
|
+
end
|
@@ -1,16 +1,15 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require File.dirname(__FILE__) + '/../abstract_unit'
|
3
3
|
|
4
|
-
#generate the greatest logging class that ever lived
|
5
4
|
class TestLogDevice < Logger::LogDevice
|
6
5
|
attr :last_message, true
|
7
6
|
|
8
7
|
def initialize
|
9
|
-
|
8
|
+
@last_message=String.new
|
10
9
|
end
|
11
10
|
|
12
11
|
def write(message)
|
13
|
-
|
12
|
+
@last_message << message
|
14
13
|
end
|
15
14
|
|
16
15
|
def clear
|
@@ -23,14 +22,13 @@ TestLog = TestLogDevice.new
|
|
23
22
|
RAILS_DEFAULT_LOGGER = Logger.new(TestLog)
|
24
23
|
ActionController::Base.logger = RAILS_DEFAULT_LOGGER
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
ActionController::Base.
|
31
|
-
|
32
|
-
|
33
|
-
ActionController::Routing::Routes.connect "test", :controller => 'test', :action => 'render_to_cache'
|
25
|
+
def use_store
|
26
|
+
#generate a random key to ensure the cache is always in a different location
|
27
|
+
RANDOM_KEY = rand(99999999).to_s
|
28
|
+
FILE_STORE_PATH = File.dirname(__FILE__) + '/../temp/' + RANDOM_KEY
|
29
|
+
ActionController::Base.perform_caching = true
|
30
|
+
ActionController::Base.fragment_cache_store = :file_store, FILE_STORE_PATH
|
31
|
+
end
|
34
32
|
|
35
33
|
class TestController < ActionController::Base
|
36
34
|
caches_action :render_to_cache, :index
|
@@ -45,48 +43,32 @@ class FileStoreTest < Test::Unit::TestCase
|
|
45
43
|
def setup
|
46
44
|
@request = ActionController::TestRequest.new
|
47
45
|
@response = ActionController::TestResponse.new
|
46
|
+
@controller = TestController.new
|
48
47
|
@request.host = "hostname.com"
|
49
48
|
end
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
@request.path_parameters = {:controller => "test"}
|
54
|
-
assert_fragment_cached do process_request end
|
55
|
-
end
|
56
|
-
|
57
|
-
#To prime the cache with hostname.com/test/render_to_cache
|
58
|
-
def test_render_to_cache_prime_b
|
59
|
-
@request.path_parameters = {:action => "render_to_cache", :controller => "test"}
|
60
|
-
assert_fragment_cached do process_request end
|
49
|
+
|
50
|
+
def teardown
|
51
|
+
FileUtils.rm_rf(FILE_STORE_PATH)
|
61
52
|
end
|
62
53
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
assert_fragment_hit do process_request end
|
54
|
+
def test_render_cached
|
55
|
+
assert_fragment_cached { get :render_to_cache }
|
56
|
+
assert_fragment_hit { get :render_to_cache }
|
67
57
|
end
|
68
58
|
|
69
|
-
#To hit the cache with hostname.com/test/render_to_cache
|
70
|
-
def test_render_to_cache_zhit_b
|
71
|
-
@request.path_parameters = {:action => "render_to_cache", :controller => "test"}
|
72
|
-
assert_fragment_hit do process_request end
|
73
|
-
end
|
74
59
|
|
75
60
|
private
|
76
|
-
def
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
def assert_fragment_cached(&proc)
|
81
|
-
proc.call
|
61
|
+
def assert_fragment_cached
|
62
|
+
yield
|
82
63
|
assert(TestLog.last_message.include?("Cached fragment:"), "--ERROR-- FileStore write failed ----")
|
83
64
|
assert(!TestLog.last_message.include?("Couldn't create cache directory:"), "--ERROR-- FileStore create directory failed ----")
|
84
65
|
TestLog.clear
|
85
66
|
end
|
86
67
|
|
87
|
-
def assert_fragment_hit
|
88
|
-
|
89
|
-
assert(TestLog.last_message.include?(
|
68
|
+
def assert_fragment_hit
|
69
|
+
yield
|
70
|
+
assert(TestLog.last_message.include?("Fragment read:"), "--ERROR-- Fragment not found in FileStore ----")
|
71
|
+
assert(!TestLog.last_message.include?("Cached fragment:"), "--ERROR-- Did cache ----")
|
90
72
|
TestLog.clear
|
91
73
|
end
|
92
74
|
end
|
@@ -4,6 +4,10 @@ class CaptureController < ActionController::Base
|
|
4
4
|
def self.controller_name; "test"; end
|
5
5
|
def self.controller_path; "test"; end
|
6
6
|
|
7
|
+
def content_for
|
8
|
+
render :layout => "talk_from_action"
|
9
|
+
end
|
10
|
+
|
7
11
|
def rescue_action(e) raise end
|
8
12
|
end
|
9
13
|
|
@@ -27,11 +31,16 @@ class CaptureTest < Test::Unit::TestCase
|
|
27
31
|
get :capturing
|
28
32
|
assert_equal "Dreamy days", @response.body.strip
|
29
33
|
end
|
34
|
+
|
35
|
+
def test_content_for
|
36
|
+
get :content_for
|
37
|
+
assert_equal "<title>Putting stuff in the title!</title>\n\nGreat stuff!", @response.body
|
38
|
+
end
|
30
39
|
|
31
40
|
def test_update_element_with_capture
|
32
41
|
get :update_element_with_capture
|
33
42
|
assert_equal(
|
34
|
-
"<script type=\"text/javascript\"
|
43
|
+
"<script type=\"text/javascript\">\n//<![CDATA[\n$('products').innerHTML = '\\n <p>Product 1</p>\\n <p>Product 2</p>\\n';\n\n//]]>\n</script>" +
|
35
44
|
"\n\n$('status').innerHTML = '\\n <b>You bought something!</b>\\n';",
|
36
45
|
@response.body.strip
|
37
46
|
)
|
data/test/controller/cgi_test.rb
CHANGED
@@ -1,18 +1,9 @@
|
|
1
|
-
|
1
|
+
require File.dirname(__FILE__) + '/../abstract_unit'
|
2
|
+
require 'action_controller/cgi_process'
|
3
|
+
require 'action_controller/cgi_ext/cgi_ext'
|
2
4
|
|
3
|
-
require 'test/unit'
|
4
|
-
require 'action_controller/cgi_ext/cgi_methods'
|
5
|
-
require 'stringio'
|
6
|
-
|
7
|
-
class MockUploadedFile < StringIO
|
8
|
-
def content_type
|
9
|
-
"img/jpeg"
|
10
|
-
end
|
11
5
|
|
12
|
-
|
13
|
-
"my_file.doc"
|
14
|
-
end
|
15
|
-
end
|
6
|
+
require 'stringio'
|
16
7
|
|
17
8
|
class CGITest < Test::Unit::TestCase
|
18
9
|
def setup
|
@@ -24,6 +15,8 @@ class CGITest < Test::Unit::TestCase
|
|
24
15
|
"action=update_order&full_name=Lau%20Taarnskov&products=4&products=2&products=3"
|
25
16
|
@query_string_with_many_equal = "action=create_customer&full_name=abc=def=ghi"
|
26
17
|
@query_string_without_equal = "action"
|
18
|
+
@query_string_with_many_ampersands =
|
19
|
+
"&action=create_customer&&&full_name=David%20Heinemeier%20Hansson"
|
27
20
|
end
|
28
21
|
|
29
22
|
def test_query_string
|
@@ -76,7 +69,14 @@ class CGITest < Test::Unit::TestCase
|
|
76
69
|
CGIMethods.parse_query_parameters(@query_string_without_equal)
|
77
70
|
)
|
78
71
|
end
|
79
|
-
|
72
|
+
|
73
|
+
def test_query_string_with_many_ampersands
|
74
|
+
assert_equal(
|
75
|
+
{ "action" => "create_customer", "full_name" => "David Heinemeier Hansson"},
|
76
|
+
CGIMethods.parse_query_parameters(@query_string_with_many_ampersands)
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
80
|
def test_parse_params
|
81
81
|
input = {
|
82
82
|
"customers[boston][first][name]" => [ "David" ],
|
@@ -116,15 +116,20 @@ class CGITest < Test::Unit::TestCase
|
|
116
116
|
end
|
117
117
|
|
118
118
|
def test_parse_params_from_multipart_upload
|
119
|
-
|
119
|
+
mockup = Struct.new(:content_type, :original_filename)
|
120
|
+
file = mockup.new('img/jpeg', 'foo.jpg')
|
121
|
+
ie_file = mockup.new('img/jpeg', 'c:\\Documents and Settings\\foo\\Desktop\\bar.jpg')
|
120
122
|
|
121
123
|
input = {
|
122
124
|
"something" => [ StringIO.new("") ],
|
123
125
|
"array_of_stringios" => [[ StringIO.new("One"), StringIO.new("Two") ]],
|
124
126
|
"mixed_types_array" => [[ StringIO.new("Three"), "NotStringIO" ]],
|
125
|
-
"mixed_types_as_checkboxes[strings][nested]" => [[
|
127
|
+
"mixed_types_as_checkboxes[strings][nested]" => [[ file, "String", StringIO.new("StringIO")]],
|
128
|
+
"ie_mixed_types_as_checkboxes[strings][nested]" => [[ ie_file, "String", StringIO.new("StringIO")]],
|
126
129
|
"products[string]" => [ StringIO.new("Apple Computer") ],
|
127
|
-
"products[file]" => [
|
130
|
+
"products[file]" => [ file ],
|
131
|
+
"ie_products[string]" => [ StringIO.new("Microsoft") ],
|
132
|
+
"ie_products[file]" => [ ie_file ]
|
128
133
|
}
|
129
134
|
|
130
135
|
expected_output = {
|
@@ -132,17 +137,35 @@ class CGITest < Test::Unit::TestCase
|
|
132
137
|
"array_of_stringios" => ["One", "Two"],
|
133
138
|
"mixed_types_array" => [ "Three", "NotStringIO" ],
|
134
139
|
"mixed_types_as_checkboxes" => {
|
135
|
-
"strings"=> {
|
136
|
-
"nested"=>[
|
140
|
+
"strings" => {
|
141
|
+
"nested" => [ file, "String", "StringIO" ]
|
137
142
|
},
|
138
143
|
},
|
139
|
-
"
|
140
|
-
|
141
|
-
|
144
|
+
"ie_mixed_types_as_checkboxes" => {
|
145
|
+
"strings" => {
|
146
|
+
"nested" => [ ie_file, "String", "StringIO" ]
|
147
|
+
},
|
148
|
+
},
|
149
|
+
"products" => {
|
150
|
+
"string" => "Apple Computer",
|
151
|
+
"file" => file
|
152
|
+
},
|
153
|
+
"ie_products" => {
|
154
|
+
"string" => "Microsoft",
|
155
|
+
"file" => ie_file
|
142
156
|
}
|
143
157
|
}
|
144
158
|
|
145
|
-
|
159
|
+
params = CGIMethods.parse_request_parameters(input)
|
160
|
+
assert_equal expected_output, params
|
161
|
+
|
162
|
+
# Lone filenames are preserved.
|
163
|
+
assert_equal 'foo.jpg', params['mixed_types_as_checkboxes']['strings']['nested'].first.original_filename
|
164
|
+
assert_equal 'foo.jpg', params['products']['file'].original_filename
|
165
|
+
|
166
|
+
# But full Windows paths are reduced to their basename.
|
167
|
+
assert_equal 'bar.jpg', params['ie_mixed_types_as_checkboxes']['strings']['nested'].first.original_filename
|
168
|
+
assert_equal 'bar.jpg', params['ie_products']['file'].original_filename
|
146
169
|
end
|
147
170
|
|
148
171
|
def test_parse_params_with_file
|
@@ -206,3 +229,102 @@ class CGITest < Test::Unit::TestCase
|
|
206
229
|
end
|
207
230
|
end
|
208
231
|
|
232
|
+
class MultipartCGITest < Test::Unit::TestCase
|
233
|
+
FIXTURE_PATH = File.dirname(__FILE__) + '/../fixtures/multipart'
|
234
|
+
|
235
|
+
def setup
|
236
|
+
ENV['REQUEST_METHOD'] = 'POST'
|
237
|
+
ENV['CONTENT_LENGTH'] = '0'
|
238
|
+
ENV['CONTENT_TYPE'] = 'multipart/form-data, boundary=AaB03x'
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_single_parameter
|
242
|
+
params = process('single_parameter')
|
243
|
+
assert_equal({ 'foo' => 'bar' }, params)
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_text_file
|
247
|
+
params = process('text_file')
|
248
|
+
assert_equal %w(file foo), params.keys.sort
|
249
|
+
assert_equal 'bar', params['foo']
|
250
|
+
|
251
|
+
file = params['file']
|
252
|
+
assert_kind_of StringIO, file
|
253
|
+
assert_equal 'file.txt', file.original_filename
|
254
|
+
assert_equal "text/plain\r", file.content_type
|
255
|
+
assert_equal 'contents', file.read
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_large_text_file
|
259
|
+
params = process('large_text_file')
|
260
|
+
assert_equal %w(file foo), params.keys.sort
|
261
|
+
assert_equal 'bar', params['foo']
|
262
|
+
|
263
|
+
file = params['file']
|
264
|
+
assert_kind_of Tempfile, file
|
265
|
+
assert_equal 'file.txt', file.original_filename
|
266
|
+
assert_equal "text/plain\r", file.content_type
|
267
|
+
assert ('a' * 20480) == file.read
|
268
|
+
end
|
269
|
+
|
270
|
+
def test_binary_file
|
271
|
+
params = process('binary_file')
|
272
|
+
assert_equal %w(file flowers foo), params.keys.sort
|
273
|
+
assert_equal 'bar', params['foo']
|
274
|
+
|
275
|
+
file = params['file']
|
276
|
+
assert_kind_of StringIO, file
|
277
|
+
assert_equal 'file.txt', file.original_filename
|
278
|
+
assert_equal "text/plain\r", file.content_type
|
279
|
+
assert_equal 'contents', file.read
|
280
|
+
|
281
|
+
file = params['flowers']
|
282
|
+
assert_kind_of StringIO, file
|
283
|
+
assert_equal 'flowers.jpg', file.original_filename
|
284
|
+
assert_equal "image/jpeg\r", file.content_type
|
285
|
+
assert_equal 19512, file.size
|
286
|
+
#assert_equal File.read(File.dirname(__FILE__) + '/../../../activerecord/test/fixtures/flowers.jpg'), file.read
|
287
|
+
end
|
288
|
+
|
289
|
+
def test_mixed_files
|
290
|
+
params = process('mixed_files')
|
291
|
+
assert_equal %w(files foo), params.keys.sort
|
292
|
+
assert_equal 'bar', params['foo']
|
293
|
+
|
294
|
+
# Ruby CGI doesn't handle multipart/mixed for us.
|
295
|
+
assert_kind_of StringIO, params['files']
|
296
|
+
assert_equal 19756, params['files'].size
|
297
|
+
end
|
298
|
+
|
299
|
+
private
|
300
|
+
def process(name)
|
301
|
+
old_stdin = $stdin
|
302
|
+
File.open(File.join(FIXTURE_PATH, name), 'rb') do |file|
|
303
|
+
ENV['CONTENT_LENGTH'] = file.stat.size.to_s
|
304
|
+
$stdin = file
|
305
|
+
CGIMethods.parse_request_parameters CGI.new.params
|
306
|
+
end
|
307
|
+
ensure
|
308
|
+
$stdin = old_stdin
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
|
313
|
+
class CGIRequestTest < Test::Unit::TestCase
|
314
|
+
def setup
|
315
|
+
@request_hash = {"HTTP_MAX_FORWARDS"=>"10", "SERVER_NAME"=>"glu.ttono.us:8007", "FCGI_ROLE"=>"RESPONDER", "HTTP_X_FORWARDED_HOST"=>"glu.ttono.us", "HTTP_ACCEPT_ENCODING"=>"gzip, deflate", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/312.5.1 (KHTML, like Gecko) Safari/312.3.1", "PATH_INFO"=>"", "HTTP_ACCEPT_LANGUAGE"=>"en", "HTTP_HOST"=>"glu.ttono.us:8007", "SERVER_PROTOCOL"=>"HTTP/1.1", "REDIRECT_URI"=>"/dispatch.fcgi", "SCRIPT_NAME"=>"/dispatch.fcgi", "SERVER_ADDR"=>"207.7.108.53", "REMOTE_ADDR"=>"207.7.108.53", "SERVER_SOFTWARE"=>"lighttpd/1.4.5", "HTTP_COOKIE"=>"_session_id=c84ace84796670c052c6ceb2451fb0f2; is_admin=yes", "HTTP_X_FORWARDED_SERVER"=>"glu.ttono.us", "REQUEST_URI"=>"/admin", "DOCUMENT_ROOT"=>"/home/kevinc/sites/typo/public", "SERVER_PORT"=>"8007", "QUERY_STRING"=>"", "REMOTE_PORT"=>"63137", "GATEWAY_INTERFACE"=>"CGI/1.1", "HTTP_X_FORWARDED_FOR"=>"65.88.180.234", "HTTP_ACCEPT"=>"*/*", "SCRIPT_FILENAME"=>"/home/kevinc/sites/typo/public/dispatch.fcgi", "REDIRECT_STATUS"=>"200", "REQUEST_METHOD"=>"GET"}
|
316
|
+
@fake_cgi = Struct.new(:env_table).new(@request_hash)
|
317
|
+
@request = ActionController::CgiRequest.new(@fake_cgi)
|
318
|
+
end
|
319
|
+
|
320
|
+
def test_proxy_request
|
321
|
+
assert_equal 'glu.ttono.us', @request.host_with_port
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_http_host
|
325
|
+
@request_hash.delete "HTTP_X_FORWARDED_HOST"
|
326
|
+
@request_hash['HTTP_HOST'] = "rubyonrails.org:8080"
|
327
|
+
assert_equal "rubyonrails.org:8080", @request.host_with_port
|
328
|
+
end
|
329
|
+
|
330
|
+
end
|