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
@@ -29,6 +29,9 @@ class RequestTest < Test::Unit::TestCase
29
29
 
30
30
  @request.env['HTTP_X_FORWARDED_FOR'] = '10.0.0.1,3.4.5.6'
31
31
  assert_equal '3.4.5.6', @request.remote_ip
32
+
33
+ @request.env['HTTP_X_FORWARDED_FOR'] = '10.0.0.1, 10.0.0.1, 3.4.5.6'
34
+ assert_equal '3.4.5.6', @request.remote_ip
32
35
 
33
36
  @request.env['HTTP_X_FORWARDED_FOR'] = '127.0.0.1,3.4.5.6'
34
37
  assert_equal '127.0.0.1', @request.remote_ip
@@ -44,10 +47,16 @@ class RequestTest < Test::Unit::TestCase
44
47
 
45
48
  @request.host = "www.rubyonrails.co.uk"
46
49
  assert_equal "rubyonrails.co.uk", @request.domain(2)
47
-
50
+
48
51
  @request.host = "192.168.1.200"
49
52
  assert_nil @request.domain
50
53
 
54
+ @request.host = "foo.192.168.1.200"
55
+ assert_nil @request.domain
56
+
57
+ @request.host = "192.168.1.200.com"
58
+ assert_equal "200.com", @request.domain
59
+
51
60
  @request.host = nil
52
61
  assert_nil @request.domain
53
62
  end
@@ -65,10 +74,19 @@ class RequestTest < Test::Unit::TestCase
65
74
  @request.host = "foobar.foobar.com"
66
75
  assert_equal %w( foobar ), @request.subdomains
67
76
 
77
+ @request.host = "192.168.1.200"
78
+ assert_equal [], @request.subdomains
79
+
80
+ @request.host = "foo.192.168.1.200"
81
+ assert_equal [], @request.subdomains
82
+
83
+ @request.host = "192.168.1.200.com"
84
+ assert_equal %w( 192 168 1 ), @request.subdomains
85
+
68
86
  @request.host = nil
69
87
  assert_equal [], @request.subdomains
70
88
  end
71
-
89
+
72
90
  def test_port_string
73
91
  @request.port = 80
74
92
  assert_equal "", @request.port_string
@@ -76,14 +94,14 @@ class RequestTest < Test::Unit::TestCase
76
94
  @request.port = 8080
77
95
  assert_equal ":8080", @request.port_string
78
96
  end
79
-
97
+
80
98
  def test_relative_url_root
81
99
  @request.env['SCRIPT_NAME'] = "/hieraki/dispatch.cgi"
82
100
  @request.env['SERVER_SOFTWARE'] = 'lighttpd/1.2.3'
83
101
  assert_equal '', @request.relative_url_root, "relative_url_root should be disabled on lighttpd"
84
102
 
85
103
  @request.env['SERVER_SOFTWARE'] = 'apache/1.2.3 some random text'
86
-
104
+
87
105
  @request.env['SCRIPT_NAME'] = nil
88
106
  assert_equal "", @request.relative_url_root
89
107
 
@@ -99,19 +117,19 @@ class RequestTest < Test::Unit::TestCase
99
117
 
100
118
  @request.relative_url_root = nil
101
119
  @request.env['SCRIPT_NAME'] = "/collaboration/hieraki/dispatch.cgi"
102
- assert_equal "/collaboration/hieraki", @request.relative_url_root
103
-
120
+ assert_equal "/collaboration/hieraki", @request.relative_url_root
121
+
104
122
  # apache/scgi case
105
123
  @request.relative_url_root = nil
106
124
  @request.env['SCRIPT_NAME'] = "/collaboration/hieraki"
107
- assert_equal "/collaboration/hieraki", @request.relative_url_root
108
-
125
+ assert_equal "/collaboration/hieraki", @request.relative_url_root
126
+
109
127
  @request.relative_url_root = nil
110
128
  @request.env['SCRIPT_NAME'] = "/hieraki/dispatch.cgi"
111
129
  @request.env['SERVER_SOFTWARE'] = 'lighttpd/1.2.3'
112
130
  @request.env['RAILS_RELATIVE_URL_ROOT'] = "/hieraki"
113
131
  assert_equal "/hieraki", @request.relative_url_root
114
-
132
+
115
133
  # @env overrides path guess
116
134
  @request.relative_url_root = nil
117
135
  @request.env['SCRIPT_NAME'] = "/hieraki/dispatch.cgi"
@@ -119,15 +137,15 @@ class RequestTest < Test::Unit::TestCase
119
137
  @request.env['RAILS_RELATIVE_URL_ROOT'] = "/real_url"
120
138
  assert_equal "/real_url", @request.relative_url_root
121
139
  end
122
-
140
+
123
141
  def test_request_uri
124
142
  @request.env['SERVER_SOFTWARE'] = 'Apache 42.342.3432'
125
-
143
+
126
144
  @request.relative_url_root = nil
127
145
  @request.set_REQUEST_URI "http://www.rubyonrails.org/path/of/some/uri?mapped=1"
128
146
  assert_equal "/path/of/some/uri?mapped=1", @request.request_uri
129
147
  assert_equal "/path/of/some/uri", @request.path
130
-
148
+
131
149
  @request.relative_url_root = nil
132
150
  @request.set_REQUEST_URI "http://www.rubyonrails.org/path/of/some/uri"
133
151
  assert_equal "/path/of/some/uri", @request.request_uri
@@ -147,25 +165,25 @@ class RequestTest < Test::Unit::TestCase
147
165
  @request.set_REQUEST_URI "/?m=b"
148
166
  assert_equal "/?m=b", @request.request_uri
149
167
  assert_equal "/", @request.path
150
-
168
+
151
169
  @request.relative_url_root = nil
152
170
  @request.set_REQUEST_URI "/"
153
171
  @request.env['SCRIPT_NAME'] = "/dispatch.cgi"
154
172
  assert_equal "/", @request.request_uri
155
- assert_equal "/", @request.path
173
+ assert_equal "/", @request.path
156
174
 
157
175
  @request.relative_url_root = nil
158
176
  @request.set_REQUEST_URI "/hieraki/"
159
177
  @request.env['SCRIPT_NAME'] = "/hieraki/dispatch.cgi"
160
178
  assert_equal "/hieraki/", @request.request_uri
161
- assert_equal "/", @request.path
179
+ assert_equal "/", @request.path
162
180
 
163
181
  @request.relative_url_root = nil
164
182
  @request.set_REQUEST_URI "/collaboration/hieraki/books/edit/2"
165
183
  @request.env['SCRIPT_NAME'] = "/collaboration/hieraki/dispatch.cgi"
166
184
  assert_equal "/collaboration/hieraki/books/edit/2", @request.request_uri
167
185
  assert_equal "/books/edit/2", @request.path
168
-
186
+
169
187
  # The following tests are for when REQUEST_URI is not supplied (as in IIS)
170
188
  @request.relative_url_root = nil
171
189
  @request.set_REQUEST_URI nil
@@ -234,34 +252,36 @@ class RequestTest < Test::Unit::TestCase
234
252
  end
235
253
 
236
254
 
237
- def test_host_with_port
255
+ def test_host_with_default_port
238
256
  @request.host = "rubyonrails.org"
239
257
  @request.port = 80
240
258
  assert_equal "rubyonrails.org", @request.host_with_port
241
-
259
+ end
260
+
261
+ def test_host_with_non_default_port
242
262
  @request.host = "rubyonrails.org"
243
263
  @request.port = 81
244
264
  assert_equal "rubyonrails.org:81", @request.host_with_port
245
265
  end
246
-
266
+
247
267
  def test_server_software
248
268
  assert_equal nil, @request.server_software
249
-
269
+
250
270
  @request.env['SERVER_SOFTWARE'] = 'Apache3.422'
251
271
  assert_equal 'apache', @request.server_software
252
-
272
+
253
273
  @request.env['SERVER_SOFTWARE'] = 'lighttpd(1.1.4)'
254
274
  assert_equal 'lighttpd', @request.server_software
255
275
  end
256
-
276
+
257
277
  def test_xml_http_request
258
278
  assert !@request.xml_http_request?
259
279
  assert !@request.xhr?
260
-
280
+
261
281
  @request.env['HTTP_X_REQUESTED_WITH'] = "DefinitelyNotAjax1.0"
262
282
  assert !@request.xml_http_request?
263
283
  assert !@request.xhr?
264
-
284
+
265
285
  @request.env['HTTP_X_REQUESTED_WITH'] = "XMLHttpRequest"
266
286
  assert @request.xml_http_request?
267
287
  assert @request.xhr?
@@ -286,11 +306,26 @@ class RequestTest < Test::Unit::TestCase
286
306
  end
287
307
  end
288
308
 
309
+ def test_invalid_http_method_raises_exception
310
+ set_request_method_to :random_method
311
+ assert_raises(ActionController::UnknownHttpMethod) do
312
+ @request.method
313
+ end
314
+ end
315
+
289
316
  def test_allow_method_hacking_on_post
290
317
  set_request_method_to :post
291
- [:get, :put, :delete].each do |method|
318
+ [:get, :head, :put, :post, :delete].each do |method|
292
319
  @request.instance_eval { @parameters = { :_method => method } ; @request_method = nil }
293
- assert_equal method, @request.method
320
+ assert_equal(method == :head ? :get : method, @request.method)
321
+ end
322
+ end
323
+
324
+ def test_invalid_method_hacking_on_post_raises_exception
325
+ set_request_method_to :post
326
+ @request.instance_eval { @parameters = { :_method => :random_method } ; @request_method = nil }
327
+ assert_raises(ActionController::UnknownHttpMethod) do
328
+ @request.method
294
329
  end
295
330
  end
296
331
 
@@ -301,7 +336,7 @@ class RequestTest < Test::Unit::TestCase
301
336
  assert_equal method, @request.method
302
337
  end
303
338
  end
304
-
339
+
305
340
  def test_head_masquarading_as_get
306
341
  set_request_method_to :head
307
342
  assert_equal :get, @request.method
@@ -309,9 +344,492 @@ class RequestTest < Test::Unit::TestCase
309
344
  assert @request.head?
310
345
  end
311
346
 
347
+ def test_xml_format
348
+ @request.instance_eval { @parameters = { :format => 'xml' } }
349
+ assert_equal Mime::XML, @request.format
350
+ end
351
+
352
+ def test_xhtml_format
353
+ @request.instance_eval { @parameters = { :format => 'xhtml' } }
354
+ assert_equal Mime::HTML, @request.format
355
+ end
356
+
357
+ def test_txt_format
358
+ @request.instance_eval { @parameters = { :format => 'txt' } }
359
+ assert_equal Mime::TEXT, @request.format
360
+ end
361
+
362
+ def test_nil_format
363
+ @request.instance_eval { @parameters = { :format => nil } }
364
+ @request.env["HTTP_ACCEPT"] = "text/javascript"
365
+ assert_equal Mime::JS, @request.format
366
+ end
367
+
368
+ def test_content_type
369
+ @request.env["CONTENT_TYPE"] = "text/html"
370
+ assert_equal Mime::HTML, @request.content_type
371
+ end
372
+
373
+ def test_content_no_type
374
+ assert_equal nil, @request.content_type
375
+ end
376
+
377
+ def test_content_type_xml
378
+ @request.env["CONTENT_TYPE"] = "application/xml"
379
+ assert_equal Mime::XML, @request.content_type
380
+ end
381
+
382
+ def test_content_type_with_charset
383
+ @request.env["CONTENT_TYPE"] = "application/xml; charset=UTF-8"
384
+ assert_equal Mime::XML, @request.content_type
385
+ end
386
+
387
+ def test_user_agent
388
+ assert_not_nil @request.user_agent
389
+ end
390
+
391
+ def test_parameters
392
+ @request.instance_eval { @request_parameters = { "foo" => 1 } }
393
+ @request.instance_eval { @query_parameters = { "bar" => 2 } }
394
+
395
+ assert_equal({"foo" => 1, "bar" => 2}, @request.parameters)
396
+ assert_equal({"foo" => 1}, @request.request_parameters)
397
+ assert_equal({"bar" => 2}, @request.query_parameters)
398
+ end
399
+
312
400
  protected
313
401
  def set_request_method_to(method)
314
402
  @request.env['REQUEST_METHOD'] = method.to_s.upcase
315
403
  @request.instance_eval { @request_method = nil }
316
404
  end
317
405
  end
406
+
407
+
408
+ class UrlEncodedRequestParameterParsingTest < Test::Unit::TestCase
409
+ def setup
410
+ @query_string = "action=create_customer&full_name=David%20Heinemeier%20Hansson&customerId=1"
411
+ @query_string_with_empty = "action=create_customer&full_name="
412
+ @query_string_with_array = "action=create_customer&selected[]=1&selected[]=2&selected[]=3"
413
+ @query_string_with_amps = "action=create_customer&name=Don%27t+%26+Does"
414
+ @query_string_with_multiple_of_same_name =
415
+ "action=update_order&full_name=Lau%20Taarnskov&products=4&products=2&products=3"
416
+ @query_string_with_many_equal = "action=create_customer&full_name=abc=def=ghi"
417
+ @query_string_without_equal = "action"
418
+ @query_string_with_many_ampersands =
419
+ "&action=create_customer&&&full_name=David%20Heinemeier%20Hansson"
420
+ @query_string_with_empty_key = "action=create_customer&full_name=David%20Heinemeier%20Hansson&=Save"
421
+ end
422
+
423
+ def test_query_string
424
+ assert_equal(
425
+ { "action" => "create_customer", "full_name" => "David Heinemeier Hansson", "customerId" => "1"},
426
+ ActionController::AbstractRequest.parse_query_parameters(@query_string)
427
+ )
428
+ end
429
+
430
+ def test_deep_query_string
431
+ expected = {'x' => {'y' => {'z' => '10'}}}
432
+ assert_equal(expected, ActionController::AbstractRequest.parse_query_parameters('x[y][z]=10'))
433
+ end
434
+
435
+ def test_deep_query_string_with_array
436
+ assert_equal({'x' => {'y' => {'z' => ['10']}}}, ActionController::AbstractRequest.parse_query_parameters('x[y][z][]=10'))
437
+ assert_equal({'x' => {'y' => {'z' => ['10', '5']}}}, ActionController::AbstractRequest.parse_query_parameters('x[y][z][]=10&x[y][z][]=5'))
438
+ end
439
+
440
+ def test_deep_query_string_with_array_of_hash
441
+ assert_equal({'x' => {'y' => [{'z' => '10'}]}}, ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10'))
442
+ assert_equal({'x' => {'y' => [{'z' => '10', 'w' => '10'}]}}, ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][w]=10'))
443
+ end
444
+
445
+ def test_deep_query_string_with_array_of_hashes_with_one_pair
446
+ assert_equal({'x' => {'y' => [{'z' => '10'}, {'z' => '20'}]}}, ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][z]=20'))
447
+ assert_equal("10", ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][z]=20')["x"]["y"].first["z"])
448
+ assert_equal("10", ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][z]=20').with_indifferent_access[:x][:y].first[:z])
449
+ end
450
+
451
+ def test_deep_query_string_with_array_of_hashes_with_multiple_pairs
452
+ assert_equal(
453
+ {'x' => {'y' => [{'z' => '10', 'w' => 'a'}, {'z' => '20', 'w' => 'b'}]}},
454
+ ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][w]=a&x[y][][z]=20&x[y][][w]=b')
455
+ )
456
+ end
457
+
458
+ def test_query_string_with_nil
459
+ assert_equal(
460
+ { "action" => "create_customer", "full_name" => ''},
461
+ ActionController::AbstractRequest.parse_query_parameters(@query_string_with_empty)
462
+ )
463
+ end
464
+
465
+ def test_query_string_with_array
466
+ assert_equal(
467
+ { "action" => "create_customer", "selected" => ["1", "2", "3"]},
468
+ ActionController::AbstractRequest.parse_query_parameters(@query_string_with_array)
469
+ )
470
+ end
471
+
472
+ def test_query_string_with_amps
473
+ assert_equal(
474
+ { "action" => "create_customer", "name" => "Don't & Does"},
475
+ ActionController::AbstractRequest.parse_query_parameters(@query_string_with_amps)
476
+ )
477
+ end
478
+
479
+ def test_query_string_with_many_equal
480
+ assert_equal(
481
+ { "action" => "create_customer", "full_name" => "abc=def=ghi"},
482
+ ActionController::AbstractRequest.parse_query_parameters(@query_string_with_many_equal)
483
+ )
484
+ end
485
+
486
+ def test_query_string_without_equal
487
+ assert_equal(
488
+ { "action" => nil },
489
+ ActionController::AbstractRequest.parse_query_parameters(@query_string_without_equal)
490
+ )
491
+ end
492
+
493
+ def test_query_string_with_empty_key
494
+ assert_equal(
495
+ { "action" => "create_customer", "full_name" => "David Heinemeier Hansson" },
496
+ ActionController::AbstractRequest.parse_query_parameters(@query_string_with_empty_key)
497
+ )
498
+ end
499
+
500
+ def test_query_string_with_many_ampersands
501
+ assert_equal(
502
+ { "action" => "create_customer", "full_name" => "David Heinemeier Hansson"},
503
+ ActionController::AbstractRequest.parse_query_parameters(@query_string_with_many_ampersands)
504
+ )
505
+ end
506
+
507
+ def test_unbalanced_query_string_with_array
508
+ assert_equal(
509
+ {'location' => ["1", "2"], 'age_group' => ["2"]},
510
+ ActionController::AbstractRequest.parse_query_parameters("location[]=1&location[]=2&age_group[]=2")
511
+ )
512
+ assert_equal(
513
+ {'location' => ["1", "2"], 'age_group' => ["2"]},
514
+ ActionController::AbstractRequest.parse_request_parameters({'location[]' => ["1", "2"],
515
+ 'age_group[]' => ["2"]})
516
+ )
517
+ end
518
+
519
+
520
+ def test_request_hash_parsing
521
+ query = {
522
+ "note[viewers][viewer][][type]" => ["User", "Group"],
523
+ "note[viewers][viewer][][id]" => ["1", "2"]
524
+ }
525
+
526
+ expected = { "note" => { "viewers"=>{"viewer"=>[{ "id"=>"1", "type"=>"User"}, {"type"=>"Group", "id"=>"2"} ]} } }
527
+
528
+ assert_equal(expected, ActionController::AbstractRequest.parse_request_parameters(query))
529
+ end
530
+
531
+
532
+ def test_parse_params
533
+ input = {
534
+ "customers[boston][first][name]" => [ "David" ],
535
+ "customers[boston][first][url]" => [ "http://David" ],
536
+ "customers[boston][second][name]" => [ "Allan" ],
537
+ "customers[boston][second][url]" => [ "http://Allan" ],
538
+ "something_else" => [ "blah" ],
539
+ "something_nil" => [ nil ],
540
+ "something_empty" => [ "" ],
541
+ "products[first]" => [ "Apple Computer" ],
542
+ "products[second]" => [ "Pc" ],
543
+ "" => [ 'Save' ]
544
+ }
545
+
546
+ expected_output = {
547
+ "customers" => {
548
+ "boston" => {
549
+ "first" => {
550
+ "name" => "David",
551
+ "url" => "http://David"
552
+ },
553
+ "second" => {
554
+ "name" => "Allan",
555
+ "url" => "http://Allan"
556
+ }
557
+ }
558
+ },
559
+ "something_else" => "blah",
560
+ "something_empty" => "",
561
+ "something_nil" => "",
562
+ "products" => {
563
+ "first" => "Apple Computer",
564
+ "second" => "Pc"
565
+ }
566
+ }
567
+
568
+ assert_equal expected_output, ActionController::AbstractRequest.parse_request_parameters(input)
569
+ end
570
+
571
+ UploadedStringIO = ActionController::UploadedStringIO
572
+ class MockUpload < UploadedStringIO
573
+ def initialize(content_type, original_path, *args)
574
+ self.content_type = content_type
575
+ self.original_path = original_path
576
+ super *args
577
+ end
578
+ end
579
+
580
+ def test_parse_params_from_multipart_upload
581
+ file = MockUpload.new('img/jpeg', 'foo.jpg')
582
+ ie_file = MockUpload.new('img/jpeg', 'c:\\Documents and Settings\\foo\\Desktop\\bar.jpg')
583
+ non_file_text_part = MockUpload.new('text/plain', '', 'abc')
584
+
585
+ input = {
586
+ "something" => [ UploadedStringIO.new("") ],
587
+ "array_of_stringios" => [[ UploadedStringIO.new("One"), UploadedStringIO.new("Two") ]],
588
+ "mixed_types_array" => [[ UploadedStringIO.new("Three"), "NotStringIO" ]],
589
+ "mixed_types_as_checkboxes[strings][nested]" => [[ file, "String", UploadedStringIO.new("StringIO")]],
590
+ "ie_mixed_types_as_checkboxes[strings][nested]" => [[ ie_file, "String", UploadedStringIO.new("StringIO")]],
591
+ "products[string]" => [ UploadedStringIO.new("Apple Computer") ],
592
+ "products[file]" => [ file ],
593
+ "ie_products[string]" => [ UploadedStringIO.new("Microsoft") ],
594
+ "ie_products[file]" => [ ie_file ],
595
+ "text_part" => [non_file_text_part]
596
+ }
597
+
598
+ expected_output = {
599
+ "something" => "",
600
+ "array_of_stringios" => ["One", "Two"],
601
+ "mixed_types_array" => [ "Three", "NotStringIO" ],
602
+ "mixed_types_as_checkboxes" => {
603
+ "strings" => {
604
+ "nested" => [ file, "String", "StringIO" ]
605
+ },
606
+ },
607
+ "ie_mixed_types_as_checkboxes" => {
608
+ "strings" => {
609
+ "nested" => [ ie_file, "String", "StringIO" ]
610
+ },
611
+ },
612
+ "products" => {
613
+ "string" => "Apple Computer",
614
+ "file" => file
615
+ },
616
+ "ie_products" => {
617
+ "string" => "Microsoft",
618
+ "file" => ie_file
619
+ },
620
+ "text_part" => "abc"
621
+ }
622
+
623
+ params = ActionController::AbstractRequest.parse_request_parameters(input)
624
+ assert_equal expected_output, params
625
+
626
+ # Lone filenames are preserved.
627
+ assert_equal 'foo.jpg', params['mixed_types_as_checkboxes']['strings']['nested'].first.original_filename
628
+ assert_equal 'foo.jpg', params['products']['file'].original_filename
629
+
630
+ # But full Windows paths are reduced to their basename.
631
+ assert_equal 'bar.jpg', params['ie_mixed_types_as_checkboxes']['strings']['nested'].first.original_filename
632
+ assert_equal 'bar.jpg', params['ie_products']['file'].original_filename
633
+ end
634
+
635
+ def test_parse_params_with_file
636
+ input = {
637
+ "customers[boston][first][name]" => [ "David" ],
638
+ "something_else" => [ "blah" ],
639
+ "logo" => [ File.new(File.dirname(__FILE__) + "/cgi_test.rb").path ]
640
+ }
641
+
642
+ expected_output = {
643
+ "customers" => {
644
+ "boston" => {
645
+ "first" => {
646
+ "name" => "David"
647
+ }
648
+ }
649
+ },
650
+ "something_else" => "blah",
651
+ "logo" => File.new(File.dirname(__FILE__) + "/cgi_test.rb").path,
652
+ }
653
+
654
+ assert_equal expected_output, ActionController::AbstractRequest.parse_request_parameters(input)
655
+ end
656
+
657
+ def test_parse_params_with_array
658
+ input = { "selected[]" => [ "1", "2", "3" ] }
659
+
660
+ expected_output = { "selected" => [ "1", "2", "3" ] }
661
+
662
+ assert_equal expected_output, ActionController::AbstractRequest.parse_request_parameters(input)
663
+ end
664
+
665
+ def test_parse_params_with_non_alphanumeric_name
666
+ input = { "a/b[c]" => %w(d) }
667
+ expected = { "a/b" => { "c" => "d" }}
668
+ assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
669
+ end
670
+
671
+ def test_parse_params_with_single_brackets_in_middle
672
+ input = { "a/b[c]d" => %w(e) }
673
+ expected = { "a/b" => {} }
674
+ assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
675
+ end
676
+
677
+ def test_parse_params_with_separated_brackets
678
+ input = { "a/b@[c]d[e]" => %w(f) }
679
+ expected = { "a/b@" => { }}
680
+ assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
681
+ end
682
+
683
+ def test_parse_params_with_separated_brackets_and_array
684
+ input = { "a/b@[c]d[e][]" => %w(f) }
685
+ expected = { "a/b@" => { }}
686
+ assert_equal expected , ActionController::AbstractRequest.parse_request_parameters(input)
687
+ end
688
+
689
+ def test_parse_params_with_unmatched_brackets_and_array
690
+ input = { "a/b@[c][d[e][]" => %w(f) }
691
+ expected = { "a/b@" => { "c" => { }}}
692
+ assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
693
+ end
694
+
695
+ def test_parse_params_with_nil_key
696
+ input = { nil => nil, "test2" => %w(value1) }
697
+ expected = { "test2" => "value1" }
698
+ assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
699
+ end
700
+ end
701
+
702
+
703
+ class MultipartRequestParameterParsingTest < Test::Unit::TestCase
704
+ FIXTURE_PATH = File.dirname(__FILE__) + '/../fixtures/multipart'
705
+
706
+ def test_single_parameter
707
+ params = process('single_parameter')
708
+ assert_equal({ 'foo' => 'bar' }, params)
709
+ end
710
+
711
+ def test_bracketed_param
712
+ assert_equal({ 'foo' => { 'baz' => 'bar'}}, process('bracketed_param'))
713
+ end
714
+
715
+ def test_text_file
716
+ params = process('text_file')
717
+ assert_equal %w(file foo), params.keys.sort
718
+ assert_equal 'bar', params['foo']
719
+
720
+ file = params['file']
721
+ assert_kind_of StringIO, file
722
+ assert_equal 'file.txt', file.original_filename
723
+ assert_equal "text/plain", file.content_type
724
+ assert_equal 'contents', file.read
725
+ end
726
+
727
+ def test_large_text_file
728
+ params = process('large_text_file')
729
+ assert_equal %w(file foo), params.keys.sort
730
+ assert_equal 'bar', params['foo']
731
+
732
+ file = params['file']
733
+ assert_kind_of Tempfile, file
734
+ assert_equal 'file.txt', file.original_filename
735
+ assert_equal "text/plain", file.content_type
736
+ assert ('a' * 20480) == file.read
737
+ end
738
+
739
+ uses_mocha "test_no_rewind_stream" do
740
+ def test_no_rewind_stream
741
+ # Ensures that parse_multipart_form_parameters works with streams that cannot be rewound
742
+ file = File.open(File.join(FIXTURE_PATH, 'large_text_file'), 'rb')
743
+ file.expects(:rewind).raises(Errno::ESPIPE)
744
+ params = ActionController::AbstractRequest.parse_multipart_form_parameters(file, 'AaB03x', file.stat.size, {})
745
+ assert_not_equal 0, file.pos # file was not rewound after reading
746
+ end
747
+ end
748
+
749
+ def test_binary_file
750
+ params = process('binary_file')
751
+ assert_equal %w(file flowers foo), params.keys.sort
752
+ assert_equal 'bar', params['foo']
753
+
754
+ file = params['file']
755
+ assert_kind_of StringIO, file
756
+ assert_equal 'file.csv', file.original_filename
757
+ assert_nil file.content_type
758
+ assert_equal 'contents', file.read
759
+
760
+ file = params['flowers']
761
+ assert_kind_of StringIO, file
762
+ assert_equal 'flowers.jpg', file.original_filename
763
+ assert_equal "image/jpeg", file.content_type
764
+ assert_equal 19512, file.size
765
+ #assert_equal File.read(File.dirname(__FILE__) + '/../../../activerecord/test/fixtures/flowers.jpg'), file.read
766
+ end
767
+
768
+ def test_mixed_files
769
+ params = process('mixed_files')
770
+ assert_equal %w(files foo), params.keys.sort
771
+ assert_equal 'bar', params['foo']
772
+
773
+ # Ruby CGI doesn't handle multipart/mixed for us.
774
+ assert_kind_of String, params['files']
775
+ assert_equal 19756, params['files'].size
776
+ end
777
+
778
+ private
779
+ def process(name)
780
+ File.open(File.join(FIXTURE_PATH, name), 'rb') do |file|
781
+ params = ActionController::AbstractRequest.parse_multipart_form_parameters(file, 'AaB03x', file.stat.size, {})
782
+ assert_equal 0, file.pos # file was rewound after reading
783
+ params
784
+ end
785
+ end
786
+ end
787
+
788
+
789
+ class XmlParamsParsingTest < Test::Unit::TestCase
790
+ def test_single_file
791
+ person = parse_body("<person><name>David</name><avatar type='file' name='me.jpg' content_type='image/jpg'>#{Base64.encode64('ABC')}</avatar></person>")
792
+
793
+ assert_equal "image/jpg", person['person']['avatar'].content_type
794
+ assert_equal "me.jpg", person['person']['avatar'].original_filename
795
+ assert_equal "ABC", person['person']['avatar'].read
796
+ end
797
+
798
+ def test_multiple_files
799
+ person = parse_body(<<-end_body)
800
+ <person>
801
+ <name>David</name>
802
+ <avatars>
803
+ <avatar type='file' name='me.jpg' content_type='image/jpg'>#{Base64.encode64('ABC')}</avatar>
804
+ <avatar type='file' name='you.gif' content_type='image/gif'>#{Base64.encode64('DEF')}</avatar>
805
+ </avatars>
806
+ </person>
807
+ end_body
808
+
809
+ assert_equal "image/jpg", person['person']['avatars']['avatar'].first.content_type
810
+ assert_equal "me.jpg", person['person']['avatars']['avatar'].first.original_filename
811
+ assert_equal "ABC", person['person']['avatars']['avatar'].first.read
812
+
813
+ assert_equal "image/gif", person['person']['avatars']['avatar'].last.content_type
814
+ assert_equal "you.gif", person['person']['avatars']['avatar'].last.original_filename
815
+ assert_equal "DEF", person['person']['avatars']['avatar'].last.read
816
+ end
817
+
818
+ private
819
+ def parse_body(body)
820
+ env = { 'CONTENT_TYPE' => 'application/xml',
821
+ 'CONTENT_LENGTH' => body.size.to_s }
822
+ cgi = ActionController::Integration::Session::StubCGI.new(env, body)
823
+ ActionController::CgiRequest.new(cgi).request_parameters
824
+ end
825
+ end
826
+
827
+ class LegacyXmlParamsParsingTest < XmlParamsParsingTest
828
+ private
829
+ def parse_body(body)
830
+ env = { 'HTTP_X_POST_DATA_FORMAT' => 'xml',
831
+ 'CONTENT_LENGTH' => body.size.to_s }
832
+ cgi = ActionController::Integration::Session::StubCGI.new(env, body)
833
+ ActionController::CgiRequest.new(cgi).request_parameters
834
+ end
835
+ end