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.

Files changed (317) hide show
  1. data/CHANGELOG +1400 -20
  2. data/MIT-LICENSE +1 -1
  3. data/README +5 -5
  4. data/RUNNING_UNIT_TESTS +4 -5
  5. data/Rakefile +5 -6
  6. data/install.rb +2 -2
  7. data/lib/action_controller.rb +11 -15
  8. data/lib/action_controller/assertions.rb +12 -25
  9. data/lib/action_controller/assertions/dom_assertions.rb +18 -4
  10. data/lib/action_controller/assertions/model_assertions.rb +8 -1
  11. data/lib/action_controller/assertions/response_assertions.rb +35 -12
  12. data/lib/action_controller/assertions/routing_assertions.rb +56 -12
  13. data/lib/action_controller/assertions/selector_assertions.rb +105 -38
  14. data/lib/action_controller/assertions/tag_assertions.rb +28 -15
  15. data/lib/action_controller/base.rb +318 -250
  16. data/lib/action_controller/benchmarking.rb +33 -29
  17. data/lib/action_controller/caching.rb +130 -64
  18. data/lib/action_controller/cgi_ext.rb +16 -0
  19. data/lib/action_controller/cgi_ext/{cookie_performance_fix.rb → cookie.rb} +25 -40
  20. data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
  21. data/lib/action_controller/cgi_ext/session.rb +73 -0
  22. data/lib/action_controller/cgi_ext/stdinput.rb +23 -0
  23. data/lib/action_controller/cgi_process.rb +34 -57
  24. data/lib/action_controller/components.rb +19 -36
  25. data/lib/action_controller/cookies.rb +10 -9
  26. data/lib/action_controller/dispatcher.rb +195 -0
  27. data/lib/action_controller/filters.rb +35 -34
  28. data/lib/action_controller/flash.rb +30 -35
  29. data/lib/action_controller/helpers.rb +121 -47
  30. data/lib/action_controller/http_authentication.rb +126 -0
  31. data/lib/action_controller/integration.rb +105 -101
  32. data/lib/action_controller/layout.rb +59 -47
  33. data/lib/action_controller/mime_responds.rb +57 -68
  34. data/lib/action_controller/mime_type.rb +43 -80
  35. data/lib/action_controller/mime_types.rb +20 -0
  36. data/lib/action_controller/polymorphic_routes.rb +88 -0
  37. data/lib/action_controller/record_identifier.rb +91 -0
  38. data/lib/action_controller/request.rb +553 -88
  39. data/lib/action_controller/request_forgery_protection.rb +126 -0
  40. data/lib/action_controller/request_profiler.rb +138 -0
  41. data/lib/action_controller/rescue.rb +185 -69
  42. data/lib/action_controller/resources.rb +211 -172
  43. data/lib/action_controller/response.rb +49 -8
  44. data/lib/action_controller/routing.rb +359 -236
  45. data/lib/action_controller/routing_optimisation.rb +119 -0
  46. data/lib/action_controller/session/active_record_store.rb +3 -2
  47. data/lib/action_controller/session/cookie_store.rb +161 -0
  48. data/lib/action_controller/session/mem_cache_store.rb +9 -16
  49. data/lib/action_controller/session_management.rb +17 -8
  50. data/lib/action_controller/streaming.rb +6 -3
  51. data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
  52. data/lib/action_controller/templates/rescues/{_trace.rhtml → _trace.erb} +0 -0
  53. data/lib/action_controller/templates/rescues/{diagnostics.rhtml → diagnostics.erb} +2 -2
  54. data/lib/action_controller/templates/rescues/{layout.rhtml → layout.erb} +0 -0
  55. data/lib/action_controller/templates/rescues/{missing_template.rhtml → missing_template.erb} +0 -0
  56. data/lib/action_controller/templates/rescues/{routing_error.rhtml → routing_error.erb} +0 -0
  57. data/lib/action_controller/templates/rescues/{template_error.rhtml → template_error.erb} +2 -2
  58. data/lib/action_controller/templates/rescues/{unknown_action.rhtml → unknown_action.erb} +0 -0
  59. data/lib/action_controller/test_case.rb +53 -0
  60. data/lib/action_controller/test_process.rb +59 -46
  61. data/lib/action_controller/url_rewriter.rb +48 -24
  62. data/lib/action_controller/vendor/html-scanner/html/document.rb +7 -4
  63. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
  64. data/lib/action_controller/vendor/html-scanner/html/selector.rb +11 -6
  65. data/lib/action_controller/verification.rb +27 -21
  66. data/lib/action_pack.rb +1 -1
  67. data/lib/action_pack/version.rb +4 -4
  68. data/lib/action_view.rb +2 -3
  69. data/lib/action_view/base.rb +218 -63
  70. data/lib/action_view/compiled_templates.rb +1 -2
  71. data/lib/action_view/helpers/active_record_helper.rb +35 -17
  72. data/lib/action_view/helpers/asset_tag_helper.rb +395 -87
  73. data/lib/action_view/helpers/atom_feed_helper.rb +111 -0
  74. data/lib/action_view/helpers/benchmark_helper.rb +12 -5
  75. data/lib/action_view/helpers/cache_helper.rb +29 -0
  76. data/lib/action_view/helpers/capture_helper.rb +97 -63
  77. data/lib/action_view/helpers/date_helper.rb +295 -35
  78. data/lib/action_view/helpers/debug_helper.rb +6 -2
  79. data/lib/action_view/helpers/form_helper.rb +354 -111
  80. data/lib/action_view/helpers/form_options_helper.rb +171 -109
  81. data/lib/action_view/helpers/form_tag_helper.rb +332 -76
  82. data/lib/action_view/helpers/javascript_helper.rb +35 -11
  83. data/lib/action_view/helpers/javascripts/controls.js +484 -354
  84. data/lib/action_view/helpers/javascripts/dragdrop.js +88 -58
  85. data/lib/action_view/helpers/javascripts/effects.js +396 -364
  86. data/lib/action_view/helpers/javascripts/prototype.js +2817 -1107
  87. data/lib/action_view/helpers/number_helper.rb +84 -60
  88. data/lib/action_view/helpers/prototype_helper.rb +419 -43
  89. data/lib/action_view/helpers/record_identification_helper.rb +20 -0
  90. data/lib/action_view/helpers/record_tag_helper.rb +59 -0
  91. data/lib/action_view/helpers/sanitize_helper.rb +223 -0
  92. data/lib/action_view/helpers/scriptaculous_helper.rb +63 -4
  93. data/lib/action_view/helpers/tag_helper.rb +69 -39
  94. data/lib/action_view/helpers/text_helper.rb +221 -148
  95. data/lib/action_view/helpers/url_helper.rb +283 -165
  96. data/lib/action_view/partials.rb +134 -62
  97. data/lib/action_view/template_error.rb +4 -12
  98. data/lib/actionpack.rb +1 -0
  99. data/test/abstract_unit.rb +21 -1
  100. data/test/action_view_test.rb +26 -0
  101. data/test/active_record_unit.rb +12 -20
  102. data/test/activerecord/active_record_store_test.rb +2 -2
  103. data/test/activerecord/render_partial_with_record_identification_test.rb +74 -0
  104. data/test/controller/action_pack_assertions_test.rb +21 -152
  105. data/test/controller/addresses_render_test.rb +2 -7
  106. data/test/controller/assert_select_test.rb +120 -14
  107. data/test/controller/base_test.rb +11 -13
  108. data/test/controller/caching_test.rb +125 -5
  109. data/test/controller/capture_test.rb +23 -16
  110. data/test/controller/cgi_test.rb +66 -391
  111. data/test/controller/components_test.rb +31 -42
  112. data/test/controller/content_type_test.rb +1 -1
  113. data/test/controller/cookie_test.rb +42 -14
  114. data/test/controller/deprecation/deprecated_base_methods_test.rb +1 -42
  115. data/test/controller/dispatcher_test.rb +123 -0
  116. data/test/controller/fake_models.rb +5 -0
  117. data/test/controller/filters_test.rb +44 -7
  118. data/test/controller/flash_test.rb +46 -2
  119. data/test/controller/fragment_store_setting_test.rb +10 -8
  120. data/test/controller/helper_test.rb +19 -2
  121. data/test/controller/html-scanner/document_test.rb +124 -0
  122. data/test/controller/html-scanner/node_test.rb +69 -0
  123. data/test/controller/html-scanner/sanitizer_test.rb +250 -0
  124. data/test/controller/html-scanner/tag_node_test.rb +239 -0
  125. data/test/controller/html-scanner/text_node_test.rb +51 -0
  126. data/test/controller/html-scanner/tokenizer_test.rb +125 -0
  127. data/test/controller/http_authentication_test.rb +54 -0
  128. data/test/controller/integration_test.rb +12 -26
  129. data/test/controller/layout_test.rb +64 -12
  130. data/test/controller/mime_responds_test.rb +193 -38
  131. data/test/controller/mime_type_test.rb +30 -8
  132. data/test/controller/new_render_test.rb +104 -22
  133. data/test/controller/polymorphic_routes_test.rb +98 -0
  134. data/test/controller/record_identifier_test.rb +103 -0
  135. data/test/controller/redirect_test.rb +120 -18
  136. data/test/controller/render_test.rb +195 -45
  137. data/test/controller/request_forgery_protection_test.rb +217 -0
  138. data/test/controller/request_test.rb +545 -27
  139. data/test/controller/rescue_test.rb +501 -0
  140. data/test/controller/resources_test.rb +258 -132
  141. data/test/controller/routing_test.rb +502 -106
  142. data/test/controller/selector_test.rb +5 -5
  143. data/test/controller/send_file_test.rb +17 -7
  144. data/test/controller/session/cookie_store_test.rb +246 -0
  145. data/test/controller/session/mem_cache_store_test.rb +182 -0
  146. data/test/controller/session_fixation_test.rb +8 -11
  147. data/test/controller/session_management_test.rb +7 -7
  148. data/test/controller/test_test.rb +150 -38
  149. data/test/controller/url_rewriter_test.rb +87 -12
  150. data/test/controller/verification_test.rb +11 -0
  151. data/test/controller/view_paths_test.rb +137 -0
  152. data/test/controller/webservice_test.rb +11 -75
  153. data/test/fixtures/addresses/{list.rhtml → list.erb} +0 -0
  154. data/test/fixtures/db_definitions/sqlite.sql +2 -1
  155. data/test/fixtures/developer.rb +2 -0
  156. data/test/fixtures/fun/games/{hello_world.rhtml → hello_world.erb} +0 -0
  157. data/test/fixtures/helpers/fun/pdf_helper.rb +1 -1
  158. data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
  159. data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
  160. data/test/fixtures/layouts/{builder.rxml → builder.builder} +0 -0
  161. data/test/fixtures/layouts/{standard.rhtml → standard.erb} +0 -0
  162. data/test/fixtures/layouts/{talk_from_action.rhtml → talk_from_action.erb} +0 -0
  163. data/test/fixtures/layouts/{yield.rhtml → yield.erb} +0 -0
  164. data/test/fixtures/multipart/binary_file +0 -0
  165. data/test/fixtures/multipart/bracketed_param +5 -0
  166. data/test/fixtures/override/test/hello_world.erb +1 -0
  167. data/test/fixtures/override2/layouts/test/sub.erb +1 -0
  168. data/test/fixtures/post_test/layouts/post.html.erb +1 -0
  169. data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
  170. data/test/fixtures/post_test/post/index.html.erb +1 -0
  171. data/test/fixtures/post_test/post/index.iphone.erb +1 -0
  172. data/test/fixtures/post_test/super_post/index.html.erb +1 -0
  173. data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
  174. data/test/fixtures/public/404.html +1 -0
  175. data/test/fixtures/public/500.html +1 -0
  176. data/test/fixtures/public/javascripts/application.js +0 -1
  177. data/test/fixtures/public/javascripts/bank.js +1 -0
  178. data/test/fixtures/public/javascripts/robber.js +1 -0
  179. data/test/fixtures/public/stylesheets/bank.css +1 -0
  180. data/test/fixtures/public/stylesheets/robber.css +1 -0
  181. data/test/fixtures/replies.yml +2 -0
  182. data/test/fixtures/reply.rb +2 -1
  183. data/test/fixtures/respond_to/{all_types_with_layout.rhtml → all_types_with_layout.html.erb} +0 -0
  184. data/test/fixtures/respond_to/{all_types_with_layout.rjs → all_types_with_layout.js.rjs} +0 -0
  185. data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
  186. data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
  187. data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
  188. data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
  189. data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
  190. data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
  191. data/test/fixtures/respond_to/{using_defaults.rhtml → using_defaults.html.erb} +0 -0
  192. data/test/fixtures/respond_to/{using_defaults.rjs → using_defaults.js.rjs} +0 -0
  193. data/test/fixtures/respond_to/{using_defaults.rxml → using_defaults.xml.builder} +0 -0
  194. data/test/fixtures/respond_to/{using_defaults_with_type_list.rhtml → using_defaults_with_type_list.html.erb} +0 -0
  195. data/test/fixtures/respond_to/{using_defaults_with_type_list.rjs → using_defaults_with_type_list.js.rjs} +0 -0
  196. data/test/fixtures/respond_to/{using_defaults_with_type_list.rxml → using_defaults_with_type_list.xml.builder} +0 -0
  197. data/test/fixtures/scope/test/{modgreet.rhtml → modgreet.erb} +0 -0
  198. data/test/fixtures/test/{_customer.rhtml → _customer.erb} +0 -0
  199. data/test/fixtures/test/{_customer_greeting.rhtml → _customer_greeting.erb} +0 -0
  200. data/test/fixtures/test/_hash_greeting.erb +1 -0
  201. data/test/fixtures/test/_hash_object.erb +2 -0
  202. data/test/fixtures/test/{_hello.rxml → _hello.builder} +0 -0
  203. data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
  204. data/test/fixtures/test/_partial.erb +1 -0
  205. data/test/fixtures/test/_partial.html.erb +1 -0
  206. data/test/fixtures/test/_partial.js.erb +1 -0
  207. data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
  208. data/test/fixtures/test/{_partial_only.rhtml → _partial_only.erb} +0 -0
  209. data/test/fixtures/test/{_person.rhtml → _person.erb} +0 -0
  210. data/test/fixtures/test/{action_talk_to_layout.rhtml → action_talk_to_layout.erb} +0 -0
  211. data/test/fixtures/test/{block_content_for.rhtml → block_content_for.erb} +0 -0
  212. data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
  213. data/test/fixtures/test/{capturing.rhtml → capturing.erb} +0 -0
  214. data/test/fixtures/test/{content_for.rhtml → content_for.erb} +0 -0
  215. data/test/fixtures/test/content_for_concatenated.erb +3 -0
  216. data/test/fixtures/test/content_for_with_parameter.erb +2 -0
  217. data/test/fixtures/test/dot.directory/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
  218. data/test/fixtures/test/{erb_content_for.rhtml → erb_content_for.erb} +0 -0
  219. data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
  220. data/test/fixtures/test/formatted_xml_erb.builder +1 -0
  221. data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
  222. data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
  223. data/test/fixtures/test/{greeting.rhtml → greeting.erb} +0 -0
  224. data/test/fixtures/test/{hello.rxml → hello.builder} +0 -0
  225. data/test/fixtures/test/{hello_world.rxml → hello_world.builder} +0 -0
  226. data/test/fixtures/test/{hello_world.rhtml → hello_world.erb} +0 -0
  227. data/test/fixtures/test/{hello_world_container.rxml → hello_world_container.builder} +0 -0
  228. data/test/fixtures/test/{hello_world_with_layout_false.rhtml → hello_world_with_layout_false.erb} +0 -0
  229. data/test/fixtures/test/{hello_xml_world.rxml → hello_xml_world.builder} +0 -0
  230. data/test/fixtures/test/list.erb +1 -0
  231. data/test/fixtures/test/{non_erb_block_content_for.rxml → non_erb_block_content_for.builder} +0 -0
  232. data/test/fixtures/test/{potential_conflicts.rhtml → potential_conflicts.erb} +0 -0
  233. data/test/fixtures/test/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
  234. data/test/fixtures/test/{render_file_with_locals.rhtml → render_file_with_locals.erb} +0 -0
  235. data/test/fixtures/test/{render_to_string_test.rhtml → render_to_string_test.erb} +0 -0
  236. data/test/fixtures/test/{update_element_with_capture.rhtml → update_element_with_capture.erb} +0 -0
  237. data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
  238. data/test/fixtures/topic.rb +1 -1
  239. data/test/template/active_record_helper_test.rb +67 -20
  240. data/test/template/asset_tag_helper_test.rb +222 -54
  241. data/test/template/atom_feed_helper_test.rb +101 -0
  242. data/test/template/benchmark_helper_test.rb +2 -2
  243. data/test/template/compiled_templates_test.rb +76 -32
  244. data/test/template/date_helper_test.rb +125 -9
  245. data/test/template/form_helper_test.rb +326 -33
  246. data/test/template/form_options_helper_test.rb +822 -15
  247. data/test/template/form_tag_helper_test.rb +96 -30
  248. data/test/template/javascript_helper_test.rb +61 -13
  249. data/test/template/number_helper_test.rb +12 -11
  250. data/test/template/prototype_helper_test.rb +185 -24
  251. data/test/template/sanitize_helper_test.rb +49 -0
  252. data/test/template/scriptaculous_helper_test.rb +9 -3
  253. data/test/template/tag_helper_test.rb +13 -2
  254. data/test/template/text_helper_test.rb +38 -52
  255. data/test/template/url_helper_test.rb +216 -46
  256. metadata +144 -116
  257. data/examples/.htaccess +0 -24
  258. data/examples/address_book/index.rhtml +0 -33
  259. data/examples/address_book/layout.rhtml +0 -8
  260. data/examples/address_book_controller.cgi +0 -9
  261. data/examples/address_book_controller.fcgi +0 -6
  262. data/examples/address_book_controller.rb +0 -52
  263. data/examples/address_book_controller.rbx +0 -4
  264. data/examples/benchmark.rb +0 -52
  265. data/examples/benchmark_with_ar.fcgi +0 -89
  266. data/examples/blog_controller.cgi +0 -53
  267. data/examples/debate/index.rhtml +0 -14
  268. data/examples/debate/new_topic.rhtml +0 -22
  269. data/examples/debate/topic.rhtml +0 -32
  270. data/examples/debate_controller.cgi +0 -57
  271. data/lib/action_controller/assertions/deprecated_assertions.rb +0 -228
  272. data/lib/action_controller/cgi_ext/cgi_ext.rb +0 -36
  273. data/lib/action_controller/cgi_ext/cgi_methods.rb +0 -211
  274. data/lib/action_controller/cgi_ext/pstore_performance_fix.rb +0 -30
  275. data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +0 -95
  276. data/lib/action_controller/cgi_ext/session_performance_fix.rb +0 -30
  277. data/lib/action_controller/deprecated_dependencies.rb +0 -65
  278. data/lib/action_controller/deprecated_redirects.rb +0 -17
  279. data/lib/action_controller/deprecated_request_methods.rb +0 -34
  280. data/lib/action_controller/macros/auto_complete.rb +0 -53
  281. data/lib/action_controller/macros/in_place_editing.rb +0 -33
  282. data/lib/action_controller/pagination.rb +0 -408
  283. data/lib/action_controller/scaffolding.rb +0 -189
  284. data/lib/action_controller/templates/rescues/_request_and_response.rhtml +0 -44
  285. data/lib/action_controller/templates/scaffolds/edit.rhtml +0 -7
  286. data/lib/action_controller/templates/scaffolds/layout.rhtml +0 -69
  287. data/lib/action_controller/templates/scaffolds/list.rhtml +0 -27
  288. data/lib/action_controller/templates/scaffolds/new.rhtml +0 -6
  289. data/lib/action_controller/templates/scaffolds/show.rhtml +0 -9
  290. data/lib/action_controller/vendor/xml_node.rb +0 -97
  291. data/lib/action_view/helpers/deprecated_helper.rb +0 -37
  292. data/lib/action_view/helpers/java_script_macros_helper.rb +0 -233
  293. data/lib/action_view/helpers/pagination_helper.rb +0 -86
  294. data/test/activerecord/active_record_assertions_test.rb +0 -92
  295. data/test/activerecord/pagination_test.rb +0 -165
  296. data/test/controller/deprecated_instance_variables_test.rb +0 -48
  297. data/test/controller/raw_post_test.rb +0 -68
  298. data/test/fixtures/deprecated_instance_variables/_cookies_ivar.rhtml +0 -1
  299. data/test/fixtures/deprecated_instance_variables/_cookies_method.rhtml +0 -1
  300. data/test/fixtures/deprecated_instance_variables/_flash_ivar.rhtml +0 -1
  301. data/test/fixtures/deprecated_instance_variables/_flash_method.rhtml +0 -1
  302. data/test/fixtures/deprecated_instance_variables/_headers_ivar.rhtml +0 -1
  303. data/test/fixtures/deprecated_instance_variables/_headers_method.rhtml +0 -1
  304. data/test/fixtures/deprecated_instance_variables/_params_ivar.rhtml +0 -1
  305. data/test/fixtures/deprecated_instance_variables/_params_method.rhtml +0 -1
  306. data/test/fixtures/deprecated_instance_variables/_request_ivar.rhtml +0 -1
  307. data/test/fixtures/deprecated_instance_variables/_request_method.rhtml +0 -1
  308. data/test/fixtures/deprecated_instance_variables/_response_ivar.rhtml +0 -1
  309. data/test/fixtures/deprecated_instance_variables/_response_method.rhtml +0 -1
  310. data/test/fixtures/deprecated_instance_variables/_session_ivar.rhtml +0 -1
  311. data/test/fixtures/deprecated_instance_variables/_session_method.rhtml +0 -1
  312. data/test/fixtures/respond_to/layouts/standard.rhtml +0 -1
  313. data/test/fixtures/test/_hash_object.rhtml +0 -1
  314. data/test/fixtures/test/list.rhtml +0 -1
  315. data/test/template/deprecated_helper_test.rb +0 -36
  316. data/test/template/deprecated_instance_variables_test.rb +0 -43
  317. data/test/template/java_script_macros_helper_test.rb +0 -109
@@ -0,0 +1,501 @@
1
+ require File.dirname(__FILE__) + '/../abstract_unit'
2
+
3
+ uses_mocha 'rescue' do
4
+
5
+ class RescueController < ActionController::Base
6
+ class NotAuthorized < StandardError
7
+ end
8
+ class NotAuthorizedToRescueAsString < StandardError
9
+ end
10
+
11
+ class RecordInvalid < StandardError
12
+ end
13
+ class RecordInvalidToRescueAsString < StandardError
14
+ end
15
+
16
+ class NotAllowed < StandardError
17
+ end
18
+ class NotAllowedToRescueAsString < StandardError
19
+ end
20
+
21
+ class InvalidRequest < StandardError
22
+ end
23
+ class InvalidRequestToRescueAsString < StandardError
24
+ end
25
+
26
+ class BadGateway < StandardError
27
+ end
28
+ class BadGatewayToRescueAsString < StandardError
29
+ end
30
+
31
+ class ResourceUnavailable < StandardError
32
+ end
33
+ class ResourceUnavailableToRescueAsString < StandardError
34
+ end
35
+
36
+ # We use a fully-qualified name in some strings, and a relative constant
37
+ # name in some other to test correct handling of both cases.
38
+
39
+ rescue_from NotAuthorized, :with => :deny_access
40
+ rescue_from 'RescueController::NotAuthorizedToRescueAsString', :with => :deny_access
41
+
42
+ rescue_from RecordInvalid, :with => :show_errors
43
+ rescue_from 'RescueController::RecordInvalidToRescueAsString', :with => :show_errors
44
+
45
+ rescue_from NotAllowed, :with => proc { head :forbidden }
46
+ rescue_from 'RescueController::NotAllowedToRescueAsString', :with => proc { head :forbidden }
47
+
48
+ rescue_from InvalidRequest, :with => proc { |exception| render :text => exception.message }
49
+ rescue_from 'InvalidRequestToRescueAsString', :with => proc { |exception| render :text => exception.message }
50
+
51
+ rescue_from BadGateway do
52
+ head :status => 502
53
+ end
54
+ rescue_from 'BadGatewayToRescueAsString' do
55
+ head :status => 502
56
+ end
57
+
58
+ rescue_from ResourceUnavailable do |exception|
59
+ render :text => exception.message
60
+ end
61
+ rescue_from 'ResourceUnavailableToRescueAsString' do |exception|
62
+ render :text => exception.message
63
+ end
64
+
65
+ def raises
66
+ render :text => 'already rendered'
67
+ raise "don't panic!"
68
+ end
69
+
70
+ def method_not_allowed
71
+ raise ActionController::MethodNotAllowed.new(:get, :head, :put)
72
+ end
73
+
74
+ def not_implemented
75
+ raise ActionController::NotImplemented.new(:get, :put)
76
+ end
77
+
78
+ def not_authorized
79
+ raise NotAuthorized
80
+ end
81
+ def not_authorized_raise_as_string
82
+ raise NotAuthorizedToRescueAsString
83
+ end
84
+
85
+ def not_allowed
86
+ raise NotAllowed
87
+ end
88
+ def not_allowed_raise_as_string
89
+ raise NotAllowedToRescueAsString
90
+ end
91
+
92
+ def invalid_request
93
+ raise InvalidRequest
94
+ end
95
+ def invalid_request_raise_as_string
96
+ raise InvalidRequestToRescueAsString
97
+ end
98
+
99
+ def record_invalid
100
+ raise RecordInvalid
101
+ end
102
+ def record_invalid_raise_as_string
103
+ raise RecordInvalidToRescueAsString
104
+ end
105
+
106
+ def bad_gateway
107
+ raise BadGateway
108
+ end
109
+ def bad_gateway_raise_as_string
110
+ raise BadGatewayToRescueAsString
111
+ end
112
+
113
+ def resource_unavailable
114
+ raise ResourceUnavailable
115
+ end
116
+ def resource_unavailable_raise_as_string
117
+ raise ResourceUnavailableToRescueAsString
118
+ end
119
+
120
+ def missing_template
121
+ end
122
+
123
+ protected
124
+ def deny_access
125
+ head :forbidden
126
+ end
127
+
128
+ def show_errors(exception)
129
+ head :unprocessable_entity
130
+ end
131
+ end
132
+
133
+ class RescueTest < Test::Unit::TestCase
134
+ FIXTURE_PUBLIC = "#{File.dirname(__FILE__)}/../fixtures".freeze
135
+
136
+ def setup
137
+ @controller = RescueController.new
138
+ @request = ActionController::TestRequest.new
139
+ @response = ActionController::TestResponse.new
140
+
141
+ RescueController.consider_all_requests_local = true
142
+ @request.remote_addr = '1.2.3.4'
143
+ @request.host = 'example.com'
144
+
145
+ begin
146
+ raise 'foo'
147
+ rescue => @exception
148
+ end
149
+ end
150
+
151
+ def test_rescue_action_locally_if_all_requests_local
152
+ @controller.expects(:local_request?).never
153
+ @controller.expects(:rescue_action_locally).with(@exception)
154
+ @controller.expects(:rescue_action_in_public).never
155
+
156
+ with_all_requests_local do
157
+ @controller.send :rescue_action, @exception
158
+ end
159
+ end
160
+
161
+ def test_rescue_action_locally_if_remote_addr_is_localhost
162
+ @controller.expects(:local_request?).returns(true)
163
+ @controller.expects(:rescue_action_locally).with(@exception)
164
+ @controller.expects(:rescue_action_in_public).never
165
+
166
+ with_all_requests_local false do
167
+ @controller.send :rescue_action, @exception
168
+ end
169
+ end
170
+
171
+ def test_rescue_action_in_public_otherwise
172
+ @controller.expects(:local_request?).returns(false)
173
+ @controller.expects(:rescue_action_locally).never
174
+ @controller.expects(:rescue_action_in_public).with(@exception)
175
+
176
+ with_all_requests_local false do
177
+ @controller.send :rescue_action, @exception
178
+ end
179
+ end
180
+
181
+ def test_rescue_action_in_public_with_error_file
182
+ with_rails_root FIXTURE_PUBLIC do
183
+ with_all_requests_local false do
184
+ get :raises
185
+ end
186
+ end
187
+
188
+ assert_response :internal_server_error
189
+ body = File.read("#{FIXTURE_PUBLIC}/public/500.html")
190
+ assert_equal body, @response.body
191
+ end
192
+
193
+ def test_rescue_action_in_public_without_error_file
194
+ with_rails_root '/tmp' do
195
+ with_all_requests_local false do
196
+ get :raises
197
+ end
198
+ end
199
+
200
+ assert_response :internal_server_error
201
+ assert_equal ' ', @response.body
202
+ end
203
+
204
+ def test_rescue_unknown_action_in_public_with_error_file
205
+ with_rails_root FIXTURE_PUBLIC do
206
+ with_all_requests_local false do
207
+ get :foobar_doesnt_exist
208
+ end
209
+ end
210
+
211
+ assert_response :not_found
212
+ body = File.read("#{FIXTURE_PUBLIC}/public/404.html")
213
+ assert_equal body, @response.body
214
+ end
215
+
216
+ def test_rescue_unknown_action_in_public_without_error_file
217
+ with_rails_root '/tmp' do
218
+ with_all_requests_local false do
219
+ get :foobar_doesnt_exist
220
+ end
221
+ end
222
+
223
+ assert_response :not_found
224
+ assert_equal ' ', @response.body
225
+ end
226
+
227
+ def test_rescue_missing_template_in_public
228
+ with_rails_root FIXTURE_PUBLIC do
229
+ with_all_requests_local true do
230
+ get :missing_template
231
+ end
232
+ end
233
+
234
+ assert_response :internal_server_error
235
+ assert @response.body.include?('missing_template'), "Response should include the template name."
236
+ end
237
+
238
+ def test_rescue_action_locally
239
+ get :raises
240
+ assert_response :internal_server_error
241
+ assert_template 'diagnostics.erb'
242
+ assert @response.body.include?('RescueController#raises'), "Response should include controller and action."
243
+ assert @response.body.include?("don't panic"), "Response should include exception message."
244
+ end
245
+
246
+ def test_local_request_when_remote_addr_is_localhost
247
+ @controller.expects(:request).returns(@request).at_least_once
248
+ with_remote_addr '127.0.0.1' do
249
+ assert @controller.send(:local_request?)
250
+ end
251
+ end
252
+
253
+ def test_local_request_when_remote_addr_isnt_locahost
254
+ @controller.expects(:request).returns(@request)
255
+ with_remote_addr '1.2.3.4' do
256
+ assert !@controller.send(:local_request?)
257
+ end
258
+ end
259
+
260
+ def test_rescue_responses
261
+ responses = ActionController::Base.rescue_responses
262
+
263
+ assert_equal ActionController::Rescue::DEFAULT_RESCUE_RESPONSE, responses.default
264
+ assert_equal ActionController::Rescue::DEFAULT_RESCUE_RESPONSE, responses[Exception.new]
265
+
266
+ assert_equal :not_found, responses[ActionController::RoutingError.name]
267
+ assert_equal :not_found, responses[ActionController::UnknownAction.name]
268
+ assert_equal :not_found, responses['ActiveRecord::RecordNotFound']
269
+ assert_equal :conflict, responses['ActiveRecord::StaleObjectError']
270
+ assert_equal :unprocessable_entity, responses['ActiveRecord::RecordInvalid']
271
+ assert_equal :unprocessable_entity, responses['ActiveRecord::RecordNotSaved']
272
+ assert_equal :method_not_allowed, responses['ActionController::MethodNotAllowed']
273
+ assert_equal :not_implemented, responses['ActionController::NotImplemented']
274
+ end
275
+
276
+ def test_rescue_templates
277
+ templates = ActionController::Base.rescue_templates
278
+
279
+ assert_equal ActionController::Rescue::DEFAULT_RESCUE_TEMPLATE, templates.default
280
+ assert_equal ActionController::Rescue::DEFAULT_RESCUE_TEMPLATE, templates[Exception.new]
281
+
282
+ assert_equal 'missing_template', templates[ActionController::MissingTemplate.name]
283
+ assert_equal 'routing_error', templates[ActionController::RoutingError.name]
284
+ assert_equal 'unknown_action', templates[ActionController::UnknownAction.name]
285
+ assert_equal 'template_error', templates[ActionView::TemplateError.name]
286
+ end
287
+
288
+ def test_clean_backtrace
289
+ with_rails_root nil do
290
+ # No action if RAILS_ROOT isn't set.
291
+ cleaned = @controller.send(:clean_backtrace, @exception)
292
+ assert_equal @exception.backtrace, cleaned
293
+ end
294
+
295
+ with_rails_root Dir.pwd do
296
+ # RAILS_ROOT is removed from backtrace.
297
+ cleaned = @controller.send(:clean_backtrace, @exception)
298
+ expected = @exception.backtrace.map { |line| line.sub(RAILS_ROOT, '') }
299
+ assert_equal expected, cleaned
300
+
301
+ # No action if backtrace is nil.
302
+ assert_nil @controller.send(:clean_backtrace, Exception.new)
303
+ end
304
+ end
305
+
306
+ def test_not_implemented
307
+ with_all_requests_local false do
308
+ head :not_implemented
309
+ end
310
+ assert_response :not_implemented
311
+ assert_equal "GET, PUT", @response.headers['Allow']
312
+ end
313
+
314
+ def test_method_not_allowed
315
+ with_all_requests_local false do
316
+ get :method_not_allowed
317
+ end
318
+ assert_response :method_not_allowed
319
+ assert_equal "GET, HEAD, PUT", @response.headers['Allow']
320
+ end
321
+
322
+ def test_rescue_handler
323
+ get :not_authorized
324
+ assert_response :forbidden
325
+ end
326
+ def test_rescue_handler_string
327
+ get :not_authorized_raise_as_string
328
+ assert_response :forbidden
329
+ end
330
+
331
+ def test_rescue_handler_with_argument
332
+ @controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) }
333
+ get :record_invalid
334
+ end
335
+ def test_rescue_handler_with_argument_as_string
336
+ @controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) }
337
+ get :record_invalid_raise_as_string
338
+ end
339
+
340
+ def test_proc_rescue_handler
341
+ get :not_allowed
342
+ assert_response :forbidden
343
+ end
344
+ def test_proc_rescue_handler_as_string
345
+ get :not_allowed_raise_as_string
346
+ assert_response :forbidden
347
+ end
348
+
349
+ def test_proc_rescue_handle_with_argument
350
+ get :invalid_request
351
+ assert_equal "RescueController::InvalidRequest", @response.body
352
+ end
353
+ def test_proc_rescue_handle_with_argument_as_string
354
+ get :invalid_request_raise_as_string
355
+ assert_equal "RescueController::InvalidRequestToRescueAsString", @response.body
356
+ end
357
+
358
+ def test_block_rescue_handler
359
+ get :bad_gateway
360
+ assert_response 502
361
+ end
362
+ def test_block_rescue_handler_as_string
363
+ get :bad_gateway_raise_as_string
364
+ assert_response 502
365
+ end
366
+
367
+ def test_block_rescue_handler_with_argument
368
+ get :resource_unavailable
369
+ assert_equal "RescueController::ResourceUnavailable", @response.body
370
+ end
371
+
372
+ def test_block_rescue_handler_with_argument_as_string
373
+ get :resource_unavailable_raise_as_string
374
+ assert_equal "RescueController::ResourceUnavailableToRescueAsString", @response.body
375
+ end
376
+
377
+
378
+ protected
379
+ def with_all_requests_local(local = true)
380
+ old_local, ActionController::Base.consider_all_requests_local =
381
+ ActionController::Base.consider_all_requests_local, local
382
+ yield
383
+ ensure
384
+ ActionController::Base.consider_all_requests_local = old_local
385
+ end
386
+
387
+ def with_remote_addr(addr)
388
+ old_remote_addr, @request.remote_addr = @request.remote_addr, addr
389
+ yield
390
+ ensure
391
+ @request.remote_addr = old_remote_addr
392
+ end
393
+
394
+ def with_rails_root(path = nil)
395
+ old_rails_root = RAILS_ROOT if defined?(RAILS_ROOT)
396
+ if path
397
+ silence_warnings { Object.const_set(:RAILS_ROOT, path) }
398
+ else
399
+ Object.remove_const(:RAILS_ROOT) rescue nil
400
+ end
401
+
402
+ yield
403
+
404
+ ensure
405
+ if old_rails_root
406
+ silence_warnings { Object.const_set(:RAILS_ROOT, old_rails_root) }
407
+ else
408
+ Object.remove_const(:RAILS_ROOT) rescue nil
409
+ end
410
+ end
411
+ end
412
+
413
+ class ExceptionInheritanceRescueController < ActionController::Base
414
+
415
+ class ParentException < StandardError
416
+ end
417
+
418
+ class ChildException < ParentException
419
+ end
420
+
421
+ class GrandchildException < ChildException
422
+ end
423
+
424
+ rescue_from ChildException, :with => lambda { head :ok }
425
+ rescue_from ParentException, :with => lambda { head :created }
426
+ rescue_from GrandchildException, :with => lambda { head :no_content }
427
+
428
+ def raise_parent_exception
429
+ raise ParentException
430
+ end
431
+
432
+ def raise_child_exception
433
+ raise ChildException
434
+ end
435
+
436
+ def raise_grandchild_exception
437
+ raise GrandchildException
438
+ end
439
+ end
440
+
441
+ class ExceptionInheritanceRescueTest < Test::Unit::TestCase
442
+
443
+ def setup
444
+ @controller = ExceptionInheritanceRescueController.new
445
+ @request = ActionController::TestRequest.new
446
+ @response = ActionController::TestResponse.new
447
+ end
448
+
449
+ def test_bottom_first
450
+ get :raise_grandchild_exception
451
+ assert_response :no_content
452
+ end
453
+
454
+ def test_inheritance_works
455
+ get :raise_child_exception
456
+ assert_response :created
457
+ end
458
+ end
459
+
460
+ class ControllerInheritanceRescueController < ExceptionInheritanceRescueController
461
+ class FirstExceptionInChildController < StandardError
462
+ end
463
+
464
+ class SecondExceptionInChildController < StandardError
465
+ end
466
+
467
+ rescue_from FirstExceptionInChildController, 'SecondExceptionInChildController', :with => lambda { head :gone }
468
+
469
+ def raise_first_exception_in_child_controller
470
+ raise FirstExceptionInChildController
471
+ end
472
+
473
+ def raise_second_exception_in_child_controller
474
+ raise SecondExceptionInChildController
475
+ end
476
+ end
477
+
478
+ class ControllerInheritanceRescueControllerTest < Test::Unit::TestCase
479
+
480
+ def setup
481
+ @controller = ControllerInheritanceRescueController.new
482
+ @request = ActionController::TestRequest.new
483
+ @response = ActionController::TestResponse.new
484
+ end
485
+
486
+ def test_first_exception_in_child_controller
487
+ get :raise_first_exception_in_child_controller
488
+ assert_response :gone
489
+ end
490
+
491
+ def test_second_exception_in_child_controller
492
+ get :raise_second_exception_in_child_controller
493
+ assert_response :gone
494
+ end
495
+
496
+ def test_exception_in_parent_controller
497
+ get :raise_parent_exception
498
+ assert_response :created
499
+ end
500
+ end
501
+ end # uses_mocha