actionpack 1.13.6 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (317) hide show
  1. data/CHANGELOG +1400 -20
  2. data/MIT-LICENSE +1 -1
  3. data/README +5 -5
  4. data/RUNNING_UNIT_TESTS +4 -5
  5. data/Rakefile +5 -6
  6. data/install.rb +2 -2
  7. data/lib/action_controller.rb +11 -15
  8. data/lib/action_controller/assertions.rb +12 -25
  9. data/lib/action_controller/assertions/dom_assertions.rb +18 -4
  10. data/lib/action_controller/assertions/model_assertions.rb +8 -1
  11. data/lib/action_controller/assertions/response_assertions.rb +35 -12
  12. data/lib/action_controller/assertions/routing_assertions.rb +56 -12
  13. data/lib/action_controller/assertions/selector_assertions.rb +105 -38
  14. data/lib/action_controller/assertions/tag_assertions.rb +28 -15
  15. data/lib/action_controller/base.rb +318 -250
  16. data/lib/action_controller/benchmarking.rb +33 -29
  17. data/lib/action_controller/caching.rb +130 -64
  18. data/lib/action_controller/cgi_ext.rb +16 -0
  19. data/lib/action_controller/cgi_ext/{cookie_performance_fix.rb → cookie.rb} +25 -40
  20. data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
  21. data/lib/action_controller/cgi_ext/session.rb +73 -0
  22. data/lib/action_controller/cgi_ext/stdinput.rb +23 -0
  23. data/lib/action_controller/cgi_process.rb +34 -57
  24. data/lib/action_controller/components.rb +19 -36
  25. data/lib/action_controller/cookies.rb +10 -9
  26. data/lib/action_controller/dispatcher.rb +195 -0
  27. data/lib/action_controller/filters.rb +35 -34
  28. data/lib/action_controller/flash.rb +30 -35
  29. data/lib/action_controller/helpers.rb +121 -47
  30. data/lib/action_controller/http_authentication.rb +126 -0
  31. data/lib/action_controller/integration.rb +105 -101
  32. data/lib/action_controller/layout.rb +59 -47
  33. data/lib/action_controller/mime_responds.rb +57 -68
  34. data/lib/action_controller/mime_type.rb +43 -80
  35. data/lib/action_controller/mime_types.rb +20 -0
  36. data/lib/action_controller/polymorphic_routes.rb +88 -0
  37. data/lib/action_controller/record_identifier.rb +91 -0
  38. data/lib/action_controller/request.rb +553 -88
  39. data/lib/action_controller/request_forgery_protection.rb +126 -0
  40. data/lib/action_controller/request_profiler.rb +138 -0
  41. data/lib/action_controller/rescue.rb +185 -69
  42. data/lib/action_controller/resources.rb +211 -172
  43. data/lib/action_controller/response.rb +49 -8
  44. data/lib/action_controller/routing.rb +359 -236
  45. data/lib/action_controller/routing_optimisation.rb +119 -0
  46. data/lib/action_controller/session/active_record_store.rb +3 -2
  47. data/lib/action_controller/session/cookie_store.rb +161 -0
  48. data/lib/action_controller/session/mem_cache_store.rb +9 -16
  49. data/lib/action_controller/session_management.rb +17 -8
  50. data/lib/action_controller/streaming.rb +6 -3
  51. data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
  52. data/lib/action_controller/templates/rescues/{_trace.rhtml → _trace.erb} +0 -0
  53. data/lib/action_controller/templates/rescues/{diagnostics.rhtml → diagnostics.erb} +2 -2
  54. data/lib/action_controller/templates/rescues/{layout.rhtml → layout.erb} +0 -0
  55. data/lib/action_controller/templates/rescues/{missing_template.rhtml → missing_template.erb} +0 -0
  56. data/lib/action_controller/templates/rescues/{routing_error.rhtml → routing_error.erb} +0 -0
  57. data/lib/action_controller/templates/rescues/{template_error.rhtml → template_error.erb} +2 -2
  58. data/lib/action_controller/templates/rescues/{unknown_action.rhtml → unknown_action.erb} +0 -0
  59. data/lib/action_controller/test_case.rb +53 -0
  60. data/lib/action_controller/test_process.rb +59 -46
  61. data/lib/action_controller/url_rewriter.rb +48 -24
  62. data/lib/action_controller/vendor/html-scanner/html/document.rb +7 -4
  63. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
  64. data/lib/action_controller/vendor/html-scanner/html/selector.rb +11 -6
  65. data/lib/action_controller/verification.rb +27 -21
  66. data/lib/action_pack.rb +1 -1
  67. data/lib/action_pack/version.rb +4 -4
  68. data/lib/action_view.rb +2 -3
  69. data/lib/action_view/base.rb +218 -63
  70. data/lib/action_view/compiled_templates.rb +1 -2
  71. data/lib/action_view/helpers/active_record_helper.rb +35 -17
  72. data/lib/action_view/helpers/asset_tag_helper.rb +395 -87
  73. data/lib/action_view/helpers/atom_feed_helper.rb +111 -0
  74. data/lib/action_view/helpers/benchmark_helper.rb +12 -5
  75. data/lib/action_view/helpers/cache_helper.rb +29 -0
  76. data/lib/action_view/helpers/capture_helper.rb +97 -63
  77. data/lib/action_view/helpers/date_helper.rb +295 -35
  78. data/lib/action_view/helpers/debug_helper.rb +6 -2
  79. data/lib/action_view/helpers/form_helper.rb +354 -111
  80. data/lib/action_view/helpers/form_options_helper.rb +171 -109
  81. data/lib/action_view/helpers/form_tag_helper.rb +332 -76
  82. data/lib/action_view/helpers/javascript_helper.rb +35 -11
  83. data/lib/action_view/helpers/javascripts/controls.js +484 -354
  84. data/lib/action_view/helpers/javascripts/dragdrop.js +88 -58
  85. data/lib/action_view/helpers/javascripts/effects.js +396 -364
  86. data/lib/action_view/helpers/javascripts/prototype.js +2817 -1107
  87. data/lib/action_view/helpers/number_helper.rb +84 -60
  88. data/lib/action_view/helpers/prototype_helper.rb +419 -43
  89. data/lib/action_view/helpers/record_identification_helper.rb +20 -0
  90. data/lib/action_view/helpers/record_tag_helper.rb +59 -0
  91. data/lib/action_view/helpers/sanitize_helper.rb +223 -0
  92. data/lib/action_view/helpers/scriptaculous_helper.rb +63 -4
  93. data/lib/action_view/helpers/tag_helper.rb +69 -39
  94. data/lib/action_view/helpers/text_helper.rb +221 -148
  95. data/lib/action_view/helpers/url_helper.rb +283 -165
  96. data/lib/action_view/partials.rb +134 -62
  97. data/lib/action_view/template_error.rb +4 -12
  98. data/lib/actionpack.rb +1 -0
  99. data/test/abstract_unit.rb +21 -1
  100. data/test/action_view_test.rb +26 -0
  101. data/test/active_record_unit.rb +12 -20
  102. data/test/activerecord/active_record_store_test.rb +2 -2
  103. data/test/activerecord/render_partial_with_record_identification_test.rb +74 -0
  104. data/test/controller/action_pack_assertions_test.rb +21 -152
  105. data/test/controller/addresses_render_test.rb +2 -7
  106. data/test/controller/assert_select_test.rb +120 -14
  107. data/test/controller/base_test.rb +11 -13
  108. data/test/controller/caching_test.rb +125 -5
  109. data/test/controller/capture_test.rb +23 -16
  110. data/test/controller/cgi_test.rb +66 -391
  111. data/test/controller/components_test.rb +31 -42
  112. data/test/controller/content_type_test.rb +1 -1
  113. data/test/controller/cookie_test.rb +42 -14
  114. data/test/controller/deprecation/deprecated_base_methods_test.rb +1 -42
  115. data/test/controller/dispatcher_test.rb +123 -0
  116. data/test/controller/fake_models.rb +5 -0
  117. data/test/controller/filters_test.rb +44 -7
  118. data/test/controller/flash_test.rb +46 -2
  119. data/test/controller/fragment_store_setting_test.rb +10 -8
  120. data/test/controller/helper_test.rb +19 -2
  121. data/test/controller/html-scanner/document_test.rb +124 -0
  122. data/test/controller/html-scanner/node_test.rb +69 -0
  123. data/test/controller/html-scanner/sanitizer_test.rb +250 -0
  124. data/test/controller/html-scanner/tag_node_test.rb +239 -0
  125. data/test/controller/html-scanner/text_node_test.rb +51 -0
  126. data/test/controller/html-scanner/tokenizer_test.rb +125 -0
  127. data/test/controller/http_authentication_test.rb +54 -0
  128. data/test/controller/integration_test.rb +12 -26
  129. data/test/controller/layout_test.rb +64 -12
  130. data/test/controller/mime_responds_test.rb +193 -38
  131. data/test/controller/mime_type_test.rb +30 -8
  132. data/test/controller/new_render_test.rb +104 -22
  133. data/test/controller/polymorphic_routes_test.rb +98 -0
  134. data/test/controller/record_identifier_test.rb +103 -0
  135. data/test/controller/redirect_test.rb +120 -18
  136. data/test/controller/render_test.rb +195 -45
  137. data/test/controller/request_forgery_protection_test.rb +217 -0
  138. data/test/controller/request_test.rb +545 -27
  139. data/test/controller/rescue_test.rb +501 -0
  140. data/test/controller/resources_test.rb +258 -132
  141. data/test/controller/routing_test.rb +502 -106
  142. data/test/controller/selector_test.rb +5 -5
  143. data/test/controller/send_file_test.rb +17 -7
  144. data/test/controller/session/cookie_store_test.rb +246 -0
  145. data/test/controller/session/mem_cache_store_test.rb +182 -0
  146. data/test/controller/session_fixation_test.rb +8 -11
  147. data/test/controller/session_management_test.rb +7 -7
  148. data/test/controller/test_test.rb +150 -38
  149. data/test/controller/url_rewriter_test.rb +87 -12
  150. data/test/controller/verification_test.rb +11 -0
  151. data/test/controller/view_paths_test.rb +137 -0
  152. data/test/controller/webservice_test.rb +11 -75
  153. data/test/fixtures/addresses/{list.rhtml → list.erb} +0 -0
  154. data/test/fixtures/db_definitions/sqlite.sql +2 -1
  155. data/test/fixtures/developer.rb +2 -0
  156. data/test/fixtures/fun/games/{hello_world.rhtml → hello_world.erb} +0 -0
  157. data/test/fixtures/helpers/fun/pdf_helper.rb +1 -1
  158. data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
  159. data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
  160. data/test/fixtures/layouts/{builder.rxml → builder.builder} +0 -0
  161. data/test/fixtures/layouts/{standard.rhtml → standard.erb} +0 -0
  162. data/test/fixtures/layouts/{talk_from_action.rhtml → talk_from_action.erb} +0 -0
  163. data/test/fixtures/layouts/{yield.rhtml → yield.erb} +0 -0
  164. data/test/fixtures/multipart/binary_file +0 -0
  165. data/test/fixtures/multipart/bracketed_param +5 -0
  166. data/test/fixtures/override/test/hello_world.erb +1 -0
  167. data/test/fixtures/override2/layouts/test/sub.erb +1 -0
  168. data/test/fixtures/post_test/layouts/post.html.erb +1 -0
  169. data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
  170. data/test/fixtures/post_test/post/index.html.erb +1 -0
  171. data/test/fixtures/post_test/post/index.iphone.erb +1 -0
  172. data/test/fixtures/post_test/super_post/index.html.erb +1 -0
  173. data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
  174. data/test/fixtures/public/404.html +1 -0
  175. data/test/fixtures/public/500.html +1 -0
  176. data/test/fixtures/public/javascripts/application.js +0 -1
  177. data/test/fixtures/public/javascripts/bank.js +1 -0
  178. data/test/fixtures/public/javascripts/robber.js +1 -0
  179. data/test/fixtures/public/stylesheets/bank.css +1 -0
  180. data/test/fixtures/public/stylesheets/robber.css +1 -0
  181. data/test/fixtures/replies.yml +2 -0
  182. data/test/fixtures/reply.rb +2 -1
  183. data/test/fixtures/respond_to/{all_types_with_layout.rhtml → all_types_with_layout.html.erb} +0 -0
  184. data/test/fixtures/respond_to/{all_types_with_layout.rjs → all_types_with_layout.js.rjs} +0 -0
  185. data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
  186. data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
  187. data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
  188. data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
  189. data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
  190. data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
  191. data/test/fixtures/respond_to/{using_defaults.rhtml → using_defaults.html.erb} +0 -0
  192. data/test/fixtures/respond_to/{using_defaults.rjs → using_defaults.js.rjs} +0 -0
  193. data/test/fixtures/respond_to/{using_defaults.rxml → using_defaults.xml.builder} +0 -0
  194. data/test/fixtures/respond_to/{using_defaults_with_type_list.rhtml → using_defaults_with_type_list.html.erb} +0 -0
  195. data/test/fixtures/respond_to/{using_defaults_with_type_list.rjs → using_defaults_with_type_list.js.rjs} +0 -0
  196. data/test/fixtures/respond_to/{using_defaults_with_type_list.rxml → using_defaults_with_type_list.xml.builder} +0 -0
  197. data/test/fixtures/scope/test/{modgreet.rhtml → modgreet.erb} +0 -0
  198. data/test/fixtures/test/{_customer.rhtml → _customer.erb} +0 -0
  199. data/test/fixtures/test/{_customer_greeting.rhtml → _customer_greeting.erb} +0 -0
  200. data/test/fixtures/test/_hash_greeting.erb +1 -0
  201. data/test/fixtures/test/_hash_object.erb +2 -0
  202. data/test/fixtures/test/{_hello.rxml → _hello.builder} +0 -0
  203. data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
  204. data/test/fixtures/test/_partial.erb +1 -0
  205. data/test/fixtures/test/_partial.html.erb +1 -0
  206. data/test/fixtures/test/_partial.js.erb +1 -0
  207. data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
  208. data/test/fixtures/test/{_partial_only.rhtml → _partial_only.erb} +0 -0
  209. data/test/fixtures/test/{_person.rhtml → _person.erb} +0 -0
  210. data/test/fixtures/test/{action_talk_to_layout.rhtml → action_talk_to_layout.erb} +0 -0
  211. data/test/fixtures/test/{block_content_for.rhtml → block_content_for.erb} +0 -0
  212. data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
  213. data/test/fixtures/test/{capturing.rhtml → capturing.erb} +0 -0
  214. data/test/fixtures/test/{content_for.rhtml → content_for.erb} +0 -0
  215. data/test/fixtures/test/content_for_concatenated.erb +3 -0
  216. data/test/fixtures/test/content_for_with_parameter.erb +2 -0
  217. data/test/fixtures/test/dot.directory/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
  218. data/test/fixtures/test/{erb_content_for.rhtml → erb_content_for.erb} +0 -0
  219. data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
  220. data/test/fixtures/test/formatted_xml_erb.builder +1 -0
  221. data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
  222. data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
  223. data/test/fixtures/test/{greeting.rhtml → greeting.erb} +0 -0
  224. data/test/fixtures/test/{hello.rxml → hello.builder} +0 -0
  225. data/test/fixtures/test/{hello_world.rxml → hello_world.builder} +0 -0
  226. data/test/fixtures/test/{hello_world.rhtml → hello_world.erb} +0 -0
  227. data/test/fixtures/test/{hello_world_container.rxml → hello_world_container.builder} +0 -0
  228. data/test/fixtures/test/{hello_world_with_layout_false.rhtml → hello_world_with_layout_false.erb} +0 -0
  229. data/test/fixtures/test/{hello_xml_world.rxml → hello_xml_world.builder} +0 -0
  230. data/test/fixtures/test/list.erb +1 -0
  231. data/test/fixtures/test/{non_erb_block_content_for.rxml → non_erb_block_content_for.builder} +0 -0
  232. data/test/fixtures/test/{potential_conflicts.rhtml → potential_conflicts.erb} +0 -0
  233. data/test/fixtures/test/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
  234. data/test/fixtures/test/{render_file_with_locals.rhtml → render_file_with_locals.erb} +0 -0
  235. data/test/fixtures/test/{render_to_string_test.rhtml → render_to_string_test.erb} +0 -0
  236. data/test/fixtures/test/{update_element_with_capture.rhtml → update_element_with_capture.erb} +0 -0
  237. data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
  238. data/test/fixtures/topic.rb +1 -1
  239. data/test/template/active_record_helper_test.rb +67 -20
  240. data/test/template/asset_tag_helper_test.rb +222 -54
  241. data/test/template/atom_feed_helper_test.rb +101 -0
  242. data/test/template/benchmark_helper_test.rb +2 -2
  243. data/test/template/compiled_templates_test.rb +76 -32
  244. data/test/template/date_helper_test.rb +125 -9
  245. data/test/template/form_helper_test.rb +326 -33
  246. data/test/template/form_options_helper_test.rb +822 -15
  247. data/test/template/form_tag_helper_test.rb +96 -30
  248. data/test/template/javascript_helper_test.rb +61 -13
  249. data/test/template/number_helper_test.rb +12 -11
  250. data/test/template/prototype_helper_test.rb +185 -24
  251. data/test/template/sanitize_helper_test.rb +49 -0
  252. data/test/template/scriptaculous_helper_test.rb +9 -3
  253. data/test/template/tag_helper_test.rb +13 -2
  254. data/test/template/text_helper_test.rb +38 -52
  255. data/test/template/url_helper_test.rb +216 -46
  256. metadata +144 -116
  257. data/examples/.htaccess +0 -24
  258. data/examples/address_book/index.rhtml +0 -33
  259. data/examples/address_book/layout.rhtml +0 -8
  260. data/examples/address_book_controller.cgi +0 -9
  261. data/examples/address_book_controller.fcgi +0 -6
  262. data/examples/address_book_controller.rb +0 -52
  263. data/examples/address_book_controller.rbx +0 -4
  264. data/examples/benchmark.rb +0 -52
  265. data/examples/benchmark_with_ar.fcgi +0 -89
  266. data/examples/blog_controller.cgi +0 -53
  267. data/examples/debate/index.rhtml +0 -14
  268. data/examples/debate/new_topic.rhtml +0 -22
  269. data/examples/debate/topic.rhtml +0 -32
  270. data/examples/debate_controller.cgi +0 -57
  271. data/lib/action_controller/assertions/deprecated_assertions.rb +0 -228
  272. data/lib/action_controller/cgi_ext/cgi_ext.rb +0 -36
  273. data/lib/action_controller/cgi_ext/cgi_methods.rb +0 -211
  274. data/lib/action_controller/cgi_ext/pstore_performance_fix.rb +0 -30
  275. data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +0 -95
  276. data/lib/action_controller/cgi_ext/session_performance_fix.rb +0 -30
  277. data/lib/action_controller/deprecated_dependencies.rb +0 -65
  278. data/lib/action_controller/deprecated_redirects.rb +0 -17
  279. data/lib/action_controller/deprecated_request_methods.rb +0 -34
  280. data/lib/action_controller/macros/auto_complete.rb +0 -53
  281. data/lib/action_controller/macros/in_place_editing.rb +0 -33
  282. data/lib/action_controller/pagination.rb +0 -408
  283. data/lib/action_controller/scaffolding.rb +0 -189
  284. data/lib/action_controller/templates/rescues/_request_and_response.rhtml +0 -44
  285. data/lib/action_controller/templates/scaffolds/edit.rhtml +0 -7
  286. data/lib/action_controller/templates/scaffolds/layout.rhtml +0 -69
  287. data/lib/action_controller/templates/scaffolds/list.rhtml +0 -27
  288. data/lib/action_controller/templates/scaffolds/new.rhtml +0 -6
  289. data/lib/action_controller/templates/scaffolds/show.rhtml +0 -9
  290. data/lib/action_controller/vendor/xml_node.rb +0 -97
  291. data/lib/action_view/helpers/deprecated_helper.rb +0 -37
  292. data/lib/action_view/helpers/java_script_macros_helper.rb +0 -233
  293. data/lib/action_view/helpers/pagination_helper.rb +0 -86
  294. data/test/activerecord/active_record_assertions_test.rb +0 -92
  295. data/test/activerecord/pagination_test.rb +0 -165
  296. data/test/controller/deprecated_instance_variables_test.rb +0 -48
  297. data/test/controller/raw_post_test.rb +0 -68
  298. data/test/fixtures/deprecated_instance_variables/_cookies_ivar.rhtml +0 -1
  299. data/test/fixtures/deprecated_instance_variables/_cookies_method.rhtml +0 -1
  300. data/test/fixtures/deprecated_instance_variables/_flash_ivar.rhtml +0 -1
  301. data/test/fixtures/deprecated_instance_variables/_flash_method.rhtml +0 -1
  302. data/test/fixtures/deprecated_instance_variables/_headers_ivar.rhtml +0 -1
  303. data/test/fixtures/deprecated_instance_variables/_headers_method.rhtml +0 -1
  304. data/test/fixtures/deprecated_instance_variables/_params_ivar.rhtml +0 -1
  305. data/test/fixtures/deprecated_instance_variables/_params_method.rhtml +0 -1
  306. data/test/fixtures/deprecated_instance_variables/_request_ivar.rhtml +0 -1
  307. data/test/fixtures/deprecated_instance_variables/_request_method.rhtml +0 -1
  308. data/test/fixtures/deprecated_instance_variables/_response_ivar.rhtml +0 -1
  309. data/test/fixtures/deprecated_instance_variables/_response_method.rhtml +0 -1
  310. data/test/fixtures/deprecated_instance_variables/_session_ivar.rhtml +0 -1
  311. data/test/fixtures/deprecated_instance_variables/_session_method.rhtml +0 -1
  312. data/test/fixtures/respond_to/layouts/standard.rhtml +0 -1
  313. data/test/fixtures/test/_hash_object.rhtml +0 -1
  314. data/test/fixtures/test/list.rhtml +0 -1
  315. data/test/template/deprecated_helper_test.rb +0 -36
  316. data/test/template/deprecated_instance_variables_test.rb +0 -43
  317. data/test/template/java_script_macros_helper_test.rb +0 -109
@@ -75,23 +75,21 @@ class ControllerInstanceTests < Test::Unit::TestCase
75
75
  def test_action_methods
76
76
  @empty_controllers.each do |c|
77
77
  hide_mocha_methods_from_controller(c)
78
- assert_equal Set.new, c.send(:action_methods), "#{c.controller_path} should be empty!"
78
+ assert_equal Set.new, c.send!(:action_methods), "#{c.controller_path} should be empty!"
79
79
  end
80
80
  @non_empty_controllers.each do |c|
81
81
  hide_mocha_methods_from_controller(c)
82
- assert_equal Set.new('public_action'), c.send(:action_methods), "#{c.controller_path} should not be empty!"
82
+ assert_equal Set.new(%w(public_action)), c.send!(:action_methods), "#{c.controller_path} should not be empty!"
83
83
  end
84
84
  end
85
-
85
+
86
86
  protected
87
-
88
- # Mocha adds methods to Object which are then included in the public_instance_methods
89
- # This method hides those from the controller so the above tests won't know the difference
90
- def hide_mocha_methods_from_controller(controller)
91
- mocha_methods = [:expects, :metaclass, :mocha, :mocha_inspect, :reset_mocha, :stubba_object, :stubba_method, :stubs, :verify, :__is_a__, :__metaclass__]
92
- controller.class.send(:hide_action, *mocha_methods)
93
- end
94
-
87
+ # Mocha adds some public instance methods to Object that would be
88
+ # considered actions, so explicitly hide_action them.
89
+ def hide_mocha_methods_from_controller(controller)
90
+ mocha_methods = [:expects, :metaclass, :mocha, :mocha_inspect, :reset_mocha, :stubba_object, :stubba_method, :stubs, :verify, :__metaclass__, :__is_a__]
91
+ controller.class.send!(:hide_action, *mocha_methods)
92
+ end
95
93
  end
96
94
 
97
95
 
@@ -118,7 +116,7 @@ class PerformActionTest < Test::Unit::TestCase
118
116
 
119
117
  def test_method_missing_is_not_an_action_name
120
118
  use_controller MethodMissingController
121
- assert ! @controller.send(:action_methods).include?('method_missing')
119
+ assert ! @controller.send!(:action_methods).include?('method_missing')
122
120
 
123
121
  get :method_missing
124
122
  assert_response :success
@@ -133,4 +131,4 @@ class PerformActionTest < Test::Unit::TestCase
133
131
  get :another_hidden_action
134
132
  assert_response 404
135
133
  end
136
- end
134
+ end
@@ -2,9 +2,8 @@ require 'fileutils'
2
2
  require File.dirname(__FILE__) + '/../abstract_unit'
3
3
 
4
4
  CACHE_DIR = 'test_cache'
5
- # Don't change '/../temp/' cavalierly or you might hoze something you don't want hozed
5
+ # Don't change '/../temp/' cavalierly or you might hose something you don't want hosed
6
6
  FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR)
7
- ActionController::Base.perform_caching = true
8
7
  ActionController::Base.page_cache_directory = FILE_STORE_PATH
9
8
  ActionController::Base.fragment_cache_store = :file_store, FILE_STORE_PATH
10
9
 
@@ -26,10 +25,26 @@ class PageCachingTestController < ActionController::Base
26
25
  def not_found
27
26
  head :not_found
28
27
  end
28
+
29
+ def custom_path
30
+ render :text => "Super soaker"
31
+ cache_page("Super soaker", "/index.html")
32
+ end
33
+
34
+ def expire_custom_path
35
+ expire_page("/index.html")
36
+ head :ok
37
+ end
38
+
39
+ def trailing_slash
40
+ render :text => "Sneak attack"
41
+ end
29
42
  end
30
43
 
31
44
  class PageCachingTest < Test::Unit::TestCase
32
45
  def setup
46
+ ActionController::Base.perform_caching = true
47
+
33
48
  ActionController::Routing::Routes.draw do |map|
34
49
  map.main '', :controller => 'posts'
35
50
  map.resources :posts
@@ -51,6 +66,8 @@ class PageCachingTest < Test::Unit::TestCase
51
66
 
52
67
  def teardown
53
68
  FileUtils.rm_rf(File.dirname(FILE_STORE_PATH))
69
+
70
+ ActionController::Base.perform_caching = false
54
71
  end
55
72
 
56
73
  def test_page_caching_resources_saves_to_correct_path_with_extension_even_if_default_route
@@ -66,6 +83,38 @@ class PageCachingTest < Test::Unit::TestCase
66
83
  assert_page_cached :ok, "get with ok status should have been cached"
67
84
  end
68
85
 
86
+ def test_should_cache_with_custom_path
87
+ get :custom_path
88
+ assert File.exist?("#{FILE_STORE_PATH}/index.html")
89
+ end
90
+
91
+ def test_should_expire_cache_with_custom_path
92
+ get :custom_path
93
+ assert File.exist?("#{FILE_STORE_PATH}/index.html")
94
+
95
+ get :expire_custom_path
96
+ assert !File.exist?("#{FILE_STORE_PATH}/index.html")
97
+ end
98
+
99
+ def test_should_cache_without_trailing_slash_on_url
100
+ @controller.class.cache_page 'cached content', '/page_caching_test/trailing_slash'
101
+ assert File.exist?("#{FILE_STORE_PATH}/page_caching_test/trailing_slash.html")
102
+ end
103
+
104
+ def test_should_cache_with_trailing_slash_on_url
105
+ @controller.class.cache_page 'cached content', '/page_caching_test/trailing_slash/'
106
+ assert File.exist?("#{FILE_STORE_PATH}/page_caching_test/trailing_slash.html")
107
+ end
108
+
109
+ uses_mocha("should_cache_ok_at_custom_path") do
110
+ def test_should_cache_ok_at_custom_path
111
+ @request.expects(:path).returns("/index.html")
112
+ get :ok
113
+ assert_response :ok
114
+ assert File.exist?("#{FILE_STORE_PATH}/index.html")
115
+ end
116
+ end
117
+
69
118
  [:ok, :no_content, :found, :not_found].each do |status|
70
119
  [:get, :post, :put, :delete].each do |method|
71
120
  unless method == :get and status == :ok
@@ -93,15 +142,29 @@ class PageCachingTest < Test::Unit::TestCase
93
142
  end
94
143
  end
95
144
 
145
+
96
146
  class ActionCachingTestController < ActionController::Base
97
- caches_action :index
147
+ caches_action :index, :redirected, :forbidden
148
+ caches_action :show, :cache_path => 'http://test.host/custom/show'
149
+ caches_action :edit, :cache_path => Proc.new { |c| c.params[:id] ? "http://test.host/#{c.params[:id]};edit" : "http://test.host/edit" }
98
150
 
99
151
  def index
100
- sleep 0.01
101
152
  @cache_this = Time.now.to_f.to_s
102
153
  render :text => @cache_this
103
154
  end
104
155
 
156
+ def redirected
157
+ redirect_to :action => 'index'
158
+ end
159
+
160
+ def forbidden
161
+ render :text => "Forbidden"
162
+ headers["Status"] = "403 Forbidden"
163
+ end
164
+
165
+ alias_method :show, :index
166
+ alias_method :edit, :index
167
+
105
168
  def expire
106
169
  expire_action :controller => 'action_caching_test', :action => 'index'
107
170
  render :nothing => true
@@ -146,11 +209,32 @@ class ActionCacheTest < Test::Unit::TestCase
146
209
  get :index
147
210
  cached_time = content_to_cache
148
211
  assert_equal cached_time, @response.body
212
+ assert_cache_exists 'hostname.com/action_caching_test'
149
213
  reset!
150
214
 
151
215
  get :index
152
216
  assert_equal cached_time, @response.body
153
217
  end
218
+
219
+ def test_action_cache_with_custom_cache_path
220
+ get :show
221
+ cached_time = content_to_cache
222
+ assert_equal cached_time, @response.body
223
+ assert_cache_exists 'test.host/custom/show'
224
+ reset!
225
+
226
+ get :show
227
+ assert_equal cached_time, @response.body
228
+ end
229
+
230
+ def test_action_cache_with_custom_cache_path_in_block
231
+ get :edit
232
+ assert_cache_exists 'test.host/edit'
233
+ reset!
234
+
235
+ get :edit, :id => 1
236
+ assert_cache_exists 'test.host/1;edit'
237
+ end
154
238
 
155
239
  def test_cache_expiration
156
240
  get :index
@@ -178,21 +262,45 @@ class ActionCacheTest < Test::Unit::TestCase
178
262
  @request.host = 'jamis.hostname.com'
179
263
  get :index
180
264
  jamis_cache = content_to_cache
181
-
265
+
266
+ reset!
267
+
182
268
  @request.host = 'david.hostname.com'
183
269
  get :index
184
270
  david_cache = content_to_cache
185
271
  assert_not_equal jamis_cache, @response.body
186
272
 
273
+ reset!
274
+
187
275
  @request.host = 'jamis.hostname.com'
188
276
  get :index
189
277
  assert_equal jamis_cache, @response.body
190
278
 
279
+ reset!
280
+
191
281
  @request.host = 'david.hostname.com'
192
282
  get :index
193
283
  assert_equal david_cache, @response.body
194
284
  end
195
285
 
286
+ def test_redirect_is_not_cached
287
+ get :redirected
288
+ assert_response :redirect
289
+ reset!
290
+
291
+ get :redirected
292
+ assert_response :redirect
293
+ end
294
+
295
+ def test_forbidden_is_not_cached
296
+ get :forbidden
297
+ assert_response :forbidden
298
+ reset!
299
+
300
+ get :forbidden
301
+ assert_response :forbidden
302
+ end
303
+
196
304
  def test_xml_version_of_resource_is_treated_as_different_cache
197
305
  @mock_controller.mock_url_for = 'http://example.org/posts/'
198
306
  @mock_controller.mock_path = '/posts/index.xml'
@@ -200,6 +308,13 @@ class ActionCacheTest < Test::Unit::TestCase
200
308
  assert_equal 'xml', path_object.extension
201
309
  assert_equal 'example.org/posts/index.xml', path_object.path
202
310
  end
311
+
312
+ def test_correct_content_type_is_returned_for_cache_hit
313
+ # run it twice to cache it the first time
314
+ get :index, :id => 'content-type.xml'
315
+ get :index, :id => 'content-type.xml'
316
+ assert_equal 'application/xml', @response.content_type
317
+ end
203
318
 
204
319
  def test_empty_path_is_normalized
205
320
  @mock_controller.mock_url_for = 'http://example.org/'
@@ -226,4 +341,9 @@ class ActionCacheTest < Test::Unit::TestCase
226
341
  @controller = ActionCachingTestController.new
227
342
  @request.host = 'hostname.com'
228
343
  end
344
+
345
+ def assert_cache_exists(path)
346
+ full_path = File.join(FILE_STORE_PATH, path + '.cache')
347
+ assert File.exist?(full_path), "#{full_path.inspect} does not exist."
348
+ end
229
349
  end
@@ -8,6 +8,14 @@ class CaptureController < ActionController::Base
8
8
  render :layout => "talk_from_action"
9
9
  end
10
10
 
11
+ def content_for_with_parameter
12
+ render :layout => "talk_from_action"
13
+ end
14
+
15
+ def content_for_concatenated
16
+ render :layout => "talk_from_action"
17
+ end
18
+
11
19
  def erb_content_for
12
20
  render :layout => "talk_from_action"
13
21
  end
@@ -23,7 +31,7 @@ class CaptureController < ActionController::Base
23
31
  def rescue_action(e) raise end
24
32
  end
25
33
 
26
- CaptureController.template_root = File.dirname(__FILE__) + "/../fixtures/"
34
+ CaptureController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
27
35
 
28
36
  class CaptureTest < Test::Unit::TestCase
29
37
  def setup
@@ -49,8 +57,18 @@ class CaptureTest < Test::Unit::TestCase
49
57
  assert_equal expected_content_for_output, @response.body
50
58
  end
51
59
 
60
+ def test_should_concatentate_content_for
61
+ get :content_for_concatenated
62
+ assert_equal expected_content_for_output, @response.body
63
+ end
64
+
52
65
  def test_erb_content_for
53
- get :content_for
66
+ get :erb_content_for
67
+ assert_equal expected_content_for_output, @response.body
68
+ end
69
+
70
+ def test_should_set_content_for_with_parameter
71
+ get :content_for_with_parameter
54
72
  assert_equal expected_content_for_output, @response.body
55
73
  end
56
74
 
@@ -64,19 +82,8 @@ class CaptureTest < Test::Unit::TestCase
64
82
  assert_equal expected_content_for_output, @response.body
65
83
  end
66
84
 
67
- def test_update_element_with_capture
68
- assert_deprecated 'update_element_function' do
69
- get :update_element_with_capture
70
- end
71
- assert_equal(
72
- "<script type=\"text/javascript\">\n//<![CDATA[\n$('products').innerHTML = '\\n <p>Product 1</p>\\n <p>Product 2</p>\\n';\n\n//]]>\n</script>" +
73
- "\n\n$('status').innerHTML = '\\n <b>You bought something!</b>\\n';",
74
- @response.body.strip
75
- )
76
- end
77
-
78
85
  private
79
- def expected_content_for_output
80
- "<title>Putting stuff in the title!</title>\n\nGreat stuff!"
81
- end
86
+ def expected_content_for_output
87
+ "<title>Putting stuff in the title!</title>\n\nGreat stuff!"
88
+ end
82
89
  end
@@ -1,381 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../abstract_unit'
2
2
  require 'action_controller/cgi_process'
3
- require 'action_controller/cgi_ext/cgi_ext'
4
-
5
-
6
- require 'stringio'
7
-
8
- class CGITest < Test::Unit::TestCase
9
- def setup
10
- @query_string = "action=create_customer&full_name=David%20Heinemeier%20Hansson&customerId=1"
11
- @query_string_with_nil = "action=create_customer&full_name="
12
- @query_string_with_array = "action=create_customer&selected[]=1&selected[]=2&selected[]=3"
13
- @query_string_with_amps = "action=create_customer&name=Don%27t+%26+Does"
14
- @query_string_with_multiple_of_same_name =
15
- "action=update_order&full_name=Lau%20Taarnskov&products=4&products=2&products=3"
16
- @query_string_with_many_equal = "action=create_customer&full_name=abc=def=ghi"
17
- @query_string_without_equal = "action"
18
- @query_string_with_many_ampersands =
19
- "&action=create_customer&&&full_name=David%20Heinemeier%20Hansson"
20
- @query_string_with_empty_key = "action=create_customer&full_name=David%20Heinemeier%20Hansson&=Save"
21
- end
22
-
23
- def test_query_string
24
- assert_equal(
25
- { "action" => "create_customer", "full_name" => "David Heinemeier Hansson", "customerId" => "1"},
26
- CGIMethods.parse_query_parameters(@query_string)
27
- )
28
- end
29
-
30
- def test_deep_query_string
31
- expected = {'x' => {'y' => {'z' => '10'}}}
32
- assert_equal(expected, CGIMethods.parse_query_parameters('x[y][z]=10'))
33
- end
34
-
35
- def test_deep_query_string_with_array
36
- assert_equal({'x' => {'y' => {'z' => ['10']}}}, CGIMethods.parse_query_parameters('x[y][z][]=10'))
37
- assert_equal({'x' => {'y' => {'z' => ['10', '5']}}}, CGIMethods.parse_query_parameters('x[y][z][]=10&x[y][z][]=5'))
38
- end
39
-
40
- def test_deep_query_string_with_array_of_hash
41
- assert_equal({'x' => {'y' => [{'z' => '10'}]}}, CGIMethods.parse_query_parameters('x[y][][z]=10'))
42
- assert_equal({'x' => {'y' => [{'z' => '10', 'w' => '10'}]}}, CGIMethods.parse_query_parameters('x[y][][z]=10&x[y][][w]=10'))
43
- end
44
-
45
- def test_deep_query_string_with_array_of_hashes_with_one_pair
46
- assert_equal({'x' => {'y' => [{'z' => '10'}, {'z' => '20'}]}}, CGIMethods.parse_query_parameters('x[y][][z]=10&x[y][][z]=20'))
47
- assert_equal("10", CGIMethods.parse_query_parameters('x[y][][z]=10&x[y][][z]=20')["x"]["y"].first["z"])
48
- assert_equal("10", CGIMethods.parse_query_parameters('x[y][][z]=10&x[y][][z]=20').with_indifferent_access[:x][:y].first[:z])
49
- end
50
-
51
- def test_request_hash_parsing
52
- query = {
53
- "note[viewers][viewer][][type]" => ["User", "Group"],
54
- "note[viewers][viewer][][id]" => ["1", "2"]
55
- }
56
-
57
- expected = { "note" => { "viewers"=>{"viewer"=>[{ "id"=>"1", "type"=>"User"}, {"type"=>"Group", "id"=>"2"} ]} } }
58
-
59
- assert_equal(expected, CGIMethods.parse_request_parameters(query))
60
- end
61
-
62
- def test_deep_query_string_with_array_of_hashes_with_multiple_pairs
63
- assert_equal(
64
- {'x' => {'y' => [{'z' => '10', 'w' => 'a'}, {'z' => '20', 'w' => 'b'}]}},
65
- CGIMethods.parse_query_parameters('x[y][][z]=10&x[y][][w]=a&x[y][][z]=20&x[y][][w]=b')
66
- )
67
- end
68
-
69
- def test_query_string_with_nil
70
- assert_equal(
71
- { "action" => "create_customer", "full_name" => nil},
72
- CGIMethods.parse_query_parameters(@query_string_with_nil)
73
- )
74
- end
75
-
76
- def test_query_string_with_array
77
- assert_equal(
78
- { "action" => "create_customer", "selected" => ["1", "2", "3"]},
79
- CGIMethods.parse_query_parameters(@query_string_with_array)
80
- )
81
- end
82
-
83
- def test_query_string_with_amps
84
- assert_equal(
85
- { "action" => "create_customer", "name" => "Don't & Does"},
86
- CGIMethods.parse_query_parameters(@query_string_with_amps)
87
- )
88
- end
89
-
90
- def test_query_string_with_many_equal
91
- assert_equal(
92
- { "action" => "create_customer", "full_name" => "abc=def=ghi"},
93
- CGIMethods.parse_query_parameters(@query_string_with_many_equal)
94
- )
95
- end
96
-
97
- def test_query_string_without_equal
98
- assert_equal(
99
- { "action" => nil },
100
- CGIMethods.parse_query_parameters(@query_string_without_equal)
101
- )
102
- end
103
-
104
- def test_query_string_with_empty_key
105
- assert_equal(
106
- { "action" => "create_customer", "full_name" => "David Heinemeier Hansson" },
107
- CGIMethods.parse_query_parameters(@query_string_with_empty_key)
108
- )
109
- end
110
-
111
- def test_query_string_with_many_ampersands
112
- assert_equal(
113
- { "action" => "create_customer", "full_name" => "David Heinemeier Hansson"},
114
- CGIMethods.parse_query_parameters(@query_string_with_many_ampersands)
115
- )
116
- end
117
-
118
- def test_parse_params
119
- input = {
120
- "customers[boston][first][name]" => [ "David" ],
121
- "customers[boston][first][url]" => [ "http://David" ],
122
- "customers[boston][second][name]" => [ "Allan" ],
123
- "customers[boston][second][url]" => [ "http://Allan" ],
124
- "something_else" => [ "blah" ],
125
- "something_nil" => [ nil ],
126
- "something_empty" => [ "" ],
127
- "products[first]" => [ "Apple Computer" ],
128
- "products[second]" => [ "Pc" ],
129
- "" => [ 'Save' ]
130
- }
131
-
132
- expected_output = {
133
- "customers" => {
134
- "boston" => {
135
- "first" => {
136
- "name" => "David",
137
- "url" => "http://David"
138
- },
139
- "second" => {
140
- "name" => "Allan",
141
- "url" => "http://Allan"
142
- }
143
- }
144
- },
145
- "something_else" => "blah",
146
- "something_empty" => "",
147
- "something_nil" => "",
148
- "products" => {
149
- "first" => "Apple Computer",
150
- "second" => "Pc"
151
- }
152
- }
153
-
154
- assert_equal expected_output, CGIMethods.parse_request_parameters(input)
155
- end
156
-
157
- def test_parse_params_from_multipart_upload
158
- mockup = Struct.new(:content_type, :original_filename, :read, :rewind)
159
- file = mockup.new('img/jpeg', 'foo.jpg')
160
- ie_file = mockup.new('img/jpeg', 'c:\\Documents and Settings\\foo\\Desktop\\bar.jpg')
161
- non_file_text_part = mockup.new('text/plain', '', 'abc')
162
-
163
- input = {
164
- "something" => [ StringIO.new("") ],
165
- "array_of_stringios" => [[ StringIO.new("One"), StringIO.new("Two") ]],
166
- "mixed_types_array" => [[ StringIO.new("Three"), "NotStringIO" ]],
167
- "mixed_types_as_checkboxes[strings][nested]" => [[ file, "String", StringIO.new("StringIO")]],
168
- "ie_mixed_types_as_checkboxes[strings][nested]" => [[ ie_file, "String", StringIO.new("StringIO")]],
169
- "products[string]" => [ StringIO.new("Apple Computer") ],
170
- "products[file]" => [ file ],
171
- "ie_products[string]" => [ StringIO.new("Microsoft") ],
172
- "ie_products[file]" => [ ie_file ],
173
- "text_part" => [non_file_text_part]
174
- }
175
-
176
- expected_output = {
177
- "something" => "",
178
- "array_of_stringios" => ["One", "Two"],
179
- "mixed_types_array" => [ "Three", "NotStringIO" ],
180
- "mixed_types_as_checkboxes" => {
181
- "strings" => {
182
- "nested" => [ file, "String", "StringIO" ]
183
- },
184
- },
185
- "ie_mixed_types_as_checkboxes" => {
186
- "strings" => {
187
- "nested" => [ ie_file, "String", "StringIO" ]
188
- },
189
- },
190
- "products" => {
191
- "string" => "Apple Computer",
192
- "file" => file
193
- },
194
- "ie_products" => {
195
- "string" => "Microsoft",
196
- "file" => ie_file
197
- },
198
- "text_part" => "abc"
199
- }
200
-
201
- params = CGIMethods.parse_request_parameters(input)
202
- assert_equal expected_output, params
203
-
204
- # Lone filenames are preserved.
205
- assert_equal 'foo.jpg', params['mixed_types_as_checkboxes']['strings']['nested'].first.original_filename
206
- assert_equal 'foo.jpg', params['products']['file'].original_filename
207
-
208
- # But full Windows paths are reduced to their basename.
209
- assert_equal 'bar.jpg', params['ie_mixed_types_as_checkboxes']['strings']['nested'].first.original_filename
210
- assert_equal 'bar.jpg', params['ie_products']['file'].original_filename
211
- end
212
-
213
- def test_parse_params_with_file
214
- input = {
215
- "customers[boston][first][name]" => [ "David" ],
216
- "something_else" => [ "blah" ],
217
- "logo" => [ File.new(File.dirname(__FILE__) + "/cgi_test.rb").path ]
218
- }
219
-
220
- expected_output = {
221
- "customers" => {
222
- "boston" => {
223
- "first" => {
224
- "name" => "David"
225
- }
226
- }
227
- },
228
- "something_else" => "blah",
229
- "logo" => File.new(File.dirname(__FILE__) + "/cgi_test.rb").path,
230
- }
231
-
232
- assert_equal expected_output, CGIMethods.parse_request_parameters(input)
233
- end
234
-
235
- def test_parse_params_with_array
236
- input = { "selected[]" => [ "1", "2", "3" ] }
237
-
238
- expected_output = { "selected" => [ "1", "2", "3" ] }
239
-
240
- assert_equal expected_output, CGIMethods.parse_request_parameters(input)
241
- end
242
-
243
- def test_parse_params_with_non_alphanumeric_name
244
- input = { "a/b[c]" => %w(d) }
245
- expected = { "a/b" => { "c" => "d" }}
246
- assert_equal expected, CGIMethods.parse_request_parameters(input)
247
- end
248
-
249
- def test_parse_params_with_single_brackets_in_middle
250
- input = { "a/b[c]d" => %w(e) }
251
- expected = { "a/b" => {} }
252
- assert_equal expected, CGIMethods.parse_request_parameters(input)
253
- end
254
-
255
- def test_parse_params_with_separated_brackets
256
- input = { "a/b@[c]d[e]" => %w(f) }
257
- expected = { "a/b@" => { }}
258
- assert_equal expected, CGIMethods.parse_request_parameters(input)
259
- end
260
-
261
- def test_parse_params_with_separated_brackets_and_array
262
- input = { "a/b@[c]d[e][]" => %w(f) }
263
- expected = { "a/b@" => { }}
264
- assert_equal expected , CGIMethods.parse_request_parameters(input)
265
- end
266
-
267
- def test_parse_params_with_unmatched_brackets_and_array
268
- input = { "a/b@[c][d[e][]" => %w(f) }
269
- expected = { "a/b@" => { "c" => { }}}
270
- assert_equal expected, CGIMethods.parse_request_parameters(input)
271
- end
272
-
273
- def test_parse_params_with_nil_key
274
- input = { nil => nil, "test2" => %w(value1) }
275
- expected = { "test2" => "value1" }
276
- assert_equal expected, CGIMethods.parse_request_parameters(input)
277
- end
278
- end
279
-
280
-
281
- class MultipartCGITest < Test::Unit::TestCase
282
- FIXTURE_PATH = File.dirname(__FILE__) + '/../fixtures/multipart'
283
3
 
284
- def setup
285
- ENV['REQUEST_METHOD'] = 'POST'
286
- ENV['CONTENT_LENGTH'] = '0'
287
- ENV['CONTENT_TYPE'] = 'multipart/form-data, boundary=AaB03x'
288
- end
289
-
290
- def test_single_parameter
291
- params = process('single_parameter')
292
- assert_equal({ 'foo' => 'bar' }, params)
293
- end
294
-
295
- def test_text_file
296
- params = process('text_file')
297
- assert_equal %w(file foo), params.keys.sort
298
- assert_equal 'bar', params['foo']
299
-
300
- file = params['file']
301
- assert_kind_of StringIO, file
302
- assert_equal 'file.txt', file.original_filename
303
- assert_equal "text/plain\r", file.content_type
304
- assert_equal 'contents', file.read
305
- end
306
-
307
- def test_large_text_file
308
- params = process('large_text_file')
309
- assert_equal %w(file foo), params.keys.sort
310
- assert_equal 'bar', params['foo']
311
-
312
- file = params['file']
313
- assert_kind_of Tempfile, file
314
- assert_equal 'file.txt', file.original_filename
315
- assert_equal "text/plain\r", file.content_type
316
- assert ('a' * 20480) == file.read
317
- end
318
-
319
- def test_binary_file
320
- params = process('binary_file')
321
- assert_equal %w(file flowers foo), params.keys.sort
322
- assert_equal 'bar', params['foo']
323
-
324
- file = params['file']
325
- assert_kind_of StringIO, file
326
- assert_equal 'file.txt', file.original_filename
327
- assert_equal "text/plain\r", file.content_type
328
- assert_equal 'contents', file.read
329
-
330
- file = params['flowers']
331
- assert_kind_of StringIO, file
332
- assert_equal 'flowers.jpg', file.original_filename
333
- assert_equal "image/jpeg\r", file.content_type
334
- assert_equal 19512, file.size
335
- #assert_equal File.read(File.dirname(__FILE__) + '/../../../activerecord/test/fixtures/flowers.jpg'), file.read
336
- end
337
-
338
- def test_mixed_files
339
- params = process('mixed_files')
340
- assert_equal %w(files foo), params.keys.sort
341
- assert_equal 'bar', params['foo']
342
-
343
- # Ruby CGI doesn't handle multipart/mixed for us.
344
- assert_kind_of String, params['files']
345
- assert_equal 19756, params['files'].size
346
- end
347
-
348
- # Rewind readable cgi params so others may reread them (such as CGI::Session
349
- # when passing the session id in a multipart form).
350
- def test_multipart_param_rewound
351
- params = process('text_file')
352
- assert_equal 'bar', @cgi.params['foo'][0].read
353
- end
354
-
355
- private
356
- def process(name)
357
- old_stdin = $stdin
358
- File.open(File.join(FIXTURE_PATH, name), 'rb') do |file|
359
- ENV['CONTENT_LENGTH'] = file.stat.size.to_s
360
- $stdin = file
361
- @cgi = CGI.new
362
- CGIMethods.parse_request_parameters @cgi.params
363
- end
364
- ensure
365
- $stdin = old_stdin
366
- end
367
- end
368
-
369
- # Ensures that PUT works with multipart as well as POST.
370
- class PutMultipartCGITest < MultipartCGITest
371
- def setup
372
- super
373
- ENV['REQUEST_METHOD'] = 'PUT'
374
- end
375
- end
376
-
377
-
378
- class CGIRequestTest < Test::Unit::TestCase
4
+ class BaseCgiTest < Test::Unit::TestCase
379
5
  def setup
380
6
  @request_hash = {"HTTP_MAX_FORWARDS"=>"10", "SERVER_NAME"=>"glu.ttono.us:8007", "FCGI_ROLE"=>"RESPONDER", "HTTP_X_FORWARDED_HOST"=>"glu.ttono.us", "HTTP_ACCEPT_ENCODING"=>"gzip, deflate", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/312.5.1 (KHTML, like Gecko) Safari/312.3.1", "PATH_INFO"=>"", "HTTP_ACCEPT_LANGUAGE"=>"en", "HTTP_HOST"=>"glu.ttono.us:8007", "SERVER_PROTOCOL"=>"HTTP/1.1", "REDIRECT_URI"=>"/dispatch.fcgi", "SCRIPT_NAME"=>"/dispatch.fcgi", "SERVER_ADDR"=>"207.7.108.53", "REMOTE_ADDR"=>"207.7.108.53", "SERVER_SOFTWARE"=>"lighttpd/1.4.5", "HTTP_COOKIE"=>"_session_id=c84ace84796670c052c6ceb2451fb0f2; is_admin=yes", "HTTP_X_FORWARDED_SERVER"=>"glu.ttono.us", "REQUEST_URI"=>"/admin", "DOCUMENT_ROOT"=>"/home/kevinc/sites/typo/public", "SERVER_PORT"=>"8007", "QUERY_STRING"=>"", "REMOTE_PORT"=>"63137", "GATEWAY_INTERFACE"=>"CGI/1.1", "HTTP_X_FORWARDED_FOR"=>"65.88.180.234", "HTTP_ACCEPT"=>"*/*", "SCRIPT_FILENAME"=>"/home/kevinc/sites/typo/public/dispatch.fcgi", "REDIRECT_STATUS"=>"200", "REQUEST_METHOD"=>"GET"}
381
7
  # cookie as returned by some Nokia phone browsers (no space after semicolon separator)
@@ -383,20 +9,25 @@ class CGIRequestTest < Test::Unit::TestCase
383
9
  @fake_cgi = Struct.new(:env_table).new(@request_hash)
384
10
  @request = ActionController::CgiRequest.new(@fake_cgi)
385
11
  end
386
-
12
+
13
+ def default_test; end
14
+ end
15
+
16
+
17
+ class CgiRequestTest < BaseCgiTest
387
18
  def test_proxy_request
388
19
  assert_equal 'glu.ttono.us', @request.host_with_port
389
20
  end
390
-
21
+
391
22
  def test_http_host
392
23
  @request_hash.delete "HTTP_X_FORWARDED_HOST"
393
24
  @request_hash['HTTP_HOST'] = "rubyonrails.org:8080"
394
25
  assert_equal "rubyonrails.org:8080", @request.host_with_port
395
-
26
+
396
27
  @request_hash['HTTP_X_FORWARDED_HOST'] = "www.firsthost.org, www.secondhost.org"
397
28
  assert_equal "www.secondhost.org", @request.host
398
29
  end
399
-
30
+
400
31
  def test_http_host_with_default_port_overrides_server_port
401
32
  @request_hash.delete "HTTP_X_FORWARDED_HOST"
402
33
  @request_hash['HTTP_HOST'] = "rubyonrails.org"
@@ -416,25 +47,69 @@ class CGIRequestTest < Test::Unit::TestCase
416
47
  assert_equal "207.7.108.53:8007", @request.host_with_port
417
48
  end
418
49
 
50
+ def test_host_with_port_if_http_standard_port_is_specified
51
+ @request_hash['HTTP_X_FORWARDED_HOST'] = "glu.ttono.us:80"
52
+ assert_equal "glu.ttono.us", @request.host_with_port
53
+ end
54
+
55
+ def test_host_with_port_if_https_standard_port_is_specified
56
+ @request_hash['HTTP_X_FORWARDED_PROTO'] = "https"
57
+ @request_hash['HTTP_X_FORWARDED_HOST'] = "glu.ttono.us:443"
58
+ assert_equal "glu.ttono.us", @request.host_with_port
59
+ end
60
+
61
+ def test_host_if_ipv6_reference
62
+ @request_hash.delete "HTTP_X_FORWARDED_HOST"
63
+ @request_hash['HTTP_HOST'] = "[2001:1234:5678:9abc:def0::dead:beef]"
64
+ assert_equal "[2001:1234:5678:9abc:def0::dead:beef]", @request.host
65
+ end
66
+
67
+ def test_host_if_ipv6_reference_with_port
68
+ @request_hash.delete "HTTP_X_FORWARDED_HOST"
69
+ @request_hash['HTTP_HOST'] = "[2001:1234:5678:9abc:def0::dead:beef]:8008"
70
+ assert_equal "[2001:1234:5678:9abc:def0::dead:beef]", @request.host
71
+ end
72
+
419
73
  def test_cookie_syntax_resilience
420
74
  cookies = CGI::Cookie::parse(@request_hash["HTTP_COOKIE"]);
421
75
  assert_equal ["c84ace84796670c052c6ceb2451fb0f2"], cookies["_session_id"]
422
76
  assert_equal ["yes"], cookies["is_admin"]
423
-
77
+
424
78
  alt_cookies = CGI::Cookie::parse(@alt_cookie_fmt_request_hash["HTTP_COOKIE"]);
425
79
  assert_equal ["c84ace84796670c052c6ceb2451fb0f2"], alt_cookies["_session_id"]
426
80
  assert_equal ["yes"], alt_cookies["is_admin"]
427
81
  end
428
-
429
- def test_unbalanced_query_string_with_array
430
- assert_equal(
431
- {'location' => ["1", "2"], 'age_group' => ["2"]},
432
- CGIMethods.parse_query_parameters("location[]=1&location[]=2&age_group[]=2")
433
- )
434
- assert_equal(
435
- {'location' => ["1", "2"], 'age_group' => ["2"]},
436
- CGIMethods.parse_request_parameters({'location[]' => ["1", "2"],
437
- 'age_group[]' => ["2"]})
438
- )
82
+ end
83
+
84
+
85
+ class CgiRequestParamsParsingTest < BaseCgiTest
86
+ def test_doesnt_break_when_content_type_has_charset
87
+ data = 'flamenco=love'
88
+ @request.env['CONTENT_LENGTH'] = data.length
89
+ @request.env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8'
90
+ @request.env['RAW_POST_DATA'] = data
91
+ assert_equal({"flamenco"=> "love"}, @request.request_parameters)
92
+ end
93
+
94
+ def test_doesnt_interpret_request_uri_as_query_string_when_missing
95
+ @request.env['REQUEST_URI'] = 'foo'
96
+ assert_equal({}, @request.query_parameters)
97
+ end
98
+ end
99
+
100
+
101
+ class CgiRequestNeedsRewoundTest < BaseCgiTest
102
+ def test_body_should_be_rewound
103
+ data = 'foo'
104
+ fake_cgi = Struct.new(:env_table, :query_string, :stdinput).new(@request_hash, '', StringIO.new(data))
105
+ fake_cgi.env_table['CONTENT_LENGTH'] = data.length
106
+ fake_cgi.env_table['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8'
107
+
108
+ # Read the request body by parsing params.
109
+ request = ActionController::CgiRequest.new(fake_cgi)
110
+ request.request_parameters
111
+
112
+ # Should have rewound the body.
113
+ assert_equal 0, request.body.pos
439
114
  end
440
115
  end