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,172 @@
1
+ module ActionController #:nodoc:
2
+ # The flash provides a way to pass temporary objects between actions. Anything you place in the flash will be exposed
3
+ # to the very next action and then cleared out. This is a great way of doing notices and alerts, such as a create
4
+ # action that sets <tt>flash[:notice] = "Successfully created"</tt> before redirecting to a display action that can
5
+ # then expose the flash to its template. Actually, that exposure is automatically done. Example:
6
+ #
7
+ # class WeblogController < ActionController::Base
8
+ # def create
9
+ # # save post
10
+ # flash[:notice] = "Successfully created post"
11
+ # redirect_to :action => "display", :params => { :id => post.id }
12
+ # end
13
+ #
14
+ # def display
15
+ # # doesn't need to assign the flash notice to the template, that's done automatically
16
+ # end
17
+ # end
18
+ #
19
+ # display.erb
20
+ # <% if flash[:notice] %><div class="notice"><%= flash[:notice] %></div><% end %>
21
+ #
22
+ # This example just places a string in the flash, but you can put any object in there. And of course, you can put as
23
+ # many as you like at a time too. Just remember: They'll be gone by the time the next action has been performed.
24
+ #
25
+ # See docs on the FlashHash class for more details about the flash.
26
+ module Flash
27
+ def self.included(base)
28
+ base.class_eval do
29
+ include InstanceMethods
30
+ alias_method_chain :assign_shortcuts, :flash
31
+ alias_method_chain :reset_session, :flash
32
+ end
33
+ end
34
+
35
+
36
+ class FlashNow #:nodoc:
37
+ def initialize(flash)
38
+ @flash = flash
39
+ end
40
+
41
+ def []=(k, v)
42
+ @flash[k] = v
43
+ @flash.discard(k)
44
+ v
45
+ end
46
+
47
+ def [](k)
48
+ @flash[k]
49
+ end
50
+ end
51
+
52
+ class FlashHash < Hash
53
+ def initialize #:nodoc:
54
+ super
55
+ @used = {}
56
+ end
57
+
58
+ def []=(k, v) #:nodoc:
59
+ keep(k)
60
+ super
61
+ end
62
+
63
+ def update(h) #:nodoc:
64
+ h.keys.each { |k| keep(k) }
65
+ super
66
+ end
67
+
68
+ alias :merge! :update
69
+
70
+ def replace(h) #:nodoc:
71
+ @used = {}
72
+ super
73
+ end
74
+
75
+ # Sets a flash that will not be available to the next action, only to the current.
76
+ #
77
+ # flash.now[:message] = "Hello current action"
78
+ #
79
+ # This method enables you to use the flash as a central messaging system in your app.
80
+ # When you need to pass an object to the next action, you use the standard flash assign (<tt>[]=</tt>).
81
+ # When you need to pass an object to the current action, you use <tt>now</tt>, and your object will
82
+ # vanish when the current action is done.
83
+ #
84
+ # Entries set via <tt>now</tt> are accessed the same way as standard entries: <tt>flash['my-key']</tt>.
85
+ def now
86
+ FlashNow.new(self)
87
+ end
88
+
89
+ # Keeps either the entire current flash or a specific flash entry available for the next action:
90
+ #
91
+ # flash.keep # keeps the entire flash
92
+ # flash.keep(:notice) # keeps only the "notice" entry, the rest of the flash is discarded
93
+ def keep(k = nil)
94
+ use(k, false)
95
+ end
96
+
97
+ # Marks the entire flash or a single flash entry to be discarded by the end of the current action:
98
+ #
99
+ # flash.discard # discard the entire flash at the end of the current action
100
+ # flash.discard(:warning) # discard only the "warning" entry at the end of the current action
101
+ def discard(k = nil)
102
+ use(k)
103
+ end
104
+
105
+ # Mark for removal entries that were kept, and delete unkept ones.
106
+ #
107
+ # This method is called automatically by filters, so you generally don't need to care about it.
108
+ def sweep #:nodoc:
109
+ keys.each do |k|
110
+ unless @used[k]
111
+ use(k)
112
+ else
113
+ delete(k)
114
+ @used.delete(k)
115
+ end
116
+ end
117
+
118
+ # clean up after keys that could have been left over by calling reject! or shift on the flash
119
+ (@used.keys - keys).each{ |k| @used.delete(k) }
120
+ end
121
+
122
+ private
123
+ # Used internally by the <tt>keep</tt> and <tt>discard</tt> methods
124
+ # use() # marks the entire flash as used
125
+ # use('msg') # marks the "msg" entry as used
126
+ # use(nil, false) # marks the entire flash as unused (keeps it around for one more action)
127
+ # use('msg', false) # marks the "msg" entry as unused (keeps it around for one more action)
128
+ def use(k=nil, v=true)
129
+ unless k.nil?
130
+ @used[k] = v
131
+ else
132
+ keys.each{ |key| use(key, v) }
133
+ end
134
+ end
135
+ end
136
+
137
+ module InstanceMethods #:nodoc:
138
+ protected
139
+ def reset_session_with_flash
140
+ reset_session_without_flash
141
+ remove_instance_variable(:@_flash)
142
+ flash(:refresh)
143
+ end
144
+
145
+ # Access the contents of the flash. Use <tt>flash["notice"]</tt> to read a notice you put there or
146
+ # <tt>flash["notice"] = "hello"</tt> to put a new one.
147
+ # Note that if sessions are disabled only flash.now will work.
148
+ def flash(refresh = false) #:doc:
149
+ if !defined?(@_flash) || refresh
150
+ @_flash =
151
+ if session.is_a?(Hash)
152
+ # don't put flash in session if disabled
153
+ FlashHash.new
154
+ else
155
+ # otherwise, session is a CGI::Session or a TestSession
156
+ # so make sure it gets retrieved from/saved to session storage after request processing
157
+ session["flash"] ||= FlashHash.new
158
+ end
159
+ end
160
+
161
+ @_flash
162
+ end
163
+
164
+ private
165
+ def assign_shortcuts_with_flash(request, response) #:nodoc:
166
+ assign_shortcuts_without_flash(request, response)
167
+ flash(:refresh)
168
+ flash.sweep if @_session && !component_request?
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,31 @@
1
+ module ActionController
2
+ module Http
3
+ class Headers < ::Hash
4
+
5
+ def initialize(constructor = {})
6
+ if constructor.is_a?(Hash)
7
+ super()
8
+ update(constructor)
9
+ else
10
+ super(constructor)
11
+ end
12
+ end
13
+
14
+ def [](header_name)
15
+ if include?(header_name)
16
+ super
17
+ else
18
+ super(normalize_header(header_name))
19
+ end
20
+ end
21
+
22
+
23
+ private
24
+ # Takes an HTTP header name and returns it in the
25
+ # format
26
+ def normalize_header(header_name)
27
+ "HTTP_#{header_name.upcase.gsub(/-/, '_')}"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,221 @@
1
+ # FIXME: helper { ... } is broken on Ruby 1.9
2
+ module ActionController #:nodoc:
3
+ module Helpers #:nodoc:
4
+ HELPERS_DIR = (defined?(RAILS_ROOT) ? "#{RAILS_ROOT}/app/helpers" : "app/helpers")
5
+
6
+ def self.included(base)
7
+ # Initialize the base module to aggregate its helpers.
8
+ base.class_inheritable_accessor :master_helper_module
9
+ base.master_helper_module = Module.new
10
+
11
+ # Extend base with class methods to declare helpers.
12
+ base.extend(ClassMethods)
13
+
14
+ base.class_eval do
15
+ # Wrap inherited to create a new master helper module for subclasses.
16
+ class << self
17
+ alias_method_chain :inherited, :helper
18
+ end
19
+ end
20
+ end
21
+
22
+ # The Rails framework provides a large number of helpers for working with +assets+, +dates+, +forms+,
23
+ # +numbers+ and Active Record objects, to name a few. These helpers are available to all templates
24
+ # by default.
25
+ #
26
+ # In addition to using the standard template helpers provided in the Rails framework, creating custom helpers to
27
+ # extract complicated logic or reusable functionality is strongly encouraged. By default, the controller will
28
+ # include a helper whose name matches that of the controller, e.g., <tt>MyController</tt> will automatically
29
+ # include <tt>MyHelper</tt>.
30
+ #
31
+ # Additional helpers can be specified using the +helper+ class method in <tt>ActionController::Base</tt> or any
32
+ # controller which inherits from it.
33
+ #
34
+ # ==== Examples
35
+ # The +to_s+ method from the Time class can be wrapped in a helper method to display a custom message if
36
+ # the Time object is blank:
37
+ #
38
+ # module FormattedTimeHelper
39
+ # def format_time(time, format=:long, blank_message="&nbsp;")
40
+ # time.blank? ? blank_message : time.to_s(format)
41
+ # end
42
+ # end
43
+ #
44
+ # FormattedTimeHelper can now be included in a controller, using the +helper+ class method:
45
+ #
46
+ # class EventsController < ActionController::Base
47
+ # helper FormattedTimeHelper
48
+ # def index
49
+ # @events = Event.find(:all)
50
+ # end
51
+ # end
52
+ #
53
+ # Then, in any view rendered by <tt>EventController</tt>, the <tt>format_time</tt> method can be called:
54
+ #
55
+ # <% @events.each do |event| -%>
56
+ # <p>
57
+ # <% format_time(event.time, :short, "N/A") %> | <%= event.name %>
58
+ # </p>
59
+ # <% end -%>
60
+ #
61
+ # Finally, assuming we have two event instances, one which has a time and one which does not,
62
+ # the output might look like this:
63
+ #
64
+ # 23 Aug 11:30 | Carolina Railhawks Soccer Match
65
+ # N/A | Carolina Railhaws Training Workshop
66
+ #
67
+ module ClassMethods
68
+ # Makes all the (instance) methods in the helper module available to templates rendered through this controller.
69
+ # See ActionView::Helpers (link:classes/ActionView/Helpers.html) for more about making your own helper modules
70
+ # available to the templates.
71
+ def add_template_helper(helper_module) #:nodoc:
72
+ master_helper_module.module_eval { include helper_module }
73
+ end
74
+
75
+ # The +helper+ class method can take a series of helper module names, a block, or both.
76
+ #
77
+ # * <tt>*args</tt>: One or more modules, strings or symbols, or the special symbol <tt>:all</tt>.
78
+ # * <tt>&block</tt>: A block defining helper methods.
79
+ #
80
+ # ==== Examples
81
+ # When the argument is a string or symbol, the method will provide the "_helper" suffix, require the file
82
+ # and include the module in the template class. The second form illustrates how to include custom helpers
83
+ # when working with namespaced controllers, or other cases where the file containing the helper definition is not
84
+ # in one of Rails' standard load paths:
85
+ # helper :foo # => requires 'foo_helper' and includes FooHelper
86
+ # helper 'resources/foo' # => requires 'resources/foo_helper' and includes Resources::FooHelper
87
+ #
88
+ # When the argument is a module it will be included directly in the template class.
89
+ # helper FooHelper # => includes FooHelper
90
+ #
91
+ # When the argument is the symbol <tt>:all</tt>, the controller will include all helpers from
92
+ # <tt>app/helpers/**/*.rb</tt> under RAILS_ROOT.
93
+ # helper :all
94
+ #
95
+ # Additionally, the +helper+ class method can receive and evaluate a block, making the methods defined available
96
+ # to the template.
97
+ # # One line
98
+ # helper { def hello() "Hello, world!" end }
99
+ # # Multi-line
100
+ # helper do
101
+ # def foo(bar)
102
+ # "#{bar} is the very best"
103
+ # end
104
+ # end
105
+ #
106
+ # Finally, all the above styles can be mixed together, and the +helper+ method can be invoked with a mix of
107
+ # +symbols+, +strings+, +modules+ and blocks.
108
+ # helper(:three, BlindHelper) { def mice() 'mice' end }
109
+ #
110
+ def helper(*args, &block)
111
+ args.flatten.each do |arg|
112
+ case arg
113
+ when Module
114
+ add_template_helper(arg)
115
+ when :all
116
+ helper(all_application_helpers)
117
+ when String, Symbol
118
+ file_name = arg.to_s.underscore + '_helper'
119
+ class_name = file_name.camelize
120
+
121
+ begin
122
+ require_dependency(file_name)
123
+ rescue LoadError => load_error
124
+ requiree = / -- (.*?)(\.rb)?$/.match(load_error.message).to_a[1]
125
+ if requiree == file_name
126
+ msg = "Missing helper file helpers/#{file_name}.rb"
127
+ raise LoadError.new(msg).copy_blame!(load_error)
128
+ else
129
+ raise
130
+ end
131
+ end
132
+
133
+ add_template_helper(class_name.constantize)
134
+ else
135
+ raise ArgumentError, "helper expects String, Symbol, or Module argument (was: #{args.inspect})"
136
+ end
137
+ end
138
+
139
+ # Evaluate block in template class if given.
140
+ master_helper_module.module_eval(&block) if block_given?
141
+ end
142
+
143
+ # Declare a controller method as a helper. For example, the following
144
+ # makes the +current_user+ controller method available to the view:
145
+ # class ApplicationController < ActionController::Base
146
+ # helper_method :current_user, :logged_in?
147
+ #
148
+ # def current_user
149
+ # @current_user ||= User.find_by_id(session[:user])
150
+ # end
151
+ #
152
+ # def logged_in?
153
+ # current_user != nil
154
+ # end
155
+ # end
156
+ #
157
+ # In a view:
158
+ # <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
159
+ def helper_method(*methods)
160
+ methods.flatten.each do |method|
161
+ master_helper_module.module_eval <<-end_eval
162
+ def #{method}(*args, &block)
163
+ controller.send(%(#{method}), *args, &block)
164
+ end
165
+ end_eval
166
+ end
167
+ end
168
+
169
+ # Declares helper accessors for controller attributes. For example, the
170
+ # following adds new +name+ and <tt>name=</tt> instance methods to a
171
+ # controller and makes them available to the view:
172
+ # helper_attr :name
173
+ # attr_accessor :name
174
+ def helper_attr(*attrs)
175
+ attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") }
176
+ end
177
+
178
+ # Provides a proxy to access helpers methods from outside the view.
179
+ def helpers
180
+ unless @helper_proxy
181
+ @helper_proxy = ActionView::Base.new
182
+ @helper_proxy.extend master_helper_module
183
+ else
184
+ @helper_proxy
185
+ end
186
+ end
187
+
188
+ private
189
+ def default_helper_module!
190
+ unless name.blank?
191
+ module_name = name.sub(/Controller$|$/, 'Helper')
192
+ module_path = module_name.split('::').map { |m| m.underscore }.join('/')
193
+ require_dependency module_path
194
+ helper module_name.constantize
195
+ end
196
+ rescue MissingSourceFile => e
197
+ raise unless e.is_missing? module_path
198
+ rescue NameError => e
199
+ raise unless e.missing_name? module_name
200
+ end
201
+
202
+ def inherited_with_helper(child)
203
+ inherited_without_helper(child)
204
+
205
+ begin
206
+ child.master_helper_module = Module.new
207
+ child.master_helper_module.send! :include, master_helper_module
208
+ child.send! :default_helper_module!
209
+ rescue MissingSourceFile => e
210
+ raise unless e.is_missing?("helpers/#{child.controller_path}_helper")
211
+ end
212
+ end
213
+
214
+ # Extract helper names from files in app/helpers/**/*.rb
215
+ def all_application_helpers
216
+ extract = /^#{Regexp.quote(HELPERS_DIR)}\/?(.*)_helper.rb$/
217
+ Dir["#{HELPERS_DIR}/**/*_helper.rb"].map { |file| file.sub extract, '\1' }
218
+ end
219
+ end
220
+ end
221
+ end
@@ -0,0 +1,124 @@
1
+ module ActionController
2
+ module HttpAuthentication
3
+ # Makes it dead easy to do HTTP Basic authentication.
4
+ #
5
+ # Simple Basic example:
6
+ #
7
+ # class PostsController < ApplicationController
8
+ # USER_NAME, PASSWORD = "dhh", "secret"
9
+ #
10
+ # before_filter :authenticate, :except => [ :index ]
11
+ #
12
+ # def index
13
+ # render :text => "Everyone can see me!"
14
+ # end
15
+ #
16
+ # def edit
17
+ # render :text => "I'm only accessible if you know the password"
18
+ # end
19
+ #
20
+ # private
21
+ # def authenticate
22
+ # authenticate_or_request_with_http_basic do |user_name, password|
23
+ # user_name == USER_NAME && password == PASSWORD
24
+ # end
25
+ # end
26
+ # end
27
+ #
28
+ #
29
+ # Here is a more advanced Basic example where only Atom feeds and the XML API is protected by HTTP authentication,
30
+ # the regular HTML interface is protected by a session approach:
31
+ #
32
+ # class ApplicationController < ActionController::Base
33
+ # before_filter :set_account, :authenticate
34
+ #
35
+ # protected
36
+ # def set_account
37
+ # @account = Account.find_by_url_name(request.subdomains.first)
38
+ # end
39
+ #
40
+ # def authenticate
41
+ # case request.format
42
+ # when Mime::XML, Mime::ATOM
43
+ # if user = authenticate_with_http_basic { |u, p| @account.users.authenticate(u, p) }
44
+ # @current_user = user
45
+ # else
46
+ # request_http_basic_authentication
47
+ # end
48
+ # else
49
+ # if session_authenticated?
50
+ # @current_user = @account.users.find(session[:authenticated][:user_id])
51
+ # else
52
+ # redirect_to(login_url) and return false
53
+ # end
54
+ # end
55
+ # end
56
+ # end
57
+ #
58
+ #
59
+ # In your integration tests, you can do something like this:
60
+ #
61
+ # def test_access_granted_from_xml
62
+ # get(
63
+ # "/notes/1.xml", nil,
64
+ # :authorization => ActionController::HttpAuthentication::Basic.encode_credentials(users(:dhh).name, users(:dhh).password)
65
+ # )
66
+ #
67
+ # assert_equal 200, status
68
+ # end
69
+ #
70
+ #
71
+ # On shared hosts, Apache sometimes doesn't pass authentication headers to
72
+ # FCGI instances. If your environment matches this description and you cannot
73
+ # authenticate, try this rule in your Apache setup:
74
+ #
75
+ # RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
76
+ module Basic
77
+ extend self
78
+
79
+ module ControllerMethods
80
+ def authenticate_or_request_with_http_basic(realm = "Application", &login_procedure)
81
+ authenticate_with_http_basic(&login_procedure) || request_http_basic_authentication(realm)
82
+ end
83
+
84
+ def authenticate_with_http_basic(&login_procedure)
85
+ HttpAuthentication::Basic.authenticate(self, &login_procedure)
86
+ end
87
+
88
+ def request_http_basic_authentication(realm = "Application")
89
+ HttpAuthentication::Basic.authentication_request(self, realm)
90
+ end
91
+ end
92
+
93
+ def authenticate(controller, &login_procedure)
94
+ unless authorization(controller.request).blank?
95
+ login_procedure.call(*user_name_and_password(controller.request))
96
+ end
97
+ end
98
+
99
+ def user_name_and_password(request)
100
+ decode_credentials(request).split(/:/, 2)
101
+ end
102
+
103
+ def authorization(request)
104
+ request.env['HTTP_AUTHORIZATION'] ||
105
+ request.env['X-HTTP_AUTHORIZATION'] ||
106
+ request.env['X_HTTP_AUTHORIZATION'] ||
107
+ request.env['REDIRECT_X_HTTP_AUTHORIZATION']
108
+ end
109
+
110
+ def decode_credentials(request)
111
+ ActiveSupport::Base64.decode64(authorization(request).split.last || '')
112
+ end
113
+
114
+ def encode_credentials(user_name, password)
115
+ "Basic #{ActiveSupport::Base64.encode64("#{user_name}:#{password}")}"
116
+ end
117
+
118
+ def authentication_request(controller, realm)
119
+ controller.headers["WWW-Authenticate"] = %(Basic realm="#{realm.gsub(/"/, "")}")
120
+ controller.send! :render, :text => "HTTP Basic: Access denied.\n", :status => :unauthorized
121
+ end
122
+ end
123
+ end
124
+ end