actionpack 2.3.2 → 2.3.3

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.

Files changed (117) hide show
  1. data/CHANGELOG +5 -0
  2. data/Rakefile +10 -9
  3. data/lib/action_controller.rb +2 -7
  4. data/lib/action_controller/assertions/response_assertions.rb +11 -3
  5. data/lib/action_controller/base.rb +7 -2
  6. data/lib/action_controller/caching.rb +1 -1
  7. data/lib/action_controller/caching/actions.rb +9 -1
  8. data/lib/action_controller/caching/sweeper.rb +45 -0
  9. data/lib/action_controller/caching/sweeping.rb +0 -42
  10. data/lib/action_controller/failsafe.rb +40 -6
  11. data/lib/action_controller/flash.rb +11 -3
  12. data/lib/action_controller/http_authentication.rb +5 -2
  13. data/lib/action_controller/integration.rb +5 -12
  14. data/lib/action_controller/middlewares.rb +0 -1
  15. data/lib/action_controller/reloader.rb +34 -3
  16. data/lib/action_controller/request.rb +6 -2
  17. data/lib/action_controller/response.rb +2 -2
  18. data/lib/action_controller/routing/route_set.rb +2 -1
  19. data/lib/action_controller/streaming.rb +1 -1
  20. data/lib/action_controller/test_process.rb +9 -1
  21. data/lib/action_pack/version.rb +1 -1
  22. data/lib/action_view/helpers.rb +1 -1
  23. data/lib/action_view/helpers/asset_tag_helper.rb +21 -9
  24. data/lib/action_view/helpers/date_helper.rb +2 -2
  25. data/lib/action_view/helpers/form_helper.rb +25 -12
  26. data/lib/action_view/helpers/form_options_helper.rb +2 -0
  27. data/lib/action_view/helpers/form_tag_helper.rb +10 -4
  28. data/lib/action_view/helpers/number_helper.rb +1 -1
  29. data/lib/action_view/helpers/prototype_helper.rb +7 -7
  30. data/lib/action_view/helpers/scriptaculous_helper.rb +5 -5
  31. data/lib/action_view/helpers/text_helper.rb +3 -3
  32. data/lib/action_view/helpers/url_helper.rb +1 -1
  33. data/lib/action_view/paths.rb +1 -1
  34. data/lib/action_view/template.rb +22 -33
  35. data/test/abstract_unit.rb +1 -1
  36. data/test/activerecord/active_record_store_test.rb +3 -3
  37. data/test/controller/action_pack_assertions_test.rb +27 -0
  38. data/test/controller/caching_test.rb +39 -0
  39. data/test/controller/cookie_test.rb +10 -0
  40. data/test/controller/dispatcher_test.rb +9 -7
  41. data/test/controller/failsafe_test.rb +60 -0
  42. data/test/controller/filter_params_test.rb +2 -1
  43. data/test/controller/flash_test.rb +6 -1
  44. data/test/controller/http_digest_authentication_test.rb +34 -3
  45. data/test/controller/integration_test.rb +31 -3
  46. data/test/controller/redirect_test.rb +4 -1
  47. data/test/controller/reloader_test.rb +97 -0
  48. data/test/controller/render_test.rb +19 -9
  49. data/test/controller/request/multipart_params_parsing_test.rb +1 -62
  50. data/test/controller/request/test_request_test.rb +35 -0
  51. data/test/controller/request/url_encoded_params_parsing_test.rb +0 -38
  52. data/test/controller/request_test.rb +218 -230
  53. data/test/controller/resources_test.rb +8 -0
  54. data/test/controller/routing_test.rb +21 -0
  55. data/test/controller/send_file_test.rb +1 -1
  56. data/test/controller/session/cookie_store_test.rb +9 -32
  57. data/test/controller/test_test.rb +8 -0
  58. data/test/fixtures/failsafe/500.html +1 -0
  59. data/test/template/active_record_helper_test.rb +1 -1
  60. data/test/template/asset_tag_helper_test.rb +46 -0
  61. data/test/template/form_helper_test.rb +117 -6
  62. data/test/template/form_options_helper_test.rb +22 -0
  63. data/test/template/form_tag_helper_test.rb +23 -6
  64. data/test/template/prototype_helper_test.rb +11 -11
  65. data/test/template/template_test.rb +32 -0
  66. metadata +20 -63
  67. data/lib/action_controller/rewindable_input.rb +0 -28
  68. data/lib/action_controller/vendor/rack-1.0/rack.rb +0 -89
  69. data/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb +0 -22
  70. data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb +0 -37
  71. data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb +0 -37
  72. data/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb +0 -58
  73. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb +0 -124
  74. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb +0 -51
  75. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb +0 -55
  76. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb +0 -40
  77. data/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb +0 -480
  78. data/lib/action_controller/vendor/rack-1.0/rack/builder.rb +0 -63
  79. data/lib/action_controller/vendor/rack-1.0/rack/cascade.rb +0 -36
  80. data/lib/action_controller/vendor/rack-1.0/rack/chunked.rb +0 -49
  81. data/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb +0 -61
  82. data/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb +0 -45
  83. data/lib/action_controller/vendor/rack-1.0/rack/content_length.rb +0 -29
  84. data/lib/action_controller/vendor/rack-1.0/rack/content_type.rb +0 -23
  85. data/lib/action_controller/vendor/rack-1.0/rack/deflater.rb +0 -85
  86. data/lib/action_controller/vendor/rack-1.0/rack/directory.rb +0 -153
  87. data/lib/action_controller/vendor/rack-1.0/rack/file.rb +0 -88
  88. data/lib/action_controller/vendor/rack-1.0/rack/handler.rb +0 -48
  89. data/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb +0 -61
  90. data/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb +0 -8
  91. data/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb +0 -89
  92. data/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb +0 -55
  93. data/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb +0 -84
  94. data/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb +0 -59
  95. data/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb +0 -8
  96. data/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb +0 -18
  97. data/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb +0 -67
  98. data/lib/action_controller/vendor/rack-1.0/rack/head.rb +0 -19
  99. data/lib/action_controller/vendor/rack-1.0/rack/lint.rb +0 -462
  100. data/lib/action_controller/vendor/rack-1.0/rack/lobster.rb +0 -65
  101. data/lib/action_controller/vendor/rack-1.0/rack/lock.rb +0 -16
  102. data/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb +0 -27
  103. data/lib/action_controller/vendor/rack-1.0/rack/mime.rb +0 -204
  104. data/lib/action_controller/vendor/rack-1.0/rack/mock.rb +0 -160
  105. data/lib/action_controller/vendor/rack-1.0/rack/recursive.rb +0 -57
  106. data/lib/action_controller/vendor/rack-1.0/rack/reloader.rb +0 -64
  107. data/lib/action_controller/vendor/rack-1.0/rack/request.rb +0 -241
  108. data/lib/action_controller/vendor/rack-1.0/rack/response.rb +0 -179
  109. data/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb +0 -142
  110. data/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb +0 -91
  111. data/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb +0 -109
  112. data/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb +0 -100
  113. data/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb +0 -349
  114. data/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb +0 -106
  115. data/lib/action_controller/vendor/rack-1.0/rack/static.rb +0 -38
  116. data/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb +0 -55
  117. data/lib/action_controller/vendor/rack-1.0/rack/utils.rb +0 -392
@@ -43,7 +43,7 @@ module ActionView
43
43
  # You can change the behaviour with various options, see
44
44
  # http://script.aculo.us for more documentation.
45
45
  def visual_effect(name, element_id = false, js_options = {})
46
- element = element_id ? element_id.to_json : "element"
46
+ element = element_id ? ActiveSupport::JSON.encode(element_id) : "element"
47
47
 
48
48
  js_options[:queue] = if js_options[:queue].is_a?(Hash)
49
49
  '{' + js_options[:queue].map {|k, v| k == :limit ? "#{k}:#{v}" : "#{k}:'#{v}'" }.join(',') + '}'
@@ -138,7 +138,7 @@ module ActionView
138
138
  end
139
139
 
140
140
  def sortable_element_js(element_id, options = {}) #:nodoc:
141
- options[:with] ||= "Sortable.serialize(#{element_id.to_json})"
141
+ options[:with] ||= "Sortable.serialize(#{ActiveSupport::JSON.encode(element_id)})"
142
142
  options[:onUpdate] ||= "function(){" + remote_function(options) + "}"
143
143
  options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) }
144
144
 
@@ -149,7 +149,7 @@ module ActionView
149
149
  options[:containment] = array_or_string_for_javascript(options[:containment]) if options[:containment]
150
150
  options[:only] = array_or_string_for_javascript(options[:only]) if options[:only]
151
151
 
152
- %(Sortable.create(#{element_id.to_json}, #{options_for_javascript(options)});)
152
+ %(Sortable.create(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});)
153
153
  end
154
154
 
155
155
  # Makes the element with the DOM ID specified by +element_id+ draggable.
@@ -164,7 +164,7 @@ module ActionView
164
164
  end
165
165
 
166
166
  def draggable_element_js(element_id, options = {}) #:nodoc:
167
- %(new Draggable(#{element_id.to_json}, #{options_for_javascript(options)});)
167
+ %(new Draggable(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});)
168
168
  end
169
169
 
170
170
  # Makes the element with the DOM ID specified by +element_id+ receive
@@ -219,7 +219,7 @@ module ActionView
219
219
  # Confirmation happens during the onDrop callback, so it can be removed from the options
220
220
  options.delete(:confirm) if options[:confirm]
221
221
 
222
- %(Droppables.add(#{element_id.to_json}, #{options_for_javascript(options)});)
222
+ %(Droppables.add(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});)
223
223
  end
224
224
  end
225
225
  end
@@ -271,8 +271,8 @@ module ActionView
271
271
  end
272
272
 
273
273
  # Returns the text with all the Markdown codes turned into HTML tags.
274
- # <i>This method requires BlueCloth[http://www.deveiate.org/projects/BlueCloth]
275
- # to be available</i>.
274
+ # <i>This method requires BlueCloth[http://www.deveiate.org/projects/BlueCloth] or another
275
+ # Markdown library to be installed.</i>.
276
276
  #
277
277
  # ==== Examples
278
278
  # markdown("We are using __Markdown__ now!")
@@ -288,7 +288,7 @@ module ActionView
288
288
  # markdown('![The ROR logo](http://rubyonrails.com/images/rails.png "Ruby on Rails")')
289
289
  # # => '<p><img src="http://rubyonrails.com/images/rails.png" alt="The ROR logo" title="Ruby on Rails" /></p>'
290
290
  def markdown(text)
291
- text.blank? ? "" : BlueCloth.new(text).to_html
291
+ text.blank? ? "" : Markdown.new(text).to_html
292
292
  end
293
293
 
294
294
  # Returns +text+ transformed into HTML using simple formatting rules.
@@ -1,4 +1,4 @@
1
- require 'action_view/helpers/javascript_helper'
1
+ #require 'action_view/helpers/javascript_helper'
2
2
 
3
3
  module ActionView
4
4
  module Helpers #:nodoc:
@@ -61,7 +61,7 @@ module ActionView #:nodoc:
61
61
  end
62
62
  end
63
63
 
64
- return Template.new(original_template_path, original_template_path =~ /\A\// ? "" : ".") if File.file?(original_template_path)
64
+ return Template.new(original_template_path) if File.file?(original_template_path)
65
65
 
66
66
  raise MissingTemplate.new(self, original_template_path, format)
67
67
  end
@@ -107,9 +107,8 @@ module ActionView #:nodoc:
107
107
  attr_accessor :locale, :name, :format, :extension
108
108
  delegate :to_s, :to => :path
109
109
 
110
- def initialize(template_path, load_path)
111
- @template_path = template_path.dup
112
- @load_path, @filename = load_path, File.join(load_path, template_path)
110
+ def initialize(template_path, load_path = nil)
111
+ @template_path, @load_path = template_path.dup, load_path
113
112
  @base_path, @name, @locale, @format, @extension = split(template_path)
114
113
  @base_path.to_s.gsub!(/\/$/, '') # Push to split method
115
114
 
@@ -180,6 +179,12 @@ module ActionView #:nodoc:
180
179
  @@exempt_from_layout.any? { |exempted| path =~ exempted }
181
180
  end
182
181
 
182
+ def filename
183
+ # no load_path means this is an "absolute pathed" template
184
+ load_path ? File.join(load_path, template_path) : template_path
185
+ end
186
+ memoize :filename
187
+
183
188
  def source
184
189
  File.read(filename)
185
190
  end
@@ -212,46 +217,30 @@ module ActionView #:nodoc:
212
217
  end
213
218
 
214
219
  def valid_locale?(locale)
215
- I18n.available_locales.include?(locale.to_sym)
220
+ locale && I18n.available_locales.include?(locale.to_sym)
216
221
  end
217
222
 
218
223
  # Returns file split into an array
219
224
  # [base_path, name, locale, format, extension]
220
225
  def split(file)
221
226
  if m = file.to_s.match(/^(.*\/)?([^\.]+)\.(.*)$/)
222
- base_path = m[1]
223
- name = m[2]
224
- extensions = m[3]
225
- else
226
- return
227
+ [m[1], m[2], *parse_extensions(m[3])]
227
228
  end
229
+ end
228
230
 
229
- locale = nil
230
- format = nil
231
- extension = nil
232
-
233
- if m = extensions.split(".")
234
- if valid_locale?(m[0]) && m[1] && valid_extension?(m[2]) # All three
235
- locale = m[0]
236
- format = m[1]
237
- extension = m[2]
238
- elsif m[0] && m[1] && valid_extension?(m[2]) # Multipart formats
239
- format = "#{m[0]}.#{m[1]}"
240
- extension = m[2]
241
- elsif valid_locale?(m[0]) && valid_extension?(m[1]) # locale and extension
242
- locale = m[0]
243
- extension = m[1]
244
- elsif valid_extension?(m[1]) # format and extension
245
- format = m[0]
246
- extension = m[1]
247
- elsif valid_extension?(m[0]) # Just extension
248
- extension = m[0]
249
- else # No extension
250
- format = m[0]
251
- end
231
+ # returns parsed extensions as an array
232
+ # [locale, format, extension]
233
+ def parse_extensions(extensions)
234
+ exts = extensions.split(".")
235
+
236
+ if extension = valid_extension?(exts.last) && exts.pop || nil
237
+ locale = valid_locale?(exts.first) && exts.shift || nil
238
+ format = exts.join('.') if exts.any? # join('.') is needed for multipart templates
239
+ else # no extension, just format
240
+ format = exts.last
252
241
  end
253
242
 
254
- [base_path, name, locale, format, extension]
243
+ [locale, format, extension]
255
244
  end
256
245
  end
257
246
  end
@@ -8,7 +8,7 @@ require 'yaml'
8
8
  require 'stringio'
9
9
  require 'test/unit'
10
10
 
11
- gem 'mocha', '>= 0.9.5'
11
+ gem 'mocha', '>= 0.9.7'
12
12
  require 'mocha'
13
13
 
14
14
  begin
@@ -27,9 +27,9 @@ class ActiveRecordStoreTest < ActionController::IntegrationTest
27
27
  end
28
28
 
29
29
  def call_reset_session
30
- session[:bar]
30
+ session[:foo]
31
31
  reset_session
32
- session[:bar] = "baz"
32
+ session[:foo] = "baz"
33
33
  head :ok
34
34
  end
35
35
 
@@ -86,7 +86,7 @@ class ActiveRecordStoreTest < ActionController::IntegrationTest
86
86
 
87
87
  get '/get_session_value'
88
88
  assert_response :success
89
- assert_equal 'foo: nil', response.body
89
+ assert_equal 'foo: "baz"', response.body
90
90
 
91
91
  get '/get_session_id'
92
92
  assert_response :success
@@ -11,6 +11,9 @@ class ActionPackAssertionsController < ActionController::Base
11
11
 
12
12
  # a standard template
13
13
  def hello_xml_world() render :template => "test/hello_xml_world"; end
14
+
15
+ # a standard partial
16
+ def partial() render :partial => 'test/partial'; end
14
17
 
15
18
  # a redirect to an internal location
16
19
  def redirect_internal() redirect_to "/nothing"; end
@@ -332,6 +335,30 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
332
335
  assert @response.rendered[:template]
333
336
  assert 'hello_world', @response.rendered[:template].to_s
334
337
  end
338
+
339
+ def test_assert_template_with_partial
340
+ get :partial
341
+ assert_template :partial => '_partial'
342
+ end
343
+
344
+ def test_assert_template_with_nil
345
+ get :nothing
346
+ assert_template nil
347
+ end
348
+
349
+ def test_assert_template_with_string
350
+ get :hello_world
351
+ assert_template 'hello_world'
352
+ end
353
+
354
+ def test_assert_template_with_symbol
355
+ get :hello_world
356
+ assert_template :hello_world
357
+ end
358
+
359
+ def test_assert_template_with_bad_argument
360
+ assert_raise(ArgumentError) { assert_template 1 }
361
+ end
335
362
 
336
363
  # check the redirection location
337
364
  def test_redirection_location
@@ -1,5 +1,6 @@
1
1
  require 'fileutils'
2
2
  require 'abstract_unit'
3
+ require 'active_record_unit'
3
4
 
4
5
  CACHE_DIR = 'test_cache'
5
6
  # Don't change '/../temp/' cavalierly or you might hose something you don't want hosed
@@ -7,6 +8,10 @@ FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR)
7
8
  ActionController::Base.page_cache_directory = FILE_STORE_PATH
8
9
  ActionController::Base.cache_store = :file_store, FILE_STORE_PATH
9
10
 
11
+ # Force sweeper classes to load
12
+ ActionController::Caching::Sweeper
13
+ ActionController::Caching::Sweeping
14
+
10
15
  class PageCachingTestController < ActionController::Base
11
16
  caches_page :ok, :no_content, :if => Proc.new { |c| !c.request.format.json? }
12
17
  caches_page :found, :not_found
@@ -152,6 +157,7 @@ class ActionCachingTestController < ActionController::Base
152
157
  caches_action :edit, :cache_path => Proc.new { |c| c.params[:id] ? "http://test.host/#{c.params[:id]};edit" : "http://test.host/edit" }
153
158
  caches_action :with_layout
154
159
  caches_action :layout_false, :layout => false
160
+ caches_action :record_not_found, :four_oh_four, :simple_runtime_error
155
161
 
156
162
  layout 'talk_from_action.erb'
157
163
 
@@ -174,6 +180,18 @@ class ActionCachingTestController < ActionController::Base
174
180
  render :text => @cache_this, :layout => true
175
181
  end
176
182
 
183
+ def record_not_found
184
+ raise ActiveRecord::RecordNotFound, "oops!"
185
+ end
186
+
187
+ def four_oh_four
188
+ render :text => "404'd!", :status => 404
189
+ end
190
+
191
+ def simple_runtime_error
192
+ raise "oops!"
193
+ end
194
+
177
195
  alias_method :show, :index
178
196
  alias_method :edit, :index
179
197
  alias_method :destroy, :index
@@ -456,6 +474,27 @@ class ActionCacheTest < ActionController::TestCase
456
474
  assert_response :success
457
475
  end
458
476
 
477
+ def test_record_not_found_returns_404_for_multiple_requests
478
+ get :record_not_found
479
+ assert_response 404
480
+ get :record_not_found
481
+ assert_response 404
482
+ end
483
+
484
+ def test_four_oh_four_returns_404_for_multiple_requests
485
+ get :four_oh_four
486
+ assert_response 404
487
+ get :four_oh_four
488
+ assert_response 404
489
+ end
490
+
491
+ def test_simple_runtime_error_returns_500_for_multiple_requests
492
+ get :simple_runtime_error
493
+ assert_response 500
494
+ get :simple_runtime_error
495
+ assert_response 500
496
+ end
497
+
459
498
  private
460
499
  def content_to_cache
461
500
  assigns(:cache_this)
@@ -6,6 +6,10 @@ class CookieTest < ActionController::TestCase
6
6
  cookies["user_name"] = "david"
7
7
  end
8
8
 
9
+ def set_with_with_escapable_characters
10
+ cookies["that & guy"] = "foo & bar => baz"
11
+ end
12
+
9
13
  def authenticate_for_fourteen_days
10
14
  cookies["user_name"] = { "value" => "david", "expires" => Time.utc(2005, 10, 10,5) }
11
15
  end
@@ -53,6 +57,12 @@ class CookieTest < ActionController::TestCase
53
57
  assert_equal({"user_name" => "david"}, @response.cookies)
54
58
  end
55
59
 
60
+ def test_setting_with_escapable_characters
61
+ get :set_with_with_escapable_characters
62
+ assert_equal ["that+%26+guy=foo+%26+bar+%3D%3E+baz; path=/"], @response.headers["Set-Cookie"]
63
+ assert_equal({"that & guy" => "foo & bar => baz"}, @response.cookies)
64
+ end
65
+
56
66
  def test_setting_cookie_for_fourteen_days
57
67
  get :authenticate_for_fourteen_days
58
68
  assert_equal ["user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT"], @response.headers["Set-Cookie"]
@@ -25,7 +25,8 @@ class DispatcherTest < Test::Unit::TestCase
25
25
 
26
26
  def test_clears_dependencies_after_dispatch_if_in_loading_mode
27
27
  ActiveSupport::Dependencies.expects(:clear).once
28
- dispatch(false)
28
+ # Close the response so dependencies kicks in
29
+ dispatch(false).last.close
29
30
  end
30
31
 
31
32
  def test_reloads_routes_before_dispatch_if_in_loading_mode
@@ -49,13 +50,14 @@ class DispatcherTest < Test::Unit::TestCase
49
50
  Dispatcher.any_instance.expects(:dispatch).raises('b00m')
50
51
  ActionController::Failsafe.any_instance.expects(:log_failsafe_exception)
51
52
 
53
+ response = nil
52
54
  assert_nothing_raised do
53
- assert_equal [
54
- 500,
55
- {"Content-Type" => "text/html"},
56
- "<html><body><h1>500 Internal Server Error</h1></body></html>"
57
- ], dispatch
55
+ response = dispatch
58
56
  end
57
+ assert_equal 3, response.size
58
+ assert_equal 500, response[0]
59
+ assert_equal({"Content-Type" => "text/html"}, response[1])
60
+ assert_match /500 Internal Server Error/, response[2].join
59
61
  end
60
62
 
61
63
  def test_prepare_callbacks
@@ -94,7 +96,7 @@ class DispatcherTest < Test::Unit::TestCase
94
96
  def dispatch(cache_classes = true)
95
97
  ActionController::Routing::RouteSet.any_instance.stubs(:call).returns([200, {}, 'response'])
96
98
  Dispatcher.define_dispatcher_callbacks(cache_classes)
97
- Dispatcher.new.call({})
99
+ Dispatcher.new.call({'rack.input' => StringIO.new('')})
98
100
  end
99
101
 
100
102
  def assert_subclasses(howmany, klass, message = klass.subclasses.inspect)
@@ -0,0 +1,60 @@
1
+ require 'abstract_unit'
2
+ require 'stringio'
3
+ require 'logger'
4
+
5
+ class FailsafeTest < ActionController::TestCase
6
+ FIXTURE_PUBLIC = "#{File.dirname(__FILE__)}/../fixtures/failsafe".freeze
7
+
8
+ def setup
9
+ @old_error_file_path = ActionController::Failsafe.error_file_path
10
+ ActionController::Failsafe.error_file_path = FIXTURE_PUBLIC
11
+ @app = mock
12
+ @log_io = StringIO.new
13
+ @logger = Logger.new(@log_io)
14
+ @failsafe = ActionController::Failsafe.new(@app)
15
+ @failsafe.stubs(:failsafe_logger).returns(@logger)
16
+ end
17
+
18
+ def teardown
19
+ ActionController::Failsafe.error_file_path = @old_error_file_path
20
+ end
21
+
22
+ def app_will_raise_error!
23
+ @app.expects(:call).then.raises(RuntimeError.new("Printer on fire"))
24
+ end
25
+
26
+ def test_calls_app_and_returns_its_return_value
27
+ @app.expects(:call).returns([200, { "Content-Type" => "text/html" }, "ok"])
28
+ assert_equal [200, { "Content-Type" => "text/html" }, "ok"], @failsafe.call({})
29
+ end
30
+
31
+ def test_writes_to_log_file_on_exception
32
+ app_will_raise_error!
33
+ @failsafe.call({})
34
+ assert_match /Printer on fire/, @log_io.string # Logs exception message.
35
+ assert_match /failsafe_test\.rb/, @log_io.string # Logs backtrace.
36
+ end
37
+
38
+ def test_returns_500_internal_server_error_on_exception
39
+ app_will_raise_error!
40
+ response = @failsafe.call({})
41
+ assert_equal 3, response.size # It is a valid Rack response.
42
+ assert_equal 500, response[0] # Status is 500.
43
+ end
44
+
45
+ def test_renders_error_page_file_with_erb
46
+ app_will_raise_error!
47
+ response = @failsafe.call({})
48
+ assert_equal 500, response[0]
49
+ assert_equal "hello my world", response[2].join
50
+ end
51
+
52
+ def test_returns_a_default_message_if_erb_rendering_failed
53
+ app_will_raise_error!
54
+ @failsafe.expects(:render_template).raises(RuntimeError.new("Harddisk is crashing"))
55
+ response = @failsafe.call({})
56
+ assert_equal 500, response[0]
57
+ assert_match /500 Internal Server Error/, response[2].join
58
+ assert_match %r(please read this web application's log file), response[2].join
59
+ end
60
+ end
@@ -23,7 +23,8 @@ class FilterParamTest < Test::Unit::TestCase
23
23
  [{'foo'=>'bar', 'bar'=>'foo'},{'foo'=>'[FILTERED]', 'bar'=>'foo'},%w'foo baz'],
24
24
  [{'foo'=>'bar', 'baz'=>'foo'},{'foo'=>'[FILTERED]', 'baz'=>'[FILTERED]'},%w'foo baz'],
25
25
  [{'bar'=>{'foo'=>'bar','bar'=>'foo'}},{'bar'=>{'foo'=>'[FILTERED]','bar'=>'foo'}},%w'fo'],
26
- [{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana']]
26
+ [{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana'],
27
+ [{'baz'=>[{'foo'=>'baz'}]}, {'baz'=>[{'foo'=>'[FILTERED]'}]}, %w(foo)]]
27
28
 
28
29
  test_hashes.each do |before_filter, after_filter, filter_words|
29
30
  FilterParamController.filter_parameter_logging(*filter_words)
@@ -121,7 +121,7 @@ class FlashTest < ActionController::TestCase
121
121
  assert_nil @response.template.assigns["flash_copy"]["that"], "On second flash"
122
122
  assert_equal "hello again", @response.template.assigns["flash_copy"]["this"], "On second flash"
123
123
  end
124
-
124
+
125
125
  def test_flash_after_reset_session
126
126
  get :use_flash_after_reset_session
127
127
  assert_equal "hello", @response.template.assigns["flashy_that"]
@@ -139,4 +139,9 @@ class FlashTest < ActionController::TestCase
139
139
  get :std_action
140
140
  assert_nil @response.template.assigns["flash_copy"]["foo"]
141
141
  end
142
+
143
+ def test_does_not_set_the_session_if_the_flash_is_empty
144
+ get :std_action
145
+ assert_nil session["flash"]
146
+ end
142
147
  end