actionpack 1.13.6 → 2.0.0
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 +1400 -20
- data/MIT-LICENSE +1 -1
- data/README +5 -5
- data/RUNNING_UNIT_TESTS +4 -5
- data/Rakefile +5 -6
- data/install.rb +2 -2
- data/lib/action_controller.rb +11 -15
- data/lib/action_controller/assertions.rb +12 -25
- data/lib/action_controller/assertions/dom_assertions.rb +18 -4
- data/lib/action_controller/assertions/model_assertions.rb +8 -1
- data/lib/action_controller/assertions/response_assertions.rb +35 -12
- data/lib/action_controller/assertions/routing_assertions.rb +56 -12
- data/lib/action_controller/assertions/selector_assertions.rb +105 -38
- data/lib/action_controller/assertions/tag_assertions.rb +28 -15
- data/lib/action_controller/base.rb +318 -250
- data/lib/action_controller/benchmarking.rb +33 -29
- data/lib/action_controller/caching.rb +130 -64
- data/lib/action_controller/cgi_ext.rb +16 -0
- data/lib/action_controller/cgi_ext/{cookie_performance_fix.rb → cookie.rb} +25 -40
- data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
- data/lib/action_controller/cgi_ext/session.rb +73 -0
- data/lib/action_controller/cgi_ext/stdinput.rb +23 -0
- data/lib/action_controller/cgi_process.rb +34 -57
- data/lib/action_controller/components.rb +19 -36
- data/lib/action_controller/cookies.rb +10 -9
- data/lib/action_controller/dispatcher.rb +195 -0
- data/lib/action_controller/filters.rb +35 -34
- data/lib/action_controller/flash.rb +30 -35
- data/lib/action_controller/helpers.rb +121 -47
- data/lib/action_controller/http_authentication.rb +126 -0
- data/lib/action_controller/integration.rb +105 -101
- data/lib/action_controller/layout.rb +59 -47
- data/lib/action_controller/mime_responds.rb +57 -68
- data/lib/action_controller/mime_type.rb +43 -80
- data/lib/action_controller/mime_types.rb +20 -0
- data/lib/action_controller/polymorphic_routes.rb +88 -0
- data/lib/action_controller/record_identifier.rb +91 -0
- data/lib/action_controller/request.rb +553 -88
- data/lib/action_controller/request_forgery_protection.rb +126 -0
- data/lib/action_controller/request_profiler.rb +138 -0
- data/lib/action_controller/rescue.rb +185 -69
- data/lib/action_controller/resources.rb +211 -172
- data/lib/action_controller/response.rb +49 -8
- data/lib/action_controller/routing.rb +359 -236
- data/lib/action_controller/routing_optimisation.rb +119 -0
- data/lib/action_controller/session/active_record_store.rb +3 -2
- data/lib/action_controller/session/cookie_store.rb +161 -0
- data/lib/action_controller/session/mem_cache_store.rb +9 -16
- data/lib/action_controller/session_management.rb +17 -8
- data/lib/action_controller/streaming.rb +6 -3
- data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
- data/lib/action_controller/templates/rescues/{_trace.rhtml → _trace.erb} +0 -0
- data/lib/action_controller/templates/rescues/{diagnostics.rhtml → diagnostics.erb} +2 -2
- data/lib/action_controller/templates/rescues/{layout.rhtml → layout.erb} +0 -0
- data/lib/action_controller/templates/rescues/{missing_template.rhtml → missing_template.erb} +0 -0
- data/lib/action_controller/templates/rescues/{routing_error.rhtml → routing_error.erb} +0 -0
- data/lib/action_controller/templates/rescues/{template_error.rhtml → template_error.erb} +2 -2
- data/lib/action_controller/templates/rescues/{unknown_action.rhtml → unknown_action.erb} +0 -0
- data/lib/action_controller/test_case.rb +53 -0
- data/lib/action_controller/test_process.rb +59 -46
- data/lib/action_controller/url_rewriter.rb +48 -24
- data/lib/action_controller/vendor/html-scanner/html/document.rb +7 -4
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +11 -6
- data/lib/action_controller/verification.rb +27 -21
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +4 -4
- data/lib/action_view.rb +2 -3
- data/lib/action_view/base.rb +218 -63
- data/lib/action_view/compiled_templates.rb +1 -2
- data/lib/action_view/helpers/active_record_helper.rb +35 -17
- data/lib/action_view/helpers/asset_tag_helper.rb +395 -87
- data/lib/action_view/helpers/atom_feed_helper.rb +111 -0
- data/lib/action_view/helpers/benchmark_helper.rb +12 -5
- data/lib/action_view/helpers/cache_helper.rb +29 -0
- data/lib/action_view/helpers/capture_helper.rb +97 -63
- data/lib/action_view/helpers/date_helper.rb +295 -35
- data/lib/action_view/helpers/debug_helper.rb +6 -2
- data/lib/action_view/helpers/form_helper.rb +354 -111
- data/lib/action_view/helpers/form_options_helper.rb +171 -109
- data/lib/action_view/helpers/form_tag_helper.rb +332 -76
- data/lib/action_view/helpers/javascript_helper.rb +35 -11
- data/lib/action_view/helpers/javascripts/controls.js +484 -354
- data/lib/action_view/helpers/javascripts/dragdrop.js +88 -58
- data/lib/action_view/helpers/javascripts/effects.js +396 -364
- data/lib/action_view/helpers/javascripts/prototype.js +2817 -1107
- data/lib/action_view/helpers/number_helper.rb +84 -60
- data/lib/action_view/helpers/prototype_helper.rb +419 -43
- data/lib/action_view/helpers/record_identification_helper.rb +20 -0
- data/lib/action_view/helpers/record_tag_helper.rb +59 -0
- data/lib/action_view/helpers/sanitize_helper.rb +223 -0
- data/lib/action_view/helpers/scriptaculous_helper.rb +63 -4
- data/lib/action_view/helpers/tag_helper.rb +69 -39
- data/lib/action_view/helpers/text_helper.rb +221 -148
- data/lib/action_view/helpers/url_helper.rb +283 -165
- data/lib/action_view/partials.rb +134 -62
- data/lib/action_view/template_error.rb +4 -12
- data/lib/actionpack.rb +1 -0
- data/test/abstract_unit.rb +21 -1
- data/test/action_view_test.rb +26 -0
- data/test/active_record_unit.rb +12 -20
- data/test/activerecord/active_record_store_test.rb +2 -2
- data/test/activerecord/render_partial_with_record_identification_test.rb +74 -0
- data/test/controller/action_pack_assertions_test.rb +21 -152
- data/test/controller/addresses_render_test.rb +2 -7
- data/test/controller/assert_select_test.rb +120 -14
- data/test/controller/base_test.rb +11 -13
- data/test/controller/caching_test.rb +125 -5
- data/test/controller/capture_test.rb +23 -16
- data/test/controller/cgi_test.rb +66 -391
- data/test/controller/components_test.rb +31 -42
- data/test/controller/content_type_test.rb +1 -1
- data/test/controller/cookie_test.rb +42 -14
- data/test/controller/deprecation/deprecated_base_methods_test.rb +1 -42
- data/test/controller/dispatcher_test.rb +123 -0
- data/test/controller/fake_models.rb +5 -0
- data/test/controller/filters_test.rb +44 -7
- data/test/controller/flash_test.rb +46 -2
- data/test/controller/fragment_store_setting_test.rb +10 -8
- data/test/controller/helper_test.rb +19 -2
- data/test/controller/html-scanner/document_test.rb +124 -0
- data/test/controller/html-scanner/node_test.rb +69 -0
- data/test/controller/html-scanner/sanitizer_test.rb +250 -0
- data/test/controller/html-scanner/tag_node_test.rb +239 -0
- data/test/controller/html-scanner/text_node_test.rb +51 -0
- data/test/controller/html-scanner/tokenizer_test.rb +125 -0
- data/test/controller/http_authentication_test.rb +54 -0
- data/test/controller/integration_test.rb +12 -26
- data/test/controller/layout_test.rb +64 -12
- data/test/controller/mime_responds_test.rb +193 -38
- data/test/controller/mime_type_test.rb +30 -8
- data/test/controller/new_render_test.rb +104 -22
- data/test/controller/polymorphic_routes_test.rb +98 -0
- data/test/controller/record_identifier_test.rb +103 -0
- data/test/controller/redirect_test.rb +120 -18
- data/test/controller/render_test.rb +195 -45
- data/test/controller/request_forgery_protection_test.rb +217 -0
- data/test/controller/request_test.rb +545 -27
- data/test/controller/rescue_test.rb +501 -0
- data/test/controller/resources_test.rb +258 -132
- data/test/controller/routing_test.rb +502 -106
- data/test/controller/selector_test.rb +5 -5
- data/test/controller/send_file_test.rb +17 -7
- data/test/controller/session/cookie_store_test.rb +246 -0
- data/test/controller/session/mem_cache_store_test.rb +182 -0
- data/test/controller/session_fixation_test.rb +8 -11
- data/test/controller/session_management_test.rb +7 -7
- data/test/controller/test_test.rb +150 -38
- data/test/controller/url_rewriter_test.rb +87 -12
- data/test/controller/verification_test.rb +11 -0
- data/test/controller/view_paths_test.rb +137 -0
- data/test/controller/webservice_test.rb +11 -75
- data/test/fixtures/addresses/{list.rhtml → list.erb} +0 -0
- data/test/fixtures/db_definitions/sqlite.sql +2 -1
- data/test/fixtures/developer.rb +2 -0
- data/test/fixtures/fun/games/{hello_world.rhtml → hello_world.erb} +0 -0
- data/test/fixtures/helpers/fun/pdf_helper.rb +1 -1
- data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
- data/test/fixtures/layouts/{builder.rxml → builder.builder} +0 -0
- data/test/fixtures/layouts/{standard.rhtml → standard.erb} +0 -0
- data/test/fixtures/layouts/{talk_from_action.rhtml → talk_from_action.erb} +0 -0
- data/test/fixtures/layouts/{yield.rhtml → yield.erb} +0 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/multipart/bracketed_param +5 -0
- data/test/fixtures/override/test/hello_world.erb +1 -0
- data/test/fixtures/override2/layouts/test/sub.erb +1 -0
- data/test/fixtures/post_test/layouts/post.html.erb +1 -0
- data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
- data/test/fixtures/post_test/post/index.html.erb +1 -0
- data/test/fixtures/post_test/post/index.iphone.erb +1 -0
- data/test/fixtures/post_test/super_post/index.html.erb +1 -0
- data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
- data/test/fixtures/public/404.html +1 -0
- data/test/fixtures/public/500.html +1 -0
- data/test/fixtures/public/javascripts/application.js +0 -1
- data/test/fixtures/public/javascripts/bank.js +1 -0
- data/test/fixtures/public/javascripts/robber.js +1 -0
- data/test/fixtures/public/stylesheets/bank.css +1 -0
- data/test/fixtures/public/stylesheets/robber.css +1 -0
- data/test/fixtures/replies.yml +2 -0
- data/test/fixtures/reply.rb +2 -1
- data/test/fixtures/respond_to/{all_types_with_layout.rhtml → all_types_with_layout.html.erb} +0 -0
- data/test/fixtures/respond_to/{all_types_with_layout.rjs → all_types_with_layout.js.rjs} +0 -0
- data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
- data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
- data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
- data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
- data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
- data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
- data/test/fixtures/respond_to/{using_defaults.rhtml → using_defaults.html.erb} +0 -0
- data/test/fixtures/respond_to/{using_defaults.rjs → using_defaults.js.rjs} +0 -0
- data/test/fixtures/respond_to/{using_defaults.rxml → using_defaults.xml.builder} +0 -0
- data/test/fixtures/respond_to/{using_defaults_with_type_list.rhtml → using_defaults_with_type_list.html.erb} +0 -0
- data/test/fixtures/respond_to/{using_defaults_with_type_list.rjs → using_defaults_with_type_list.js.rjs} +0 -0
- data/test/fixtures/respond_to/{using_defaults_with_type_list.rxml → using_defaults_with_type_list.xml.builder} +0 -0
- data/test/fixtures/scope/test/{modgreet.rhtml → modgreet.erb} +0 -0
- data/test/fixtures/test/{_customer.rhtml → _customer.erb} +0 -0
- data/test/fixtures/test/{_customer_greeting.rhtml → _customer_greeting.erb} +0 -0
- data/test/fixtures/test/_hash_greeting.erb +1 -0
- data/test/fixtures/test/_hash_object.erb +2 -0
- data/test/fixtures/test/{_hello.rxml → _hello.builder} +0 -0
- data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
- data/test/fixtures/test/_partial.erb +1 -0
- data/test/fixtures/test/_partial.html.erb +1 -0
- data/test/fixtures/test/_partial.js.erb +1 -0
- data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
- data/test/fixtures/test/{_partial_only.rhtml → _partial_only.erb} +0 -0
- data/test/fixtures/test/{_person.rhtml → _person.erb} +0 -0
- data/test/fixtures/test/{action_talk_to_layout.rhtml → action_talk_to_layout.erb} +0 -0
- data/test/fixtures/test/{block_content_for.rhtml → block_content_for.erb} +0 -0
- data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
- data/test/fixtures/test/{capturing.rhtml → capturing.erb} +0 -0
- data/test/fixtures/test/{content_for.rhtml → content_for.erb} +0 -0
- data/test/fixtures/test/content_for_concatenated.erb +3 -0
- data/test/fixtures/test/content_for_with_parameter.erb +2 -0
- data/test/fixtures/test/dot.directory/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
- data/test/fixtures/test/{erb_content_for.rhtml → erb_content_for.erb} +0 -0
- data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
- data/test/fixtures/test/formatted_xml_erb.builder +1 -0
- data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
- data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
- data/test/fixtures/test/{greeting.rhtml → greeting.erb} +0 -0
- data/test/fixtures/test/{hello.rxml → hello.builder} +0 -0
- data/test/fixtures/test/{hello_world.rxml → hello_world.builder} +0 -0
- data/test/fixtures/test/{hello_world.rhtml → hello_world.erb} +0 -0
- data/test/fixtures/test/{hello_world_container.rxml → hello_world_container.builder} +0 -0
- data/test/fixtures/test/{hello_world_with_layout_false.rhtml → hello_world_with_layout_false.erb} +0 -0
- data/test/fixtures/test/{hello_xml_world.rxml → hello_xml_world.builder} +0 -0
- data/test/fixtures/test/list.erb +1 -0
- data/test/fixtures/test/{non_erb_block_content_for.rxml → non_erb_block_content_for.builder} +0 -0
- data/test/fixtures/test/{potential_conflicts.rhtml → potential_conflicts.erb} +0 -0
- data/test/fixtures/test/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
- data/test/fixtures/test/{render_file_with_locals.rhtml → render_file_with_locals.erb} +0 -0
- data/test/fixtures/test/{render_to_string_test.rhtml → render_to_string_test.erb} +0 -0
- data/test/fixtures/test/{update_element_with_capture.rhtml → update_element_with_capture.erb} +0 -0
- data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
- data/test/fixtures/topic.rb +1 -1
- data/test/template/active_record_helper_test.rb +67 -20
- data/test/template/asset_tag_helper_test.rb +222 -54
- data/test/template/atom_feed_helper_test.rb +101 -0
- data/test/template/benchmark_helper_test.rb +2 -2
- data/test/template/compiled_templates_test.rb +76 -32
- data/test/template/date_helper_test.rb +125 -9
- data/test/template/form_helper_test.rb +326 -33
- data/test/template/form_options_helper_test.rb +822 -15
- data/test/template/form_tag_helper_test.rb +96 -30
- data/test/template/javascript_helper_test.rb +61 -13
- data/test/template/number_helper_test.rb +12 -11
- data/test/template/prototype_helper_test.rb +185 -24
- data/test/template/sanitize_helper_test.rb +49 -0
- data/test/template/scriptaculous_helper_test.rb +9 -3
- data/test/template/tag_helper_test.rb +13 -2
- data/test/template/text_helper_test.rb +38 -52
- data/test/template/url_helper_test.rb +216 -46
- metadata +144 -116
- data/examples/.htaccess +0 -24
- data/examples/address_book/index.rhtml +0 -33
- data/examples/address_book/layout.rhtml +0 -8
- data/examples/address_book_controller.cgi +0 -9
- data/examples/address_book_controller.fcgi +0 -6
- data/examples/address_book_controller.rb +0 -52
- data/examples/address_book_controller.rbx +0 -4
- data/examples/benchmark.rb +0 -52
- data/examples/benchmark_with_ar.fcgi +0 -89
- data/examples/blog_controller.cgi +0 -53
- data/examples/debate/index.rhtml +0 -14
- data/examples/debate/new_topic.rhtml +0 -22
- data/examples/debate/topic.rhtml +0 -32
- data/examples/debate_controller.cgi +0 -57
- data/lib/action_controller/assertions/deprecated_assertions.rb +0 -228
- data/lib/action_controller/cgi_ext/cgi_ext.rb +0 -36
- data/lib/action_controller/cgi_ext/cgi_methods.rb +0 -211
- data/lib/action_controller/cgi_ext/pstore_performance_fix.rb +0 -30
- data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +0 -95
- data/lib/action_controller/cgi_ext/session_performance_fix.rb +0 -30
- data/lib/action_controller/deprecated_dependencies.rb +0 -65
- data/lib/action_controller/deprecated_redirects.rb +0 -17
- data/lib/action_controller/deprecated_request_methods.rb +0 -34
- data/lib/action_controller/macros/auto_complete.rb +0 -53
- data/lib/action_controller/macros/in_place_editing.rb +0 -33
- data/lib/action_controller/pagination.rb +0 -408
- data/lib/action_controller/scaffolding.rb +0 -189
- data/lib/action_controller/templates/rescues/_request_and_response.rhtml +0 -44
- data/lib/action_controller/templates/scaffolds/edit.rhtml +0 -7
- data/lib/action_controller/templates/scaffolds/layout.rhtml +0 -69
- data/lib/action_controller/templates/scaffolds/list.rhtml +0 -27
- data/lib/action_controller/templates/scaffolds/new.rhtml +0 -6
- data/lib/action_controller/templates/scaffolds/show.rhtml +0 -9
- data/lib/action_controller/vendor/xml_node.rb +0 -97
- data/lib/action_view/helpers/deprecated_helper.rb +0 -37
- data/lib/action_view/helpers/java_script_macros_helper.rb +0 -233
- data/lib/action_view/helpers/pagination_helper.rb +0 -86
- data/test/activerecord/active_record_assertions_test.rb +0 -92
- data/test/activerecord/pagination_test.rb +0 -165
- data/test/controller/deprecated_instance_variables_test.rb +0 -48
- data/test/controller/raw_post_test.rb +0 -68
- data/test/fixtures/deprecated_instance_variables/_cookies_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_cookies_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_flash_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_flash_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_headers_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_headers_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_params_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_params_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_request_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_request_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_response_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_response_method.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_session_ivar.rhtml +0 -1
- data/test/fixtures/deprecated_instance_variables/_session_method.rhtml +0 -1
- data/test/fixtures/respond_to/layouts/standard.rhtml +0 -1
- data/test/fixtures/test/_hash_object.rhtml +0 -1
- data/test/fixtures/test/list.rhtml +0 -1
- data/test/template/deprecated_helper_test.rb +0 -36
- data/test/template/deprecated_instance_variables_test.rb +0 -43
- data/test/template/java_script_macros_helper_test.rb +0 -109
@@ -75,23 +75,21 @@ class ControllerInstanceTests < Test::Unit::TestCase
|
|
75
75
|
def test_action_methods
|
76
76
|
@empty_controllers.each do |c|
|
77
77
|
hide_mocha_methods_from_controller(c)
|
78
|
-
assert_equal Set.new, c.send(:action_methods), "#{c.controller_path} should be empty!"
|
78
|
+
assert_equal Set.new, c.send!(:action_methods), "#{c.controller_path} should be empty!"
|
79
79
|
end
|
80
80
|
@non_empty_controllers.each do |c|
|
81
81
|
hide_mocha_methods_from_controller(c)
|
82
|
-
assert_equal Set.new(
|
82
|
+
assert_equal Set.new(%w(public_action)), c.send!(:action_methods), "#{c.controller_path} should not be empty!"
|
83
83
|
end
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
protected
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end
|
94
|
-
|
87
|
+
# Mocha adds some public instance methods to Object that would be
|
88
|
+
# considered actions, so explicitly hide_action them.
|
89
|
+
def hide_mocha_methods_from_controller(controller)
|
90
|
+
mocha_methods = [:expects, :metaclass, :mocha, :mocha_inspect, :reset_mocha, :stubba_object, :stubba_method, :stubs, :verify, :__metaclass__, :__is_a__]
|
91
|
+
controller.class.send!(:hide_action, *mocha_methods)
|
92
|
+
end
|
95
93
|
end
|
96
94
|
|
97
95
|
|
@@ -118,7 +116,7 @@ class PerformActionTest < Test::Unit::TestCase
|
|
118
116
|
|
119
117
|
def test_method_missing_is_not_an_action_name
|
120
118
|
use_controller MethodMissingController
|
121
|
-
assert ! @controller.send(:action_methods).include?('method_missing')
|
119
|
+
assert ! @controller.send!(:action_methods).include?('method_missing')
|
122
120
|
|
123
121
|
get :method_missing
|
124
122
|
assert_response :success
|
@@ -133,4 +131,4 @@ class PerformActionTest < Test::Unit::TestCase
|
|
133
131
|
get :another_hidden_action
|
134
132
|
assert_response 404
|
135
133
|
end
|
136
|
-
end
|
134
|
+
end
|
@@ -2,9 +2,8 @@ require 'fileutils'
|
|
2
2
|
require File.dirname(__FILE__) + '/../abstract_unit'
|
3
3
|
|
4
4
|
CACHE_DIR = 'test_cache'
|
5
|
-
# Don't change '/../temp/' cavalierly or you might
|
5
|
+
# Don't change '/../temp/' cavalierly or you might hose something you don't want hosed
|
6
6
|
FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR)
|
7
|
-
ActionController::Base.perform_caching = true
|
8
7
|
ActionController::Base.page_cache_directory = FILE_STORE_PATH
|
9
8
|
ActionController::Base.fragment_cache_store = :file_store, FILE_STORE_PATH
|
10
9
|
|
@@ -26,10 +25,26 @@ class PageCachingTestController < ActionController::Base
|
|
26
25
|
def not_found
|
27
26
|
head :not_found
|
28
27
|
end
|
28
|
+
|
29
|
+
def custom_path
|
30
|
+
render :text => "Super soaker"
|
31
|
+
cache_page("Super soaker", "/index.html")
|
32
|
+
end
|
33
|
+
|
34
|
+
def expire_custom_path
|
35
|
+
expire_page("/index.html")
|
36
|
+
head :ok
|
37
|
+
end
|
38
|
+
|
39
|
+
def trailing_slash
|
40
|
+
render :text => "Sneak attack"
|
41
|
+
end
|
29
42
|
end
|
30
43
|
|
31
44
|
class PageCachingTest < Test::Unit::TestCase
|
32
45
|
def setup
|
46
|
+
ActionController::Base.perform_caching = true
|
47
|
+
|
33
48
|
ActionController::Routing::Routes.draw do |map|
|
34
49
|
map.main '', :controller => 'posts'
|
35
50
|
map.resources :posts
|
@@ -51,6 +66,8 @@ class PageCachingTest < Test::Unit::TestCase
|
|
51
66
|
|
52
67
|
def teardown
|
53
68
|
FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
|
69
|
+
|
70
|
+
ActionController::Base.perform_caching = false
|
54
71
|
end
|
55
72
|
|
56
73
|
def test_page_caching_resources_saves_to_correct_path_with_extension_even_if_default_route
|
@@ -66,6 +83,38 @@ class PageCachingTest < Test::Unit::TestCase
|
|
66
83
|
assert_page_cached :ok, "get with ok status should have been cached"
|
67
84
|
end
|
68
85
|
|
86
|
+
def test_should_cache_with_custom_path
|
87
|
+
get :custom_path
|
88
|
+
assert File.exist?("#{FILE_STORE_PATH}/index.html")
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_should_expire_cache_with_custom_path
|
92
|
+
get :custom_path
|
93
|
+
assert File.exist?("#{FILE_STORE_PATH}/index.html")
|
94
|
+
|
95
|
+
get :expire_custom_path
|
96
|
+
assert !File.exist?("#{FILE_STORE_PATH}/index.html")
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_should_cache_without_trailing_slash_on_url
|
100
|
+
@controller.class.cache_page 'cached content', '/page_caching_test/trailing_slash'
|
101
|
+
assert File.exist?("#{FILE_STORE_PATH}/page_caching_test/trailing_slash.html")
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_should_cache_with_trailing_slash_on_url
|
105
|
+
@controller.class.cache_page 'cached content', '/page_caching_test/trailing_slash/'
|
106
|
+
assert File.exist?("#{FILE_STORE_PATH}/page_caching_test/trailing_slash.html")
|
107
|
+
end
|
108
|
+
|
109
|
+
uses_mocha("should_cache_ok_at_custom_path") do
|
110
|
+
def test_should_cache_ok_at_custom_path
|
111
|
+
@request.expects(:path).returns("/index.html")
|
112
|
+
get :ok
|
113
|
+
assert_response :ok
|
114
|
+
assert File.exist?("#{FILE_STORE_PATH}/index.html")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
69
118
|
[:ok, :no_content, :found, :not_found].each do |status|
|
70
119
|
[:get, :post, :put, :delete].each do |method|
|
71
120
|
unless method == :get and status == :ok
|
@@ -93,15 +142,29 @@ class PageCachingTest < Test::Unit::TestCase
|
|
93
142
|
end
|
94
143
|
end
|
95
144
|
|
145
|
+
|
96
146
|
class ActionCachingTestController < ActionController::Base
|
97
|
-
caches_action :index
|
147
|
+
caches_action :index, :redirected, :forbidden
|
148
|
+
caches_action :show, :cache_path => 'http://test.host/custom/show'
|
149
|
+
caches_action :edit, :cache_path => Proc.new { |c| c.params[:id] ? "http://test.host/#{c.params[:id]};edit" : "http://test.host/edit" }
|
98
150
|
|
99
151
|
def index
|
100
|
-
sleep 0.01
|
101
152
|
@cache_this = Time.now.to_f.to_s
|
102
153
|
render :text => @cache_this
|
103
154
|
end
|
104
155
|
|
156
|
+
def redirected
|
157
|
+
redirect_to :action => 'index'
|
158
|
+
end
|
159
|
+
|
160
|
+
def forbidden
|
161
|
+
render :text => "Forbidden"
|
162
|
+
headers["Status"] = "403 Forbidden"
|
163
|
+
end
|
164
|
+
|
165
|
+
alias_method :show, :index
|
166
|
+
alias_method :edit, :index
|
167
|
+
|
105
168
|
def expire
|
106
169
|
expire_action :controller => 'action_caching_test', :action => 'index'
|
107
170
|
render :nothing => true
|
@@ -146,11 +209,32 @@ class ActionCacheTest < Test::Unit::TestCase
|
|
146
209
|
get :index
|
147
210
|
cached_time = content_to_cache
|
148
211
|
assert_equal cached_time, @response.body
|
212
|
+
assert_cache_exists 'hostname.com/action_caching_test'
|
149
213
|
reset!
|
150
214
|
|
151
215
|
get :index
|
152
216
|
assert_equal cached_time, @response.body
|
153
217
|
end
|
218
|
+
|
219
|
+
def test_action_cache_with_custom_cache_path
|
220
|
+
get :show
|
221
|
+
cached_time = content_to_cache
|
222
|
+
assert_equal cached_time, @response.body
|
223
|
+
assert_cache_exists 'test.host/custom/show'
|
224
|
+
reset!
|
225
|
+
|
226
|
+
get :show
|
227
|
+
assert_equal cached_time, @response.body
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_action_cache_with_custom_cache_path_in_block
|
231
|
+
get :edit
|
232
|
+
assert_cache_exists 'test.host/edit'
|
233
|
+
reset!
|
234
|
+
|
235
|
+
get :edit, :id => 1
|
236
|
+
assert_cache_exists 'test.host/1;edit'
|
237
|
+
end
|
154
238
|
|
155
239
|
def test_cache_expiration
|
156
240
|
get :index
|
@@ -178,21 +262,45 @@ class ActionCacheTest < Test::Unit::TestCase
|
|
178
262
|
@request.host = 'jamis.hostname.com'
|
179
263
|
get :index
|
180
264
|
jamis_cache = content_to_cache
|
181
|
-
|
265
|
+
|
266
|
+
reset!
|
267
|
+
|
182
268
|
@request.host = 'david.hostname.com'
|
183
269
|
get :index
|
184
270
|
david_cache = content_to_cache
|
185
271
|
assert_not_equal jamis_cache, @response.body
|
186
272
|
|
273
|
+
reset!
|
274
|
+
|
187
275
|
@request.host = 'jamis.hostname.com'
|
188
276
|
get :index
|
189
277
|
assert_equal jamis_cache, @response.body
|
190
278
|
|
279
|
+
reset!
|
280
|
+
|
191
281
|
@request.host = 'david.hostname.com'
|
192
282
|
get :index
|
193
283
|
assert_equal david_cache, @response.body
|
194
284
|
end
|
195
285
|
|
286
|
+
def test_redirect_is_not_cached
|
287
|
+
get :redirected
|
288
|
+
assert_response :redirect
|
289
|
+
reset!
|
290
|
+
|
291
|
+
get :redirected
|
292
|
+
assert_response :redirect
|
293
|
+
end
|
294
|
+
|
295
|
+
def test_forbidden_is_not_cached
|
296
|
+
get :forbidden
|
297
|
+
assert_response :forbidden
|
298
|
+
reset!
|
299
|
+
|
300
|
+
get :forbidden
|
301
|
+
assert_response :forbidden
|
302
|
+
end
|
303
|
+
|
196
304
|
def test_xml_version_of_resource_is_treated_as_different_cache
|
197
305
|
@mock_controller.mock_url_for = 'http://example.org/posts/'
|
198
306
|
@mock_controller.mock_path = '/posts/index.xml'
|
@@ -200,6 +308,13 @@ class ActionCacheTest < Test::Unit::TestCase
|
|
200
308
|
assert_equal 'xml', path_object.extension
|
201
309
|
assert_equal 'example.org/posts/index.xml', path_object.path
|
202
310
|
end
|
311
|
+
|
312
|
+
def test_correct_content_type_is_returned_for_cache_hit
|
313
|
+
# run it twice to cache it the first time
|
314
|
+
get :index, :id => 'content-type.xml'
|
315
|
+
get :index, :id => 'content-type.xml'
|
316
|
+
assert_equal 'application/xml', @response.content_type
|
317
|
+
end
|
203
318
|
|
204
319
|
def test_empty_path_is_normalized
|
205
320
|
@mock_controller.mock_url_for = 'http://example.org/'
|
@@ -226,4 +341,9 @@ class ActionCacheTest < Test::Unit::TestCase
|
|
226
341
|
@controller = ActionCachingTestController.new
|
227
342
|
@request.host = 'hostname.com'
|
228
343
|
end
|
344
|
+
|
345
|
+
def assert_cache_exists(path)
|
346
|
+
full_path = File.join(FILE_STORE_PATH, path + '.cache')
|
347
|
+
assert File.exist?(full_path), "#{full_path.inspect} does not exist."
|
348
|
+
end
|
229
349
|
end
|
@@ -8,6 +8,14 @@ class CaptureController < ActionController::Base
|
|
8
8
|
render :layout => "talk_from_action"
|
9
9
|
end
|
10
10
|
|
11
|
+
def content_for_with_parameter
|
12
|
+
render :layout => "talk_from_action"
|
13
|
+
end
|
14
|
+
|
15
|
+
def content_for_concatenated
|
16
|
+
render :layout => "talk_from_action"
|
17
|
+
end
|
18
|
+
|
11
19
|
def erb_content_for
|
12
20
|
render :layout => "talk_from_action"
|
13
21
|
end
|
@@ -23,7 +31,7 @@ class CaptureController < ActionController::Base
|
|
23
31
|
def rescue_action(e) raise end
|
24
32
|
end
|
25
33
|
|
26
|
-
CaptureController.
|
34
|
+
CaptureController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
|
27
35
|
|
28
36
|
class CaptureTest < Test::Unit::TestCase
|
29
37
|
def setup
|
@@ -49,8 +57,18 @@ class CaptureTest < Test::Unit::TestCase
|
|
49
57
|
assert_equal expected_content_for_output, @response.body
|
50
58
|
end
|
51
59
|
|
60
|
+
def test_should_concatentate_content_for
|
61
|
+
get :content_for_concatenated
|
62
|
+
assert_equal expected_content_for_output, @response.body
|
63
|
+
end
|
64
|
+
|
52
65
|
def test_erb_content_for
|
53
|
-
get :
|
66
|
+
get :erb_content_for
|
67
|
+
assert_equal expected_content_for_output, @response.body
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_should_set_content_for_with_parameter
|
71
|
+
get :content_for_with_parameter
|
54
72
|
assert_equal expected_content_for_output, @response.body
|
55
73
|
end
|
56
74
|
|
@@ -64,19 +82,8 @@ class CaptureTest < Test::Unit::TestCase
|
|
64
82
|
assert_equal expected_content_for_output, @response.body
|
65
83
|
end
|
66
84
|
|
67
|
-
def test_update_element_with_capture
|
68
|
-
assert_deprecated 'update_element_function' do
|
69
|
-
get :update_element_with_capture
|
70
|
-
end
|
71
|
-
assert_equal(
|
72
|
-
"<script type=\"text/javascript\">\n//<![CDATA[\n$('products').innerHTML = '\\n <p>Product 1</p>\\n <p>Product 2</p>\\n';\n\n//]]>\n</script>" +
|
73
|
-
"\n\n$('status').innerHTML = '\\n <b>You bought something!</b>\\n';",
|
74
|
-
@response.body.strip
|
75
|
-
)
|
76
|
-
end
|
77
|
-
|
78
85
|
private
|
79
|
-
|
80
|
-
|
81
|
-
|
86
|
+
def expected_content_for_output
|
87
|
+
"<title>Putting stuff in the title!</title>\n\nGreat stuff!"
|
88
|
+
end
|
82
89
|
end
|
data/test/controller/cgi_test.rb
CHANGED
@@ -1,381 +1,7 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../abstract_unit'
|
2
2
|
require 'action_controller/cgi_process'
|
3
|
-
require 'action_controller/cgi_ext/cgi_ext'
|
4
|
-
|
5
|
-
|
6
|
-
require 'stringio'
|
7
|
-
|
8
|
-
class CGITest < Test::Unit::TestCase
|
9
|
-
def setup
|
10
|
-
@query_string = "action=create_customer&full_name=David%20Heinemeier%20Hansson&customerId=1"
|
11
|
-
@query_string_with_nil = "action=create_customer&full_name="
|
12
|
-
@query_string_with_array = "action=create_customer&selected[]=1&selected[]=2&selected[]=3"
|
13
|
-
@query_string_with_amps = "action=create_customer&name=Don%27t+%26+Does"
|
14
|
-
@query_string_with_multiple_of_same_name =
|
15
|
-
"action=update_order&full_name=Lau%20Taarnskov&products=4&products=2&products=3"
|
16
|
-
@query_string_with_many_equal = "action=create_customer&full_name=abc=def=ghi"
|
17
|
-
@query_string_without_equal = "action"
|
18
|
-
@query_string_with_many_ampersands =
|
19
|
-
"&action=create_customer&&&full_name=David%20Heinemeier%20Hansson"
|
20
|
-
@query_string_with_empty_key = "action=create_customer&full_name=David%20Heinemeier%20Hansson&=Save"
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_query_string
|
24
|
-
assert_equal(
|
25
|
-
{ "action" => "create_customer", "full_name" => "David Heinemeier Hansson", "customerId" => "1"},
|
26
|
-
CGIMethods.parse_query_parameters(@query_string)
|
27
|
-
)
|
28
|
-
end
|
29
|
-
|
30
|
-
def test_deep_query_string
|
31
|
-
expected = {'x' => {'y' => {'z' => '10'}}}
|
32
|
-
assert_equal(expected, CGIMethods.parse_query_parameters('x[y][z]=10'))
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_deep_query_string_with_array
|
36
|
-
assert_equal({'x' => {'y' => {'z' => ['10']}}}, CGIMethods.parse_query_parameters('x[y][z][]=10'))
|
37
|
-
assert_equal({'x' => {'y' => {'z' => ['10', '5']}}}, CGIMethods.parse_query_parameters('x[y][z][]=10&x[y][z][]=5'))
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_deep_query_string_with_array_of_hash
|
41
|
-
assert_equal({'x' => {'y' => [{'z' => '10'}]}}, CGIMethods.parse_query_parameters('x[y][][z]=10'))
|
42
|
-
assert_equal({'x' => {'y' => [{'z' => '10', 'w' => '10'}]}}, CGIMethods.parse_query_parameters('x[y][][z]=10&x[y][][w]=10'))
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_deep_query_string_with_array_of_hashes_with_one_pair
|
46
|
-
assert_equal({'x' => {'y' => [{'z' => '10'}, {'z' => '20'}]}}, CGIMethods.parse_query_parameters('x[y][][z]=10&x[y][][z]=20'))
|
47
|
-
assert_equal("10", CGIMethods.parse_query_parameters('x[y][][z]=10&x[y][][z]=20')["x"]["y"].first["z"])
|
48
|
-
assert_equal("10", CGIMethods.parse_query_parameters('x[y][][z]=10&x[y][][z]=20').with_indifferent_access[:x][:y].first[:z])
|
49
|
-
end
|
50
|
-
|
51
|
-
def test_request_hash_parsing
|
52
|
-
query = {
|
53
|
-
"note[viewers][viewer][][type]" => ["User", "Group"],
|
54
|
-
"note[viewers][viewer][][id]" => ["1", "2"]
|
55
|
-
}
|
56
|
-
|
57
|
-
expected = { "note" => { "viewers"=>{"viewer"=>[{ "id"=>"1", "type"=>"User"}, {"type"=>"Group", "id"=>"2"} ]} } }
|
58
|
-
|
59
|
-
assert_equal(expected, CGIMethods.parse_request_parameters(query))
|
60
|
-
end
|
61
|
-
|
62
|
-
def test_deep_query_string_with_array_of_hashes_with_multiple_pairs
|
63
|
-
assert_equal(
|
64
|
-
{'x' => {'y' => [{'z' => '10', 'w' => 'a'}, {'z' => '20', 'w' => 'b'}]}},
|
65
|
-
CGIMethods.parse_query_parameters('x[y][][z]=10&x[y][][w]=a&x[y][][z]=20&x[y][][w]=b')
|
66
|
-
)
|
67
|
-
end
|
68
|
-
|
69
|
-
def test_query_string_with_nil
|
70
|
-
assert_equal(
|
71
|
-
{ "action" => "create_customer", "full_name" => nil},
|
72
|
-
CGIMethods.parse_query_parameters(@query_string_with_nil)
|
73
|
-
)
|
74
|
-
end
|
75
|
-
|
76
|
-
def test_query_string_with_array
|
77
|
-
assert_equal(
|
78
|
-
{ "action" => "create_customer", "selected" => ["1", "2", "3"]},
|
79
|
-
CGIMethods.parse_query_parameters(@query_string_with_array)
|
80
|
-
)
|
81
|
-
end
|
82
|
-
|
83
|
-
def test_query_string_with_amps
|
84
|
-
assert_equal(
|
85
|
-
{ "action" => "create_customer", "name" => "Don't & Does"},
|
86
|
-
CGIMethods.parse_query_parameters(@query_string_with_amps)
|
87
|
-
)
|
88
|
-
end
|
89
|
-
|
90
|
-
def test_query_string_with_many_equal
|
91
|
-
assert_equal(
|
92
|
-
{ "action" => "create_customer", "full_name" => "abc=def=ghi"},
|
93
|
-
CGIMethods.parse_query_parameters(@query_string_with_many_equal)
|
94
|
-
)
|
95
|
-
end
|
96
|
-
|
97
|
-
def test_query_string_without_equal
|
98
|
-
assert_equal(
|
99
|
-
{ "action" => nil },
|
100
|
-
CGIMethods.parse_query_parameters(@query_string_without_equal)
|
101
|
-
)
|
102
|
-
end
|
103
|
-
|
104
|
-
def test_query_string_with_empty_key
|
105
|
-
assert_equal(
|
106
|
-
{ "action" => "create_customer", "full_name" => "David Heinemeier Hansson" },
|
107
|
-
CGIMethods.parse_query_parameters(@query_string_with_empty_key)
|
108
|
-
)
|
109
|
-
end
|
110
|
-
|
111
|
-
def test_query_string_with_many_ampersands
|
112
|
-
assert_equal(
|
113
|
-
{ "action" => "create_customer", "full_name" => "David Heinemeier Hansson"},
|
114
|
-
CGIMethods.parse_query_parameters(@query_string_with_many_ampersands)
|
115
|
-
)
|
116
|
-
end
|
117
|
-
|
118
|
-
def test_parse_params
|
119
|
-
input = {
|
120
|
-
"customers[boston][first][name]" => [ "David" ],
|
121
|
-
"customers[boston][first][url]" => [ "http://David" ],
|
122
|
-
"customers[boston][second][name]" => [ "Allan" ],
|
123
|
-
"customers[boston][second][url]" => [ "http://Allan" ],
|
124
|
-
"something_else" => [ "blah" ],
|
125
|
-
"something_nil" => [ nil ],
|
126
|
-
"something_empty" => [ "" ],
|
127
|
-
"products[first]" => [ "Apple Computer" ],
|
128
|
-
"products[second]" => [ "Pc" ],
|
129
|
-
"" => [ 'Save' ]
|
130
|
-
}
|
131
|
-
|
132
|
-
expected_output = {
|
133
|
-
"customers" => {
|
134
|
-
"boston" => {
|
135
|
-
"first" => {
|
136
|
-
"name" => "David",
|
137
|
-
"url" => "http://David"
|
138
|
-
},
|
139
|
-
"second" => {
|
140
|
-
"name" => "Allan",
|
141
|
-
"url" => "http://Allan"
|
142
|
-
}
|
143
|
-
}
|
144
|
-
},
|
145
|
-
"something_else" => "blah",
|
146
|
-
"something_empty" => "",
|
147
|
-
"something_nil" => "",
|
148
|
-
"products" => {
|
149
|
-
"first" => "Apple Computer",
|
150
|
-
"second" => "Pc"
|
151
|
-
}
|
152
|
-
}
|
153
|
-
|
154
|
-
assert_equal expected_output, CGIMethods.parse_request_parameters(input)
|
155
|
-
end
|
156
|
-
|
157
|
-
def test_parse_params_from_multipart_upload
|
158
|
-
mockup = Struct.new(:content_type, :original_filename, :read, :rewind)
|
159
|
-
file = mockup.new('img/jpeg', 'foo.jpg')
|
160
|
-
ie_file = mockup.new('img/jpeg', 'c:\\Documents and Settings\\foo\\Desktop\\bar.jpg')
|
161
|
-
non_file_text_part = mockup.new('text/plain', '', 'abc')
|
162
|
-
|
163
|
-
input = {
|
164
|
-
"something" => [ StringIO.new("") ],
|
165
|
-
"array_of_stringios" => [[ StringIO.new("One"), StringIO.new("Two") ]],
|
166
|
-
"mixed_types_array" => [[ StringIO.new("Three"), "NotStringIO" ]],
|
167
|
-
"mixed_types_as_checkboxes[strings][nested]" => [[ file, "String", StringIO.new("StringIO")]],
|
168
|
-
"ie_mixed_types_as_checkboxes[strings][nested]" => [[ ie_file, "String", StringIO.new("StringIO")]],
|
169
|
-
"products[string]" => [ StringIO.new("Apple Computer") ],
|
170
|
-
"products[file]" => [ file ],
|
171
|
-
"ie_products[string]" => [ StringIO.new("Microsoft") ],
|
172
|
-
"ie_products[file]" => [ ie_file ],
|
173
|
-
"text_part" => [non_file_text_part]
|
174
|
-
}
|
175
|
-
|
176
|
-
expected_output = {
|
177
|
-
"something" => "",
|
178
|
-
"array_of_stringios" => ["One", "Two"],
|
179
|
-
"mixed_types_array" => [ "Three", "NotStringIO" ],
|
180
|
-
"mixed_types_as_checkboxes" => {
|
181
|
-
"strings" => {
|
182
|
-
"nested" => [ file, "String", "StringIO" ]
|
183
|
-
},
|
184
|
-
},
|
185
|
-
"ie_mixed_types_as_checkboxes" => {
|
186
|
-
"strings" => {
|
187
|
-
"nested" => [ ie_file, "String", "StringIO" ]
|
188
|
-
},
|
189
|
-
},
|
190
|
-
"products" => {
|
191
|
-
"string" => "Apple Computer",
|
192
|
-
"file" => file
|
193
|
-
},
|
194
|
-
"ie_products" => {
|
195
|
-
"string" => "Microsoft",
|
196
|
-
"file" => ie_file
|
197
|
-
},
|
198
|
-
"text_part" => "abc"
|
199
|
-
}
|
200
|
-
|
201
|
-
params = CGIMethods.parse_request_parameters(input)
|
202
|
-
assert_equal expected_output, params
|
203
|
-
|
204
|
-
# Lone filenames are preserved.
|
205
|
-
assert_equal 'foo.jpg', params['mixed_types_as_checkboxes']['strings']['nested'].first.original_filename
|
206
|
-
assert_equal 'foo.jpg', params['products']['file'].original_filename
|
207
|
-
|
208
|
-
# But full Windows paths are reduced to their basename.
|
209
|
-
assert_equal 'bar.jpg', params['ie_mixed_types_as_checkboxes']['strings']['nested'].first.original_filename
|
210
|
-
assert_equal 'bar.jpg', params['ie_products']['file'].original_filename
|
211
|
-
end
|
212
|
-
|
213
|
-
def test_parse_params_with_file
|
214
|
-
input = {
|
215
|
-
"customers[boston][first][name]" => [ "David" ],
|
216
|
-
"something_else" => [ "blah" ],
|
217
|
-
"logo" => [ File.new(File.dirname(__FILE__) + "/cgi_test.rb").path ]
|
218
|
-
}
|
219
|
-
|
220
|
-
expected_output = {
|
221
|
-
"customers" => {
|
222
|
-
"boston" => {
|
223
|
-
"first" => {
|
224
|
-
"name" => "David"
|
225
|
-
}
|
226
|
-
}
|
227
|
-
},
|
228
|
-
"something_else" => "blah",
|
229
|
-
"logo" => File.new(File.dirname(__FILE__) + "/cgi_test.rb").path,
|
230
|
-
}
|
231
|
-
|
232
|
-
assert_equal expected_output, CGIMethods.parse_request_parameters(input)
|
233
|
-
end
|
234
|
-
|
235
|
-
def test_parse_params_with_array
|
236
|
-
input = { "selected[]" => [ "1", "2", "3" ] }
|
237
|
-
|
238
|
-
expected_output = { "selected" => [ "1", "2", "3" ] }
|
239
|
-
|
240
|
-
assert_equal expected_output, CGIMethods.parse_request_parameters(input)
|
241
|
-
end
|
242
|
-
|
243
|
-
def test_parse_params_with_non_alphanumeric_name
|
244
|
-
input = { "a/b[c]" => %w(d) }
|
245
|
-
expected = { "a/b" => { "c" => "d" }}
|
246
|
-
assert_equal expected, CGIMethods.parse_request_parameters(input)
|
247
|
-
end
|
248
|
-
|
249
|
-
def test_parse_params_with_single_brackets_in_middle
|
250
|
-
input = { "a/b[c]d" => %w(e) }
|
251
|
-
expected = { "a/b" => {} }
|
252
|
-
assert_equal expected, CGIMethods.parse_request_parameters(input)
|
253
|
-
end
|
254
|
-
|
255
|
-
def test_parse_params_with_separated_brackets
|
256
|
-
input = { "a/b@[c]d[e]" => %w(f) }
|
257
|
-
expected = { "a/b@" => { }}
|
258
|
-
assert_equal expected, CGIMethods.parse_request_parameters(input)
|
259
|
-
end
|
260
|
-
|
261
|
-
def test_parse_params_with_separated_brackets_and_array
|
262
|
-
input = { "a/b@[c]d[e][]" => %w(f) }
|
263
|
-
expected = { "a/b@" => { }}
|
264
|
-
assert_equal expected , CGIMethods.parse_request_parameters(input)
|
265
|
-
end
|
266
|
-
|
267
|
-
def test_parse_params_with_unmatched_brackets_and_array
|
268
|
-
input = { "a/b@[c][d[e][]" => %w(f) }
|
269
|
-
expected = { "a/b@" => { "c" => { }}}
|
270
|
-
assert_equal expected, CGIMethods.parse_request_parameters(input)
|
271
|
-
end
|
272
|
-
|
273
|
-
def test_parse_params_with_nil_key
|
274
|
-
input = { nil => nil, "test2" => %w(value1) }
|
275
|
-
expected = { "test2" => "value1" }
|
276
|
-
assert_equal expected, CGIMethods.parse_request_parameters(input)
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
|
-
|
281
|
-
class MultipartCGITest < Test::Unit::TestCase
|
282
|
-
FIXTURE_PATH = File.dirname(__FILE__) + '/../fixtures/multipart'
|
283
3
|
|
284
|
-
|
285
|
-
ENV['REQUEST_METHOD'] = 'POST'
|
286
|
-
ENV['CONTENT_LENGTH'] = '0'
|
287
|
-
ENV['CONTENT_TYPE'] = 'multipart/form-data, boundary=AaB03x'
|
288
|
-
end
|
289
|
-
|
290
|
-
def test_single_parameter
|
291
|
-
params = process('single_parameter')
|
292
|
-
assert_equal({ 'foo' => 'bar' }, params)
|
293
|
-
end
|
294
|
-
|
295
|
-
def test_text_file
|
296
|
-
params = process('text_file')
|
297
|
-
assert_equal %w(file foo), params.keys.sort
|
298
|
-
assert_equal 'bar', params['foo']
|
299
|
-
|
300
|
-
file = params['file']
|
301
|
-
assert_kind_of StringIO, file
|
302
|
-
assert_equal 'file.txt', file.original_filename
|
303
|
-
assert_equal "text/plain\r", file.content_type
|
304
|
-
assert_equal 'contents', file.read
|
305
|
-
end
|
306
|
-
|
307
|
-
def test_large_text_file
|
308
|
-
params = process('large_text_file')
|
309
|
-
assert_equal %w(file foo), params.keys.sort
|
310
|
-
assert_equal 'bar', params['foo']
|
311
|
-
|
312
|
-
file = params['file']
|
313
|
-
assert_kind_of Tempfile, file
|
314
|
-
assert_equal 'file.txt', file.original_filename
|
315
|
-
assert_equal "text/plain\r", file.content_type
|
316
|
-
assert ('a' * 20480) == file.read
|
317
|
-
end
|
318
|
-
|
319
|
-
def test_binary_file
|
320
|
-
params = process('binary_file')
|
321
|
-
assert_equal %w(file flowers foo), params.keys.sort
|
322
|
-
assert_equal 'bar', params['foo']
|
323
|
-
|
324
|
-
file = params['file']
|
325
|
-
assert_kind_of StringIO, file
|
326
|
-
assert_equal 'file.txt', file.original_filename
|
327
|
-
assert_equal "text/plain\r", file.content_type
|
328
|
-
assert_equal 'contents', file.read
|
329
|
-
|
330
|
-
file = params['flowers']
|
331
|
-
assert_kind_of StringIO, file
|
332
|
-
assert_equal 'flowers.jpg', file.original_filename
|
333
|
-
assert_equal "image/jpeg\r", file.content_type
|
334
|
-
assert_equal 19512, file.size
|
335
|
-
#assert_equal File.read(File.dirname(__FILE__) + '/../../../activerecord/test/fixtures/flowers.jpg'), file.read
|
336
|
-
end
|
337
|
-
|
338
|
-
def test_mixed_files
|
339
|
-
params = process('mixed_files')
|
340
|
-
assert_equal %w(files foo), params.keys.sort
|
341
|
-
assert_equal 'bar', params['foo']
|
342
|
-
|
343
|
-
# Ruby CGI doesn't handle multipart/mixed for us.
|
344
|
-
assert_kind_of String, params['files']
|
345
|
-
assert_equal 19756, params['files'].size
|
346
|
-
end
|
347
|
-
|
348
|
-
# Rewind readable cgi params so others may reread them (such as CGI::Session
|
349
|
-
# when passing the session id in a multipart form).
|
350
|
-
def test_multipart_param_rewound
|
351
|
-
params = process('text_file')
|
352
|
-
assert_equal 'bar', @cgi.params['foo'][0].read
|
353
|
-
end
|
354
|
-
|
355
|
-
private
|
356
|
-
def process(name)
|
357
|
-
old_stdin = $stdin
|
358
|
-
File.open(File.join(FIXTURE_PATH, name), 'rb') do |file|
|
359
|
-
ENV['CONTENT_LENGTH'] = file.stat.size.to_s
|
360
|
-
$stdin = file
|
361
|
-
@cgi = CGI.new
|
362
|
-
CGIMethods.parse_request_parameters @cgi.params
|
363
|
-
end
|
364
|
-
ensure
|
365
|
-
$stdin = old_stdin
|
366
|
-
end
|
367
|
-
end
|
368
|
-
|
369
|
-
# Ensures that PUT works with multipart as well as POST.
|
370
|
-
class PutMultipartCGITest < MultipartCGITest
|
371
|
-
def setup
|
372
|
-
super
|
373
|
-
ENV['REQUEST_METHOD'] = 'PUT'
|
374
|
-
end
|
375
|
-
end
|
376
|
-
|
377
|
-
|
378
|
-
class CGIRequestTest < Test::Unit::TestCase
|
4
|
+
class BaseCgiTest < Test::Unit::TestCase
|
379
5
|
def setup
|
380
6
|
@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"}
|
381
7
|
# cookie as returned by some Nokia phone browsers (no space after semicolon separator)
|
@@ -383,20 +9,25 @@ class CGIRequestTest < Test::Unit::TestCase
|
|
383
9
|
@fake_cgi = Struct.new(:env_table).new(@request_hash)
|
384
10
|
@request = ActionController::CgiRequest.new(@fake_cgi)
|
385
11
|
end
|
386
|
-
|
12
|
+
|
13
|
+
def default_test; end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
class CgiRequestTest < BaseCgiTest
|
387
18
|
def test_proxy_request
|
388
19
|
assert_equal 'glu.ttono.us', @request.host_with_port
|
389
20
|
end
|
390
|
-
|
21
|
+
|
391
22
|
def test_http_host
|
392
23
|
@request_hash.delete "HTTP_X_FORWARDED_HOST"
|
393
24
|
@request_hash['HTTP_HOST'] = "rubyonrails.org:8080"
|
394
25
|
assert_equal "rubyonrails.org:8080", @request.host_with_port
|
395
|
-
|
26
|
+
|
396
27
|
@request_hash['HTTP_X_FORWARDED_HOST'] = "www.firsthost.org, www.secondhost.org"
|
397
28
|
assert_equal "www.secondhost.org", @request.host
|
398
29
|
end
|
399
|
-
|
30
|
+
|
400
31
|
def test_http_host_with_default_port_overrides_server_port
|
401
32
|
@request_hash.delete "HTTP_X_FORWARDED_HOST"
|
402
33
|
@request_hash['HTTP_HOST'] = "rubyonrails.org"
|
@@ -416,25 +47,69 @@ class CGIRequestTest < Test::Unit::TestCase
|
|
416
47
|
assert_equal "207.7.108.53:8007", @request.host_with_port
|
417
48
|
end
|
418
49
|
|
50
|
+
def test_host_with_port_if_http_standard_port_is_specified
|
51
|
+
@request_hash['HTTP_X_FORWARDED_HOST'] = "glu.ttono.us:80"
|
52
|
+
assert_equal "glu.ttono.us", @request.host_with_port
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_host_with_port_if_https_standard_port_is_specified
|
56
|
+
@request_hash['HTTP_X_FORWARDED_PROTO'] = "https"
|
57
|
+
@request_hash['HTTP_X_FORWARDED_HOST'] = "glu.ttono.us:443"
|
58
|
+
assert_equal "glu.ttono.us", @request.host_with_port
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_host_if_ipv6_reference
|
62
|
+
@request_hash.delete "HTTP_X_FORWARDED_HOST"
|
63
|
+
@request_hash['HTTP_HOST'] = "[2001:1234:5678:9abc:def0::dead:beef]"
|
64
|
+
assert_equal "[2001:1234:5678:9abc:def0::dead:beef]", @request.host
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_host_if_ipv6_reference_with_port
|
68
|
+
@request_hash.delete "HTTP_X_FORWARDED_HOST"
|
69
|
+
@request_hash['HTTP_HOST'] = "[2001:1234:5678:9abc:def0::dead:beef]:8008"
|
70
|
+
assert_equal "[2001:1234:5678:9abc:def0::dead:beef]", @request.host
|
71
|
+
end
|
72
|
+
|
419
73
|
def test_cookie_syntax_resilience
|
420
74
|
cookies = CGI::Cookie::parse(@request_hash["HTTP_COOKIE"]);
|
421
75
|
assert_equal ["c84ace84796670c052c6ceb2451fb0f2"], cookies["_session_id"]
|
422
76
|
assert_equal ["yes"], cookies["is_admin"]
|
423
|
-
|
77
|
+
|
424
78
|
alt_cookies = CGI::Cookie::parse(@alt_cookie_fmt_request_hash["HTTP_COOKIE"]);
|
425
79
|
assert_equal ["c84ace84796670c052c6ceb2451fb0f2"], alt_cookies["_session_id"]
|
426
80
|
assert_equal ["yes"], alt_cookies["is_admin"]
|
427
81
|
end
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
class CgiRequestParamsParsingTest < BaseCgiTest
|
86
|
+
def test_doesnt_break_when_content_type_has_charset
|
87
|
+
data = 'flamenco=love'
|
88
|
+
@request.env['CONTENT_LENGTH'] = data.length
|
89
|
+
@request.env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8'
|
90
|
+
@request.env['RAW_POST_DATA'] = data
|
91
|
+
assert_equal({"flamenco"=> "love"}, @request.request_parameters)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_doesnt_interpret_request_uri_as_query_string_when_missing
|
95
|
+
@request.env['REQUEST_URI'] = 'foo'
|
96
|
+
assert_equal({}, @request.query_parameters)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
class CgiRequestNeedsRewoundTest < BaseCgiTest
|
102
|
+
def test_body_should_be_rewound
|
103
|
+
data = 'foo'
|
104
|
+
fake_cgi = Struct.new(:env_table, :query_string, :stdinput).new(@request_hash, '', StringIO.new(data))
|
105
|
+
fake_cgi.env_table['CONTENT_LENGTH'] = data.length
|
106
|
+
fake_cgi.env_table['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8'
|
107
|
+
|
108
|
+
# Read the request body by parsing params.
|
109
|
+
request = ActionController::CgiRequest.new(fake_cgi)
|
110
|
+
request.request_parameters
|
111
|
+
|
112
|
+
# Should have rewound the body.
|
113
|
+
assert_equal 0, request.body.pos
|
439
114
|
end
|
440
115
|
end
|