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
@@ -3,8 +3,8 @@
|
|
3
3
|
# Under MIT and/or CC By license.
|
4
4
|
#++
|
5
5
|
|
6
|
-
require File.dirname(__FILE__)
|
7
|
-
require File.dirname(__FILE__)
|
6
|
+
require "#{File.dirname(__FILE__)}/../abstract_unit"
|
7
|
+
require "#{File.dirname(__FILE__)}/fake_controllers"
|
8
8
|
|
9
9
|
class SelectorTest < Test::Unit::TestCase
|
10
10
|
#
|
@@ -85,11 +85,11 @@ class SelectorTest < Test::Unit::TestCase
|
|
85
85
|
assert_equal 2, @matches.size
|
86
86
|
assert_equal "2", @matches[0].attributes["id"]
|
87
87
|
assert_equal "3", @matches[1].attributes["id"]
|
88
|
-
# Match
|
88
|
+
# Match element with attribute value.
|
89
89
|
select("*[title=foo]")
|
90
90
|
assert_equal 1, @matches.size
|
91
91
|
assert_equal "3", @matches[0].attributes["id"]
|
92
|
-
# Match
|
92
|
+
# Match element with attribute and attribute value.
|
93
93
|
select("[bar=foo][title]")
|
94
94
|
assert_equal 1, @matches.size
|
95
95
|
assert_equal "2", @matches[0].attributes["id"]
|
@@ -177,7 +177,7 @@ class SelectorTest < Test::Unit::TestCase
|
|
177
177
|
assert_equal 2, @matches.size
|
178
178
|
assert_equal "foo", @matches[0].attributes["href"]
|
179
179
|
assert_equal "baz", @matches[1].attributes["href"]
|
180
|
-
# And now for the three selector
|
180
|
+
# And now for the three selector challenge.
|
181
181
|
parse(%Q{<h1 id="1"><a href="foo"></a></h1><h2 id="2"><a href="bar"></a></h2><h3 id="2"><a href="baz"></a></h3>})
|
182
182
|
select("h1 a, h2 a, h3 a")
|
183
183
|
assert_equal 3, @matches.size
|
@@ -21,11 +21,13 @@ class SendFileController < ActionController::Base
|
|
21
21
|
def rescue_action(e) raise end
|
22
22
|
end
|
23
23
|
|
24
|
-
SendFileController.
|
24
|
+
SendFileController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
|
25
25
|
|
26
26
|
class SendFileTest < Test::Unit::TestCase
|
27
27
|
include TestFileUtils
|
28
28
|
|
29
|
+
Mime::Type.register "image/png", :png unless defined? Mime::PNG
|
30
|
+
|
29
31
|
def setup
|
30
32
|
@controller = SendFileController.new
|
31
33
|
@request = ActionController::TestRequest.new
|
@@ -53,6 +55,14 @@ class SendFileTest < Test::Unit::TestCase
|
|
53
55
|
assert_nothing_raised { response.body.call(response, output) }
|
54
56
|
assert_equal file_data, output.string
|
55
57
|
end
|
58
|
+
|
59
|
+
def test_file_url_based_filename
|
60
|
+
@controller.options = { :url_based_filename => true }
|
61
|
+
response = nil
|
62
|
+
assert_nothing_raised { response = process('file') }
|
63
|
+
assert_not_nil response
|
64
|
+
assert_equal "attachment", response.headers["Content-Disposition"]
|
65
|
+
end
|
56
66
|
|
57
67
|
def test_data
|
58
68
|
response = nil
|
@@ -65,17 +75,17 @@ class SendFileTest < Test::Unit::TestCase
|
|
65
75
|
|
66
76
|
def test_headers_after_send_shouldnt_include_charset
|
67
77
|
response = process('data')
|
68
|
-
assert_equal "application/octet-stream", response.
|
78
|
+
assert_equal "application/octet-stream", response.content_type
|
69
79
|
|
70
80
|
response = process('file')
|
71
|
-
assert_equal "application/octet-stream", response.
|
81
|
+
assert_equal "application/octet-stream", response.content_type
|
72
82
|
end
|
73
83
|
|
74
84
|
# Test that send_file_headers! is setting the correct HTTP headers.
|
75
85
|
def test_send_file_headers!
|
76
86
|
options = {
|
77
87
|
:length => 1,
|
78
|
-
:type =>
|
88
|
+
:type => Mime::PNG,
|
79
89
|
:disposition => 'disposition',
|
80
90
|
:filename => 'filename'
|
81
91
|
}
|
@@ -90,7 +100,7 @@ class SendFileTest < Test::Unit::TestCase
|
|
90
100
|
|
91
101
|
h = @controller.headers
|
92
102
|
assert_equal 1, h['Content-Length']
|
93
|
-
assert_equal '
|
103
|
+
assert_equal 'image/png', h['Content-Type']
|
94
104
|
assert_equal 'disposition; filename="filename"', h['Content-Disposition']
|
95
105
|
assert_equal 'binary', h['Content-Transfer-Encoding']
|
96
106
|
|
@@ -105,13 +115,13 @@ class SendFileTest < Test::Unit::TestCase
|
|
105
115
|
define_method "test_send_#{method}_status" do
|
106
116
|
@controller.options = { :stream => false, :status => 500 }
|
107
117
|
assert_nothing_raised { assert_not_nil process(method) }
|
108
|
-
assert_equal '500 Internal Server Error', @
|
118
|
+
assert_equal '500 Internal Server Error', @response.headers['Status']
|
109
119
|
end
|
110
120
|
|
111
121
|
define_method "test_default_send_#{method}_status" do
|
112
122
|
@controller.options = { :stream => false }
|
113
123
|
assert_nothing_raised { assert_not_nil process(method) }
|
114
|
-
assert_equal ActionController::Base::DEFAULT_RENDER_STATUS_CODE, @
|
124
|
+
assert_equal ActionController::Base::DEFAULT_RENDER_STATUS_CODE, @response.headers['Status']
|
115
125
|
end
|
116
126
|
end
|
117
127
|
end
|
@@ -0,0 +1,246 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../../abstract_unit"
|
2
|
+
require 'action_controller/cgi_process'
|
3
|
+
require 'action_controller/cgi_ext'
|
4
|
+
|
5
|
+
require 'stringio'
|
6
|
+
|
7
|
+
|
8
|
+
class CGI::Session::CookieStore
|
9
|
+
def ensure_secret_secure_with_test_hax(secret)
|
10
|
+
if secret == CookieStoreTest.default_session_options['secret']
|
11
|
+
return true
|
12
|
+
else
|
13
|
+
ensure_secret_secure_without_test_hax(secret)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
alias_method_chain :ensure_secret_secure, :test_hax
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
# Expose for tests.
|
21
|
+
class CGI
|
22
|
+
attr_reader :output_cookies, :output_hidden
|
23
|
+
|
24
|
+
class Session
|
25
|
+
attr_reader :dbman
|
26
|
+
|
27
|
+
class CookieStore
|
28
|
+
attr_reader :data, :original, :cookie_options
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class CookieStoreTest < Test::Unit::TestCase
|
34
|
+
def self.default_session_options
|
35
|
+
{ 'database_manager' => CGI::Session::CookieStore,
|
36
|
+
'session_key' => '_myapp_session',
|
37
|
+
'secret' => 'Keep it secret; keep it safe.',
|
38
|
+
'no_cookies' => true,
|
39
|
+
'no_hidden' => true }
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.cookies
|
43
|
+
{ :empty => ['BAgw--0686dcaccc01040f4bd4f35fe160afe9bc04c330', {}],
|
44
|
+
:a_one => ['BAh7BiIGYWkG--5689059497d7f122a7119f171aef81dcfd807fec', { 'a' => 1 }],
|
45
|
+
:typical => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7BiILbm90aWNlIgxIZXkgbm93--9d20154623b9eeea05c62ab819be0e2483238759', { 'user_id' => 123, 'flash' => { 'notice' => 'Hey now' }}],
|
46
|
+
:flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--bf9785a666d3c4ac09f7fe3353496b437546cfbf', { 'user_id' => 123, 'flash' => {} }] }
|
47
|
+
end
|
48
|
+
|
49
|
+
def setup
|
50
|
+
ENV.delete('HTTP_COOKIE')
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_raises_argument_error_if_missing_session_key
|
54
|
+
[nil, ''].each do |blank|
|
55
|
+
assert_raise(ArgumentError, blank.inspect) { new_session 'session_key' => blank }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_raises_argument_error_if_missing_secret
|
60
|
+
[nil, ''].each do |blank|
|
61
|
+
assert_raise(ArgumentError, blank.inspect) { new_session 'secret' => blank }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_raises_argument_error_if_secret_is_probably_insecure
|
66
|
+
["password", "secret", "12345678901234567890123456789"].each do |blank|
|
67
|
+
assert_raise(ArgumentError, blank.inspect) { new_session 'secret' => blank }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_reconfigures_session_to_omit_id_cookie_and_hidden_field
|
72
|
+
new_session do |session|
|
73
|
+
assert_equal true, @options['no_hidden']
|
74
|
+
assert_equal true, @options['no_cookies']
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_restore_unmarshals_missing_cookie_as_empty_hash
|
79
|
+
new_session do |session|
|
80
|
+
assert_nil session.dbman.data
|
81
|
+
assert_nil session['test']
|
82
|
+
assert_equal Hash.new, session.dbman.data
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_restore_unmarshals_good_cookies
|
87
|
+
cookies(:empty, :a_one, :typical).each do |value, expected|
|
88
|
+
set_cookie! value
|
89
|
+
new_session do |session|
|
90
|
+
assert_nil session['lazy loads the data hash']
|
91
|
+
assert_equal expected, session.dbman.data
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_restore_deletes_tampered_cookies
|
97
|
+
set_cookie! 'a--b'
|
98
|
+
new_session do |session|
|
99
|
+
assert_raise(CGI::Session::CookieStore::TamperedWithCookie) { session['fail'] }
|
100
|
+
assert_cookie_deleted session
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_close_doesnt_write_cookie_if_data_is_blank
|
105
|
+
new_session do |session|
|
106
|
+
assert_no_cookies session
|
107
|
+
session.close
|
108
|
+
assert_no_cookies session
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_close_doesnt_write_cookie_if_data_is_unchanged
|
113
|
+
set_cookie! cookie_value(:typical)
|
114
|
+
new_session do |session|
|
115
|
+
assert_no_cookies session
|
116
|
+
session['user_id'] = session['user_id']
|
117
|
+
session.close
|
118
|
+
assert_no_cookies session
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_close_raises_when_data_overflows
|
123
|
+
set_cookie! cookie_value(:empty)
|
124
|
+
new_session do |session|
|
125
|
+
session['overflow'] = 'bye!' * 1024
|
126
|
+
assert_raise(CGI::Session::CookieStore::CookieOverflow) { session.close }
|
127
|
+
assert_no_cookies session
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_close_marshals_and_writes_cookie
|
132
|
+
set_cookie! cookie_value(:typical)
|
133
|
+
new_session do |session|
|
134
|
+
assert_no_cookies session
|
135
|
+
session['flash'] = {}
|
136
|
+
assert_no_cookies session
|
137
|
+
session.close
|
138
|
+
assert_equal 1, session.cgi.output_cookies.size
|
139
|
+
cookie = session.cgi.output_cookies.first
|
140
|
+
assert_cookie cookie, cookie_value(:flashed)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_delete_writes_expired_empty_cookie_and_sets_data_to_nil
|
145
|
+
set_cookie! cookie_value(:typical)
|
146
|
+
new_session do |session|
|
147
|
+
assert_no_cookies session
|
148
|
+
session.delete
|
149
|
+
assert_cookie_deleted session
|
150
|
+
|
151
|
+
# @data is set to nil so #close doesn't send another cookie.
|
152
|
+
session.close
|
153
|
+
assert_cookie_deleted session
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_new_session_doesnt_reuse_deleted_cookie_data
|
158
|
+
set_cookie! cookie_value(:typical)
|
159
|
+
|
160
|
+
new_session do |session|
|
161
|
+
assert_not_nil session['user_id']
|
162
|
+
session.delete
|
163
|
+
|
164
|
+
# Start a new session using the same CGI instance.
|
165
|
+
post_delete_session = CGI::Session.new(session.cgi, self.class.default_session_options)
|
166
|
+
assert_nil post_delete_session['user_id']
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
private
|
171
|
+
def assert_no_cookies(session)
|
172
|
+
assert_nil session.cgi.output_cookies, session.cgi.output_cookies.inspect
|
173
|
+
end
|
174
|
+
|
175
|
+
def assert_cookie_deleted(session, message = 'Expected session deletion cookie to be set')
|
176
|
+
assert_equal 1, session.cgi.output_cookies.size
|
177
|
+
cookie = session.cgi.output_cookies.first
|
178
|
+
assert_cookie cookie, nil, 1.year.ago.to_date, message
|
179
|
+
end
|
180
|
+
|
181
|
+
def assert_cookie(cookie, value = nil, expires = nil, message = nil)
|
182
|
+
assert_equal '_myapp_session', cookie.name, message
|
183
|
+
assert_equal [value].compact, cookie.value, message
|
184
|
+
assert_equal expires, cookie.expires ? cookie.expires.to_date : cookie.expires, message
|
185
|
+
end
|
186
|
+
|
187
|
+
|
188
|
+
def cookies(*which)
|
189
|
+
self.class.cookies.values_at(*which)
|
190
|
+
end
|
191
|
+
|
192
|
+
def cookie_value(which)
|
193
|
+
self.class.cookies[which].first
|
194
|
+
end
|
195
|
+
|
196
|
+
def set_cookie!(value)
|
197
|
+
ENV['HTTP_COOKIE'] = "_myapp_session=#{value}"
|
198
|
+
end
|
199
|
+
|
200
|
+
def new_session(options = {})
|
201
|
+
with_cgi do |cgi|
|
202
|
+
assert_nil cgi.output_hidden, "Output hidden params should be empty: #{cgi.output_hidden.inspect}"
|
203
|
+
assert_nil cgi.output_cookies, "Output cookies should be empty: #{cgi.output_cookies.inspect}"
|
204
|
+
|
205
|
+
@options = self.class.default_session_options.merge(options)
|
206
|
+
session = CGI::Session.new(cgi, @options)
|
207
|
+
|
208
|
+
assert_nil cgi.output_hidden, "Output hidden params should be empty: #{cgi.output_hidden.inspect}"
|
209
|
+
assert_nil cgi.output_cookies, "Output cookies should be empty: #{cgi.output_cookies.inspect}"
|
210
|
+
|
211
|
+
yield session if block_given?
|
212
|
+
session
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def with_cgi
|
217
|
+
ENV['REQUEST_METHOD'] = 'GET'
|
218
|
+
ENV['HTTP_HOST'] = 'example.com'
|
219
|
+
ENV['QUERY_STRING'] = ''
|
220
|
+
|
221
|
+
cgi = CGI.new('query', StringIO.new(''))
|
222
|
+
yield cgi if block_given?
|
223
|
+
cgi
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
|
228
|
+
class CookieStoreWithBlockAsSecretTest < CookieStoreTest
|
229
|
+
def self.default_session_options
|
230
|
+
CookieStoreTest.default_session_options.merge 'secret' => Proc.new { 'Keep it secret; keep it safe.' }
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
class CookieStoreWithMD5DigestTest < CookieStoreTest
|
236
|
+
def self.default_session_options
|
237
|
+
CookieStoreTest.default_session_options.merge 'digest' => 'MD5'
|
238
|
+
end
|
239
|
+
|
240
|
+
def self.cookies
|
241
|
+
{ :empty => ['BAgw--0415cc0be9579b14afc22ee2d341aa21', {}],
|
242
|
+
:a_one => ['BAh7BiIGYWkG--5a0ed962089cc6600ff44168a5d59bc8', { 'a' => 1 }],
|
243
|
+
:typical => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7BiILbm90aWNlIgxIZXkgbm93--f426763f6ef435b3738b493600db8d64', { 'user_id' => 123, 'flash' => { 'notice' => 'Hey now' }}],
|
244
|
+
:flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--0af9156650dab044a53a91a4ddec2c51', { 'user_id' => 123, 'flash' => {} }] }
|
245
|
+
end
|
246
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../../abstract_unit"
|
2
|
+
require 'action_controller/cgi_process'
|
3
|
+
require 'action_controller/cgi_ext'
|
4
|
+
|
5
|
+
|
6
|
+
class CGI::Session
|
7
|
+
def cache
|
8
|
+
dbman.instance_variable_get(:@cache)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
uses_mocha 'MemCacheStore tests' do
|
14
|
+
if defined? MemCache::MemCacheError
|
15
|
+
|
16
|
+
class MemCacheStoreTest < Test::Unit::TestCase
|
17
|
+
SESSION_KEY_RE = /^session:[0-9a-z]+/
|
18
|
+
CONN_TEST_KEY = 'connection_test'
|
19
|
+
MULTI_TEST_KEY = '0123456789'
|
20
|
+
TEST_DATA = 'Hello test'
|
21
|
+
|
22
|
+
def self.get_mem_cache_if_available
|
23
|
+
begin
|
24
|
+
require 'memcache'
|
25
|
+
cache = MemCache.new('127.0.0.1')
|
26
|
+
# Test availability of the connection
|
27
|
+
cache.set(CONN_TEST_KEY, 1)
|
28
|
+
unless cache.get(CONN_TEST_KEY) == 1
|
29
|
+
puts 'Warning: memcache server available but corrupted.'
|
30
|
+
return nil
|
31
|
+
end
|
32
|
+
rescue LoadError, MemCache::MemCacheError
|
33
|
+
return nil
|
34
|
+
end
|
35
|
+
return cache
|
36
|
+
end
|
37
|
+
|
38
|
+
CACHE = get_mem_cache_if_available
|
39
|
+
|
40
|
+
|
41
|
+
def test_initialization
|
42
|
+
assert_raise(ArgumentError) { new_session('session_id' => '!invalid_id') }
|
43
|
+
new_session do |s|
|
44
|
+
assert_equal Hash.new, s.cache.get('session:' + s.session_id)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def test_storage
|
50
|
+
d = rand(0xffff)
|
51
|
+
new_session do |s|
|
52
|
+
session_key = 'session:' + s.session_id
|
53
|
+
unless CACHE
|
54
|
+
s.cache.expects(:get).with(session_key) \
|
55
|
+
.returns(:test => d)
|
56
|
+
s.cache.expects(:set).with(session_key,
|
57
|
+
has_entry(:test, d),
|
58
|
+
0)
|
59
|
+
end
|
60
|
+
s[:test] = d
|
61
|
+
s.close
|
62
|
+
assert_equal d, s.cache.get(session_key)[:test]
|
63
|
+
assert_equal d, s[:test]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def test_deletion
|
69
|
+
new_session do |s|
|
70
|
+
session_key = 'session:' + s.session_id
|
71
|
+
unless CACHE
|
72
|
+
s.cache.expects(:delete)
|
73
|
+
s.cache.expects(:get).with(session_key) \
|
74
|
+
.returns(nil)
|
75
|
+
end
|
76
|
+
s[:test] = rand(0xffff)
|
77
|
+
s.delete
|
78
|
+
assert_nil s.cache.get(session_key)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
def test_other_session_retrieval
|
84
|
+
new_session do |sa|
|
85
|
+
unless CACHE
|
86
|
+
sa.cache.expects(:set).with('session:' + sa.session_id,
|
87
|
+
has_entry(:test, TEST_DATA),
|
88
|
+
0)
|
89
|
+
end
|
90
|
+
sa[:test] = TEST_DATA
|
91
|
+
sa.close
|
92
|
+
new_session('session_id' => sa.session_id) do |sb|
|
93
|
+
unless CACHE
|
94
|
+
sb.cache.expects(:[]).with('session:' + sb.session_id) \
|
95
|
+
.returns(:test => TEST_DATA)
|
96
|
+
end
|
97
|
+
assert_equal(TEST_DATA, sb[:test])
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def test_multiple_sessions
|
104
|
+
s_slots = Array.new(10)
|
105
|
+
operation = :write
|
106
|
+
last_data = nil
|
107
|
+
reads = writes = 0
|
108
|
+
50.times do
|
109
|
+
current = rand(10)
|
110
|
+
s_slots[current] ||= new_session('session_id' => MULTI_TEST_KEY,
|
111
|
+
'new_session' => true)
|
112
|
+
s = s_slots[current]
|
113
|
+
case operation
|
114
|
+
when :write
|
115
|
+
last_data = rand(0xffff)
|
116
|
+
unless CACHE
|
117
|
+
s.cache.expects(:set).with('session:' + MULTI_TEST_KEY,
|
118
|
+
{ :test => last_data },
|
119
|
+
0)
|
120
|
+
end
|
121
|
+
s[:test] = last_data
|
122
|
+
s.close
|
123
|
+
writes += 1
|
124
|
+
when :read
|
125
|
+
# Make CGI::Session#[] think there was no data retrieval yet.
|
126
|
+
# Normally, the session caches the data during its lifetime.
|
127
|
+
s.instance_variable_set(:@data, nil)
|
128
|
+
unless CACHE
|
129
|
+
s.cache.expects(:[]).with('session:' + MULTI_TEST_KEY) \
|
130
|
+
.returns(:test => last_data)
|
131
|
+
end
|
132
|
+
d = s[:test]
|
133
|
+
assert_equal(last_data, d, "OK reads: #{reads}, OK writes: #{writes}")
|
134
|
+
reads += 1
|
135
|
+
end
|
136
|
+
operation = rand(5) == 0 ? :write : :read
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
|
142
|
+
private
|
143
|
+
def obtain_session_options
|
144
|
+
options = { 'database_manager' => CGI::Session::MemCacheStore,
|
145
|
+
'session_key' => '_test_app_session'
|
146
|
+
}
|
147
|
+
# if don't have running memcache server we use mock instead
|
148
|
+
unless CACHE
|
149
|
+
options['cache'] = c = mock
|
150
|
+
c.stubs(:[]).with(regexp_matches(SESSION_KEY_RE))
|
151
|
+
c.stubs(:get).with(regexp_matches(SESSION_KEY_RE)) \
|
152
|
+
.returns(Hash.new)
|
153
|
+
c.stubs(:add).with(regexp_matches(SESSION_KEY_RE),
|
154
|
+
instance_of(Hash),
|
155
|
+
0)
|
156
|
+
end
|
157
|
+
options
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
def new_session(options = {})
|
162
|
+
with_cgi do |cgi|
|
163
|
+
@options = obtain_session_options.merge(options)
|
164
|
+
session = CGI::Session.new(cgi, @options)
|
165
|
+
yield session if block_given?
|
166
|
+
return session
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def with_cgi
|
171
|
+
ENV['REQUEST_METHOD'] = 'GET'
|
172
|
+
ENV['HTTP_HOST'] = 'example.com'
|
173
|
+
ENV['QUERY_STRING'] = ''
|
174
|
+
|
175
|
+
cgi = CGI.new('query', StringIO.new(''))
|
176
|
+
yield cgi if block_given?
|
177
|
+
cgi
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
end # defined? MemCache
|
182
|
+
end # uses_mocha
|