eactionpack 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (338) hide show
  1. data/CHANGELOG +7 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +469 -0
  4. data/RUNNING_UNIT_TESTS +24 -0
  5. data/Rakefile +146 -0
  6. data/install.rb +30 -0
  7. data/lib/action_controller.rb +79 -0
  8. data/lib/action_controller/assertions.rb +69 -0
  9. data/lib/action_controller/assertions/dom_assertions.rb +39 -0
  10. data/lib/action_controller/assertions/model_assertions.rb +20 -0
  11. data/lib/action_controller/assertions/response_assertions.rb +172 -0
  12. data/lib/action_controller/assertions/routing_assertions.rb +146 -0
  13. data/lib/action_controller/assertions/selector_assertions.rb +491 -0
  14. data/lib/action_controller/assertions/tag_assertions.rb +130 -0
  15. data/lib/action_controller/base.rb +1288 -0
  16. data/lib/action_controller/benchmarking.rb +94 -0
  17. data/lib/action_controller/caching.rb +72 -0
  18. data/lib/action_controller/caching/actions.rb +144 -0
  19. data/lib/action_controller/caching/fragments.rb +138 -0
  20. data/lib/action_controller/caching/pages.rb +154 -0
  21. data/lib/action_controller/caching/sql_cache.rb +18 -0
  22. data/lib/action_controller/caching/sweeping.rb +97 -0
  23. data/lib/action_controller/cgi_ext.rb +16 -0
  24. data/lib/action_controller/cgi_ext/cookie.rb +110 -0
  25. data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
  26. data/lib/action_controller/cgi_ext/session.rb +73 -0
  27. data/lib/action_controller/cgi_ext/stdinput.rb +24 -0
  28. data/lib/action_controller/cgi_process.rb +223 -0
  29. data/lib/action_controller/components.rb +166 -0
  30. data/lib/action_controller/cookies.rb +96 -0
  31. data/lib/action_controller/dispatcher.rb +162 -0
  32. data/lib/action_controller/filters.rb +642 -0
  33. data/lib/action_controller/flash.rb +172 -0
  34. data/lib/action_controller/headers.rb +31 -0
  35. data/lib/action_controller/helpers.rb +221 -0
  36. data/lib/action_controller/http_authentication.rb +124 -0
  37. data/lib/action_controller/integration.rb +634 -0
  38. data/lib/action_controller/layout.rb +309 -0
  39. data/lib/action_controller/mime_responds.rb +173 -0
  40. data/lib/action_controller/mime_type.rb +186 -0
  41. data/lib/action_controller/mime_types.rb +20 -0
  42. data/lib/action_controller/polymorphic_routes.rb +191 -0
  43. data/lib/action_controller/record_identifier.rb +102 -0
  44. data/lib/action_controller/request.rb +764 -0
  45. data/lib/action_controller/request_forgery_protection.rb +140 -0
  46. data/lib/action_controller/request_profiler.rb +169 -0
  47. data/lib/action_controller/rescue.rb +258 -0
  48. data/lib/action_controller/resources.rb +572 -0
  49. data/lib/action_controller/response.rb +76 -0
  50. data/lib/action_controller/routing.rb +387 -0
  51. data/lib/action_controller/routing/builder.rb +203 -0
  52. data/lib/action_controller/routing/optimisations.rb +120 -0
  53. data/lib/action_controller/routing/recognition_optimisation.rb +162 -0
  54. data/lib/action_controller/routing/route.rb +240 -0
  55. data/lib/action_controller/routing/route_set.rb +436 -0
  56. data/lib/action_controller/routing/routing_ext.rb +46 -0
  57. data/lib/action_controller/routing/segments.rb +283 -0
  58. data/lib/action_controller/session/active_record_store.rb +340 -0
  59. data/lib/action_controller/session/cookie_store.rb +166 -0
  60. data/lib/action_controller/session/drb_server.rb +32 -0
  61. data/lib/action_controller/session/drb_store.rb +35 -0
  62. data/lib/action_controller/session/mem_cache_store.rb +98 -0
  63. data/lib/action_controller/session_management.rb +158 -0
  64. data/lib/action_controller/status_codes.rb +88 -0
  65. data/lib/action_controller/streaming.rb +155 -0
  66. data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
  67. data/lib/action_controller/templates/rescues/_trace.erb +26 -0
  68. data/lib/action_controller/templates/rescues/diagnostics.erb +11 -0
  69. data/lib/action_controller/templates/rescues/layout.erb +29 -0
  70. data/lib/action_controller/templates/rescues/missing_template.erb +2 -0
  71. data/lib/action_controller/templates/rescues/routing_error.erb +10 -0
  72. data/lib/action_controller/templates/rescues/template_error.erb +21 -0
  73. data/lib/action_controller/templates/rescues/unknown_action.erb +2 -0
  74. data/lib/action_controller/test_case.rb +83 -0
  75. data/lib/action_controller/test_process.rb +526 -0
  76. data/lib/action_controller/url_rewriter.rb +142 -0
  77. data/lib/action_controller/vendor/html-scanner/html/document.rb +68 -0
  78. data/lib/action_controller/vendor/html-scanner/html/node.rb +537 -0
  79. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
  80. data/lib/action_controller/vendor/html-scanner/html/selector.rb +828 -0
  81. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +105 -0
  82. data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
  83. data/lib/action_controller/verification.rb +130 -0
  84. data/lib/action_pack.rb +24 -0
  85. data/lib/action_pack/version.rb +9 -0
  86. data/lib/action_view.rb +44 -0
  87. data/lib/action_view/base.rb +335 -0
  88. data/lib/action_view/helpers/active_record_helper.rb +276 -0
  89. data/lib/action_view/helpers/asset_tag_helper.rb +599 -0
  90. data/lib/action_view/helpers/atom_feed_helper.rb +143 -0
  91. data/lib/action_view/helpers/benchmark_helper.rb +33 -0
  92. data/lib/action_view/helpers/cache_helper.rb +40 -0
  93. data/lib/action_view/helpers/capture_helper.rb +161 -0
  94. data/lib/action_view/helpers/date_helper.rb +711 -0
  95. data/lib/action_view/helpers/debug_helper.rb +31 -0
  96. data/lib/action_view/helpers/form_helper.rb +767 -0
  97. data/lib/action_view/helpers/form_options_helper.rb +458 -0
  98. data/lib/action_view/helpers/form_tag_helper.rb +458 -0
  99. data/lib/action_view/helpers/javascript_helper.rb +148 -0
  100. data/lib/action_view/helpers/number_helper.rb +186 -0
  101. data/lib/action_view/helpers/record_identification_helper.rb +20 -0
  102. data/lib/action_view/helpers/record_tag_helper.rb +59 -0
  103. data/lib/action_view/helpers/sanitize_helper.rb +229 -0
  104. data/lib/action_view/helpers/tag_helper.rb +134 -0
  105. data/lib/action_view/helpers/text_helper.rb +507 -0
  106. data/lib/action_view/helpers/url_helper.rb +573 -0
  107. data/lib/action_view/inline_template.rb +20 -0
  108. data/lib/action_view/partial_template.rb +70 -0
  109. data/lib/action_view/partials.rb +158 -0
  110. data/lib/action_view/template.rb +125 -0
  111. data/lib/action_view/template_error.rb +110 -0
  112. data/lib/action_view/template_finder.rb +176 -0
  113. data/lib/action_view/template_handler.rb +34 -0
  114. data/lib/action_view/template_handlers/builder.rb +27 -0
  115. data/lib/action_view/template_handlers/compilable.rb +128 -0
  116. data/lib/action_view/template_handlers/erb.rb +56 -0
  117. data/lib/action_view/test_case.rb +58 -0
  118. data/lib/actionpack.rb +1 -0
  119. data/test/abstract_unit.rb +36 -0
  120. data/test/active_record_unit.rb +105 -0
  121. data/test/activerecord/active_record_store_test.rb +141 -0
  122. data/test/activerecord/render_partial_with_record_identification_test.rb +191 -0
  123. data/test/adv_attr_test.rb +20 -0
  124. data/test/controller/action_pack_assertions_test.rb +543 -0
  125. data/test/controller/addresses_render_test.rb +43 -0
  126. data/test/controller/assert_select_test.rb +331 -0
  127. data/test/controller/base_test.rb +219 -0
  128. data/test/controller/benchmark_test.rb +32 -0
  129. data/test/controller/caching_test.rb +581 -0
  130. data/test/controller/capture_test.rb +89 -0
  131. data/test/controller/cgi_test.rb +116 -0
  132. data/test/controller/components_test.rb +140 -0
  133. data/test/controller/content_type_test.rb +139 -0
  134. data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
  135. data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
  136. data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
  137. data/test/controller/cookie_test.rb +146 -0
  138. data/test/controller/custom_handler_test.rb +45 -0
  139. data/test/controller/deprecation/deprecated_base_methods_test.rb +37 -0
  140. data/test/controller/dispatcher_test.rb +105 -0
  141. data/test/controller/fake_controllers.rb +33 -0
  142. data/test/controller/fake_models.rb +11 -0
  143. data/test/controller/filter_params_test.rb +49 -0
  144. data/test/controller/filters_test.rb +881 -0
  145. data/test/controller/flash_test.rb +146 -0
  146. data/test/controller/header_test.rb +14 -0
  147. data/test/controller/helper_test.rb +210 -0
  148. data/test/controller/html-scanner/cdata_node_test.rb +15 -0
  149. data/test/controller/html-scanner/document_test.rb +148 -0
  150. data/test/controller/html-scanner/node_test.rb +89 -0
  151. data/test/controller/html-scanner/sanitizer_test.rb +269 -0
  152. data/test/controller/html-scanner/tag_node_test.rb +238 -0
  153. data/test/controller/html-scanner/text_node_test.rb +50 -0
  154. data/test/controller/html-scanner/tokenizer_test.rb +131 -0
  155. data/test/controller/http_authentication_test.rb +54 -0
  156. data/test/controller/integration_test.rb +252 -0
  157. data/test/controller/integration_upload_test.rb +43 -0
  158. data/test/controller/layout_test.rb +255 -0
  159. data/test/controller/mime_responds_test.rb +514 -0
  160. data/test/controller/mime_type_test.rb +84 -0
  161. data/test/controller/new_render_test.rb +843 -0
  162. data/test/controller/polymorphic_routes_test.rb +174 -0
  163. data/test/controller/record_identifier_test.rb +139 -0
  164. data/test/controller/redirect_test.rb +289 -0
  165. data/test/controller/render_test.rb +484 -0
  166. data/test/controller/request_forgery_protection_test.rb +305 -0
  167. data/test/controller/request_test.rb +928 -0
  168. data/test/controller/rescue_test.rb +517 -0
  169. data/test/controller/resources_test.rb +873 -0
  170. data/test/controller/routing_test.rb +2464 -0
  171. data/test/controller/selector_test.rb +628 -0
  172. data/test/controller/send_file_test.rb +138 -0
  173. data/test/controller/session/cookie_store_test.rb +258 -0
  174. data/test/controller/session/mem_cache_store_test.rb +181 -0
  175. data/test/controller/session_fixation_test.rb +89 -0
  176. data/test/controller/session_management_test.rb +178 -0
  177. data/test/controller/test_test.rb +695 -0
  178. data/test/controller/url_rewriter_test.rb +310 -0
  179. data/test/controller/verification_test.rb +270 -0
  180. data/test/controller/view_paths_test.rb +140 -0
  181. data/test/controller/webservice_test.rb +229 -0
  182. data/test/fixtures/addresses/list.erb +1 -0
  183. data/test/fixtures/bad_customers/_bad_customer.html.erb +1 -0
  184. data/test/fixtures/companies.yml +24 -0
  185. data/test/fixtures/company.rb +10 -0
  186. data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
  187. data/test/fixtures/content_type/render_default_for_js.js.erb +1 -0
  188. data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
  189. data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
  190. data/test/fixtures/customers/_customer.html.erb +1 -0
  191. data/test/fixtures/db_definitions/sqlite.sql +49 -0
  192. data/test/fixtures/developer.rb +9 -0
  193. data/test/fixtures/developers.yml +21 -0
  194. data/test/fixtures/developers_projects.yml +13 -0
  195. data/test/fixtures/fun/games/hello_world.erb +1 -0
  196. data/test/fixtures/functional_caching/_partial.erb +3 -0
  197. data/test/fixtures/functional_caching/fragment_cached.html.erb +2 -0
  198. data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +1 -0
  199. data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +1 -0
  200. data/test/fixtures/good_customers/_good_customer.html.erb +1 -0
  201. data/test/fixtures/helpers/abc_helper.rb +5 -0
  202. data/test/fixtures/helpers/fun/games_helper.rb +3 -0
  203. data/test/fixtures/helpers/fun/pdf_helper.rb +3 -0
  204. data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
  205. data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +1 -0
  206. data/test/fixtures/layout_tests/layouts/item.rhtml +1 -0
  207. data/test/fixtures/layout_tests/layouts/layout_test.rhtml +1 -0
  208. data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
  209. data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +1 -0
  210. data/test/fixtures/layout_tests/views/hello.rhtml +1 -0
  211. data/test/fixtures/layouts/block_with_layout.erb +3 -0
  212. data/test/fixtures/layouts/builder.builder +3 -0
  213. data/test/fixtures/layouts/partial_with_layout.erb +3 -0
  214. data/test/fixtures/layouts/standard.erb +1 -0
  215. data/test/fixtures/layouts/talk_from_action.erb +2 -0
  216. data/test/fixtures/layouts/yield.erb +2 -0
  217. data/test/fixtures/mascot.rb +3 -0
  218. data/test/fixtures/mascots.yml +4 -0
  219. data/test/fixtures/mascots/_mascot.html.erb +1 -0
  220. data/test/fixtures/multipart/binary_file +0 -0
  221. data/test/fixtures/multipart/boundary_problem_file +10 -0
  222. data/test/fixtures/multipart/bracketed_param +5 -0
  223. data/test/fixtures/multipart/large_text_file +10 -0
  224. data/test/fixtures/multipart/mixed_files +0 -0
  225. data/test/fixtures/multipart/mona_lisa.jpg +0 -0
  226. data/test/fixtures/multipart/single_parameter +5 -0
  227. data/test/fixtures/multipart/text_file +10 -0
  228. data/test/fixtures/override/test/hello_world.erb +1 -0
  229. data/test/fixtures/override2/layouts/test/sub.erb +1 -0
  230. data/test/fixtures/post_test/layouts/post.html.erb +1 -0
  231. data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
  232. data/test/fixtures/post_test/post/index.html.erb +1 -0
  233. data/test/fixtures/post_test/post/index.iphone.erb +1 -0
  234. data/test/fixtures/post_test/super_post/index.html.erb +1 -0
  235. data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
  236. data/test/fixtures/project.rb +3 -0
  237. data/test/fixtures/projects.yml +7 -0
  238. data/test/fixtures/public/404.html +1 -0
  239. data/test/fixtures/public/500.html +1 -0
  240. data/test/fixtures/public/images/rails.png +0 -0
  241. data/test/fixtures/public/javascripts/application.js +1 -0
  242. data/test/fixtures/public/javascripts/bank.js +1 -0
  243. data/test/fixtures/public/javascripts/robber.js +1 -0
  244. data/test/fixtures/public/javascripts/version.1.0.js +1 -0
  245. data/test/fixtures/public/stylesheets/bank.css +1 -0
  246. data/test/fixtures/public/stylesheets/robber.css +1 -0
  247. data/test/fixtures/public/stylesheets/version.1.0.css +1 -0
  248. data/test/fixtures/replies.yml +15 -0
  249. data/test/fixtures/reply.rb +7 -0
  250. data/test/fixtures/respond_to/all_types_with_layout.html.erb +1 -0
  251. data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
  252. data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
  253. data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
  254. data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
  255. data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
  256. data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
  257. data/test/fixtures/respond_to/using_defaults.html.erb +1 -0
  258. data/test/fixtures/respond_to/using_defaults.js.rjs +1 -0
  259. data/test/fixtures/respond_to/using_defaults.xml.builder +1 -0
  260. data/test/fixtures/respond_to/using_defaults_with_type_list.html.erb +1 -0
  261. data/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +1 -0
  262. data/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder +1 -0
  263. data/test/fixtures/scope/test/modgreet.erb +1 -0
  264. data/test/fixtures/shared.html.erb +1 -0
  265. data/test/fixtures/symlink_parent/symlinked_layout.erb +5 -0
  266. data/test/fixtures/test/_customer.erb +1 -0
  267. data/test/fixtures/test/_customer_counter.erb +1 -0
  268. data/test/fixtures/test/_customer_greeting.erb +1 -0
  269. data/test/fixtures/test/_form.erb +1 -0
  270. data/test/fixtures/test/_hash_greeting.erb +1 -0
  271. data/test/fixtures/test/_hash_object.erb +2 -0
  272. data/test/fixtures/test/_hello.builder +1 -0
  273. data/test/fixtures/test/_labelling_form.erb +1 -0
  274. data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
  275. data/test/fixtures/test/_partial.erb +1 -0
  276. data/test/fixtures/test/_partial.html.erb +1 -0
  277. data/test/fixtures/test/_partial.js.erb +1 -0
  278. data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
  279. data/test/fixtures/test/_partial_only.erb +1 -0
  280. data/test/fixtures/test/_person.erb +2 -0
  281. data/test/fixtures/test/_raise.html.erb +1 -0
  282. data/test/fixtures/test/action_talk_to_layout.erb +2 -0
  283. data/test/fixtures/test/block_content_for.erb +2 -0
  284. data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
  285. data/test/fixtures/test/capturing.erb +4 -0
  286. data/test/fixtures/test/content_for.erb +2 -0
  287. data/test/fixtures/test/content_for_concatenated.erb +3 -0
  288. data/test/fixtures/test/content_for_with_parameter.erb +2 -0
  289. data/test/fixtures/test/delete_with_js.rjs +2 -0
  290. data/test/fixtures/test/dot.directory/render_file_with_ivar.erb +1 -0
  291. data/test/fixtures/test/enum_rjs_test.rjs +6 -0
  292. data/test/fixtures/test/erb_content_for.erb +2 -0
  293. data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
  294. data/test/fixtures/test/formatted_xml_erb.builder +1 -0
  295. data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
  296. data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
  297. data/test/fixtures/test/greeting.erb +1 -0
  298. data/test/fixtures/test/greeting.js.rjs +1 -0
  299. data/test/fixtures/test/hello.builder +4 -0
  300. data/test/fixtures/test/hello_world.erb +1 -0
  301. data/test/fixtures/test/hello_world_container.builder +3 -0
  302. data/test/fixtures/test/hello_world_from_rxml.builder +4 -0
  303. data/test/fixtures/test/hello_world_with_layout_false.erb +1 -0
  304. data/test/fixtures/test/hello_xml_world.builder +11 -0
  305. data/test/fixtures/test/list.erb +1 -0
  306. data/test/fixtures/test/non_erb_block_content_for.builder +4 -0
  307. data/test/fixtures/test/potential_conflicts.erb +4 -0
  308. data/test/fixtures/test/render_file_from_template.html.erb +1 -0
  309. data/test/fixtures/test/render_file_with_ivar.erb +1 -0
  310. data/test/fixtures/test/render_file_with_locals.erb +1 -0
  311. data/test/fixtures/test/render_to_string_test.erb +1 -0
  312. data/test/fixtures/test/update_element_with_capture.erb +9 -0
  313. data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
  314. data/test/fixtures/topic.rb +3 -0
  315. data/test/fixtures/topics.yml +22 -0
  316. data/test/fixtures/topics/_topic.html.erb +1 -0
  317. data/test/template/active_record_helper_test.rb +268 -0
  318. data/test/template/asset_tag_helper_test.rb +514 -0
  319. data/test/template/atom_feed_helper_test.rb +179 -0
  320. data/test/template/benchmark_helper_test.rb +60 -0
  321. data/test/template/date_helper_test.rb +1791 -0
  322. data/test/template/deprecated_erb_variable_test.rb +9 -0
  323. data/test/template/erb_util_test.rb +24 -0
  324. data/test/template/form_helper_test.rb +885 -0
  325. data/test/template/form_options_helper_test.rb +1333 -0
  326. data/test/template/form_tag_helper_test.rb +272 -0
  327. data/test/template/javascript_helper_test.rb +73 -0
  328. data/test/template/number_helper_test.rb +97 -0
  329. data/test/template/record_tag_helper_test.rb +54 -0
  330. data/test/template/sanitize_helper_test.rb +48 -0
  331. data/test/template/tag_helper_test.rb +77 -0
  332. data/test/template/template_finder_test.rb +73 -0
  333. data/test/template/template_object_test.rb +95 -0
  334. data/test/template/test_test.rb +56 -0
  335. data/test/template/text_helper_test.rb +367 -0
  336. data/test/template/url_helper_test.rb +544 -0
  337. data/test/testing_sandbox.rb +15 -0
  338. metadata +469 -0
@@ -0,0 +1,146 @@
1
+ require 'abstract_unit'
2
+
3
+ class CookieTest < Test::Unit::TestCase
4
+ class TestController < ActionController::Base
5
+ def authenticate
6
+ cookies["user_name"] = "david"
7
+ end
8
+
9
+ def authenticate_for_fourteen_days
10
+ cookies["user_name"] = { "value" => "david", "expires" => Time.local(2005, 10, 10) }
11
+ end
12
+
13
+ def authenticate_for_fourteen_days_with_symbols
14
+ cookies[:user_name] = { :value => "david", :expires => Time.local(2005, 10, 10) }
15
+ end
16
+
17
+ def set_multiple_cookies
18
+ cookies["user_name"] = { "value" => "david", "expires" => Time.local(2005, 10, 10) }
19
+ cookies["login"] = "XJ-122"
20
+ end
21
+
22
+ def access_frozen_cookies
23
+ cookies["will"] = "work"
24
+ end
25
+
26
+ def logout
27
+ cookies.delete("user_name")
28
+ end
29
+
30
+ def delete_cookie_with_path
31
+ cookies.delete("user_name", :path => '/beaten')
32
+ render :text => "hello world"
33
+ end
34
+
35
+ def authenticate_with_http_only
36
+ cookies["user_name"] = { :value => "david", :http_only => true }
37
+ end
38
+
39
+ def rescue_action(e)
40
+ raise unless ActionView::MissingTemplate # No templates here, and we don't care about the output
41
+ end
42
+ end
43
+
44
+ def setup
45
+ @request = ActionController::TestRequest.new
46
+ @response = ActionController::TestResponse.new
47
+
48
+ @controller = TestController.new
49
+ @request.host = "www.nextangle.com"
50
+ end
51
+
52
+ def test_setting_cookie
53
+ get :authenticate
54
+ assert_equal [ CGI::Cookie::new("name" => "user_name", "value" => "david") ], @response.headers["cookie"]
55
+ end
56
+
57
+ def test_setting_cookie_for_fourteen_days
58
+ get :authenticate_for_fourteen_days
59
+ assert_equal [ CGI::Cookie::new("name" => "user_name", "value" => "david", "expires" => Time.local(2005, 10, 10)) ], @response.headers["cookie"]
60
+ end
61
+
62
+ def test_setting_cookie_for_fourteen_days_with_symbols
63
+ get :authenticate_for_fourteen_days
64
+ assert_equal [ CGI::Cookie::new("name" => "user_name", "value" => "david", "expires" => Time.local(2005, 10, 10)) ], @response.headers["cookie"]
65
+ end
66
+
67
+ def test_setting_cookie_with_http_only
68
+ get :authenticate_with_http_only
69
+ assert_equal [ CGI::Cookie::new("name" => "user_name", "value" => "david", "http_only" => true) ], @response.headers["cookie"]
70
+ assert_equal CGI::Cookie::new("name" => "user_name", "value" => "david", "path" => "/", "http_only" => true).to_s, @response.headers["cookie"][0].to_s
71
+ end
72
+
73
+ def test_multiple_cookies
74
+ get :set_multiple_cookies
75
+ assert_equal 2, @response.cookies.size
76
+ end
77
+
78
+ def test_setting_test_cookie
79
+ assert_nothing_raised { get :access_frozen_cookies }
80
+ end
81
+
82
+ def test_expiring_cookie
83
+ get :logout
84
+ assert_equal [ CGI::Cookie::new("name" => "user_name", "value" => "", "expires" => Time.at(0)) ], @response.headers["cookie"]
85
+ assert_equal CGI::Cookie::new("name" => "user_name", "value" => "", "expires" => Time.at(0)).value, []
86
+ end
87
+
88
+ def test_cookiejar_accessor
89
+ @request.cookies["user_name"] = CGI::Cookie.new("name" => "user_name", "value" => "david", "expires" => Time.local(2025, 10, 10))
90
+ @controller.request = @request
91
+ jar = ActionController::CookieJar.new(@controller)
92
+ assert_equal "david", jar["user_name"]
93
+ assert_equal nil, jar["something_else"]
94
+ end
95
+
96
+ def test_cookiejar_accessor_with_array_value
97
+ a = %w{1 2 3}
98
+ @request.cookies["pages"] = CGI::Cookie.new("name" => "pages", "value" => a, "expires" => Time.local(2025, 10, 10))
99
+ @controller.request = @request
100
+ jar = ActionController::CookieJar.new(@controller)
101
+ assert_equal a, jar["pages"]
102
+ end
103
+
104
+ def test_delete_cookie_with_path
105
+ get :delete_cookie_with_path
106
+ assert_equal "/beaten", @response.headers["cookie"].first.path
107
+ assert_not_equal "/", @response.headers["cookie"].first.path
108
+ end
109
+
110
+ def test_cookie_to_s_simple_values
111
+ assert_equal 'myname=myvalue; path=', CGI::Cookie.new('myname', 'myvalue').to_s
112
+ end
113
+
114
+ def test_cookie_to_s_hash
115
+ cookie_str = CGI::Cookie.new(
116
+ 'name' => 'myname',
117
+ 'value' => 'myvalue',
118
+ 'domain' => 'mydomain',
119
+ 'path' => 'mypath',
120
+ 'expires' => Time.utc(2007, 10, 20),
121
+ 'secure' => true,
122
+ 'http_only' => true).to_s
123
+ assert_equal 'myname=myvalue; domain=mydomain; path=mypath; expires=Sat, 20 Oct 2007 00:00:00 GMT; secure; HttpOnly', cookie_str
124
+ end
125
+
126
+ def test_cookie_to_s_hash_default_not_secure_not_http_only
127
+ cookie_str = CGI::Cookie.new(
128
+ 'name' => 'myname',
129
+ 'value' => 'myvalue',
130
+ 'domain' => 'mydomain',
131
+ 'path' => 'mypath',
132
+ 'expires' => Time.utc(2007, 10, 20))
133
+ assert cookie_str !~ /secure/
134
+ assert cookie_str !~ /HttpOnly/
135
+ end
136
+
137
+ def test_cookies_should_not_be_split_on_ampersand_values
138
+ cookies = CGI::Cookie.parse('return_to=http://rubyonrails.org/search?term=api&scope=all&global=true')
139
+ assert_equal({"return_to" => ["http://rubyonrails.org/search?term=api&scope=all&global=true"]}, cookies)
140
+ end
141
+
142
+ def test_cookies_should_not_be_split_on_values_with_newlines
143
+ cookies = CGI::Cookie.new("name" => "val", "value" => "this\nis\na\ntest")
144
+ assert cookies.size == 1
145
+ end
146
+ end
@@ -0,0 +1,45 @@
1
+ require 'abstract_unit'
2
+
3
+ class CustomHandler < ActionView::TemplateHandler
4
+ def initialize( view )
5
+ @view = view
6
+ end
7
+
8
+ def render( template )
9
+ [ template.source,
10
+ template.locals,
11
+ @view ]
12
+ end
13
+ end
14
+
15
+ class CustomHandlerTest < Test::Unit::TestCase
16
+ def setup
17
+ ActionView::Template.register_template_handler "foo", CustomHandler
18
+ ActionView::Template.register_template_handler :foo2, CustomHandler
19
+ @view = ActionView::Base.new
20
+ end
21
+
22
+ def test_custom_render
23
+ template = ActionView::InlineTemplate.new(@view, "hello <%= one %>", { :one => "two" }, "foo")
24
+
25
+ result = @view.render_template(template)
26
+ assert_equal(
27
+ [ "hello <%= one %>", { :one => "two" }, @view ],
28
+ result )
29
+ end
30
+
31
+ def test_custom_render2
32
+ template = ActionView::InlineTemplate.new(@view, "hello <%= one %>", { :one => "two" }, "foo2")
33
+ result = @view.render_template(template)
34
+ assert_equal(
35
+ [ "hello <%= one %>", { :one => "two" }, @view ],
36
+ result )
37
+ end
38
+
39
+ def test_unhandled_extension
40
+ # uses the ERb handler by default if the extension isn't recognized
41
+ template = ActionView::InlineTemplate.new(@view, "hello <%= one %>", { :one => "two" }, "bar")
42
+ result = @view.render_template(template)
43
+ assert_equal "hello two", result
44
+ end
45
+ end
@@ -0,0 +1,37 @@
1
+ require 'abstract_unit'
2
+
3
+ class DeprecatedBaseMethodsTest < Test::Unit::TestCase
4
+ class Target < ActionController::Base
5
+
6
+ def home_url(greeting)
7
+ "http://example.com/#{greeting}"
8
+ end
9
+
10
+ def raises_name_error
11
+ this_method_doesnt_exist
12
+ end
13
+
14
+ def rescue_action(e) raise e end
15
+ end
16
+
17
+ Target.view_paths = [ File.dirname(__FILE__) + "/../../fixtures" ]
18
+
19
+ def setup
20
+ @request = ActionController::TestRequest.new
21
+ @response = ActionController::TestResponse.new
22
+ @controller = Target.new
23
+ end
24
+
25
+ def test_log_error_silences_deprecation_warnings
26
+ get :raises_name_error
27
+ rescue => e
28
+ assert_not_deprecated { @controller.send :log_error, e }
29
+ end
30
+
31
+ def test_assertion_failed_error_silences_deprecation_warnings
32
+ get :raises_name_error
33
+ rescue => e
34
+ error = Test::Unit::Error.new('testing ur doodz', e)
35
+ assert_not_deprecated { error.message }
36
+ end
37
+ end
@@ -0,0 +1,105 @@
1
+ require 'abstract_unit'
2
+
3
+ uses_mocha 'dispatcher tests' do
4
+
5
+ require 'action_controller/dispatcher'
6
+
7
+ class DispatcherTest < Test::Unit::TestCase
8
+ Dispatcher = ActionController::Dispatcher
9
+
10
+ def setup
11
+ @output = StringIO.new
12
+ ENV['REQUEST_METHOD'] = 'GET'
13
+
14
+ # Clear callbacks as they are redefined by Dispatcher#define_dispatcher_callbacks
15
+ Dispatcher.instance_variable_set("@prepare_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
16
+ Dispatcher.instance_variable_set("@before_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
17
+ Dispatcher.instance_variable_set("@after_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
18
+
19
+ Dispatcher.stubs(:require_dependency)
20
+
21
+ @dispatcher = Dispatcher.new(@output)
22
+ end
23
+
24
+ def teardown
25
+ ENV.delete 'REQUEST_METHOD'
26
+ end
27
+
28
+ def test_clears_dependencies_after_dispatch_if_in_loading_mode
29
+ ActionController::Routing::Routes.expects(:reload).once
30
+ ActiveSupport::Dependencies.expects(:clear).once
31
+
32
+ dispatch(@output, false)
33
+ end
34
+
35
+ def test_leaves_dependencies_after_dispatch_if_not_in_loading_mode
36
+ ActionController::Routing::Routes.expects(:reload).never
37
+ ActiveSupport::Dependencies.expects(:clear).never
38
+
39
+ dispatch
40
+ end
41
+
42
+ # Stub out dispatch error logger
43
+ class << Dispatcher
44
+ def log_failsafe_exception(status, exception); end
45
+ end
46
+
47
+ def test_failsafe_response
48
+ CGI.expects(:new).raises('some multipart parsing failure')
49
+ Dispatcher.expects(:log_failsafe_exception)
50
+
51
+ assert_nothing_raised { dispatch }
52
+
53
+ assert_equal "Status: 400 Bad Request\r\nContent-Type: text/html\r\n\r\n<html><body><h1>400 Bad Request</h1></body></html>", @output.string
54
+ end
55
+
56
+ def test_prepare_callbacks
57
+ a = b = c = nil
58
+ Dispatcher.to_prepare { |*args| a = b = c = 1 }
59
+ Dispatcher.to_prepare { |*args| b = c = 2 }
60
+ Dispatcher.to_prepare { |*args| c = 3 }
61
+
62
+ # Ensure to_prepare callbacks are not run when defined
63
+ assert_nil a || b || c
64
+
65
+ # Run callbacks
66
+ @dispatcher.send :run_callbacks, :prepare_dispatch
67
+
68
+ assert_equal 1, a
69
+ assert_equal 2, b
70
+ assert_equal 3, c
71
+
72
+ # Make sure they are only run once
73
+ a = b = c = nil
74
+ @dispatcher.send :dispatch
75
+ assert_nil a || b || c
76
+ end
77
+
78
+ def test_to_prepare_with_identifier_replaces
79
+ a = b = nil
80
+ Dispatcher.to_prepare(:unique_id) { |*args| a = b = 1 }
81
+ Dispatcher.to_prepare(:unique_id) { |*args| a = 2 }
82
+
83
+ @dispatcher.send :run_callbacks, :prepare_dispatch
84
+ assert_equal 2, a
85
+ assert_equal nil, b
86
+ end
87
+
88
+ private
89
+ def dispatch(output = @output, cache_classes = true)
90
+ controller = mock
91
+ controller.stubs(:process).returns(controller)
92
+ controller.stubs(:out).with(output).returns('response')
93
+
94
+ ActionController::Routing::Routes.stubs(:recognize).returns(controller)
95
+
96
+ Dispatcher.define_dispatcher_callbacks(cache_classes)
97
+ Dispatcher.dispatch(nil, {}, output)
98
+ end
99
+
100
+ def assert_subclasses(howmany, klass, message = klass.subclasses.inspect)
101
+ assert_equal howmany, klass.subclasses.size, message
102
+ end
103
+ end
104
+
105
+ end
@@ -0,0 +1,33 @@
1
+ class << Object; alias_method :const_available?, :const_defined?; end
2
+
3
+ class ContentController < Class.new(ActionController::Base)
4
+ end
5
+ class NotAController
6
+ end
7
+ module Admin
8
+ class << self; alias_method :const_available?, :const_defined?; end
9
+ class UserController < Class.new(ActionController::Base); end
10
+ class NewsFeedController < Class.new(ActionController::Base); end
11
+ end
12
+
13
+ # For speed test
14
+ class SpeedController < ActionController::Base; end
15
+ class SearchController < SpeedController; end
16
+ class VideosController < SpeedController; end
17
+ class VideoFileController < SpeedController; end
18
+ class VideoSharesController < SpeedController; end
19
+ class VideoAbusesController < SpeedController; end
20
+ class VideoUploadsController < SpeedController; end
21
+ class VideoVisitsController < SpeedController; end
22
+ class UsersController < SpeedController; end
23
+ class SettingsController < SpeedController; end
24
+ class ChannelsController < SpeedController; end
25
+ class ChannelVideosController < SpeedController; end
26
+ class SessionsController < SpeedController; end
27
+ class LostPasswordsController < SpeedController; end
28
+ class PagesController < SpeedController; end
29
+
30
+ ActionController::Routing::Routes.draw do |map|
31
+ map.route_one 'route_one', :controller => 'elsewhere', :action => 'flash_me'
32
+ map.connect ':controller/:action/:id'
33
+ end
@@ -0,0 +1,11 @@
1
+ class Customer < Struct.new(:name, :id)
2
+ def to_param
3
+ id.to_s
4
+ end
5
+ end
6
+
7
+ class BadCustomer < Customer
8
+ end
9
+
10
+ class GoodCustomer < Customer
11
+ end
@@ -0,0 +1,49 @@
1
+ require 'abstract_unit'
2
+
3
+ class FilterParamController < ActionController::Base
4
+ end
5
+
6
+ class FilterParamTest < Test::Unit::TestCase
7
+ def setup
8
+ @controller = FilterParamController.new
9
+ end
10
+
11
+ def test_filter_parameters
12
+ assert FilterParamController.respond_to?(:filter_parameter_logging)
13
+ assert !@controller.respond_to?(:filter_parameters)
14
+
15
+ FilterParamController.filter_parameter_logging
16
+ assert @controller.respond_to?(:filter_parameters)
17
+
18
+ test_hashes = [[{},{},[]],
19
+ [{'foo'=>nil},{'foo'=>nil},[]],
20
+ [{'foo'=>'bar'},{'foo'=>'bar'},[]],
21
+ [{'foo'=>'bar'},{'foo'=>'bar'},%w'food'],
22
+ [{'foo'=>'bar'},{'foo'=>'[FILTERED]'},%w'foo'],
23
+ [{'foo'=>'bar', 'bar'=>'foo'},{'foo'=>'[FILTERED]', 'bar'=>'foo'},%w'foo baz'],
24
+ [{'foo'=>'bar', 'baz'=>'foo'},{'foo'=>'[FILTERED]', 'baz'=>'[FILTERED]'},%w'foo baz'],
25
+ [{'bar'=>{'foo'=>'bar','bar'=>'foo'}},{'bar'=>{'foo'=>'[FILTERED]','bar'=>'foo'}},%w'fo'],
26
+ [{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana']]
27
+
28
+ test_hashes.each do |before_filter, after_filter, filter_words|
29
+ FilterParamController.filter_parameter_logging(*filter_words)
30
+ assert_equal after_filter, @controller.send!(:filter_parameters, before_filter)
31
+
32
+ filter_words.push('blah')
33
+ FilterParamController.filter_parameter_logging(*filter_words) do |key, value|
34
+ value.reverse! if key =~ /bargain/
35
+ end
36
+
37
+ before_filter['barg'] = {'bargain'=>'gain', 'blah'=>'bar', 'bar'=>{'bargain'=>{'blah'=>'foo'}}}
38
+ after_filter['barg'] = {'bargain'=>'niag', 'blah'=>'[FILTERED]', 'bar'=>{'bargain'=>{'blah'=>'[FILTERED]'}}}
39
+
40
+ assert_equal after_filter, @controller.send!(:filter_parameters, before_filter)
41
+ end
42
+ end
43
+
44
+ def test_filter_parameters_is_protected
45
+ FilterParamController.filter_parameter_logging(:foo)
46
+ assert !FilterParamController.action_methods.include?('filter_parameters')
47
+ assert_raise(NoMethodError) { @controller.filter_parameters([{'password' => '[FILTERED]'}]) }
48
+ end
49
+ end
@@ -0,0 +1,881 @@
1
+ require 'abstract_unit'
2
+
3
+ # FIXME: crashes Ruby 1.9
4
+ class FilterTest < Test::Unit::TestCase
5
+ class TestController < ActionController::Base
6
+ before_filter :ensure_login
7
+ after_filter :clean_up
8
+
9
+ def show
10
+ render :inline => "ran action"
11
+ end
12
+
13
+ private
14
+ def ensure_login
15
+ @ran_filter ||= []
16
+ @ran_filter << "ensure_login"
17
+ end
18
+
19
+ def clean_up
20
+ @ran_after_filter ||= []
21
+ @ran_after_filter << "clean_up"
22
+ end
23
+ end
24
+
25
+ class ChangingTheRequirementsController < TestController
26
+ before_filter :ensure_login, :except => [:go_wild]
27
+
28
+ def go_wild
29
+ render :text => "gobble"
30
+ end
31
+ end
32
+
33
+ class TestMultipleFiltersController < ActionController::Base
34
+ before_filter :try_1
35
+ before_filter :try_2
36
+ before_filter :try_3
37
+
38
+ (1..3).each do |i|
39
+ define_method "fail_#{i}" do
40
+ render :text => i.to_s
41
+ end
42
+ end
43
+
44
+ protected
45
+ (1..3).each do |i|
46
+ define_method "try_#{i}" do
47
+ instance_variable_set :@try, i
48
+ if action_name == "fail_#{i}"
49
+ head(404)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ class RenderingController < ActionController::Base
56
+ before_filter :render_something_else
57
+
58
+ def show
59
+ @ran_action = true
60
+ render :inline => "ran action"
61
+ end
62
+
63
+ private
64
+ def render_something_else
65
+ render :inline => "something else"
66
+ end
67
+ end
68
+
69
+ class ConditionalFilterController < ActionController::Base
70
+ def show
71
+ render :inline => "ran action"
72
+ end
73
+
74
+ def another_action
75
+ render :inline => "ran action"
76
+ end
77
+
78
+ def show_without_filter
79
+ render :inline => "ran action without filter"
80
+ end
81
+
82
+ private
83
+ def ensure_login
84
+ @ran_filter ||= []
85
+ @ran_filter << "ensure_login"
86
+ end
87
+
88
+ def clean_up_tmp
89
+ @ran_filter ||= []
90
+ @ran_filter << "clean_up_tmp"
91
+ end
92
+
93
+ def rescue_action(e) raise(e) end
94
+ end
95
+
96
+ class ConditionalCollectionFilterController < ConditionalFilterController
97
+ before_filter :ensure_login, :except => [ :show_without_filter, :another_action ]
98
+ end
99
+
100
+ class OnlyConditionSymController < ConditionalFilterController
101
+ before_filter :ensure_login, :only => :show
102
+ end
103
+
104
+ class ExceptConditionSymController < ConditionalFilterController
105
+ before_filter :ensure_login, :except => :show_without_filter
106
+ end
107
+
108
+ class BeforeAndAfterConditionController < ConditionalFilterController
109
+ before_filter :ensure_login, :only => :show
110
+ after_filter :clean_up_tmp, :only => :show
111
+ end
112
+
113
+ class OnlyConditionProcController < ConditionalFilterController
114
+ before_filter(:only => :show) {|c| c.assigns["ran_proc_filter"] = true }
115
+ end
116
+
117
+ class ExceptConditionProcController < ConditionalFilterController
118
+ before_filter(:except => :show_without_filter) {|c| c.assigns["ran_proc_filter"] = true }
119
+ end
120
+
121
+ class ConditionalClassFilter
122
+ def self.filter(controller) controller.assigns["ran_class_filter"] = true end
123
+ end
124
+
125
+ class OnlyConditionClassController < ConditionalFilterController
126
+ before_filter ConditionalClassFilter, :only => :show
127
+ end
128
+
129
+ class ExceptConditionClassController < ConditionalFilterController
130
+ before_filter ConditionalClassFilter, :except => :show_without_filter
131
+ end
132
+
133
+ class AnomolousYetValidConditionController < ConditionalFilterController
134
+ before_filter(ConditionalClassFilter, :ensure_login, Proc.new {|c| c.assigns["ran_proc_filter1"] = true }, :except => :show_without_filter) { |c| c.assigns["ran_proc_filter2"] = true}
135
+ end
136
+
137
+ class ConditionalOptionsFilter < ConditionalFilterController
138
+ before_filter :ensure_login, :if => Proc.new { |c| true }
139
+ before_filter :clean_up_tmp, :if => Proc.new { |c| false }
140
+ end
141
+
142
+ class EmptyFilterChainController < TestController
143
+ self.filter_chain.clear
144
+ def show
145
+ @action_executed = true
146
+ render :text => "yawp!"
147
+ end
148
+ end
149
+
150
+ class PrependingController < TestController
151
+ prepend_before_filter :wonderful_life
152
+ # skip_before_filter :fire_flash
153
+
154
+ private
155
+ def wonderful_life
156
+ @ran_filter ||= []
157
+ @ran_filter << "wonderful_life"
158
+ end
159
+ end
160
+
161
+ class SkippingAndLimitedController < TestController
162
+ skip_before_filter :ensure_login
163
+ before_filter :ensure_login, :only => :index
164
+
165
+ def index
166
+ render :text => 'ok'
167
+ end
168
+
169
+ def public
170
+ end
171
+ end
172
+
173
+ class SkippingAndReorderingController < TestController
174
+ skip_before_filter :ensure_login
175
+ before_filter :find_record
176
+ before_filter :ensure_login
177
+
178
+ private
179
+ def find_record
180
+ @ran_filter ||= []
181
+ @ran_filter << "find_record"
182
+ end
183
+ end
184
+
185
+ class ConditionalSkippingController < TestController
186
+ skip_before_filter :ensure_login, :only => [ :login ]
187
+ skip_after_filter :clean_up, :only => [ :login ]
188
+
189
+ before_filter :find_user, :only => [ :change_password ]
190
+
191
+ def login
192
+ render :inline => "ran action"
193
+ end
194
+
195
+ def change_password
196
+ render :inline => "ran action"
197
+ end
198
+
199
+ protected
200
+ def find_user
201
+ @ran_filter ||= []
202
+ @ran_filter << "find_user"
203
+ end
204
+ end
205
+
206
+ class ConditionalParentOfConditionalSkippingController < ConditionalFilterController
207
+ before_filter :conditional_in_parent, :only => [:show, :another_action]
208
+ after_filter :conditional_in_parent, :only => [:show, :another_action]
209
+
210
+ private
211
+
212
+ def conditional_in_parent
213
+ @ran_filter ||= []
214
+ @ran_filter << 'conditional_in_parent'
215
+ end
216
+ end
217
+
218
+ class ChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController
219
+ skip_before_filter :conditional_in_parent, :only => :another_action
220
+ skip_after_filter :conditional_in_parent, :only => :another_action
221
+ end
222
+
223
+ class AnotherChildOfConditionalParentController < ConditionalParentOfConditionalSkippingController
224
+ skip_before_filter :conditional_in_parent, :only => :show
225
+ end
226
+
227
+ class ProcController < PrependingController
228
+ before_filter(proc { |c| c.assigns["ran_proc_filter"] = true })
229
+ end
230
+
231
+ class ImplicitProcController < PrependingController
232
+ before_filter { |c| c.assigns["ran_proc_filter"] = true }
233
+ end
234
+
235
+ class AuditFilter
236
+ def self.filter(controller)
237
+ controller.assigns["was_audited"] = true
238
+ end
239
+ end
240
+
241
+ class AroundFilter
242
+ def before(controller)
243
+ @execution_log = "before"
244
+ controller.class.execution_log << " before aroundfilter " if controller.respond_to? :execution_log
245
+ controller.assigns["before_ran"] = true
246
+ end
247
+
248
+ def after(controller)
249
+ controller.assigns["execution_log"] = @execution_log + " and after"
250
+ controller.assigns["after_ran"] = true
251
+ controller.class.execution_log << " after aroundfilter " if controller.respond_to? :execution_log
252
+ end
253
+ end
254
+
255
+ class AppendedAroundFilter
256
+ def before(controller)
257
+ controller.class.execution_log << " before appended aroundfilter "
258
+ end
259
+
260
+ def after(controller)
261
+ controller.class.execution_log << " after appended aroundfilter "
262
+ end
263
+ end
264
+
265
+ class AuditController < ActionController::Base
266
+ before_filter(AuditFilter)
267
+
268
+ def show
269
+ render :text => "hello"
270
+ end
271
+ end
272
+
273
+ class AroundFilterController < PrependingController
274
+ around_filter AroundFilter.new
275
+ end
276
+
277
+ class BeforeAfterClassFilterController < PrependingController
278
+ begin
279
+ filter = AroundFilter.new
280
+ before_filter filter
281
+ after_filter filter
282
+ end
283
+ end
284
+
285
+ class MixedFilterController < PrependingController
286
+ cattr_accessor :execution_log
287
+
288
+ def initialize
289
+ @@execution_log = ""
290
+ end
291
+
292
+ before_filter { |c| c.class.execution_log << " before procfilter " }
293
+ prepend_around_filter AroundFilter.new
294
+
295
+ after_filter { |c| c.class.execution_log << " after procfilter " }
296
+ append_around_filter AppendedAroundFilter.new
297
+ end
298
+
299
+ class MixedSpecializationController < ActionController::Base
300
+ class OutOfOrder < StandardError; end
301
+
302
+ before_filter :first
303
+ before_filter :second, :only => :foo
304
+
305
+ def foo
306
+ render :text => 'foo'
307
+ end
308
+
309
+ def bar
310
+ render :text => 'bar'
311
+ end
312
+
313
+ protected
314
+ def first
315
+ @first = true
316
+ end
317
+
318
+ def second
319
+ raise OutOfOrder unless @first
320
+ end
321
+ end
322
+
323
+ class DynamicDispatchController < ActionController::Base
324
+ before_filter :choose
325
+
326
+ %w(foo bar baz).each do |action|
327
+ define_method(action) { render :text => action }
328
+ end
329
+
330
+ private
331
+ def choose
332
+ self.action_name = params[:choose]
333
+ end
334
+ end
335
+
336
+ class PrependingBeforeAndAfterController < ActionController::Base
337
+ prepend_before_filter :before_all
338
+ prepend_after_filter :after_all
339
+ before_filter :between_before_all_and_after_all
340
+
341
+ def before_all
342
+ @ran_filter ||= []
343
+ @ran_filter << 'before_all'
344
+ end
345
+
346
+ def after_all
347
+ @ran_filter ||= []
348
+ @ran_filter << 'after_all'
349
+ end
350
+
351
+ def between_before_all_and_after_all
352
+ @ran_filter ||= []
353
+ @ran_filter << 'between_before_all_and_after_all'
354
+ end
355
+ def show
356
+ render :text => 'hello'
357
+ end
358
+ end
359
+
360
+ class ErrorToRescue < Exception; end
361
+
362
+ class RescuingAroundFilterWithBlock
363
+ def filter(controller)
364
+ begin
365
+ yield
366
+ rescue ErrorToRescue => ex
367
+ controller.send! :render, :text => "I rescued this: #{ex.inspect}"
368
+ end
369
+ end
370
+ end
371
+
372
+ class RescuedController < ActionController::Base
373
+ around_filter RescuingAroundFilterWithBlock.new
374
+
375
+ def show
376
+ raise ErrorToRescue.new("Something made the bad noise.")
377
+ end
378
+
379
+ private
380
+ def rescue_action(exception)
381
+ raise exception
382
+ end
383
+ end
384
+
385
+ class NonYieldingAroundFilterController < ActionController::Base
386
+
387
+ before_filter :filter_one
388
+ around_filter :non_yielding_filter
389
+ before_filter :filter_two
390
+ after_filter :filter_three
391
+
392
+ def index
393
+ render :inline => "index"
394
+ end
395
+
396
+ #make sure the controller complains
397
+ def rescue_action(e); raise e; end
398
+
399
+ private
400
+
401
+ def filter_one
402
+ @filters ||= []
403
+ @filters << "filter_one"
404
+ end
405
+
406
+ def filter_two
407
+ @filters << "filter_two"
408
+ end
409
+
410
+ def non_yielding_filter
411
+ @filters << "zomg it didn't yield"
412
+ @filter_return_value
413
+ end
414
+
415
+ def filter_three
416
+ @filters << "filter_three"
417
+ end
418
+
419
+ end
420
+
421
+ def test_non_yielding_around_filters_not_returning_false_do_not_raise
422
+ controller = NonYieldingAroundFilterController.new
423
+ controller.instance_variable_set "@filter_return_value", true
424
+ assert_nothing_raised do
425
+ test_process(controller, "index")
426
+ end
427
+ end
428
+
429
+ def test_non_yielding_around_filters_returning_false_do_not_raise
430
+ controller = NonYieldingAroundFilterController.new
431
+ controller.instance_variable_set "@filter_return_value", false
432
+ assert_nothing_raised do
433
+ test_process(controller, "index")
434
+ end
435
+ end
436
+
437
+ def test_after_filters_are_not_run_if_around_filter_returns_false
438
+ controller = NonYieldingAroundFilterController.new
439
+ controller.instance_variable_set "@filter_return_value", false
440
+ test_process(controller, "index")
441
+ assert_equal ["filter_one", "zomg it didn't yield"], controller.assigns['filters']
442
+ end
443
+
444
+ def test_after_filters_are_not_run_if_around_filter_does_not_yield
445
+ controller = NonYieldingAroundFilterController.new
446
+ controller.instance_variable_set "@filter_return_value", true
447
+ test_process(controller, "index")
448
+ assert_equal ["filter_one", "zomg it didn't yield"], controller.assigns['filters']
449
+ end
450
+
451
+ def test_empty_filter_chain
452
+ assert_equal 0, EmptyFilterChainController.filter_chain.size
453
+ assert test_process(EmptyFilterChainController).template.assigns['action_executed']
454
+ end
455
+
456
+ def test_added_filter_to_inheritance_graph
457
+ assert_equal [ :ensure_login ], TestController.before_filters
458
+ end
459
+
460
+ def test_base_class_in_isolation
461
+ assert_equal [ ], ActionController::Base.before_filters
462
+ end
463
+
464
+ def test_prepending_filter
465
+ assert_equal [ :wonderful_life, :ensure_login ], PrependingController.before_filters
466
+ end
467
+
468
+ def test_running_filters
469
+ assert_equal %w( wonderful_life ensure_login ), test_process(PrependingController).template.assigns["ran_filter"]
470
+ end
471
+
472
+ def test_running_filters_with_proc
473
+ assert test_process(ProcController).template.assigns["ran_proc_filter"]
474
+ end
475
+
476
+ def test_running_filters_with_implicit_proc
477
+ assert test_process(ImplicitProcController).template.assigns["ran_proc_filter"]
478
+ end
479
+
480
+ def test_running_filters_with_class
481
+ assert test_process(AuditController).template.assigns["was_audited"]
482
+ end
483
+
484
+ def test_running_anomolous_yet_valid_condition_filters
485
+ response = test_process(AnomolousYetValidConditionController)
486
+ assert_equal %w( ensure_login ), response.template.assigns["ran_filter"]
487
+ assert response.template.assigns["ran_class_filter"]
488
+ assert response.template.assigns["ran_proc_filter1"]
489
+ assert response.template.assigns["ran_proc_filter2"]
490
+
491
+ response = test_process(AnomolousYetValidConditionController, "show_without_filter")
492
+ assert_equal nil, response.template.assigns["ran_filter"]
493
+ assert !response.template.assigns["ran_class_filter"]
494
+ assert !response.template.assigns["ran_proc_filter1"]
495
+ assert !response.template.assigns["ran_proc_filter2"]
496
+ end
497
+
498
+ def test_running_conditional_options
499
+ response = test_process(ConditionalOptionsFilter)
500
+ assert_equal %w( ensure_login ), response.template.assigns["ran_filter"]
501
+ end
502
+
503
+ def test_running_collection_condition_filters
504
+ assert_equal %w( ensure_login ), test_process(ConditionalCollectionFilterController).template.assigns["ran_filter"]
505
+ assert_equal nil, test_process(ConditionalCollectionFilterController, "show_without_filter").template.assigns["ran_filter"]
506
+ assert_equal nil, test_process(ConditionalCollectionFilterController, "another_action").template.assigns["ran_filter"]
507
+ end
508
+
509
+ def test_running_only_condition_filters
510
+ assert_equal %w( ensure_login ), test_process(OnlyConditionSymController).template.assigns["ran_filter"]
511
+ assert_equal nil, test_process(OnlyConditionSymController, "show_without_filter").template.assigns["ran_filter"]
512
+
513
+ assert test_process(OnlyConditionProcController).template.assigns["ran_proc_filter"]
514
+ assert !test_process(OnlyConditionProcController, "show_without_filter").template.assigns["ran_proc_filter"]
515
+
516
+ assert test_process(OnlyConditionClassController).template.assigns["ran_class_filter"]
517
+ assert !test_process(OnlyConditionClassController, "show_without_filter").template.assigns["ran_class_filter"]
518
+ end
519
+
520
+ def test_running_except_condition_filters
521
+ assert_equal %w( ensure_login ), test_process(ExceptConditionSymController).template.assigns["ran_filter"]
522
+ assert_equal nil, test_process(ExceptConditionSymController, "show_without_filter").template.assigns["ran_filter"]
523
+
524
+ assert test_process(ExceptConditionProcController).template.assigns["ran_proc_filter"]
525
+ assert !test_process(ExceptConditionProcController, "show_without_filter").template.assigns["ran_proc_filter"]
526
+
527
+ assert test_process(ExceptConditionClassController).template.assigns["ran_class_filter"]
528
+ assert !test_process(ExceptConditionClassController, "show_without_filter").template.assigns["ran_class_filter"]
529
+ end
530
+
531
+ def test_running_before_and_after_condition_filters
532
+ assert_equal %w( ensure_login clean_up_tmp), test_process(BeforeAndAfterConditionController).template.assigns["ran_filter"]
533
+ assert_equal nil, test_process(BeforeAndAfterConditionController, "show_without_filter").template.assigns["ran_filter"]
534
+ end
535
+
536
+ def test_around_filter
537
+ controller = test_process(AroundFilterController)
538
+ assert controller.template.assigns["before_ran"]
539
+ assert controller.template.assigns["after_ran"]
540
+ end
541
+
542
+ def test_before_after_class_filter
543
+ controller = test_process(BeforeAfterClassFilterController)
544
+ assert controller.template.assigns["before_ran"]
545
+ assert controller.template.assigns["after_ran"]
546
+ end
547
+
548
+ def test_having_properties_in_around_filter
549
+ controller = test_process(AroundFilterController)
550
+ assert_equal "before and after", controller.template.assigns["execution_log"]
551
+ end
552
+
553
+ def test_prepending_and_appending_around_filter
554
+ controller = test_process(MixedFilterController)
555
+ assert_equal " before aroundfilter before procfilter before appended aroundfilter " +
556
+ " after appended aroundfilter after aroundfilter after procfilter ",
557
+ MixedFilterController.execution_log
558
+ end
559
+
560
+ def test_rendering_breaks_filtering_chain
561
+ response = test_process(RenderingController)
562
+ assert_equal "something else", response.body
563
+ assert !response.template.assigns["ran_action"]
564
+ end
565
+
566
+ def test_filters_with_mixed_specialization_run_in_order
567
+ assert_nothing_raised do
568
+ response = test_process(MixedSpecializationController, 'bar')
569
+ assert_equal 'bar', response.body
570
+ end
571
+
572
+ assert_nothing_raised do
573
+ response = test_process(MixedSpecializationController, 'foo')
574
+ assert_equal 'foo', response.body
575
+ end
576
+ end
577
+
578
+ def test_dynamic_dispatch
579
+ %w(foo bar baz).each do |action|
580
+ request = ActionController::TestRequest.new
581
+ request.query_parameters[:choose] = action
582
+ response = DynamicDispatchController.process(request, ActionController::TestResponse.new)
583
+ assert_equal action, response.body
584
+ end
585
+ end
586
+
587
+ def test_running_prepended_before_and_after_filter
588
+ assert_equal 3, PrependingBeforeAndAfterController.filter_chain.length
589
+ response = test_process(PrependingBeforeAndAfterController)
590
+ assert_equal %w( before_all between_before_all_and_after_all after_all ), response.template.assigns["ran_filter"]
591
+ end
592
+
593
+ def test_skipping_and_limiting_controller
594
+ assert_equal %w( ensure_login ), test_process(SkippingAndLimitedController, "index").template.assigns["ran_filter"]
595
+ assert_nil test_process(SkippingAndLimitedController, "public").template.assigns["ran_filter"]
596
+ end
597
+
598
+ def test_skipping_and_reordering_controller
599
+ assert_equal %w( find_record ensure_login ), test_process(SkippingAndReorderingController, "index").template.assigns["ran_filter"]
600
+ end
601
+
602
+ def test_conditional_skipping_of_filters
603
+ assert_nil test_process(ConditionalSkippingController, "login").template.assigns["ran_filter"]
604
+ assert_equal %w( ensure_login find_user ), test_process(ConditionalSkippingController, "change_password").template.assigns["ran_filter"]
605
+
606
+ assert_nil test_process(ConditionalSkippingController, "login").template.controller.instance_variable_get("@ran_after_filter")
607
+ assert_equal %w( clean_up ), test_process(ConditionalSkippingController, "change_password").template.controller.instance_variable_get("@ran_after_filter")
608
+ end
609
+
610
+ def test_conditional_skipping_of_filters_when_parent_filter_is_also_conditional
611
+ assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter']
612
+ assert_nil test_process(ChildOfConditionalParentController, 'another_action').template.assigns['ran_filter']
613
+ end
614
+
615
+ def test_condition_skipping_of_filters_when_siblings_also_have_conditions
616
+ assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter'], "1"
617
+ assert_equal nil, test_process(AnotherChildOfConditionalParentController).template.assigns['ran_filter']
618
+ assert_equal %w( conditional_in_parent conditional_in_parent ), test_process(ChildOfConditionalParentController).template.assigns['ran_filter']
619
+ end
620
+
621
+ def test_changing_the_requirements
622
+ assert_equal nil, test_process(ChangingTheRequirementsController, "go_wild").template.assigns['ran_filter']
623
+ end
624
+
625
+ def test_a_rescuing_around_filter
626
+ response = nil
627
+ assert_nothing_raised do
628
+ response = test_process(RescuedController)
629
+ end
630
+
631
+ assert response.success?
632
+ assert_equal("I rescued this: #<FilterTest::ErrorToRescue: Something made the bad noise.>", response.body)
633
+ end
634
+
635
+ private
636
+ def test_process(controller, action = "show")
637
+ request = ActionController::TestRequest.new
638
+ request.action = action
639
+ controller.process(request, ActionController::TestResponse.new)
640
+ end
641
+ end
642
+
643
+
644
+
645
+ class PostsController < ActionController::Base
646
+ def rescue_action(e); raise e; end
647
+
648
+ module AroundExceptions
649
+ class Error < StandardError ; end
650
+ class Before < Error ; end
651
+ class After < Error ; end
652
+ end
653
+ include AroundExceptions
654
+
655
+ class DefaultFilter
656
+ include AroundExceptions
657
+ end
658
+
659
+ module_eval %w(raises_before raises_after raises_both no_raise no_filter).map { |action| "def #{action}; default_action end" }.join("\n")
660
+
661
+ private
662
+ def default_action
663
+ render :inline => "#{action_name} called"
664
+ end
665
+ end
666
+
667
+ class ControllerWithSymbolAsFilter < PostsController
668
+ around_filter :raise_before, :only => :raises_before
669
+ around_filter :raise_after, :only => :raises_after
670
+ around_filter :without_exception, :only => :no_raise
671
+
672
+ private
673
+ def raise_before
674
+ raise Before
675
+ yield
676
+ end
677
+
678
+ def raise_after
679
+ yield
680
+ raise After
681
+ end
682
+
683
+ def without_exception
684
+ # Do stuff...
685
+ 1 + 1
686
+
687
+ yield
688
+
689
+ # Do stuff...
690
+ 1 + 1
691
+ end
692
+ end
693
+
694
+ class ControllerWithFilterClass < PostsController
695
+ class YieldingFilter < DefaultFilter
696
+ def self.filter(controller)
697
+ yield
698
+ raise After
699
+ end
700
+ end
701
+
702
+ around_filter YieldingFilter, :only => :raises_after
703
+ end
704
+
705
+ class ControllerWithFilterInstance < PostsController
706
+ class YieldingFilter < DefaultFilter
707
+ def filter(controller)
708
+ yield
709
+ raise After
710
+ end
711
+ end
712
+
713
+ around_filter YieldingFilter.new, :only => :raises_after
714
+ end
715
+
716
+ class ControllerWithFilterMethod < PostsController
717
+ class YieldingFilter < DefaultFilter
718
+ def filter(controller)
719
+ yield
720
+ raise After
721
+ end
722
+ end
723
+
724
+ around_filter YieldingFilter.new.method(:filter), :only => :raises_after
725
+ end
726
+
727
+ class ControllerWithProcFilter < PostsController
728
+ around_filter(:only => :no_raise) do |c,b|
729
+ c.assigns['before'] = true
730
+ b.call
731
+ c.assigns['after'] = true
732
+ end
733
+ end
734
+
735
+ class ControllerWithNestedFilters < ControllerWithSymbolAsFilter
736
+ around_filter :raise_before, :raise_after, :without_exception, :only => :raises_both
737
+ end
738
+
739
+ class ControllerWithAllTypesOfFilters < PostsController
740
+ before_filter :before
741
+ around_filter :around
742
+ after_filter :after
743
+ around_filter :around_again
744
+
745
+ private
746
+ def before
747
+ @ran_filter ||= []
748
+ @ran_filter << 'before'
749
+ end
750
+
751
+ def around
752
+ @ran_filter << 'around (before yield)'
753
+ yield
754
+ @ran_filter << 'around (after yield)'
755
+ end
756
+
757
+ def after
758
+ @ran_filter << 'after'
759
+ end
760
+
761
+ def around_again
762
+ @ran_filter << 'around_again (before yield)'
763
+ yield
764
+ @ran_filter << 'around_again (after yield)'
765
+ end
766
+ end
767
+
768
+ class ControllerWithTwoLessFilters < ControllerWithAllTypesOfFilters
769
+ skip_filter :around_again
770
+ skip_filter :after
771
+ end
772
+
773
+ class YieldingAroundFiltersTest < Test::Unit::TestCase
774
+ include PostsController::AroundExceptions
775
+
776
+ def test_filters_registering
777
+ assert_equal 1, ControllerWithFilterMethod.filter_chain.size
778
+ assert_equal 1, ControllerWithFilterClass.filter_chain.size
779
+ assert_equal 1, ControllerWithFilterInstance.filter_chain.size
780
+ assert_equal 3, ControllerWithSymbolAsFilter.filter_chain.size
781
+ assert_equal 6, ControllerWithNestedFilters.filter_chain.size
782
+ assert_equal 4, ControllerWithAllTypesOfFilters.filter_chain.size
783
+ end
784
+
785
+ def test_base
786
+ controller = PostsController
787
+ assert_nothing_raised { test_process(controller,'no_raise') }
788
+ assert_nothing_raised { test_process(controller,'raises_before') }
789
+ assert_nothing_raised { test_process(controller,'raises_after') }
790
+ assert_nothing_raised { test_process(controller,'no_filter') }
791
+ end
792
+
793
+ def test_with_symbol
794
+ controller = ControllerWithSymbolAsFilter
795
+ assert_nothing_raised { test_process(controller,'no_raise') }
796
+ assert_raise(Before) { test_process(controller,'raises_before') }
797
+ assert_raise(After) { test_process(controller,'raises_after') }
798
+ assert_nothing_raised { test_process(controller,'no_raise') }
799
+ end
800
+
801
+ def test_with_class
802
+ controller = ControllerWithFilterClass
803
+ assert_nothing_raised { test_process(controller,'no_raise') }
804
+ assert_raise(After) { test_process(controller,'raises_after') }
805
+ end
806
+
807
+ def test_with_instance
808
+ controller = ControllerWithFilterInstance
809
+ assert_nothing_raised { test_process(controller,'no_raise') }
810
+ assert_raise(After) { test_process(controller,'raises_after') }
811
+ end
812
+
813
+ def test_with_method
814
+ controller = ControllerWithFilterMethod
815
+ assert_nothing_raised { test_process(controller,'no_raise') }
816
+ assert_raise(After) { test_process(controller,'raises_after') }
817
+ end
818
+
819
+ def test_with_proc
820
+ controller = test_process(ControllerWithProcFilter,'no_raise')
821
+ assert controller.template.assigns['before']
822
+ assert controller.template.assigns['after']
823
+ end
824
+
825
+ def test_nested_filters
826
+ controller = ControllerWithNestedFilters
827
+ assert_nothing_raised do
828
+ begin
829
+ test_process(controller,'raises_both')
830
+ rescue Before, After
831
+ end
832
+ end
833
+ assert_raise Before do
834
+ begin
835
+ test_process(controller,'raises_both')
836
+ rescue After
837
+ end
838
+ end
839
+ end
840
+
841
+ def test_filter_order_with_all_filter_types
842
+ controller = test_process(ControllerWithAllTypesOfFilters,'no_raise')
843
+ assert_equal 'before around (before yield) around_again (before yield) around_again (after yield) around (after yield) after',controller.template.assigns['ran_filter'].join(' ')
844
+ end
845
+
846
+ def test_filter_order_with_skip_filter_method
847
+ controller = test_process(ControllerWithTwoLessFilters,'no_raise')
848
+ assert_equal 'before around (before yield) around (after yield)',controller.template.assigns['ran_filter'].join(' ')
849
+ end
850
+
851
+ def test_first_filter_in_multiple_before_filter_chain_halts
852
+ controller = ::FilterTest::TestMultipleFiltersController.new
853
+ response = test_process(controller, 'fail_1')
854
+ assert_equal ' ', response.body
855
+ assert_equal 1, controller.instance_variable_get(:@try)
856
+ assert controller.instance_variable_get(:@before_filter_chain_aborted)
857
+ end
858
+
859
+ def test_second_filter_in_multiple_before_filter_chain_halts
860
+ controller = ::FilterTest::TestMultipleFiltersController.new
861
+ response = test_process(controller, 'fail_2')
862
+ assert_equal ' ', response.body
863
+ assert_equal 2, controller.instance_variable_get(:@try)
864
+ assert controller.instance_variable_get(:@before_filter_chain_aborted)
865
+ end
866
+
867
+ def test_last_filter_in_multiple_before_filter_chain_halts
868
+ controller = ::FilterTest::TestMultipleFiltersController.new
869
+ response = test_process(controller, 'fail_3')
870
+ assert_equal ' ', response.body
871
+ assert_equal 3, controller.instance_variable_get(:@try)
872
+ assert controller.instance_variable_get(:@before_filter_chain_aborted)
873
+ end
874
+
875
+ protected
876
+ def test_process(controller, action = "show")
877
+ request = ActionController::TestRequest.new
878
+ request.action = action
879
+ controller.process(request, ActionController::TestResponse.new)
880
+ end
881
+ end