actionpack 2.0.2 → 2.0.4
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 +45 -0
- data/Rakefile +5 -3
- data/lib/action_controller.rb +0 -0
- data/lib/action_controller/assertions/response_assertions.rb +6 -2
- data/lib/action_controller/assertions/routing_assertions.rb +5 -2
- data/lib/action_controller/base.rb +4 -3
- data/lib/action_controller/cgi_ext/cookie.rb +1 -1
- data/lib/action_controller/filters.rb +5 -3
- data/lib/action_controller/http_authentication.rb +2 -4
- data/lib/action_controller/integration.rb +3 -2
- data/lib/action_controller/layout.rb +14 -15
- data/lib/action_controller/mime_type.rb +4 -1
- data/lib/action_controller/polymorphic_routes.rb +90 -15
- data/lib/action_controller/record_identifier.rb +4 -4
- data/lib/action_controller/request.rb +29 -14
- data/lib/action_controller/request_forgery_protection.rb +41 -34
- data/lib/action_controller/request_profiler.rb +16 -6
- data/lib/action_controller/response.rb +0 -0
- data/lib/action_controller/routing.rb +3 -3
- data/lib/action_controller/session/active_record_store.rb +7 -8
- data/lib/action_controller/session/cookie_store.rb +2 -3
- data/lib/action_controller/templates/rescues/_trace.erb +5 -5
- data/lib/action_controller/test_case.rb +24 -4
- data/lib/action_controller/test_process.rb +3 -3
- data/lib/action_controller/url_rewriter.rb +29 -28
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +2 -2
- data/lib/action_controller/verification.rb +73 -57
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_view/base.rb +24 -6
- data/lib/action_view/helpers/active_record_helper.rb +1 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +12 -6
- data/lib/action_view/helpers/atom_feed_helper.rb +21 -17
- data/lib/action_view/helpers/date_helper.rb +6 -6
- data/lib/action_view/helpers/form_helper.rb +3 -2
- data/lib/action_view/helpers/form_options_helper.rb +12 -1
- data/lib/action_view/helpers/form_tag_helper.rb +18 -0
- data/lib/action_view/helpers/number_helper.rb +1 -1
- data/lib/action_view/helpers/prototype_helper.rb +1 -1
- data/lib/action_view/helpers/text_helper.rb +1 -1
- data/lib/action_view/helpers/url_helper.rb +5 -9
- data/lib/action_view/template_error.rb +11 -4
- data/test/activerecord/active_record_store_test.rb +1 -1
- data/test/activerecord/fixtures_test.rb +24 -0
- data/test/controller/action_pack_assertions_test.rb +37 -2
- data/test/controller/base_test.rb +4 -1
- data/test/controller/cgi_test.rb +4 -3
- data/test/controller/filters_test.rb +4 -7
- data/test/controller/html-scanner/sanitizer_test.rb +7 -1
- data/test/controller/integration_test.rb +0 -1
- data/test/controller/mime_type_test.rb +5 -0
- data/test/controller/new_render_test.rb +25 -2
- data/test/controller/polymorphic_routes_test.rb +106 -75
- data/test/controller/redirect_test.rb +11 -0
- data/test/controller/render_test.rb +19 -0
- data/test/controller/request_forgery_protection_test.rb +9 -0
- data/test/controller/request_test.rb +33 -5
- data/test/controller/routing_test.rb +4 -4
- data/test/controller/session/cookie_store_test.rb +0 -0
- data/test/controller/test_test.rb +43 -1
- data/test/controller/url_rewriter_test.rb +34 -4
- data/test/fixtures/layouts/block_with_layout.erb +3 -0
- data/test/fixtures/layouts/partial_with_layout.erb +3 -0
- data/test/template/asset_tag_helper_test.rb +17 -13
- data/test/template/atom_feed_helper_test.rb +52 -2
- data/test/template/compiled_templates_test.rb +5 -1
- data/test/template/date_helper_test.rb +1 -1
- data/test/template/deprecate_ivars_test.rb +51 -0
- data/test/template/form_options_helper_test.rb +29 -0
- data/test/template/form_tag_helper_test.rb +18 -0
- data/test/template/number_helper_test.rb +1 -0
- data/test/template/text_helper_test.rb +32 -14
- data/test/template/url_helper_test.rb +1 -1
- data/test/testing_sandbox.rb +8 -4
- metadata +9 -4
@@ -114,6 +114,24 @@ module ActionView
|
|
114
114
|
tag :input, { "type" => "text", "name" => name, "id" => name, "value" => value }.update(options.stringify_keys)
|
115
115
|
end
|
116
116
|
|
117
|
+
# Creates a label field
|
118
|
+
#
|
119
|
+
# ==== Options
|
120
|
+
# * Creates standard HTML attributes for the tag.
|
121
|
+
#
|
122
|
+
# ==== Examples
|
123
|
+
# label_tag 'name'
|
124
|
+
# # => <label for="name">Name</label>
|
125
|
+
#
|
126
|
+
# label_tag 'name', 'Your name'
|
127
|
+
# # => <label for="name">Your Name</label>
|
128
|
+
#
|
129
|
+
# label_tag 'name', nil, :class => 'small_label'
|
130
|
+
# # => <label for="name" class="small_label">Name</label>
|
131
|
+
def label_tag(name, text = nil, options = {})
|
132
|
+
content_tag :label, text || name.humanize, { "for" => name }.update(options.stringify_keys)
|
133
|
+
end
|
134
|
+
|
117
135
|
# Creates a hidden form input field used to transmit data that would be lost due to HTTP's statelessness or
|
118
136
|
# data that should be hidden from the user.
|
119
137
|
#
|
@@ -170,7 +170,7 @@ module ActionView
|
|
170
170
|
when size < 1.gigabyte; "%.#{precision}f MB" % (size / 1.0.megabyte)
|
171
171
|
when size < 1.terabyte; "%.#{precision}f GB" % (size / 1.0.gigabyte)
|
172
172
|
else "%.#{precision}f TB" % (size / 1.0.terabyte)
|
173
|
-
end.sub(/([0-9])
|
173
|
+
end.sub(/([0-9]\.\d*?)0+ /, '\1 ' ).sub(/\. /,' ')
|
174
174
|
rescue
|
175
175
|
nil
|
176
176
|
end
|
@@ -1019,7 +1019,7 @@ module ActionView
|
|
1019
1019
|
js_options['parameters'] = options[:with]
|
1020
1020
|
end
|
1021
1021
|
|
1022
|
-
if protect_against_forgery?
|
1022
|
+
if protect_against_forgery? && !options[:form]
|
1023
1023
|
if js_options['parameters']
|
1024
1024
|
js_options['parameters'] << " + '&"
|
1025
1025
|
else
|
@@ -436,7 +436,7 @@ module ActionView
|
|
436
436
|
[-\w]+ # subdomain or domain
|
437
437
|
(?:\.[-\w]+)* # remaining subdomains or domain
|
438
438
|
(?::\d+)? # port
|
439
|
-
(?:/(?:(?:[~\w
|
439
|
+
(?:/(?:(?:[~\w\+@%=-]|(?:[,.;:][^\s$]))+)?)* # path
|
440
440
|
(?:\?[\w\+@%&=.;-]+)? # query string
|
441
441
|
(?:\#[\w\-]*)? # trailing anchor
|
442
442
|
)
|
@@ -389,9 +389,8 @@ module ActionView
|
|
389
389
|
email_address_obfuscated.gsub!(/\./, html_options.delete("replace_dot")) if html_options.has_key?("replace_dot")
|
390
390
|
|
391
391
|
if encode == "javascript"
|
392
|
-
|
393
|
-
|
394
|
-
string << sprintf("%%%x",tmp[i])
|
392
|
+
"document.write('#{content_tag("a", name || email_address, html_options.merge({ "href" => "mailto:"+email_address+extras }))}');".each_byte do |c|
|
393
|
+
string << sprintf("%%%x", c)
|
395
394
|
end
|
396
395
|
"<script type=\"#{Mime::JS}\">eval(unescape('#{string}'))</script>"
|
397
396
|
elsif encode == "hex"
|
@@ -403,12 +402,9 @@ module ActionView
|
|
403
402
|
protocol = 'mailto:'
|
404
403
|
protocol.each_byte { |c| string << sprintf("&#%d;", c) }
|
405
404
|
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
else
|
410
|
-
string << email_address[i,1]
|
411
|
-
end
|
405
|
+
email_address.each_byte do |c|
|
406
|
+
char = c.chr
|
407
|
+
string << (char =~ /\w/ ? sprintf("%%%x", c) : char)
|
412
408
|
end
|
413
409
|
content_tag "a", name || email_address_encoded, html_options.merge({ "href" => "#{string}#{extras}" })
|
414
410
|
else
|
@@ -10,6 +10,7 @@ module ActionView
|
|
10
10
|
@base_path, @assigns, @source, @original_exception =
|
11
11
|
base_path, assigns.dup, source, original_exception
|
12
12
|
@file_path = file_path
|
13
|
+
@backtrace = compute_backtrace
|
13
14
|
end
|
14
15
|
|
15
16
|
def message
|
@@ -72,14 +73,20 @@ module ActionView
|
|
72
73
|
"#{source_extract}\n #{clean_backtrace.join("\n ")}\n\n"
|
73
74
|
end
|
74
75
|
|
76
|
+
# don't do anything nontrivial here. Any raised exception from here becomes fatal
|
77
|
+
# (and can't be rescued).
|
75
78
|
def backtrace
|
76
|
-
|
77
|
-
"#{source_location.capitalize}\n\n#{source_extract(4)}\n " +
|
78
|
-
clean_backtrace.join("\n ")
|
79
|
-
]
|
79
|
+
@backtrace
|
80
80
|
end
|
81
81
|
|
82
82
|
private
|
83
|
+
def compute_backtrace
|
84
|
+
[
|
85
|
+
"#{source_location.capitalize}\n\n#{source_extract(4)}\n " +
|
86
|
+
clean_backtrace.join("\n ")
|
87
|
+
]
|
88
|
+
end
|
89
|
+
|
83
90
|
def strip_base_path(path)
|
84
91
|
stripped_path = File.expand_path(path).gsub(@base_path, "")
|
85
92
|
stripped_path.gsub!(/^#{Regexp.escape File.expand_path(RAILS_ROOT)}/, '') if defined?(RAILS_ROOT)
|
@@ -66,7 +66,7 @@ class ActiveRecordStoreTest < ActiveRecordTestCase
|
|
66
66
|
|
67
67
|
def test_save_unloaded_session
|
68
68
|
c = session_class.connection
|
69
|
-
bogus_class = c.quote(Base64.encode64("\004\010o:\vBlammo\000"))
|
69
|
+
bogus_class = c.quote(ActiveSupport::Base64.encode64("\004\010o:\vBlammo\000"))
|
70
70
|
c.insert("INSERT INTO #{session_class.table_name} ('#{session_id_column}', 'data') VALUES ('abcdefghijklmnop', #{bogus_class})")
|
71
71
|
|
72
72
|
sess = session_class.find_by_session_id('abcdefghijklmnop')
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../active_record_unit'
|
2
|
+
require "action_controller/test_case"
|
3
|
+
|
4
|
+
class ActionController::TestCase
|
5
|
+
self.fixture_path = File.dirname(__FILE__) + '/../fixtures'
|
6
|
+
self.use_transactional_fixtures = false
|
7
|
+
end
|
8
|
+
|
9
|
+
class DeveloperController < ActionController::Base
|
10
|
+
end
|
11
|
+
|
12
|
+
class DeveloperControllerTest < ActionController::TestCase
|
13
|
+
fixtures :developers
|
14
|
+
|
15
|
+
def setup
|
16
|
+
@david = developers(:david)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_should_have_loaded_fixtures
|
20
|
+
assert_kind_of(Developer, @david)
|
21
|
+
assert_kind_of(Developer, developers(:jamis))
|
22
|
+
assert_equal(@developers.size, Developer.count)
|
23
|
+
end
|
24
|
+
end
|
@@ -124,6 +124,18 @@ class ActionPackAssertionsController < ActionController::Base
|
|
124
124
|
def rescue_action(e) raise; end
|
125
125
|
end
|
126
126
|
|
127
|
+
# Used to test that assert_response includes the exception message
|
128
|
+
# in the failure message when an action raises and assert_response
|
129
|
+
# is expecting something other than an error.
|
130
|
+
class AssertResponseWithUnexpectedErrorController < ActionController::Base
|
131
|
+
def index
|
132
|
+
raise 'FAIL'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class UserController < ActionController::Base
|
137
|
+
end
|
138
|
+
|
127
139
|
module Admin
|
128
140
|
class InnerModuleController < ActionController::Base
|
129
141
|
def index
|
@@ -161,7 +173,7 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
|
|
161
173
|
# let's get this party started
|
162
174
|
def setup
|
163
175
|
ActionController::Routing::Routes.reload
|
164
|
-
ActionController::Routing.use_controllers!(%w(action_pack_assertions admin/inner_module content admin/user))
|
176
|
+
ActionController::Routing.use_controllers!(%w(action_pack_assertions admin/inner_module user content admin/user))
|
165
177
|
@controller = ActionPackAssertionsController.new
|
166
178
|
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
|
167
179
|
end
|
@@ -255,7 +267,7 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
|
|
255
267
|
assert_redirected_to admin_inner_module_path
|
256
268
|
end
|
257
269
|
end
|
258
|
-
|
270
|
+
|
259
271
|
def test_assert_redirected_to_top_level_named_route_from_nested_controller
|
260
272
|
with_routing do |set|
|
261
273
|
set.draw do |map|
|
@@ -269,6 +281,20 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
|
|
269
281
|
end
|
270
282
|
end
|
271
283
|
|
284
|
+
|
285
|
+
def test_assert_redirected_to_top_level_named_route_with_same_controller_name_in_both_namespaces
|
286
|
+
with_routing do |set|
|
287
|
+
set.draw do |map|
|
288
|
+
# this controller exists in the admin namespace as well which is the only difference from previous test
|
289
|
+
map.top_level '/user/:id', :controller => 'user', :action => 'index'
|
290
|
+
map.connect ':controller/:action/:id'
|
291
|
+
end
|
292
|
+
@controller = Admin::InnerModuleController.new
|
293
|
+
process :redirect_to_top_level_named_route
|
294
|
+
assert_redirected_to "/user/foo"
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
272
298
|
# -- standard request/response object testing --------------------------------
|
273
299
|
|
274
300
|
# make sure that the template objects exist
|
@@ -465,6 +491,15 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
|
|
465
491
|
rescue Test::Unit::AssertionFailedError => e
|
466
492
|
end
|
467
493
|
end
|
494
|
+
|
495
|
+
def test_assert_response_uses_exception_message
|
496
|
+
@controller = AssertResponseWithUnexpectedErrorController.new
|
497
|
+
get :index
|
498
|
+
assert_response :success
|
499
|
+
flunk 'Expected non-success response'
|
500
|
+
rescue Test::Unit::AssertionFailedError => e
|
501
|
+
assert e.message.include?('FAIL')
|
502
|
+
end
|
468
503
|
end
|
469
504
|
|
470
505
|
class ActionPackHeaderTest < Test::Unit::TestCase
|
@@ -87,7 +87,10 @@ class ControllerInstanceTests < Test::Unit::TestCase
|
|
87
87
|
# Mocha adds some public instance methods to Object that would be
|
88
88
|
# considered actions, so explicitly hide_action them.
|
89
89
|
def hide_mocha_methods_from_controller(controller)
|
90
|
-
mocha_methods = [
|
90
|
+
mocha_methods = [
|
91
|
+
:expects, :mocha, :mocha_inspect, :reset_mocha, :stubba_object,
|
92
|
+
:stubba_method, :stubs, :verify, :__metaclass__, :__is_a__, :to_matcher,
|
93
|
+
]
|
91
94
|
controller.class.send!(:hide_action, *mocha_methods)
|
92
95
|
end
|
93
96
|
end
|
data/test/controller/cgi_test.rb
CHANGED
@@ -4,8 +4,9 @@ require 'action_controller/cgi_process'
|
|
4
4
|
class BaseCgiTest < Test::Unit::TestCase
|
5
5
|
def setup
|
6
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"}
|
7
|
-
#
|
8
|
-
|
7
|
+
# some Nokia phone browsers omit the space after the semicolon separator.
|
8
|
+
# some developers have grown accustomed to using comma in cookie values.
|
9
|
+
@alt_cookie_fmt_request_hash = {"HTTP_COOKIE"=>"_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes"}
|
9
10
|
@fake_cgi = Struct.new(:env_table).new(@request_hash)
|
10
11
|
@request = ActionController::CgiRequest.new(@fake_cgi)
|
11
12
|
end
|
@@ -76,7 +77,7 @@ class CgiRequestTest < BaseCgiTest
|
|
76
77
|
assert_equal ["yes"], cookies["is_admin"], cookies.inspect
|
77
78
|
|
78
79
|
alt_cookies = CGI::Cookie::parse(@alt_cookie_fmt_request_hash["HTTP_COOKIE"]);
|
79
|
-
assert_equal ["
|
80
|
+
assert_equal ["c84ace847,96670c052c6ceb2451fb0f2"], alt_cookies["_session_id"], alt_cookies.inspect
|
80
81
|
assert_equal ["yes"], alt_cookies["is_admin"], alt_cookies.inspect
|
81
82
|
end
|
82
83
|
end
|
@@ -696,10 +696,6 @@ class ControllerWithProcFilter < PostsController
|
|
696
696
|
end
|
697
697
|
end
|
698
698
|
|
699
|
-
class ControllerWithWrongFilterType < PostsController
|
700
|
-
around_filter lambda { yield }, :only => :no_raise
|
701
|
-
end
|
702
|
-
|
703
699
|
class ControllerWithNestedFilters < ControllerWithSymbolAsFilter
|
704
700
|
around_filter :raise_before, :raise_after, :without_exception, :only => :raises_both
|
705
701
|
end
|
@@ -746,14 +742,15 @@ class YieldingAroundFiltersTest < Test::Unit::TestCase
|
|
746
742
|
assert_equal 1, ControllerWithFilterClass.filter_chain.size
|
747
743
|
assert_equal 1, ControllerWithFilterInstance.filter_chain.size
|
748
744
|
assert_equal 3, ControllerWithSymbolAsFilter.filter_chain.size
|
749
|
-
assert_equal 1, ControllerWithWrongFilterType.filter_chain.size
|
750
745
|
assert_equal 6, ControllerWithNestedFilters.filter_chain.size
|
751
746
|
assert_equal 4, ControllerWithAllTypesOfFilters.filter_chain.size
|
752
747
|
end
|
753
748
|
|
754
749
|
def test_wrong_filter_type
|
755
|
-
assert_raise
|
756
|
-
|
750
|
+
assert_raise ArgumentError do
|
751
|
+
Class.new PostsController do
|
752
|
+
around_filter lambda { yield }
|
753
|
+
end
|
757
754
|
end
|
758
755
|
end
|
759
756
|
|
@@ -203,6 +203,12 @@ class SanitizerTest < Test::Unit::TestCase
|
|
203
203
|
assert_equal expected, sanitize_css(raw)
|
204
204
|
end
|
205
205
|
|
206
|
+
def test_should_sanitize_with_trailing_space
|
207
|
+
raw = "display:block; "
|
208
|
+
expected = "display: block;"
|
209
|
+
assert_equal expected, sanitize_css(raw)
|
210
|
+
end
|
211
|
+
|
206
212
|
def test_should_sanitize_xul_style_attributes
|
207
213
|
raw = %(-moz-binding:url('http://ha.ckers.org/xssmoz.xml#xss'))
|
208
214
|
assert_equal '', sanitize_css(raw)
|
@@ -247,4 +253,4 @@ protected
|
|
247
253
|
def sanitize_css(input)
|
248
254
|
(@sanitizer ||= HTML::WhiteListSanitizer.new).sanitize_css(input)
|
249
255
|
end
|
250
|
-
end
|
256
|
+
end
|
@@ -39,6 +39,11 @@ class MimeTypeTest < Test::Unit::TestCase
|
|
39
39
|
Mime.module_eval { remove_const :GIF if const_defined?(:GIF) }
|
40
40
|
end
|
41
41
|
|
42
|
+
def test_type_should_be_equal_to_symbol
|
43
|
+
assert_equal Mime::HTML, 'application/xhtml+xml'
|
44
|
+
assert_equal Mime::HTML, :html
|
45
|
+
end
|
46
|
+
|
42
47
|
def test_type_convenience_methods
|
43
48
|
types = [:html, :xml, :png, :pdf, :yaml, :url_encoded_form]
|
44
49
|
types.each do |type|
|
@@ -361,10 +361,18 @@ class NewRenderTestController < ActionController::Base
|
|
361
361
|
render :action => "calling_partial_with_layout"
|
362
362
|
end
|
363
363
|
|
364
|
+
def render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
|
365
|
+
render :action => "calling_partial_with_layout"
|
366
|
+
end
|
367
|
+
|
364
368
|
def render_using_layout_around_block
|
365
369
|
render :action => "using_layout_around_block"
|
366
370
|
end
|
367
371
|
|
372
|
+
def render_using_layout_around_block_in_main_layout_and_within_content_for_layout
|
373
|
+
render :action => "using_layout_around_block"
|
374
|
+
end
|
375
|
+
|
368
376
|
def rescue_action(e) raise end
|
369
377
|
|
370
378
|
private
|
@@ -387,6 +395,10 @@ class NewRenderTestController < ActionController::Base
|
|
387
395
|
"layouts/builder"
|
388
396
|
when "action_talk_to_layout", "layout_overriding_layout"
|
389
397
|
"layouts/talk_from_action"
|
398
|
+
when "render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout"
|
399
|
+
"layouts/partial_with_layout"
|
400
|
+
when "render_using_layout_around_block_in_main_layout_and_within_content_for_layout"
|
401
|
+
"layouts/block_with_layout"
|
390
402
|
end
|
391
403
|
end
|
392
404
|
end
|
@@ -824,9 +836,20 @@ EOS
|
|
824
836
|
get :render_call_to_partial_with_layout
|
825
837
|
assert_equal "Before (David)\nInside from partial (David)\nAfter", @response.body
|
826
838
|
end
|
827
|
-
|
839
|
+
|
840
|
+
def test_render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
|
841
|
+
get :render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
|
842
|
+
assert_equal "Before (Anthony)\nInside from partial (Anthony)\nAfter\nBefore (David)\nInside from partial (David)\nAfter\nBefore (Ramm)\nInside from partial (Ramm)\nAfter", @response.body
|
843
|
+
end
|
844
|
+
|
828
845
|
def test_using_layout_around_block
|
829
|
-
get :
|
846
|
+
get :render_using_layout_around_block
|
830
847
|
assert_equal "Before (David)\nInside from block\nAfter", @response.body
|
831
848
|
end
|
849
|
+
|
850
|
+
def test_using_layout_around_block_in_main_layout_and_within_content_for_layout
|
851
|
+
get :render_using_layout_around_block_in_main_layout_and_within_content_for_layout
|
852
|
+
assert_equal "Before (Anthony)\nInside from first block in layout\nAfter\nBefore (David)\nInside from block\nAfter\nBefore (Ramm)\nInside from second block in layout\nAfter\n", @response.body
|
853
|
+
end
|
854
|
+
|
832
855
|
end
|
@@ -5,94 +5,125 @@ class Article
|
|
5
5
|
def save; @id = 1 end
|
6
6
|
def new_record?; @id.nil? end
|
7
7
|
def name
|
8
|
-
|
8
|
+
model = self.class.name.downcase
|
9
|
+
@id.nil? ? "new #{model}" : "#{model} ##{@id}"
|
9
10
|
end
|
10
11
|
end
|
11
12
|
|
12
|
-
class Comment
|
13
|
-
attr_reader :id
|
13
|
+
class Comment < Article
|
14
14
|
def post_id; 1 end
|
15
|
-
def save; @id = 1 end
|
16
|
-
def new_record?; @id.nil? end
|
17
|
-
def name
|
18
|
-
@id.nil? ? 'new comment' : "comment ##{@id}"
|
19
|
-
end
|
20
15
|
end
|
21
16
|
|
17
|
+
class Tag < Article
|
18
|
+
def comment_id; 1 end
|
19
|
+
end
|
20
|
+
|
21
|
+
# TODO: test nested models
|
22
22
|
class Comment::Nested < Comment; end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
def articles_url
|
27
|
-
'http://www.example.com/articles'
|
28
|
-
end
|
29
|
-
alias_method :new_article_url, :articles_url
|
30
|
-
|
31
|
-
def article_url(article)
|
32
|
-
"http://www.example.com/articles/#{article.id}"
|
33
|
-
end
|
24
|
+
uses_mocha 'polymorphic URL helpers' do
|
25
|
+
class PolymorphicRoutesTest < Test::Unit::TestCase
|
34
26
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
def admin_articles_url
|
44
|
-
"http://www.example.com/admin/articles"
|
45
|
-
end
|
46
|
-
alias_method :new_admin_article_url, :admin_articles_url
|
47
|
-
|
48
|
-
def admin_article_url(article)
|
49
|
-
"http://www.example.com/admin/articles/#{article.id}"
|
50
|
-
end
|
51
|
-
|
52
|
-
def admin_article_comments_url(article)
|
53
|
-
"http://www.example.com/admin/articles/#{article.id}/comments"
|
54
|
-
end
|
27
|
+
include ActionController::PolymorphicRoutes
|
28
|
+
|
29
|
+
def setup
|
30
|
+
@article = Article.new
|
31
|
+
@comment = Comment.new
|
32
|
+
end
|
55
33
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
34
|
+
def test_with_record
|
35
|
+
@article.save
|
36
|
+
expects(:article_url).with(@article)
|
37
|
+
polymorphic_url(@article)
|
38
|
+
end
|
60
39
|
|
40
|
+
def test_with_new_record
|
41
|
+
expects(:articles_url).with()
|
42
|
+
@article.expects(:new_record?).returns(true)
|
43
|
+
polymorphic_url(@article)
|
44
|
+
end
|
61
45
|
|
62
|
-
|
63
|
-
|
46
|
+
def test_with_record_and_action
|
47
|
+
expects(:new_article_url).with()
|
48
|
+
@article.expects(:new_record?).never
|
49
|
+
polymorphic_url(@article, :action => 'new')
|
50
|
+
end
|
64
51
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
52
|
+
def test_url_helper_prefixed_with_new
|
53
|
+
expects(:new_article_url).with()
|
54
|
+
new_polymorphic_url(@article)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_url_helper_prefixed_with_edit
|
58
|
+
@article.save
|
59
|
+
expects(:edit_article_url).with(@article)
|
60
|
+
edit_polymorphic_url(@article)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_formatted_url_helper
|
64
|
+
expects(:formatted_article_url).with(@article, :pdf)
|
65
|
+
formatted_polymorphic_url([@article, :pdf])
|
66
|
+
end
|
67
|
+
|
68
|
+
# TODO: should this work?
|
69
|
+
def xtest_format_option
|
70
|
+
@article.save
|
71
|
+
expects(:article_url).with(@article, :format => :pdf)
|
72
|
+
polymorphic_url(@article, :format => :pdf)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_with_nested
|
76
|
+
@comment.save
|
77
|
+
expects(:article_comment_url).with(@article, @comment)
|
78
|
+
polymorphic_url([@article, @comment])
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_with_nested_unsaved
|
82
|
+
expects(:article_comments_url).with(@article)
|
83
|
+
polymorphic_url([@article, @comment])
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_new_with_array_and_namespace
|
87
|
+
expects(:new_admin_article_url).with()
|
88
|
+
polymorphic_url([:admin, @article], :action => 'new')
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_unsaved_with_array_and_namespace
|
92
|
+
expects(:admin_articles_url).with()
|
93
|
+
polymorphic_url([:admin, @article])
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_nested_unsaved_with_array_and_namespace
|
97
|
+
@article.save
|
98
|
+
expects(:admin_article_url).with(@article)
|
99
|
+
polymorphic_url([:admin, @article])
|
100
|
+
expects(:admin_article_comments_url).with(@article)
|
101
|
+
polymorphic_url([:admin, @article, @comment])
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_nested_with_array_and_namespace
|
105
|
+
@comment.save
|
106
|
+
expects(:admin_article_comment_url).with(@article, @comment)
|
107
|
+
polymorphic_url([:admin, @article, @comment])
|
108
|
+
|
109
|
+
# a ridiculously long named route tests correct ordering of namespaces and nesting:
|
110
|
+
@tag = Tag.new
|
111
|
+
@tag.save
|
112
|
+
expects(:site_admin_article_comment_tag_url).with(@article, @comment, @tag)
|
113
|
+
polymorphic_url([:site, :admin, @article, @comment, @tag])
|
114
|
+
end
|
115
|
+
|
116
|
+
# TODO: Needs to be updated to correctly know about whether the object is in a hash or not
|
117
|
+
def xtest_with_hash
|
118
|
+
expects(:article_url).with(@article)
|
119
|
+
@article.save
|
120
|
+
polymorphic_url(:id => @article)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_polymorphic_path_accepts_options
|
124
|
+
expects(:new_article_path).with()
|
125
|
+
polymorphic_path(@article, :action => :new)
|
126
|
+
end
|
82
127
|
|
83
|
-
def test_with_array
|
84
|
-
assert_equal(article_comments_url(@article), polymorphic_url([@article, @comment]))
|
85
|
-
@comment.save
|
86
|
-
assert_equal(article_comment_url(@article, @comment), polymorphic_url([@article, @comment]))
|
87
|
-
end
|
88
|
-
|
89
|
-
def test_with_array_and_namespace
|
90
|
-
assert_equal(admin_articles_url, polymorphic_url([:admin, @article], :action => 'new'))
|
91
|
-
assert_equal(admin_articles_url, polymorphic_url([:admin, @article]))
|
92
|
-
@article.save
|
93
|
-
assert_equal(admin_article_url(@article), polymorphic_url([:admin, @article]))
|
94
|
-
assert_equal(admin_article_comments_url(@article), polymorphic_url([:admin, @article, @comment]))
|
95
|
-
@comment.save
|
96
|
-
assert_equal(admin_article_comment_url(@article, @comment), polymorphic_url([:admin, @article, @comment]))
|
97
128
|
end
|
98
129
|
end
|