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
@@ -3,8 +3,8 @@
3
3
  # Under MIT and/or CC By license.
4
4
  #++
5
5
 
6
- require File.dirname(__FILE__) + '/../abstract_unit'
7
- require File.dirname(__FILE__) + '/fake_controllers'
6
+ require "#{File.dirname(__FILE__)}/../abstract_unit"
7
+ require "#{File.dirname(__FILE__)}/fake_controllers"
8
8
 
9
9
  class SelectorTest < Test::Unit::TestCase
10
10
  #
@@ -85,11 +85,11 @@ class SelectorTest < Test::Unit::TestCase
85
85
  assert_equal 2, @matches.size
86
86
  assert_equal "2", @matches[0].attributes["id"]
87
87
  assert_equal "3", @matches[1].attributes["id"]
88
- # Match alement with attribute value.
88
+ # Match element with attribute value.
89
89
  select("*[title=foo]")
90
90
  assert_equal 1, @matches.size
91
91
  assert_equal "3", @matches[0].attributes["id"]
92
- # Match alement with attribute and attribute value.
92
+ # Match element with attribute and attribute value.
93
93
  select("[bar=foo][title]")
94
94
  assert_equal 1, @matches.size
95
95
  assert_equal "2", @matches[0].attributes["id"]
@@ -177,7 +177,7 @@ class SelectorTest < Test::Unit::TestCase
177
177
  assert_equal 2, @matches.size
178
178
  assert_equal "foo", @matches[0].attributes["href"]
179
179
  assert_equal "baz", @matches[1].attributes["href"]
180
- # And now for the three selector challange.
180
+ # And now for the three selector challenge.
181
181
  parse(%Q{<h1 id="1"><a href="foo"></a></h1><h2 id="2"><a href="bar"></a></h2><h3 id="2"><a href="baz"></a></h3>})
182
182
  select("h1 a, h2 a, h3 a")
183
183
  assert_equal 3, @matches.size
@@ -21,11 +21,13 @@ class SendFileController < ActionController::Base
21
21
  def rescue_action(e) raise end
22
22
  end
23
23
 
24
- SendFileController.template_root = File.dirname(__FILE__) + "/../fixtures/"
24
+ SendFileController.view_paths = [ File.dirname(__FILE__) + "/../fixtures/" ]
25
25
 
26
26
  class SendFileTest < Test::Unit::TestCase
27
27
  include TestFileUtils
28
28
 
29
+ Mime::Type.register "image/png", :png unless defined? Mime::PNG
30
+
29
31
  def setup
30
32
  @controller = SendFileController.new
31
33
  @request = ActionController::TestRequest.new
@@ -53,6 +55,14 @@ class SendFileTest < Test::Unit::TestCase
53
55
  assert_nothing_raised { response.body.call(response, output) }
54
56
  assert_equal file_data, output.string
55
57
  end
58
+
59
+ def test_file_url_based_filename
60
+ @controller.options = { :url_based_filename => true }
61
+ response = nil
62
+ assert_nothing_raised { response = process('file') }
63
+ assert_not_nil response
64
+ assert_equal "attachment", response.headers["Content-Disposition"]
65
+ end
56
66
 
57
67
  def test_data
58
68
  response = nil
@@ -65,17 +75,17 @@ class SendFileTest < Test::Unit::TestCase
65
75
 
66
76
  def test_headers_after_send_shouldnt_include_charset
67
77
  response = process('data')
68
- assert_equal "application/octet-stream", response.headers["Content-Type"]
78
+ assert_equal "application/octet-stream", response.content_type
69
79
 
70
80
  response = process('file')
71
- assert_equal "application/octet-stream", response.headers["Content-Type"]
81
+ assert_equal "application/octet-stream", response.content_type
72
82
  end
73
83
 
74
84
  # Test that send_file_headers! is setting the correct HTTP headers.
75
85
  def test_send_file_headers!
76
86
  options = {
77
87
  :length => 1,
78
- :type => 'type',
88
+ :type => Mime::PNG,
79
89
  :disposition => 'disposition',
80
90
  :filename => 'filename'
81
91
  }
@@ -90,7 +100,7 @@ class SendFileTest < Test::Unit::TestCase
90
100
 
91
101
  h = @controller.headers
92
102
  assert_equal 1, h['Content-Length']
93
- assert_equal 'type', h['Content-Type']
103
+ assert_equal 'image/png', h['Content-Type']
94
104
  assert_equal 'disposition; filename="filename"', h['Content-Disposition']
95
105
  assert_equal 'binary', h['Content-Transfer-Encoding']
96
106
 
@@ -105,13 +115,13 @@ class SendFileTest < Test::Unit::TestCase
105
115
  define_method "test_send_#{method}_status" do
106
116
  @controller.options = { :stream => false, :status => 500 }
107
117
  assert_nothing_raised { assert_not_nil process(method) }
108
- assert_equal '500 Internal Server Error', @controller.headers['Status']
118
+ assert_equal '500 Internal Server Error', @response.headers['Status']
109
119
  end
110
120
 
111
121
  define_method "test_default_send_#{method}_status" do
112
122
  @controller.options = { :stream => false }
113
123
  assert_nothing_raised { assert_not_nil process(method) }
114
- assert_equal ActionController::Base::DEFAULT_RENDER_STATUS_CODE, @controller.headers['Status']
124
+ assert_equal ActionController::Base::DEFAULT_RENDER_STATUS_CODE, @response.headers['Status']
115
125
  end
116
126
  end
117
127
  end
@@ -0,0 +1,246 @@
1
+ require "#{File.dirname(__FILE__)}/../../abstract_unit"
2
+ require 'action_controller/cgi_process'
3
+ require 'action_controller/cgi_ext'
4
+
5
+ require 'stringio'
6
+
7
+
8
+ class CGI::Session::CookieStore
9
+ def ensure_secret_secure_with_test_hax(secret)
10
+ if secret == CookieStoreTest.default_session_options['secret']
11
+ return true
12
+ else
13
+ ensure_secret_secure_without_test_hax(secret)
14
+ end
15
+ end
16
+ alias_method_chain :ensure_secret_secure, :test_hax
17
+ end
18
+
19
+
20
+ # Expose for tests.
21
+ class CGI
22
+ attr_reader :output_cookies, :output_hidden
23
+
24
+ class Session
25
+ attr_reader :dbman
26
+
27
+ class CookieStore
28
+ attr_reader :data, :original, :cookie_options
29
+ end
30
+ end
31
+ end
32
+
33
+ class CookieStoreTest < Test::Unit::TestCase
34
+ def self.default_session_options
35
+ { 'database_manager' => CGI::Session::CookieStore,
36
+ 'session_key' => '_myapp_session',
37
+ 'secret' => 'Keep it secret; keep it safe.',
38
+ 'no_cookies' => true,
39
+ 'no_hidden' => true }
40
+ end
41
+
42
+ def self.cookies
43
+ { :empty => ['BAgw--0686dcaccc01040f4bd4f35fe160afe9bc04c330', {}],
44
+ :a_one => ['BAh7BiIGYWkG--5689059497d7f122a7119f171aef81dcfd807fec', { 'a' => 1 }],
45
+ :typical => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7BiILbm90aWNlIgxIZXkgbm93--9d20154623b9eeea05c62ab819be0e2483238759', { 'user_id' => 123, 'flash' => { 'notice' => 'Hey now' }}],
46
+ :flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--bf9785a666d3c4ac09f7fe3353496b437546cfbf', { 'user_id' => 123, 'flash' => {} }] }
47
+ end
48
+
49
+ def setup
50
+ ENV.delete('HTTP_COOKIE')
51
+ end
52
+
53
+ def test_raises_argument_error_if_missing_session_key
54
+ [nil, ''].each do |blank|
55
+ assert_raise(ArgumentError, blank.inspect) { new_session 'session_key' => blank }
56
+ end
57
+ end
58
+
59
+ def test_raises_argument_error_if_missing_secret
60
+ [nil, ''].each do |blank|
61
+ assert_raise(ArgumentError, blank.inspect) { new_session 'secret' => blank }
62
+ end
63
+ end
64
+
65
+ def test_raises_argument_error_if_secret_is_probably_insecure
66
+ ["password", "secret", "12345678901234567890123456789"].each do |blank|
67
+ assert_raise(ArgumentError, blank.inspect) { new_session 'secret' => blank }
68
+ end
69
+ end
70
+
71
+ def test_reconfigures_session_to_omit_id_cookie_and_hidden_field
72
+ new_session do |session|
73
+ assert_equal true, @options['no_hidden']
74
+ assert_equal true, @options['no_cookies']
75
+ end
76
+ end
77
+
78
+ def test_restore_unmarshals_missing_cookie_as_empty_hash
79
+ new_session do |session|
80
+ assert_nil session.dbman.data
81
+ assert_nil session['test']
82
+ assert_equal Hash.new, session.dbman.data
83
+ end
84
+ end
85
+
86
+ def test_restore_unmarshals_good_cookies
87
+ cookies(:empty, :a_one, :typical).each do |value, expected|
88
+ set_cookie! value
89
+ new_session do |session|
90
+ assert_nil session['lazy loads the data hash']
91
+ assert_equal expected, session.dbman.data
92
+ end
93
+ end
94
+ end
95
+
96
+ def test_restore_deletes_tampered_cookies
97
+ set_cookie! 'a--b'
98
+ new_session do |session|
99
+ assert_raise(CGI::Session::CookieStore::TamperedWithCookie) { session['fail'] }
100
+ assert_cookie_deleted session
101
+ end
102
+ end
103
+
104
+ def test_close_doesnt_write_cookie_if_data_is_blank
105
+ new_session do |session|
106
+ assert_no_cookies session
107
+ session.close
108
+ assert_no_cookies session
109
+ end
110
+ end
111
+
112
+ def test_close_doesnt_write_cookie_if_data_is_unchanged
113
+ set_cookie! cookie_value(:typical)
114
+ new_session do |session|
115
+ assert_no_cookies session
116
+ session['user_id'] = session['user_id']
117
+ session.close
118
+ assert_no_cookies session
119
+ end
120
+ end
121
+
122
+ def test_close_raises_when_data_overflows
123
+ set_cookie! cookie_value(:empty)
124
+ new_session do |session|
125
+ session['overflow'] = 'bye!' * 1024
126
+ assert_raise(CGI::Session::CookieStore::CookieOverflow) { session.close }
127
+ assert_no_cookies session
128
+ end
129
+ end
130
+
131
+ def test_close_marshals_and_writes_cookie
132
+ set_cookie! cookie_value(:typical)
133
+ new_session do |session|
134
+ assert_no_cookies session
135
+ session['flash'] = {}
136
+ assert_no_cookies session
137
+ session.close
138
+ assert_equal 1, session.cgi.output_cookies.size
139
+ cookie = session.cgi.output_cookies.first
140
+ assert_cookie cookie, cookie_value(:flashed)
141
+ end
142
+ end
143
+
144
+ def test_delete_writes_expired_empty_cookie_and_sets_data_to_nil
145
+ set_cookie! cookie_value(:typical)
146
+ new_session do |session|
147
+ assert_no_cookies session
148
+ session.delete
149
+ assert_cookie_deleted session
150
+
151
+ # @data is set to nil so #close doesn't send another cookie.
152
+ session.close
153
+ assert_cookie_deleted session
154
+ end
155
+ end
156
+
157
+ def test_new_session_doesnt_reuse_deleted_cookie_data
158
+ set_cookie! cookie_value(:typical)
159
+
160
+ new_session do |session|
161
+ assert_not_nil session['user_id']
162
+ session.delete
163
+
164
+ # Start a new session using the same CGI instance.
165
+ post_delete_session = CGI::Session.new(session.cgi, self.class.default_session_options)
166
+ assert_nil post_delete_session['user_id']
167
+ end
168
+ end
169
+
170
+ private
171
+ def assert_no_cookies(session)
172
+ assert_nil session.cgi.output_cookies, session.cgi.output_cookies.inspect
173
+ end
174
+
175
+ def assert_cookie_deleted(session, message = 'Expected session deletion cookie to be set')
176
+ assert_equal 1, session.cgi.output_cookies.size
177
+ cookie = session.cgi.output_cookies.first
178
+ assert_cookie cookie, nil, 1.year.ago.to_date, message
179
+ end
180
+
181
+ def assert_cookie(cookie, value = nil, expires = nil, message = nil)
182
+ assert_equal '_myapp_session', cookie.name, message
183
+ assert_equal [value].compact, cookie.value, message
184
+ assert_equal expires, cookie.expires ? cookie.expires.to_date : cookie.expires, message
185
+ end
186
+
187
+
188
+ def cookies(*which)
189
+ self.class.cookies.values_at(*which)
190
+ end
191
+
192
+ def cookie_value(which)
193
+ self.class.cookies[which].first
194
+ end
195
+
196
+ def set_cookie!(value)
197
+ ENV['HTTP_COOKIE'] = "_myapp_session=#{value}"
198
+ end
199
+
200
+ def new_session(options = {})
201
+ with_cgi do |cgi|
202
+ assert_nil cgi.output_hidden, "Output hidden params should be empty: #{cgi.output_hidden.inspect}"
203
+ assert_nil cgi.output_cookies, "Output cookies should be empty: #{cgi.output_cookies.inspect}"
204
+
205
+ @options = self.class.default_session_options.merge(options)
206
+ session = CGI::Session.new(cgi, @options)
207
+
208
+ assert_nil cgi.output_hidden, "Output hidden params should be empty: #{cgi.output_hidden.inspect}"
209
+ assert_nil cgi.output_cookies, "Output cookies should be empty: #{cgi.output_cookies.inspect}"
210
+
211
+ yield session if block_given?
212
+ session
213
+ end
214
+ end
215
+
216
+ def with_cgi
217
+ ENV['REQUEST_METHOD'] = 'GET'
218
+ ENV['HTTP_HOST'] = 'example.com'
219
+ ENV['QUERY_STRING'] = ''
220
+
221
+ cgi = CGI.new('query', StringIO.new(''))
222
+ yield cgi if block_given?
223
+ cgi
224
+ end
225
+ end
226
+
227
+
228
+ class CookieStoreWithBlockAsSecretTest < CookieStoreTest
229
+ def self.default_session_options
230
+ CookieStoreTest.default_session_options.merge 'secret' => Proc.new { 'Keep it secret; keep it safe.' }
231
+ end
232
+ end
233
+
234
+
235
+ class CookieStoreWithMD5DigestTest < CookieStoreTest
236
+ def self.default_session_options
237
+ CookieStoreTest.default_session_options.merge 'digest' => 'MD5'
238
+ end
239
+
240
+ def self.cookies
241
+ { :empty => ['BAgw--0415cc0be9579b14afc22ee2d341aa21', {}],
242
+ :a_one => ['BAh7BiIGYWkG--5a0ed962089cc6600ff44168a5d59bc8', { 'a' => 1 }],
243
+ :typical => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7BiILbm90aWNlIgxIZXkgbm93--f426763f6ef435b3738b493600db8d64', { 'user_id' => 123, 'flash' => { 'notice' => 'Hey now' }}],
244
+ :flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--0af9156650dab044a53a91a4ddec2c51', { 'user_id' => 123, 'flash' => {} }] }
245
+ end
246
+ end
@@ -0,0 +1,182 @@
1
+ require "#{File.dirname(__FILE__)}/../../abstract_unit"
2
+ require 'action_controller/cgi_process'
3
+ require 'action_controller/cgi_ext'
4
+
5
+
6
+ class CGI::Session
7
+ def cache
8
+ dbman.instance_variable_get(:@cache)
9
+ end
10
+ end
11
+
12
+
13
+ uses_mocha 'MemCacheStore tests' do
14
+ if defined? MemCache::MemCacheError
15
+
16
+ class MemCacheStoreTest < Test::Unit::TestCase
17
+ SESSION_KEY_RE = /^session:[0-9a-z]+/
18
+ CONN_TEST_KEY = 'connection_test'
19
+ MULTI_TEST_KEY = '0123456789'
20
+ TEST_DATA = 'Hello test'
21
+
22
+ def self.get_mem_cache_if_available
23
+ begin
24
+ require 'memcache'
25
+ cache = MemCache.new('127.0.0.1')
26
+ # Test availability of the connection
27
+ cache.set(CONN_TEST_KEY, 1)
28
+ unless cache.get(CONN_TEST_KEY) == 1
29
+ puts 'Warning: memcache server available but corrupted.'
30
+ return nil
31
+ end
32
+ rescue LoadError, MemCache::MemCacheError
33
+ return nil
34
+ end
35
+ return cache
36
+ end
37
+
38
+ CACHE = get_mem_cache_if_available
39
+
40
+
41
+ def test_initialization
42
+ assert_raise(ArgumentError) { new_session('session_id' => '!invalid_id') }
43
+ new_session do |s|
44
+ assert_equal Hash.new, s.cache.get('session:' + s.session_id)
45
+ end
46
+ end
47
+
48
+
49
+ def test_storage
50
+ d = rand(0xffff)
51
+ new_session do |s|
52
+ session_key = 'session:' + s.session_id
53
+ unless CACHE
54
+ s.cache.expects(:get).with(session_key) \
55
+ .returns(:test => d)
56
+ s.cache.expects(:set).with(session_key,
57
+ has_entry(:test, d),
58
+ 0)
59
+ end
60
+ s[:test] = d
61
+ s.close
62
+ assert_equal d, s.cache.get(session_key)[:test]
63
+ assert_equal d, s[:test]
64
+ end
65
+ end
66
+
67
+
68
+ def test_deletion
69
+ new_session do |s|
70
+ session_key = 'session:' + s.session_id
71
+ unless CACHE
72
+ s.cache.expects(:delete)
73
+ s.cache.expects(:get).with(session_key) \
74
+ .returns(nil)
75
+ end
76
+ s[:test] = rand(0xffff)
77
+ s.delete
78
+ assert_nil s.cache.get(session_key)
79
+ end
80
+ end
81
+
82
+
83
+ def test_other_session_retrieval
84
+ new_session do |sa|
85
+ unless CACHE
86
+ sa.cache.expects(:set).with('session:' + sa.session_id,
87
+ has_entry(:test, TEST_DATA),
88
+ 0)
89
+ end
90
+ sa[:test] = TEST_DATA
91
+ sa.close
92
+ new_session('session_id' => sa.session_id) do |sb|
93
+ unless CACHE
94
+ sb.cache.expects(:[]).with('session:' + sb.session_id) \
95
+ .returns(:test => TEST_DATA)
96
+ end
97
+ assert_equal(TEST_DATA, sb[:test])
98
+ end
99
+ end
100
+ end
101
+
102
+
103
+ def test_multiple_sessions
104
+ s_slots = Array.new(10)
105
+ operation = :write
106
+ last_data = nil
107
+ reads = writes = 0
108
+ 50.times do
109
+ current = rand(10)
110
+ s_slots[current] ||= new_session('session_id' => MULTI_TEST_KEY,
111
+ 'new_session' => true)
112
+ s = s_slots[current]
113
+ case operation
114
+ when :write
115
+ last_data = rand(0xffff)
116
+ unless CACHE
117
+ s.cache.expects(:set).with('session:' + MULTI_TEST_KEY,
118
+ { :test => last_data },
119
+ 0)
120
+ end
121
+ s[:test] = last_data
122
+ s.close
123
+ writes += 1
124
+ when :read
125
+ # Make CGI::Session#[] think there was no data retrieval yet.
126
+ # Normally, the session caches the data during its lifetime.
127
+ s.instance_variable_set(:@data, nil)
128
+ unless CACHE
129
+ s.cache.expects(:[]).with('session:' + MULTI_TEST_KEY) \
130
+ .returns(:test => last_data)
131
+ end
132
+ d = s[:test]
133
+ assert_equal(last_data, d, "OK reads: #{reads}, OK writes: #{writes}")
134
+ reads += 1
135
+ end
136
+ operation = rand(5) == 0 ? :write : :read
137
+ end
138
+ end
139
+
140
+
141
+
142
+ private
143
+ def obtain_session_options
144
+ options = { 'database_manager' => CGI::Session::MemCacheStore,
145
+ 'session_key' => '_test_app_session'
146
+ }
147
+ # if don't have running memcache server we use mock instead
148
+ unless CACHE
149
+ options['cache'] = c = mock
150
+ c.stubs(:[]).with(regexp_matches(SESSION_KEY_RE))
151
+ c.stubs(:get).with(regexp_matches(SESSION_KEY_RE)) \
152
+ .returns(Hash.new)
153
+ c.stubs(:add).with(regexp_matches(SESSION_KEY_RE),
154
+ instance_of(Hash),
155
+ 0)
156
+ end
157
+ options
158
+ end
159
+
160
+
161
+ def new_session(options = {})
162
+ with_cgi do |cgi|
163
+ @options = obtain_session_options.merge(options)
164
+ session = CGI::Session.new(cgi, @options)
165
+ yield session if block_given?
166
+ return session
167
+ end
168
+ end
169
+
170
+ def with_cgi
171
+ ENV['REQUEST_METHOD'] = 'GET'
172
+ ENV['HTTP_HOST'] = 'example.com'
173
+ ENV['QUERY_STRING'] = ''
174
+
175
+ cgi = CGI.new('query', StringIO.new(''))
176
+ yield cgi if block_given?
177
+ cgi
178
+ end
179
+ end
180
+
181
+ end # defined? MemCache
182
+ end # uses_mocha