actionpack 1.12.5 → 1.13.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 +517 -15
- data/MIT-LICENSE +1 -1
- data/README +18 -20
- data/Rakefile +7 -4
- data/examples/address_book_controller.rb +3 -3
- data/examples/blog_controller.cgi +3 -3
- data/examples/debate_controller.cgi +5 -5
- data/lib/action_controller.rb +2 -2
- data/lib/action_controller/assertions.rb +73 -311
- data/lib/action_controller/{deprecated_assertions.rb → assertions/deprecated_assertions.rb} +32 -8
- data/lib/action_controller/assertions/dom_assertions.rb +25 -0
- data/lib/action_controller/assertions/model_assertions.rb +12 -0
- data/lib/action_controller/assertions/response_assertions.rb +140 -0
- data/lib/action_controller/assertions/routing_assertions.rb +82 -0
- data/lib/action_controller/assertions/selector_assertions.rb +571 -0
- data/lib/action_controller/assertions/tag_assertions.rb +117 -0
- data/lib/action_controller/base.rb +334 -163
- data/lib/action_controller/benchmarking.rb +3 -6
- data/lib/action_controller/caching.rb +83 -22
- data/lib/action_controller/cgi_ext/cgi_ext.rb +0 -7
- data/lib/action_controller/cgi_ext/cgi_methods.rb +167 -173
- data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +43 -22
- data/lib/action_controller/cgi_process.rb +50 -27
- data/lib/action_controller/components.rb +21 -25
- data/lib/action_controller/cookies.rb +10 -9
- data/lib/action_controller/{dependencies.rb → deprecated_dependencies.rb} +9 -27
- data/lib/action_controller/filters.rb +448 -225
- data/lib/action_controller/flash.rb +24 -20
- data/lib/action_controller/helpers.rb +2 -5
- data/lib/action_controller/integration.rb +40 -16
- data/lib/action_controller/layout.rb +11 -8
- data/lib/action_controller/macros/auto_complete.rb +3 -2
- data/lib/action_controller/macros/in_place_editing.rb +3 -2
- data/lib/action_controller/mime_responds.rb +41 -29
- data/lib/action_controller/mime_type.rb +68 -10
- data/lib/action_controller/pagination.rb +4 -3
- data/lib/action_controller/request.rb +22 -14
- data/lib/action_controller/rescue.rb +25 -22
- data/lib/action_controller/resources.rb +302 -0
- data/lib/action_controller/response.rb +20 -2
- data/lib/action_controller/response.rb.rej +17 -0
- data/lib/action_controller/routing.rb +1165 -567
- data/lib/action_controller/scaffolding.rb +30 -31
- data/lib/action_controller/session/active_record_store.rb +2 -0
- data/lib/action_controller/session/drb_store.rb +4 -0
- data/lib/action_controller/session/mem_cache_store.rb +4 -0
- data/lib/action_controller/session_management.rb +6 -9
- data/lib/action_controller/status_codes.rb +89 -0
- data/lib/action_controller/streaming.rb +6 -15
- data/lib/action_controller/templates/rescues/_request_and_response.rhtml +5 -5
- data/lib/action_controller/templates/rescues/diagnostics.rhtml +2 -2
- data/lib/action_controller/templates/rescues/routing_error.rhtml +4 -4
- data/lib/action_controller/templates/rescues/template_error.rhtml +1 -1
- data/lib/action_controller/templates/scaffolds/list.rhtml +1 -1
- data/lib/action_controller/test_process.rb +52 -30
- data/lib/action_controller/url_rewriter.rb +63 -29
- data/lib/action_controller/vendor/html-scanner/html/document.rb +1 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +3 -4
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +822 -0
- data/lib/action_controller/verification.rb +22 -11
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +2 -2
- data/lib/action_view.rb +1 -1
- data/lib/action_view/base.rb +46 -43
- data/lib/action_view/compiled_templates.rb +1 -1
- data/lib/action_view/helpers/active_record_helper.rb +54 -17
- data/lib/action_view/helpers/asset_tag_helper.rb +97 -46
- data/lib/action_view/helpers/capture_helper.rb +1 -1
- data/lib/action_view/helpers/date_helper.rb +258 -136
- data/lib/action_view/helpers/debug_helper.rb +1 -1
- data/lib/action_view/helpers/deprecated_helper.rb +34 -0
- data/lib/action_view/helpers/form_helper.rb +75 -35
- data/lib/action_view/helpers/form_options_helper.rb +7 -5
- data/lib/action_view/helpers/form_tag_helper.rb +44 -6
- data/lib/action_view/helpers/java_script_macros_helper.rb +59 -46
- data/lib/action_view/helpers/javascript_helper.rb +71 -10
- data/lib/action_view/helpers/javascripts/controls.js +41 -23
- data/lib/action_view/helpers/javascripts/dragdrop.js +105 -76
- data/lib/action_view/helpers/javascripts/effects.js +293 -163
- data/lib/action_view/helpers/javascripts/prototype.js +897 -389
- data/lib/action_view/helpers/javascripts/prototype.js.rej +561 -0
- data/lib/action_view/helpers/number_helper.rb +111 -65
- data/lib/action_view/helpers/prototype_helper.rb +84 -109
- data/lib/action_view/helpers/scriptaculous_helper.rb +5 -0
- data/lib/action_view/helpers/tag_helper.rb +69 -16
- data/lib/action_view/helpers/text_helper.rb +149 -112
- data/lib/action_view/helpers/url_helper.rb +200 -107
- data/lib/action_view/template_error.rb +66 -42
- data/test/abstract_unit.rb +4 -2
- data/test/active_record_unit.rb +84 -56
- data/test/activerecord/active_record_assertions_test.rb +26 -18
- data/test/activerecord/active_record_store_test.rb +4 -36
- data/test/activerecord/pagination_test.rb +1 -6
- data/test/controller/action_pack_assertions_test.rb +230 -113
- data/test/controller/addresses_render_test.rb +2 -6
- data/test/controller/assert_select_test.rb +576 -0
- data/test/controller/base_test.rb +73 -3
- data/test/controller/caching_test.rb +228 -0
- data/test/controller/capture_test.rb +12 -10
- data/test/controller/cgi_test.rb +89 -12
- data/test/controller/components_test.rb +24 -2
- data/test/controller/content_type_test.rb +139 -0
- data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
- data/test/controller/cookie_test.rb +33 -25
- data/test/controller/deprecated_instance_variables_test.rb +48 -0
- data/test/controller/deprecation/deprecated_base_methods_test.rb +60 -0
- data/test/controller/fake_controllers.rb +0 -1
- data/test/controller/filters_test.rb +301 -16
- data/test/controller/flash_test.rb +19 -2
- data/test/controller/helper_test.rb +2 -2
- data/test/controller/integration_test.rb +154 -0
- data/test/controller/layout_test.rb +115 -1
- data/test/controller/mime_responds_test.rb +94 -0
- data/test/controller/mime_type_test.rb +9 -0
- data/test/controller/new_render_test.rb +161 -11
- data/test/controller/raw_post_test.rb +52 -15
- data/test/controller/redirect_test.rb +27 -14
- data/test/controller/render_test.rb +76 -29
- data/test/controller/request_test.rb +55 -4
- data/test/controller/resources_test.rb +274 -0
- data/test/controller/routing_test.rb +1533 -824
- data/test/controller/selector_test.rb +628 -0
- data/test/controller/send_file_test.rb +9 -1
- data/test/controller/session_management_test.rb +51 -0
- data/test/controller/test_test.rb +113 -29
- data/test/controller/url_rewriter_test.rb +86 -17
- data/test/controller/verification_test.rb +19 -17
- data/test/controller/webservice_test.rb +0 -7
- data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_rjs.rjs +1 -0
- data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
- data/test/fixtures/deprecated_instance_variables/_cookies_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_cookies_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_flash_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_flash_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_headers_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_headers_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_params_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_params_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_request_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_request_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_response_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_response_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_session_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_session_method.rhtml +1 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/public/javascripts/application.js +1 -0
- data/test/fixtures/test/_hello.rxml +1 -0
- data/test/fixtures/test/hello_world_container.rxml +3 -0
- data/test/fixtures/topic.rb +2 -2
- data/test/template/active_record_helper_test.rb +83 -12
- data/test/template/asset_tag_helper_test.rb +75 -95
- data/test/template/compiled_templates_test.rb +1 -0
- data/test/template/date_helper_test.rb +873 -181
- data/test/template/deprecated_helper_test.rb +36 -0
- data/test/template/deprecated_instance_variables_test.rb +43 -0
- data/test/template/form_helper_test.rb +77 -1
- data/test/template/form_options_helper_test.rb +4 -0
- data/test/template/form_tag_helper_test.rb +66 -2
- data/test/template/java_script_macros_helper_test.rb +4 -1
- data/test/template/javascript_helper_test.rb +29 -0
- data/test/template/number_helper_test.rb +63 -27
- data/test/template/prototype_helper_test.rb +77 -34
- data/test/template/tag_helper_test.rb +34 -6
- data/test/template/text_helper_test.rb +69 -34
- data/test/template/url_helper_test.rb +168 -16
- data/test/testing_sandbox.rb +7 -22
- metadata +66 -20
- data/filler.txt +0 -50
- data/lib/action_controller/code_generation.rb +0 -235
- data/lib/action_controller/vendor/xml_simple.rb +0 -1019
- data/test/controller/caching_filestore.rb +0 -74
- data/test/fixtures/application_root/app/controllers/a_class_that_contains_a_controller/poorly_placed_controller.rb +0 -7
- data/test/fixtures/application_root/app/controllers/module_that_holds_controllers/nested_controller.rb +0 -3
- data/test/fixtures/application_root/app/models/a_class_that_contains_a_controller.rb +0 -7
- data/test/fixtures/dont_load.rb +0 -3
@@ -12,6 +12,7 @@ module Submodule
|
|
12
12
|
|
13
13
|
hide_action :hidden_action
|
14
14
|
def hidden_action
|
15
|
+
raise "Noooo!"
|
15
16
|
end
|
16
17
|
|
17
18
|
def another_hidden_action
|
@@ -23,7 +24,6 @@ module Submodule
|
|
23
24
|
end
|
24
25
|
end
|
25
26
|
class EmptyController < ActionController::Base
|
26
|
-
include ActionController::Caching
|
27
27
|
end
|
28
28
|
class NonEmptyController < ActionController::Base
|
29
29
|
def public_action
|
@@ -34,10 +34,27 @@ class NonEmptyController < ActionController::Base
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
class MethodMissingController < ActionController::Base
|
38
|
+
|
39
|
+
hide_action :shouldnt_be_called
|
40
|
+
def shouldnt_be_called
|
41
|
+
raise "NO WAY!"
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def method_missing(selector)
|
47
|
+
render :text => selector.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
37
52
|
class ControllerClassTests < Test::Unit::TestCase
|
38
53
|
def test_controller_path
|
39
54
|
assert_equal 'empty', EmptyController.controller_path
|
55
|
+
assert_equal EmptyController.controller_path, EmptyController.new.controller_path
|
40
56
|
assert_equal 'submodule/contained_empty', Submodule::ContainedEmptyController.controller_path
|
57
|
+
assert_equal Submodule::ContainedEmptyController.controller_path, Submodule::ContainedEmptyController.new.controller_path
|
41
58
|
end
|
42
59
|
def test_controller_name
|
43
60
|
assert_equal 'empty', EmptyController.controller_name
|
@@ -57,10 +74,63 @@ class ControllerInstanceTests < Test::Unit::TestCase
|
|
57
74
|
|
58
75
|
def test_action_methods
|
59
76
|
@empty_controllers.each do |c|
|
60
|
-
|
77
|
+
hide_mocha_methods_from_controller(c)
|
78
|
+
assert_equal Set.new, c.send(:action_methods), "#{c.controller_path} should be empty!"
|
61
79
|
end
|
62
80
|
@non_empty_controllers.each do |c|
|
63
|
-
|
81
|
+
hide_mocha_methods_from_controller(c)
|
82
|
+
assert_equal Set.new('public_action'), c.send(:action_methods), "#{c.controller_path} should not be empty!"
|
64
83
|
end
|
65
84
|
end
|
85
|
+
|
86
|
+
protected
|
87
|
+
|
88
|
+
# Mocha adds methods to Object which are then included in the public_instance_methods
|
89
|
+
# This method hides those from the controller so the above tests won't know the difference
|
90
|
+
def hide_mocha_methods_from_controller(controller)
|
91
|
+
mocha_methods = [:expects, :metaclass, :mocha, :mocha_inspect, :reset_mocha, :stubba_object, :stubba_method, :stubs, :verify]
|
92
|
+
controller.class.send(:hide_action, *mocha_methods)
|
93
|
+
end
|
94
|
+
|
66
95
|
end
|
96
|
+
|
97
|
+
|
98
|
+
class PerformActionTest < Test::Unit::TestCase
|
99
|
+
def use_controller(controller_class)
|
100
|
+
@controller = controller_class.new
|
101
|
+
|
102
|
+
# enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
|
103
|
+
# a more accurate simulation of what happens in "real life".
|
104
|
+
@controller.logger = Logger.new(nil)
|
105
|
+
|
106
|
+
@request = ActionController::TestRequest.new
|
107
|
+
@response = ActionController::TestResponse.new
|
108
|
+
|
109
|
+
@request.host = "www.nextangle.com"
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_get_on_priv_should_show_selector
|
113
|
+
use_controller MethodMissingController
|
114
|
+
get :shouldnt_be_called
|
115
|
+
assert_response :success
|
116
|
+
assert_equal 'shouldnt_be_called', @response.body
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_method_missing_is_not_an_action_name
|
120
|
+
use_controller MethodMissingController
|
121
|
+
assert ! @controller.send(:action_methods).include?('method_missing')
|
122
|
+
|
123
|
+
get :method_missing
|
124
|
+
assert_response :success
|
125
|
+
assert_equal 'method_missing', @response.body
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_get_on_hidden_should_fail
|
129
|
+
use_controller NonEmptyController
|
130
|
+
get :hidden_action
|
131
|
+
assert_response 404
|
132
|
+
|
133
|
+
get :another_hidden_action
|
134
|
+
assert_response 404
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,228 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require File.dirname(__FILE__) + '/../abstract_unit'
|
3
|
+
|
4
|
+
CACHE_DIR = 'test_cache'
|
5
|
+
# Don't change '/../temp/' cavalierly or you might hoze something you don't want hozed
|
6
|
+
FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR)
|
7
|
+
ActionController::Base.perform_caching = true
|
8
|
+
ActionController::Base.page_cache_directory = FILE_STORE_PATH
|
9
|
+
ActionController::Base.fragment_cache_store = :file_store, FILE_STORE_PATH
|
10
|
+
|
11
|
+
class PageCachingTestController < ActionController::Base
|
12
|
+
caches_page :ok, :no_content, :found, :not_found
|
13
|
+
|
14
|
+
def ok
|
15
|
+
head :ok
|
16
|
+
end
|
17
|
+
|
18
|
+
def no_content
|
19
|
+
head :no_content
|
20
|
+
end
|
21
|
+
|
22
|
+
def found
|
23
|
+
redirect_to :action => 'ok'
|
24
|
+
end
|
25
|
+
|
26
|
+
def not_found
|
27
|
+
head :not_found
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class PageCachingTest < Test::Unit::TestCase
|
32
|
+
def setup
|
33
|
+
ActionController::Routing::Routes.draw do |map|
|
34
|
+
map.main '', :controller => 'posts'
|
35
|
+
map.resources :posts
|
36
|
+
map.connect ':controller/:action/:id'
|
37
|
+
end
|
38
|
+
|
39
|
+
@request = ActionController::TestRequest.new
|
40
|
+
@request.host = 'hostname.com'
|
41
|
+
|
42
|
+
@response = ActionController::TestResponse.new
|
43
|
+
@controller = PageCachingTestController.new
|
44
|
+
|
45
|
+
@params = {:controller => 'posts', :action => 'index', :only_path => true, :skip_relative_url_root => true}
|
46
|
+
@rewriter = ActionController::UrlRewriter.new(@request, @params)
|
47
|
+
|
48
|
+
FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
|
49
|
+
FileUtils.mkdir_p(FILE_STORE_PATH)
|
50
|
+
end
|
51
|
+
|
52
|
+
def teardown
|
53
|
+
FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_page_caching_resources_saves_to_correct_path_with_extension_even_if_default_route
|
57
|
+
@params[:format] = 'rss'
|
58
|
+
assert_equal '/posts.rss', @rewriter.rewrite(@params)
|
59
|
+
@params[:format] = nil
|
60
|
+
assert_equal '/', @rewriter.rewrite(@params)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_should_cache_get_with_ok_status
|
64
|
+
get :ok
|
65
|
+
assert_response :ok
|
66
|
+
assert_page_cached :ok, "get with ok status should have been cached"
|
67
|
+
end
|
68
|
+
|
69
|
+
[:ok, :no_content, :found, :not_found].each do |status|
|
70
|
+
[:get, :post, :put, :delete].each do |method|
|
71
|
+
unless method == :get and status == :ok
|
72
|
+
define_method "test_shouldnt_cache_#{method}_with_#{status}_status" do
|
73
|
+
@request.env['REQUEST_METHOD'] = method.to_s.upcase
|
74
|
+
process status
|
75
|
+
assert_response status
|
76
|
+
assert_page_not_cached status, "#{method} with #{status} status shouldn't have been cached"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
def assert_page_cached(action, message = "#{action} should have been cached")
|
84
|
+
assert page_cached?(action), message
|
85
|
+
end
|
86
|
+
|
87
|
+
def assert_page_not_cached(action, message = "#{action} shouldn't have been cached")
|
88
|
+
assert !page_cached?(action), message
|
89
|
+
end
|
90
|
+
|
91
|
+
def page_cached?(action)
|
92
|
+
File.exist? "#{FILE_STORE_PATH}/page_caching_test/#{action}.html"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
class ActionCachingTestController < ActionController::Base
|
97
|
+
caches_action :index
|
98
|
+
|
99
|
+
def index
|
100
|
+
@cache_this = Time.now.to_f.to_s
|
101
|
+
render :text => @cache_this
|
102
|
+
end
|
103
|
+
|
104
|
+
def expire
|
105
|
+
expire_action :controller => 'action_caching_test', :action => 'index'
|
106
|
+
render :nothing => true
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
class ActionCachingMockController
|
112
|
+
attr_accessor :mock_url_for
|
113
|
+
attr_accessor :mock_path
|
114
|
+
|
115
|
+
def initialize
|
116
|
+
yield self if block_given?
|
117
|
+
end
|
118
|
+
|
119
|
+
def url_for(*args)
|
120
|
+
@mock_url_for
|
121
|
+
end
|
122
|
+
|
123
|
+
def request
|
124
|
+
mocked_path = @mock_path
|
125
|
+
Object.new.instance_eval(<<-EVAL)
|
126
|
+
def path; '#{@mock_path}' end
|
127
|
+
self
|
128
|
+
EVAL
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class ActionCacheTest < Test::Unit::TestCase
|
133
|
+
def setup
|
134
|
+
reset!
|
135
|
+
FileUtils.mkdir_p(FILE_STORE_PATH)
|
136
|
+
@path_class = ActionController::Caching::Actions::ActionCachePath
|
137
|
+
@mock_controller = ActionCachingMockController.new
|
138
|
+
end
|
139
|
+
|
140
|
+
def teardown
|
141
|
+
FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_simple_action_cache
|
145
|
+
get :index
|
146
|
+
cached_time = content_to_cache
|
147
|
+
assert_equal cached_time, @response.body
|
148
|
+
reset!
|
149
|
+
|
150
|
+
get :index
|
151
|
+
assert_equal cached_time, @response.body
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_cache_expiration
|
155
|
+
get :index
|
156
|
+
cached_time = content_to_cache
|
157
|
+
reset!
|
158
|
+
|
159
|
+
get :index
|
160
|
+
assert_equal cached_time, @response.body
|
161
|
+
reset!
|
162
|
+
|
163
|
+
get :expire
|
164
|
+
reset!
|
165
|
+
|
166
|
+
get :index
|
167
|
+
new_cached_time = content_to_cache
|
168
|
+
assert_not_equal cached_time, @response.body
|
169
|
+
reset!
|
170
|
+
|
171
|
+
get :index
|
172
|
+
assert_response :success
|
173
|
+
assert_equal new_cached_time, @response.body
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_cache_is_scoped_by_subdomain
|
177
|
+
@request.host = 'jamis.hostname.com'
|
178
|
+
get :index
|
179
|
+
jamis_cache = content_to_cache
|
180
|
+
|
181
|
+
@request.host = 'david.hostname.com'
|
182
|
+
get :index
|
183
|
+
david_cache = content_to_cache
|
184
|
+
assert_not_equal jamis_cache, @response.body
|
185
|
+
|
186
|
+
@request.host = 'jamis.hostname.com'
|
187
|
+
get :index
|
188
|
+
assert_equal jamis_cache, @response.body
|
189
|
+
|
190
|
+
@request.host = 'david.hostname.com'
|
191
|
+
get :index
|
192
|
+
assert_equal david_cache, @response.body
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_xml_version_of_resource_is_treated_as_different_cache
|
196
|
+
@mock_controller.mock_url_for = 'http://example.org/posts/'
|
197
|
+
@mock_controller.mock_path = '/posts/index.xml'
|
198
|
+
path_object = @path_class.new(@mock_controller)
|
199
|
+
assert_equal 'xml', path_object.extension
|
200
|
+
assert_equal 'example.org/posts/index.xml', path_object.path
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_empty_path_is_normalized
|
204
|
+
@mock_controller.mock_url_for = 'http://example.org/'
|
205
|
+
@mock_controller.mock_path = '/'
|
206
|
+
|
207
|
+
assert_equal 'example.org/index', @path_class.path_for(@mock_controller)
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_file_extensions
|
211
|
+
get :index, :id => 'kitten.jpg'
|
212
|
+
get :index, :id => 'kitten.jpg'
|
213
|
+
|
214
|
+
assert_response :success
|
215
|
+
end
|
216
|
+
|
217
|
+
private
|
218
|
+
def content_to_cache
|
219
|
+
assigns(:cache_this)
|
220
|
+
end
|
221
|
+
|
222
|
+
def reset!
|
223
|
+
@request = ActionController::TestRequest.new
|
224
|
+
@response = ActionController::TestResponse.new
|
225
|
+
@controller = ActionCachingTestController.new
|
226
|
+
@request.host = 'hostname.com'
|
227
|
+
end
|
228
|
+
end
|
@@ -7,15 +7,15 @@ class CaptureController < ActionController::Base
|
|
7
7
|
def content_for
|
8
8
|
render :layout => "talk_from_action"
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def erb_content_for
|
12
12
|
render :layout => "talk_from_action"
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def block_content_for
|
16
16
|
render :layout => "talk_from_action"
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def non_erb_block_content_for
|
20
20
|
render :layout => "talk_from_action"
|
21
21
|
end
|
@@ -43,36 +43,38 @@ class CaptureTest < Test::Unit::TestCase
|
|
43
43
|
get :capturing
|
44
44
|
assert_equal "Dreamy days", @response.body.strip
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
def test_content_for
|
48
48
|
get :content_for
|
49
49
|
assert_equal expected_content_for_output, @response.body
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
def test_erb_content_for
|
53
53
|
get :content_for
|
54
54
|
assert_equal expected_content_for_output, @response.body
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
def test_block_content_for
|
58
58
|
get :block_content_for
|
59
59
|
assert_equal expected_content_for_output, @response.body
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
def test_non_erb_block_content_for
|
63
63
|
get :non_erb_block_content_for
|
64
64
|
assert_equal expected_content_for_output, @response.body
|
65
65
|
end
|
66
66
|
|
67
67
|
def test_update_element_with_capture
|
68
|
-
|
68
|
+
assert_deprecated 'update_element_function' do
|
69
|
+
get :update_element_with_capture
|
70
|
+
end
|
69
71
|
assert_equal(
|
70
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>" +
|
71
|
-
"\n\n$('status').innerHTML = '\\n <b>You bought something!</b>\\n';",
|
73
|
+
"\n\n$('status').innerHTML = '\\n <b>You bought something!</b>\\n';",
|
72
74
|
@response.body.strip
|
73
75
|
)
|
74
76
|
end
|
75
|
-
|
77
|
+
|
76
78
|
private
|
77
79
|
def expected_content_for_output
|
78
80
|
"<title>Putting stuff in the title!</title>\n\nGreat stuff!"
|
data/test/controller/cgi_test.rb
CHANGED
@@ -17,6 +17,7 @@ class CGITest < Test::Unit::TestCase
|
|
17
17
|
@query_string_without_equal = "action"
|
18
18
|
@query_string_with_many_ampersands =
|
19
19
|
"&action=create_customer&&&full_name=David%20Heinemeier%20Hansson"
|
20
|
+
@query_string_with_empty_key = "action=create_customer&full_name=David%20Heinemeier%20Hansson&=Save"
|
20
21
|
end
|
21
22
|
|
22
23
|
def test_query_string
|
@@ -27,13 +28,43 @@ class CGITest < Test::Unit::TestCase
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def test_deep_query_string
|
30
|
-
|
31
|
+
expected = {'x' => {'y' => {'z' => '10'}}}
|
32
|
+
assert_equal(expected, CGIMethods.parse_query_parameters('x[y][z]=10'))
|
31
33
|
end
|
32
34
|
|
33
35
|
def test_deep_query_string_with_array
|
34
36
|
assert_equal({'x' => {'y' => {'z' => ['10']}}}, CGIMethods.parse_query_parameters('x[y][z][]=10'))
|
35
37
|
assert_equal({'x' => {'y' => {'z' => ['10', '5']}}}, CGIMethods.parse_query_parameters('x[y][z][]=10&x[y][z][]=5'))
|
36
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
|
37
68
|
|
38
69
|
def test_query_string_with_nil
|
39
70
|
assert_equal(
|
@@ -69,6 +100,13 @@ class CGITest < Test::Unit::TestCase
|
|
69
100
|
CGIMethods.parse_query_parameters(@query_string_without_equal)
|
70
101
|
)
|
71
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
|
72
110
|
|
73
111
|
def test_query_string_with_many_ampersands
|
74
112
|
assert_equal(
|
@@ -87,7 +125,8 @@ class CGITest < Test::Unit::TestCase
|
|
87
125
|
"something_nil" => [ nil ],
|
88
126
|
"something_empty" => [ "" ],
|
89
127
|
"products[first]" => [ "Apple Computer" ],
|
90
|
-
"products[second]" => [ "Pc" ]
|
128
|
+
"products[second]" => [ "Pc" ],
|
129
|
+
"" => [ 'Save' ]
|
91
130
|
}
|
92
131
|
|
93
132
|
expected_output = {
|
@@ -116,9 +155,10 @@ class CGITest < Test::Unit::TestCase
|
|
116
155
|
end
|
117
156
|
|
118
157
|
def test_parse_params_from_multipart_upload
|
119
|
-
mockup = Struct.new(:content_type, :original_filename)
|
158
|
+
mockup = Struct.new(:content_type, :original_filename, :read, :rewind)
|
120
159
|
file = mockup.new('img/jpeg', 'foo.jpg')
|
121
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')
|
122
162
|
|
123
163
|
input = {
|
124
164
|
"something" => [ StringIO.new("") ],
|
@@ -129,9 +169,10 @@ class CGITest < Test::Unit::TestCase
|
|
129
169
|
"products[string]" => [ StringIO.new("Apple Computer") ],
|
130
170
|
"products[file]" => [ file ],
|
131
171
|
"ie_products[string]" => [ StringIO.new("Microsoft") ],
|
132
|
-
"ie_products[file]" => [ ie_file ]
|
172
|
+
"ie_products[file]" => [ ie_file ],
|
173
|
+
"text_part" => [non_file_text_part]
|
133
174
|
}
|
134
|
-
|
175
|
+
|
135
176
|
expected_output = {
|
136
177
|
"something" => "",
|
137
178
|
"array_of_stringios" => ["One", "Two"],
|
@@ -153,7 +194,8 @@ class CGITest < Test::Unit::TestCase
|
|
153
194
|
"ie_products" => {
|
154
195
|
"string" => "Microsoft",
|
155
196
|
"file" => ie_file
|
156
|
-
}
|
197
|
+
},
|
198
|
+
"text_part" => "abc"
|
157
199
|
}
|
158
200
|
|
159
201
|
params = CGIMethods.parse_request_parameters(input)
|
@@ -206,29 +248,36 @@ class CGITest < Test::Unit::TestCase
|
|
206
248
|
|
207
249
|
def test_parse_params_with_single_brackets_in_middle
|
208
250
|
input = { "a/b[c]d" => %w(e) }
|
209
|
-
expected = { "a/b
|
251
|
+
expected = { "a/b" => {} }
|
210
252
|
assert_equal expected, CGIMethods.parse_request_parameters(input)
|
211
253
|
end
|
212
254
|
|
213
255
|
def test_parse_params_with_separated_brackets
|
214
256
|
input = { "a/b@[c]d[e]" => %w(f) }
|
215
|
-
expected = { "a/b@" => {
|
257
|
+
expected = { "a/b@" => { }}
|
216
258
|
assert_equal expected, CGIMethods.parse_request_parameters(input)
|
217
259
|
end
|
218
260
|
|
219
261
|
def test_parse_params_with_separated_brackets_and_array
|
220
262
|
input = { "a/b@[c]d[e][]" => %w(f) }
|
221
|
-
expected = { "a/b@" => {
|
263
|
+
expected = { "a/b@" => { }}
|
222
264
|
assert_equal expected , CGIMethods.parse_request_parameters(input)
|
223
265
|
end
|
224
266
|
|
225
267
|
def test_parse_params_with_unmatched_brackets_and_array
|
226
268
|
input = { "a/b@[c][d[e][]" => %w(f) }
|
227
|
-
expected = { "a/b@" => { "c" => {
|
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" }
|
228
276
|
assert_equal expected, CGIMethods.parse_request_parameters(input)
|
229
277
|
end
|
230
278
|
end
|
231
279
|
|
280
|
+
|
232
281
|
class MultipartCGITest < Test::Unit::TestCase
|
233
282
|
FIXTURE_PATH = File.dirname(__FILE__) + '/../fixtures/multipart'
|
234
283
|
|
@@ -292,23 +341,39 @@ class MultipartCGITest < Test::Unit::TestCase
|
|
292
341
|
assert_equal 'bar', params['foo']
|
293
342
|
|
294
343
|
# Ruby CGI doesn't handle multipart/mixed for us.
|
295
|
-
assert_kind_of
|
344
|
+
assert_kind_of String, params['files']
|
296
345
|
assert_equal 19756, params['files'].size
|
297
346
|
end
|
298
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
|
+
|
299
355
|
private
|
300
356
|
def process(name)
|
301
357
|
old_stdin = $stdin
|
302
358
|
File.open(File.join(FIXTURE_PATH, name), 'rb') do |file|
|
303
359
|
ENV['CONTENT_LENGTH'] = file.stat.size.to_s
|
304
360
|
$stdin = file
|
305
|
-
|
361
|
+
@cgi = CGI.new
|
362
|
+
CGIMethods.parse_request_parameters @cgi.params
|
306
363
|
end
|
307
364
|
ensure
|
308
365
|
$stdin = old_stdin
|
309
366
|
end
|
310
367
|
end
|
311
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
|
+
|
312
377
|
|
313
378
|
class CGIRequestTest < Test::Unit::TestCase
|
314
379
|
def setup
|
@@ -360,4 +425,16 @@ class CGIRequestTest < Test::Unit::TestCase
|
|
360
425
|
assert_equal ["c84ace84796670c052c6ceb2451fb0f2"], alt_cookies["_session_id"]
|
361
426
|
assert_equal ["yes"], alt_cookies["is_admin"]
|
362
427
|
end
|
428
|
+
|
429
|
+
def test_unbalanced_query_string_with_array
|
430
|
+
assert_equal(
|
431
|
+
{'location' => ["1", "2"], 'age_group' => ["2"]},
|
432
|
+
CGIMethods.parse_query_parameters("location[]=1&location[]=2&age_group[]=2")
|
433
|
+
)
|
434
|
+
assert_equal(
|
435
|
+
{'location' => ["1", "2"], 'age_group' => ["2"]},
|
436
|
+
CGIMethods.parse_request_parameters({'location[]' => ["1", "2"],
|
437
|
+
'age_group[]' => ["2"]})
|
438
|
+
)
|
439
|
+
end
|
363
440
|
end
|