actionpack 2.2.3 → 2.3.2

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 (264) hide show
  1. data/CHANGELOG +433 -375
  2. data/MIT-LICENSE +1 -1
  3. data/README +21 -75
  4. data/Rakefile +1 -1
  5. data/lib/action_controller.rb +80 -43
  6. data/lib/action_controller/assertions/model_assertions.rb +1 -0
  7. data/lib/action_controller/assertions/response_assertions.rb +43 -16
  8. data/lib/action_controller/assertions/routing_assertions.rb +1 -1
  9. data/lib/action_controller/assertions/selector_assertions.rb +17 -12
  10. data/lib/action_controller/assertions/tag_assertions.rb +1 -4
  11. data/lib/action_controller/base.rb +153 -82
  12. data/lib/action_controller/benchmarking.rb +9 -9
  13. data/lib/action_controller/caching.rb +9 -11
  14. data/lib/action_controller/caching/actions.rb +11 -18
  15. data/lib/action_controller/caching/fragments.rb +28 -20
  16. data/lib/action_controller/caching/pages.rb +13 -15
  17. data/lib/action_controller/caching/sweeping.rb +2 -2
  18. data/lib/action_controller/cgi_ext.rb +0 -1
  19. data/lib/action_controller/cgi_ext/cookie.rb +2 -0
  20. data/lib/action_controller/cgi_process.rb +54 -162
  21. data/lib/action_controller/cookies.rb +13 -25
  22. data/lib/action_controller/dispatcher.rb +43 -122
  23. data/lib/action_controller/failsafe.rb +52 -0
  24. data/lib/action_controller/flash.rb +38 -47
  25. data/lib/action_controller/helpers.rb +13 -9
  26. data/lib/action_controller/http_authentication.rb +203 -23
  27. data/lib/action_controller/integration.rb +126 -70
  28. data/lib/action_controller/layout.rb +36 -39
  29. data/lib/action_controller/middleware_stack.rb +119 -0
  30. data/lib/action_controller/middlewares.rb +13 -0
  31. data/lib/action_controller/mime_responds.rb +19 -4
  32. data/lib/action_controller/mime_type.rb +8 -0
  33. data/lib/action_controller/params_parser.rb +71 -0
  34. data/lib/action_controller/performance_test.rb +0 -1
  35. data/lib/action_controller/polymorphic_routes.rb +36 -30
  36. data/lib/action_controller/reloader.rb +14 -0
  37. data/lib/action_controller/request.rb +107 -499
  38. data/lib/action_controller/request_forgery_protection.rb +7 -39
  39. data/lib/action_controller/rescue.rb +55 -35
  40. data/lib/action_controller/resources.rb +34 -31
  41. data/lib/action_controller/response.rb +99 -57
  42. data/lib/action_controller/rewindable_input.rb +28 -0
  43. data/lib/action_controller/routing.rb +7 -7
  44. data/lib/action_controller/routing/builder.rb +4 -1
  45. data/lib/action_controller/routing/optimisations.rb +1 -1
  46. data/lib/action_controller/routing/recognition_optimisation.rb +1 -2
  47. data/lib/action_controller/routing/route.rb +15 -5
  48. data/lib/action_controller/routing/route_set.rb +82 -35
  49. data/lib/action_controller/routing/segments.rb +35 -0
  50. data/lib/action_controller/session/abstract_store.rb +181 -0
  51. data/lib/action_controller/session/cookie_store.rb +197 -175
  52. data/lib/action_controller/session/mem_cache_store.rb +36 -83
  53. data/lib/action_controller/session_management.rb +26 -134
  54. data/lib/action_controller/streaming.rb +24 -7
  55. data/lib/action_controller/templates/rescues/diagnostics.erb +2 -2
  56. data/lib/action_controller/templates/rescues/template_error.erb +2 -2
  57. data/lib/action_controller/test_case.rb +87 -30
  58. data/lib/action_controller/test_process.rb +145 -104
  59. data/lib/action_controller/uploaded_file.rb +44 -0
  60. data/lib/action_controller/url_rewriter.rb +3 -6
  61. data/lib/action_controller/vendor/html-scanner.rb +16 -0
  62. data/lib/action_controller/vendor/html-scanner/html/selector.rb +1 -1
  63. data/lib/action_controller/vendor/rack-1.0/rack.rb +89 -0
  64. data/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb +22 -0
  65. data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb +37 -0
  66. data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb +37 -0
  67. data/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb +58 -0
  68. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb +124 -0
  69. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb +51 -0
  70. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb +55 -0
  71. data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb +40 -0
  72. data/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb +480 -0
  73. data/lib/action_controller/vendor/rack-1.0/rack/builder.rb +63 -0
  74. data/lib/action_controller/vendor/rack-1.0/rack/cascade.rb +36 -0
  75. data/lib/action_controller/vendor/rack-1.0/rack/chunked.rb +49 -0
  76. data/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb +61 -0
  77. data/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb +45 -0
  78. data/lib/action_controller/vendor/rack-1.0/rack/content_length.rb +29 -0
  79. data/lib/action_controller/vendor/rack-1.0/rack/content_type.rb +23 -0
  80. data/lib/action_controller/vendor/rack-1.0/rack/deflater.rb +85 -0
  81. data/lib/action_controller/vendor/rack-1.0/rack/directory.rb +153 -0
  82. data/lib/action_controller/vendor/rack-1.0/rack/file.rb +88 -0
  83. data/lib/action_controller/vendor/rack-1.0/rack/handler.rb +48 -0
  84. data/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb +61 -0
  85. data/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb +8 -0
  86. data/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb +89 -0
  87. data/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb +55 -0
  88. data/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb +84 -0
  89. data/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb +59 -0
  90. data/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb +8 -0
  91. data/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb +18 -0
  92. data/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb +67 -0
  93. data/lib/action_controller/vendor/rack-1.0/rack/head.rb +19 -0
  94. data/lib/action_controller/vendor/rack-1.0/rack/lint.rb +462 -0
  95. data/lib/action_controller/vendor/rack-1.0/rack/lobster.rb +65 -0
  96. data/lib/action_controller/vendor/rack-1.0/rack/lock.rb +16 -0
  97. data/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb +27 -0
  98. data/lib/action_controller/vendor/rack-1.0/rack/mime.rb +204 -0
  99. data/lib/action_controller/vendor/rack-1.0/rack/mock.rb +160 -0
  100. data/lib/action_controller/vendor/rack-1.0/rack/recursive.rb +57 -0
  101. data/lib/action_controller/vendor/rack-1.0/rack/reloader.rb +64 -0
  102. data/lib/action_controller/vendor/rack-1.0/rack/request.rb +241 -0
  103. data/lib/action_controller/vendor/rack-1.0/rack/response.rb +179 -0
  104. data/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb +142 -0
  105. data/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb +91 -0
  106. data/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb +109 -0
  107. data/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb +100 -0
  108. data/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb +349 -0
  109. data/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb +106 -0
  110. data/lib/action_controller/vendor/rack-1.0/rack/static.rb +38 -0
  111. data/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb +55 -0
  112. data/lib/action_controller/vendor/rack-1.0/rack/utils.rb +392 -0
  113. data/lib/action_controller/verification.rb +1 -1
  114. data/lib/action_pack.rb +1 -1
  115. data/lib/action_pack/version.rb +2 -2
  116. data/lib/action_view.rb +22 -17
  117. data/lib/action_view/base.rb +53 -79
  118. data/lib/action_view/erb/util.rb +38 -0
  119. data/lib/action_view/helpers.rb +24 -5
  120. data/lib/action_view/helpers/active_record_helper.rb +2 -2
  121. data/lib/action_view/helpers/asset_tag_helper.rb +81 -50
  122. data/lib/action_view/helpers/atom_feed_helper.rb +1 -1
  123. data/lib/action_view/helpers/benchmark_helper.rb +26 -5
  124. data/lib/action_view/helpers/date_helper.rb +82 -7
  125. data/lib/action_view/helpers/form_helper.rb +295 -64
  126. data/lib/action_view/helpers/form_options_helper.rb +160 -18
  127. data/lib/action_view/helpers/form_tag_helper.rb +2 -2
  128. data/lib/action_view/helpers/number_helper.rb +31 -18
  129. data/lib/action_view/helpers/prototype_helper.rb +2 -12
  130. data/lib/action_view/helpers/sanitize_helper.rb +0 -10
  131. data/lib/action_view/helpers/scriptaculous_helper.rb +1 -0
  132. data/lib/action_view/helpers/tag_helper.rb +3 -4
  133. data/lib/action_view/helpers/text_helper.rb +99 -122
  134. data/lib/action_view/helpers/translation_helper.rb +19 -1
  135. data/lib/action_view/helpers/url_helper.rb +25 -2
  136. data/lib/action_view/inline_template.rb +1 -1
  137. data/lib/action_view/locale/en.yml +19 -1
  138. data/lib/action_view/partials.rb +46 -9
  139. data/lib/action_view/paths.rb +28 -84
  140. data/lib/action_view/reloadable_template.rb +117 -0
  141. data/lib/action_view/renderable.rb +28 -35
  142. data/lib/action_view/renderable_partial.rb +3 -4
  143. data/lib/action_view/template.rb +172 -31
  144. data/lib/action_view/template_error.rb +8 -9
  145. data/lib/action_view/template_handler.rb +1 -1
  146. data/lib/action_view/template_handlers.rb +9 -6
  147. data/lib/action_view/template_handlers/erb.rb +2 -39
  148. data/lib/action_view/template_handlers/rjs.rb +1 -0
  149. data/lib/action_view/test_case.rb +27 -1
  150. data/test/abstract_unit.rb +23 -17
  151. data/test/active_record_unit.rb +5 -4
  152. data/test/activerecord/active_record_store_test.rb +139 -106
  153. data/test/activerecord/render_partial_with_record_identification_test.rb +5 -21
  154. data/test/controller/action_pack_assertions_test.rb +25 -23
  155. data/test/controller/addresses_render_test.rb +3 -6
  156. data/test/controller/assert_select_test.rb +83 -70
  157. data/test/controller/base_test.rb +11 -13
  158. data/test/controller/benchmark_test.rb +3 -3
  159. data/test/controller/caching_test.rb +34 -24
  160. data/test/controller/capture_test.rb +3 -6
  161. data/test/controller/content_type_test.rb +3 -6
  162. data/test/controller/cookie_test.rb +31 -66
  163. data/test/controller/deprecation/deprecated_base_methods_test.rb +9 -11
  164. data/test/controller/dispatcher_test.rb +23 -28
  165. data/test/controller/fake_models.rb +8 -0
  166. data/test/controller/filters_test.rb +6 -2
  167. data/test/controller/flash_test.rb +2 -6
  168. data/test/controller/helper_test.rb +15 -1
  169. data/test/controller/html-scanner/document_test.rb +1 -1
  170. data/test/controller/html-scanner/sanitizer_test.rb +1 -1
  171. data/test/controller/http_basic_authentication_test.rb +88 -0
  172. data/test/controller/http_digest_authentication_test.rb +178 -0
  173. data/test/controller/integration_test.rb +56 -52
  174. data/test/controller/layout_test.rb +46 -44
  175. data/test/controller/middleware_stack_test.rb +90 -0
  176. data/test/controller/mime_responds_test.rb +7 -11
  177. data/test/controller/mime_type_test.rb +9 -0
  178. data/test/controller/polymorphic_routes_test.rb +235 -151
  179. data/test/controller/rack_test.rb +52 -81
  180. data/test/controller/redirect_test.rb +6 -14
  181. data/test/controller/render_test.rb +273 -60
  182. data/test/controller/request/json_params_parsing_test.rb +45 -0
  183. data/test/controller/request/multipart_params_parsing_test.rb +223 -0
  184. data/test/controller/request/query_string_parsing_test.rb +120 -0
  185. data/test/controller/request/url_encoded_params_parsing_test.rb +184 -0
  186. data/test/controller/request/xml_params_parsing_test.rb +88 -0
  187. data/test/controller/request_forgery_protection_test.rb +17 -98
  188. data/test/controller/request_test.rb +45 -530
  189. data/test/controller/rescue_test.rb +45 -22
  190. data/test/controller/resources_test.rb +112 -37
  191. data/test/controller/routing_test.rb +1442 -1384
  192. data/test/controller/selector_test.rb +3 -3
  193. data/test/controller/send_file_test.rb +30 -3
  194. data/test/controller/session/cookie_store_test.rb +169 -240
  195. data/test/controller/session/mem_cache_store_test.rb +94 -148
  196. data/test/controller/session/test_session_test.rb +58 -0
  197. data/test/controller/test_test.rb +32 -13
  198. data/test/controller/url_rewriter_test.rb +54 -4
  199. data/test/controller/verification_test.rb +1 -1
  200. data/test/controller/view_paths_test.rb +15 -15
  201. data/test/controller/webservice_test.rb +178 -147
  202. data/test/fixtures/alternate_helpers/foo_helper.rb +3 -0
  203. data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
  204. data/test/fixtures/layouts/default_html.html.erb +1 -0
  205. data/test/fixtures/layouts/xhr.html.erb +2 -0
  206. data/test/fixtures/multipart/empty +10 -0
  207. data/test/fixtures/multipart/hello.txt +1 -0
  208. data/test/fixtures/multipart/none +9 -0
  209. data/test/fixtures/public/500.da.html +1 -0
  210. data/test/fixtures/quiz/questions/_question.html.erb +1 -0
  211. data/test/fixtures/replies.yml +1 -1
  212. data/test/fixtures/test/_one.html.erb +1 -0
  213. data/test/fixtures/test/_two.html.erb +1 -0
  214. data/test/fixtures/test/dont_pick_me +1 -0
  215. data/test/fixtures/test/hello.builder +1 -1
  216. data/test/fixtures/test/hello_world.da.html.erb +1 -0
  217. data/test/fixtures/test/hello_world.erb~ +1 -0
  218. data/test/fixtures/test/hello_world.pt-BR.html.erb +1 -0
  219. data/test/fixtures/test/malformed/malformed.en.html.erb~ +1 -0
  220. data/test/fixtures/test/malformed/malformed.erb~ +1 -0
  221. data/test/fixtures/test/malformed/malformed.html.erb~ +1 -0
  222. data/test/fixtures/test/render_explicit_html_template.js.rjs +1 -0
  223. data/test/fixtures/test/render_implicit_html_template.js.rjs +1 -0
  224. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +1 -0
  225. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +1 -0
  226. data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +1 -0
  227. data/test/fixtures/test/utf8.html.erb +2 -0
  228. data/test/template/active_record_helper_i18n_test.rb +31 -33
  229. data/test/template/active_record_helper_test.rb +34 -0
  230. data/test/template/asset_tag_helper_test.rb +52 -14
  231. data/test/template/atom_feed_helper_test.rb +3 -5
  232. data/test/template/benchmark_helper_test.rb +50 -24
  233. data/test/template/compiled_templates_test.rb +177 -33
  234. data/test/template/date_helper_i18n_test.rb +88 -81
  235. data/test/template/date_helper_test.rb +427 -43
  236. data/test/template/form_helper_test.rb +243 -44
  237. data/test/template/form_options_helper_test.rb +631 -565
  238. data/test/template/form_tag_helper_test.rb +9 -2
  239. data/test/template/javascript_helper_test.rb +0 -5
  240. data/test/template/number_helper_i18n_test.rb +60 -48
  241. data/test/template/number_helper_test.rb +1 -0
  242. data/test/template/render_test.rb +117 -35
  243. data/test/template/test_test.rb +4 -6
  244. data/test/template/text_helper_test.rb +129 -50
  245. data/test/template/translation_helper_test.rb +23 -19
  246. data/test/template/url_helper_test.rb +35 -2
  247. data/test/view/test_case_test.rb +8 -0
  248. metadata +197 -23
  249. data/lib/action_controller/assertions.rb +0 -69
  250. data/lib/action_controller/caching/sql_cache.rb +0 -18
  251. data/lib/action_controller/cgi_ext/session.rb +0 -53
  252. data/lib/action_controller/components.rb +0 -169
  253. data/lib/action_controller/rack_process.rb +0 -297
  254. data/lib/action_controller/request_profiler.rb +0 -169
  255. data/lib/action_controller/session/active_record_store.rb +0 -340
  256. data/lib/action_controller/session/drb_server.rb +0 -32
  257. data/lib/action_controller/session/drb_store.rb +0 -35
  258. data/test/controller/cgi_test.rb +0 -269
  259. data/test/controller/components_test.rb +0 -156
  260. data/test/controller/http_authentication_test.rb +0 -54
  261. data/test/controller/integration_upload_test.rb +0 -43
  262. data/test/controller/session_fixation_test.rb +0 -89
  263. data/test/controller/session_management_test.rb +0 -178
  264. data/test/fixtures/test/hello_world.js +0 -1
@@ -0,0 +1,88 @@
1
+ require 'abstract_unit'
2
+
3
+ class XmlParamsParsingTest < ActionController::IntegrationTest
4
+ class TestController < ActionController::Base
5
+ class << self
6
+ attr_accessor :last_request_parameters
7
+ end
8
+
9
+ def parse
10
+ self.class.last_request_parameters = request.request_parameters
11
+ head :ok
12
+ end
13
+ end
14
+
15
+ def teardown
16
+ TestController.last_request_parameters = nil
17
+ end
18
+
19
+ test "parses hash params" do
20
+ with_test_routing do
21
+ xml = "<person><name>David</name></person>"
22
+ post "/parse", xml, default_headers
23
+ assert_response :ok
24
+ assert_equal({"person" => {"name" => "David"}}, TestController.last_request_parameters)
25
+ end
26
+ end
27
+
28
+ test "parses single file" do
29
+ with_test_routing do
30
+ xml = "<person><name>David</name><avatar type='file' name='me.jpg' content_type='image/jpg'>#{ActiveSupport::Base64.encode64('ABC')}</avatar></person>"
31
+ post "/parse", xml, default_headers
32
+ assert_response :ok
33
+
34
+ person = TestController.last_request_parameters
35
+ assert_equal "image/jpg", person['person']['avatar'].content_type
36
+ assert_equal "me.jpg", person['person']['avatar'].original_filename
37
+ assert_equal "ABC", person['person']['avatar'].read
38
+ end
39
+ end
40
+
41
+ test "parses multiple files" do
42
+ xml = <<-end_body
43
+ <person>
44
+ <name>David</name>
45
+ <avatars>
46
+ <avatar type='file' name='me.jpg' content_type='image/jpg'>#{ActiveSupport::Base64.encode64('ABC')}</avatar>
47
+ <avatar type='file' name='you.gif' content_type='image/gif'>#{ActiveSupport::Base64.encode64('DEF')}</avatar>
48
+ </avatars>
49
+ </person>
50
+ end_body
51
+
52
+ with_test_routing do
53
+ post "/parse", xml, default_headers
54
+ assert_response :ok
55
+ end
56
+
57
+ person = TestController.last_request_parameters
58
+
59
+ assert_equal "image/jpg", person['person']['avatars']['avatar'].first.content_type
60
+ assert_equal "me.jpg", person['person']['avatars']['avatar'].first.original_filename
61
+ assert_equal "ABC", person['person']['avatars']['avatar'].first.read
62
+
63
+ assert_equal "image/gif", person['person']['avatars']['avatar'].last.content_type
64
+ assert_equal "you.gif", person['person']['avatars']['avatar'].last.original_filename
65
+ assert_equal "DEF", person['person']['avatars']['avatar'].last.read
66
+ end
67
+
68
+ private
69
+ def with_test_routing
70
+ with_routing do |set|
71
+ set.draw do |map|
72
+ map.connect ':action', :controller => "xml_params_parsing_test/test"
73
+ end
74
+ yield
75
+ end
76
+ end
77
+
78
+ def default_headers
79
+ {'CONTENT_TYPE' => 'application/xml'}
80
+ end
81
+ end
82
+
83
+ class LegacyXmlParamsParsingTest < XmlParamsParsingTest
84
+ private
85
+ def default_headers
86
+ {'HTTP_X_POST_DATA_FORMAT' => 'xml'}
87
+ end
88
+ end
@@ -5,13 +5,6 @@ ActionController::Routing::Routes.draw do |map|
5
5
  map.connect ':controller/:action/:id'
6
6
  end
7
7
 
8
- # simulates cookie session store
9
- class FakeSessionDbMan
10
- def self.generate_digest(data)
11
- Digest::SHA1.hexdigest("secure")
12
- end
13
- end
14
-
15
8
  # common controller actions
16
9
  module RequestForgeryProtectionActions
17
10
  def index
@@ -35,30 +28,11 @@ end
35
28
 
36
29
  # sample controllers
37
30
  class RequestForgeryProtectionController < ActionController::Base
38
- include RequestForgeryProtectionActions
39
- protect_from_forgery :only => :index, :secret => 'abc'
40
- end
41
-
42
- class RequestForgeryProtectionWithoutSecretController < ActionController::Base
43
- include RequestForgeryProtectionActions
44
- protect_from_forgery
45
- end
46
-
47
- # no token is given, assume the cookie store is used
48
- class CsrfCookieMonsterController < ActionController::Base
49
31
  include RequestForgeryProtectionActions
50
32
  protect_from_forgery :only => :index
51
33
  end
52
34
 
53
- # sessions are turned off
54
- class SessionOffController < ActionController::Base
55
- protect_from_forgery :secret => 'foobar'
56
- session :off
57
- def rescue_action(e) raise e end
58
- include RequestForgeryProtectionActions
59
- end
60
-
61
- class FreeCookieController < CsrfCookieMonsterController
35
+ class FreeCookieController < RequestForgeryProtectionController
62
36
  self.allow_forgery_protection = false
63
37
 
64
38
  def index
@@ -105,17 +79,17 @@ module RequestForgeryProtectionTests
105
79
 
106
80
  def test_should_not_allow_html_post_without_token
107
81
  @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
108
- assert_raises(ActionController::InvalidAuthenticityToken) { post :index, :format => :html }
82
+ assert_raise(ActionController::InvalidAuthenticityToken) { post :index, :format => :html }
109
83
  end
110
84
 
111
85
  def test_should_not_allow_html_put_without_token
112
86
  @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
113
- assert_raises(ActionController::InvalidAuthenticityToken) { put :index, :format => :html }
87
+ assert_raise(ActionController::InvalidAuthenticityToken) { put :index, :format => :html }
114
88
  end
115
89
 
116
90
  def test_should_not_allow_html_delete_without_token
117
91
  @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
118
- assert_raises(ActionController::InvalidAuthenticityToken) { delete :index, :format => :html }
92
+ assert_raise(ActionController::InvalidAuthenticityToken) { delete :index, :format => :html }
119
93
  end
120
94
 
121
95
  def test_should_allow_api_formatted_post_without_token
@@ -137,42 +111,42 @@ module RequestForgeryProtectionTests
137
111
  end
138
112
 
139
113
  def test_should_not_allow_api_formatted_post_sent_as_url_encoded_form_without_token
140
- assert_raises(ActionController::InvalidAuthenticityToken) do
114
+ assert_raise(ActionController::InvalidAuthenticityToken) do
141
115
  @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
142
116
  post :index, :format => 'xml'
143
117
  end
144
118
  end
145
119
 
146
120
  def test_should_not_allow_api_formatted_put_sent_as_url_encoded_form_without_token
147
- assert_raises(ActionController::InvalidAuthenticityToken) do
121
+ assert_raise(ActionController::InvalidAuthenticityToken) do
148
122
  @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
149
123
  put :index, :format => 'xml'
150
124
  end
151
125
  end
152
126
 
153
127
  def test_should_not_allow_api_formatted_delete_sent_as_url_encoded_form_without_token
154
- assert_raises(ActionController::InvalidAuthenticityToken) do
128
+ assert_raise(ActionController::InvalidAuthenticityToken) do
155
129
  @request.env['CONTENT_TYPE'] = Mime::URL_ENCODED_FORM.to_s
156
130
  delete :index, :format => 'xml'
157
131
  end
158
132
  end
159
133
 
160
134
  def test_should_not_allow_api_formatted_post_sent_as_multipart_form_without_token
161
- assert_raises(ActionController::InvalidAuthenticityToken) do
135
+ assert_raise(ActionController::InvalidAuthenticityToken) do
162
136
  @request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s
163
137
  post :index, :format => 'xml'
164
138
  end
165
139
  end
166
140
 
167
141
  def test_should_not_allow_api_formatted_put_sent_as_multipart_form_without_token
168
- assert_raises(ActionController::InvalidAuthenticityToken) do
142
+ assert_raise(ActionController::InvalidAuthenticityToken) do
169
143
  @request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s
170
144
  put :index, :format => 'xml'
171
145
  end
172
146
  end
173
147
 
174
148
  def test_should_not_allow_api_formatted_delete_sent_as_multipart_form_without_token
175
- assert_raises(ActionController::InvalidAuthenticityToken) do
149
+ assert_raise(ActionController::InvalidAuthenticityToken) do
176
150
  @request.env['CONTENT_TYPE'] = Mime::MULTIPART_FORM.to_s
177
151
  delete :index, :format => 'xml'
178
152
  end
@@ -230,62 +204,28 @@ end
230
204
 
231
205
  # OK let's get our test on
232
206
 
233
- class RequestForgeryProtectionControllerTest < Test::Unit::TestCase
207
+ class RequestForgeryProtectionControllerTest < ActionController::TestCase
234
208
  include RequestForgeryProtectionTests
235
209
  def setup
236
210
  @controller = RequestForgeryProtectionController.new
237
211
  @request = ActionController::TestRequest.new
238
212
  @request.format = :html
239
213
  @response = ActionController::TestResponse.new
240
- class << @request.session
241
- def session_id() '123' end
242
- end
243
- @token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
244
- ActionController::Base.request_forgery_protection_token = :authenticity_token
245
- end
246
- end
214
+ @token = "cf50faa3fe97702ca1ae"
247
215
 
248
- class RequestForgeryProtectionWithoutSecretControllerTest < Test::Unit::TestCase
249
- def setup
250
- @controller = RequestForgeryProtectionWithoutSecretController.new
251
- @request = ActionController::TestRequest.new
252
- @response = ActionController::TestResponse.new
253
- class << @request.session
254
- def session_id() '123' end
255
- end
256
- @token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
216
+ ActiveSupport::SecureRandom.stubs(:base64).returns(@token)
257
217
  ActionController::Base.request_forgery_protection_token = :authenticity_token
258
218
  end
259
-
260
- # def test_should_raise_error_without_secret
261
- # assert_raises ActionController::InvalidAuthenticityToken do
262
- # get :index
263
- # end
264
- # end
265
219
  end
266
220
 
267
- class CsrfCookieMonsterControllerTest < Test::Unit::TestCase
268
- include RequestForgeryProtectionTests
269
- def setup
270
- @controller = CsrfCookieMonsterController.new
271
- @request = ActionController::TestRequest.new
272
- @response = ActionController::TestResponse.new
273
- class << @request.session
274
- attr_accessor :dbman
275
- end
276
- # simulate a cookie session store
277
- @request.session.dbman = FakeSessionDbMan
278
- @token = Digest::SHA1.hexdigest("secure")
279
- ActionController::Base.request_forgery_protection_token = :authenticity_token
280
- end
281
- end
282
-
283
- class FreeCookieControllerTest < Test::Unit::TestCase
221
+ class FreeCookieControllerTest < ActionController::TestCase
284
222
  def setup
285
223
  @controller = FreeCookieController.new
286
224
  @request = ActionController::TestRequest.new
287
225
  @response = ActionController::TestResponse.new
288
- @token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
226
+ @token = "cf50faa3fe97702ca1ae"
227
+
228
+ ActiveSupport::SecureRandom.stubs(:base64).returns(@token)
289
229
  end
290
230
 
291
231
  def test_should_not_render_form_with_token_tag
@@ -304,24 +244,3 @@ class FreeCookieControllerTest < Test::Unit::TestCase
304
244
  end
305
245
  end
306
246
  end
307
-
308
- class SessionOffControllerTest < Test::Unit::TestCase
309
- def setup
310
- @controller = SessionOffController.new
311
- @request = ActionController::TestRequest.new
312
- @response = ActionController::TestResponse.new
313
- @token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('SHA1'), 'abc', '123')
314
- end
315
-
316
- # TODO: Rewrite this test.
317
- # This test was passing but for the wrong reason.
318
- # Sessions aren't really being turned off, so an exception was raised
319
- # because sessions weren't on - not because the token didn't match.
320
- #
321
- # def test_should_raise_correct_exception
322
- # @request.session = {} # session(:off) doesn't appear to work with controller tests
323
- # assert_raises(ActionController::InvalidAuthenticityToken) do
324
- # post :index, :authenticity_token => @token, :format => :html
325
- # end
326
- # end
327
- end
@@ -1,7 +1,6 @@
1
1
  require 'abstract_unit'
2
- require 'action_controller/integration'
3
2
 
4
- class RequestTest < Test::Unit::TestCase
3
+ class RequestTest < ActiveSupport::TestCase
5
4
  def setup
6
5
  ActionController::Base.relative_url_root = nil
7
6
  @request = ActionController::TestRequest.new
@@ -15,60 +14,69 @@ class RequestTest < Test::Unit::TestCase
15
14
  assert_equal '0.0.0.0', @request.remote_ip
16
15
 
17
16
  @request.remote_addr = '1.2.3.4'
18
- assert_equal '1.2.3.4', @request.remote_ip(true)
17
+ assert_equal '1.2.3.4', @request.remote_ip
19
18
 
20
19
  @request.remote_addr = '1.2.3.4,3.4.5.6'
21
- assert_equal '1.2.3.4', @request.remote_ip(true)
20
+ assert_equal '1.2.3.4', @request.remote_ip
22
21
 
23
22
  @request.env['HTTP_CLIENT_IP'] = '2.3.4.5'
24
- assert_equal '1.2.3.4', @request.remote_ip(true)
23
+ assert_equal '1.2.3.4', @request.remote_ip
25
24
 
26
25
  @request.remote_addr = '192.168.0.1'
27
- assert_equal '2.3.4.5', @request.remote_ip(true)
26
+ assert_equal '2.3.4.5', @request.remote_ip
28
27
  @request.env.delete 'HTTP_CLIENT_IP'
29
28
 
30
29
  @request.remote_addr = '1.2.3.4'
31
30
  @request.env['HTTP_X_FORWARDED_FOR'] = '3.4.5.6'
32
- assert_equal '1.2.3.4', @request.remote_ip(true)
31
+ assert_equal '1.2.3.4', @request.remote_ip
33
32
 
34
33
  @request.remote_addr = '127.0.0.1'
35
34
  @request.env['HTTP_X_FORWARDED_FOR'] = '3.4.5.6'
36
- assert_equal '3.4.5.6', @request.remote_ip(true)
35
+ assert_equal '3.4.5.6', @request.remote_ip
37
36
 
38
37
  @request.env['HTTP_X_FORWARDED_FOR'] = 'unknown,3.4.5.6'
39
- assert_equal '3.4.5.6', @request.remote_ip(true)
38
+ assert_equal '3.4.5.6', @request.remote_ip
40
39
 
41
40
  @request.env['HTTP_X_FORWARDED_FOR'] = '172.16.0.1,3.4.5.6'
42
- assert_equal '3.4.5.6', @request.remote_ip(true)
41
+ assert_equal '3.4.5.6', @request.remote_ip
43
42
 
44
43
  @request.env['HTTP_X_FORWARDED_FOR'] = '192.168.0.1,3.4.5.6'
45
- assert_equal '3.4.5.6', @request.remote_ip(true)
44
+ assert_equal '3.4.5.6', @request.remote_ip
46
45
 
47
46
  @request.env['HTTP_X_FORWARDED_FOR'] = '10.0.0.1,3.4.5.6'
48
- assert_equal '3.4.5.6', @request.remote_ip(true)
47
+ assert_equal '3.4.5.6', @request.remote_ip
49
48
 
50
49
  @request.env['HTTP_X_FORWARDED_FOR'] = '10.0.0.1, 10.0.0.1, 3.4.5.6'
51
- assert_equal '3.4.5.6', @request.remote_ip(true)
50
+ assert_equal '3.4.5.6', @request.remote_ip
52
51
 
53
52
  @request.env['HTTP_X_FORWARDED_FOR'] = '127.0.0.1,3.4.5.6'
54
- assert_equal '3.4.5.6', @request.remote_ip(true)
53
+ assert_equal '3.4.5.6', @request.remote_ip
55
54
 
56
55
  @request.env['HTTP_X_FORWARDED_FOR'] = 'unknown,192.168.0.1'
57
- assert_equal 'unknown', @request.remote_ip(true)
56
+ assert_equal 'unknown', @request.remote_ip
58
57
 
59
58
  @request.env['HTTP_X_FORWARDED_FOR'] = '9.9.9.9, 3.4.5.6, 10.0.0.1, 172.31.4.4'
60
- assert_equal '3.4.5.6', @request.remote_ip(true)
59
+ assert_equal '3.4.5.6', @request.remote_ip
61
60
 
62
61
  @request.env['HTTP_CLIENT_IP'] = '8.8.8.8'
63
- e = assert_raises(ActionController::ActionControllerError) {
64
- @request.remote_ip(true)
62
+ e = assert_raise(ActionController::ActionControllerError) {
63
+ @request.remote_ip
65
64
  }
66
65
  assert_match /IP spoofing attack/, e.message
67
66
  assert_match /HTTP_X_FORWARDED_FOR="9.9.9.9, 3.4.5.6, 10.0.0.1, 172.31.4.4"/, e.message
68
67
  assert_match /HTTP_CLIENT_IP="8.8.8.8"/, e.message
69
68
 
69
+ # turn IP Spoofing detection off.
70
+ # This is useful for sites that are aimed at non-IP clients. The typical
71
+ # example is WAP. Since the cellular network is not IP based, it's a
72
+ # leap of faith to assume that their proxies are ever going to set the
73
+ # HTTP_CLIENT_IP/HTTP_X_FORWARDED_FOR headers properly.
74
+ ActionController::Base.ip_spoofing_check = false
75
+ assert_equal('8.8.8.8', @request.remote_ip)
76
+ ActionController::Base.ip_spoofing_check = true
77
+
70
78
  @request.env['HTTP_X_FORWARDED_FOR'] = '8.8.8.8, 9.9.9.9'
71
- assert_equal '8.8.8.8', @request.remote_ip(true)
79
+ assert_equal '8.8.8.8', @request.remote_ip
72
80
 
73
81
  @request.env.delete 'HTTP_CLIENT_IP'
74
82
  @request.env.delete 'HTTP_X_FORWARDED_FOR'
@@ -181,8 +189,8 @@ class RequestTest < Test::Unit::TestCase
181
189
  @request.env['PATH_INFO'] = "/path/of/some/uri?mapped=1"
182
190
  @request.env['SCRIPT_NAME'] = "/path/dispatch.rb"
183
191
  @request.set_REQUEST_URI nil
184
- assert_equal "/path/of/some/uri?mapped=1", @request.request_uri(true)
185
- assert_equal "/of/some/uri", @request.path(true)
192
+ assert_equal "/path/of/some/uri?mapped=1", @request.request_uri
193
+ assert_equal "/of/some/uri", @request.path
186
194
  ActionController::Base.relative_url_root = nil
187
195
 
188
196
  @request.env['PATH_INFO'] = "/path/of/some/uri"
@@ -217,12 +225,12 @@ class RequestTest < Test::Unit::TestCase
217
225
 
218
226
  @request.set_REQUEST_URI '/hieraki/dispatch.cgi'
219
227
  ActionController::Base.relative_url_root = '/hieraki'
220
- assert_equal "/dispatch.cgi", @request.path(true)
228
+ assert_equal "/dispatch.cgi", @request.path
221
229
  ActionController::Base.relative_url_root = nil
222
230
 
223
231
  @request.set_REQUEST_URI '/hieraki/dispatch.cgi'
224
232
  ActionController::Base.relative_url_root = '/foo'
225
- assert_equal "/hieraki/dispatch.cgi", @request.path(true)
233
+ assert_equal "/hieraki/dispatch.cgi", @request.path
226
234
  ActionController::Base.relative_url_root = nil
227
235
 
228
236
  # This test ensures that Rails uses REQUEST_URI over PATH_INFO
@@ -230,8 +238,8 @@ class RequestTest < Test::Unit::TestCase
230
238
  @request.env['REQUEST_URI'] = "/some/path"
231
239
  @request.env['PATH_INFO'] = "/another/path"
232
240
  @request.env['SCRIPT_NAME'] = "/dispatch.cgi"
233
- assert_equal "/some/path", @request.request_uri(true)
234
- assert_equal "/some/path", @request.path(true)
241
+ assert_equal "/some/path", @request.request_uri
242
+ assert_equal "/some/path", @request.path
235
243
  end
236
244
 
237
245
  def test_host_with_default_port
@@ -247,13 +255,13 @@ class RequestTest < Test::Unit::TestCase
247
255
  end
248
256
 
249
257
  def test_server_software
250
- assert_equal nil, @request.server_software(true)
258
+ assert_equal nil, @request.server_software
251
259
 
252
260
  @request.env['SERVER_SOFTWARE'] = 'Apache3.422'
253
- assert_equal 'apache', @request.server_software(true)
261
+ assert_equal 'apache', @request.server_software
254
262
 
255
263
  @request.env['SERVER_SOFTWARE'] = 'lighttpd(1.1.4)'
256
- assert_equal 'lighttpd', @request.server_software(true)
264
+ assert_equal 'lighttpd', @request.server_software
257
265
  end
258
266
 
259
267
  def test_xml_http_request
@@ -289,25 +297,23 @@ class RequestTest < Test::Unit::TestCase
289
297
  end
290
298
 
291
299
  def test_invalid_http_method_raises_exception
292
- assert_raises(ActionController::UnknownHttpMethod) do
300
+ assert_raise(ActionController::UnknownHttpMethod) do
293
301
  self.request_method = :random_method
302
+ @request.request_method
294
303
  end
295
304
  end
296
305
 
297
306
  def test_allow_method_hacking_on_post
298
- self.request_method = :post
299
307
  [:get, :head, :options, :put, :post, :delete].each do |method|
300
- @request.instance_eval { @parameters = { :_method => method.to_s } ; @request_method = nil }
301
- @request.request_method(true)
308
+ self.request_method = method
302
309
  assert_equal(method == :head ? :get : method, @request.method)
303
310
  end
304
311
  end
305
312
 
306
313
  def test_invalid_method_hacking_on_post_raises_exception
307
- self.request_method = :post
308
- @request.instance_eval { @parameters = { :_method => :random_method } ; @request_method = nil }
309
- assert_raises(ActionController::UnknownHttpMethod) do
310
- @request.request_method(true)
314
+ assert_raise(ActionController::UnknownHttpMethod) do
315
+ self.request_method = :_random_method
316
+ @request.request_method
311
317
  end
312
318
  end
313
319
 
@@ -385,8 +391,8 @@ class RequestTest < Test::Unit::TestCase
385
391
  end
386
392
 
387
393
  def test_parameters
388
- @request.instance_eval { @request_parameters = { "foo" => 1 } }
389
- @request.instance_eval { @query_parameters = { "bar" => 2 } }
394
+ @request.stubs(:request_parameters).returns({ "foo" => 1 })
395
+ @request.stubs(:query_parameters).returns({ "bar" => 2 })
390
396
 
391
397
  assert_equal({"foo" => 1, "bar" => 2}, @request.parameters)
392
398
  assert_equal({"foo" => 1}, @request.request_parameters)
@@ -396,497 +402,6 @@ class RequestTest < Test::Unit::TestCase
396
402
  protected
397
403
  def request_method=(method)
398
404
  @request.env['REQUEST_METHOD'] = method.to_s.upcase
399
- @request.request_method(true)
400
- end
401
- end
402
-
403
- class UrlEncodedRequestParameterParsingTest < Test::Unit::TestCase
404
- def setup
405
- @query_string = "action=create_customer&full_name=David%20Heinemeier%20Hansson&customerId=1"
406
- @query_string_with_empty = "action=create_customer&full_name="
407
- @query_string_with_array = "action=create_customer&selected[]=1&selected[]=2&selected[]=3"
408
- @query_string_with_amps = "action=create_customer&name=Don%27t+%26+Does"
409
- @query_string_with_multiple_of_same_name =
410
- "action=update_order&full_name=Lau%20Taarnskov&products=4&products=2&products=3"
411
- @query_string_with_many_equal = "action=create_customer&full_name=abc=def=ghi"
412
- @query_string_without_equal = "action"
413
- @query_string_with_many_ampersands =
414
- "&action=create_customer&&&full_name=David%20Heinemeier%20Hansson"
415
- @query_string_with_empty_key = "action=create_customer&full_name=David%20Heinemeier%20Hansson&=Save"
416
- end
417
-
418
- def test_query_string
419
- assert_equal(
420
- { "action" => "create_customer", "full_name" => "David Heinemeier Hansson", "customerId" => "1"},
421
- ActionController::AbstractRequest.parse_query_parameters(@query_string)
422
- )
423
- end
424
-
425
- def test_deep_query_string
426
- expected = {'x' => {'y' => {'z' => '10'}}}
427
- assert_equal(expected, ActionController::AbstractRequest.parse_query_parameters('x[y][z]=10'))
428
- end
429
-
430
- def test_deep_query_string_with_array
431
- assert_equal({'x' => {'y' => {'z' => ['10']}}}, ActionController::AbstractRequest.parse_query_parameters('x[y][z][]=10'))
432
- assert_equal({'x' => {'y' => {'z' => ['10', '5']}}}, ActionController::AbstractRequest.parse_query_parameters('x[y][z][]=10&x[y][z][]=5'))
433
- end
434
-
435
- def test_deep_query_string_with_array_of_hash
436
- assert_equal({'x' => {'y' => [{'z' => '10'}]}}, ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10'))
437
- assert_equal({'x' => {'y' => [{'z' => '10', 'w' => '10'}]}}, ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][w]=10'))
438
- end
439
-
440
- def test_deep_query_string_with_array_of_hashes_with_one_pair
441
- assert_equal({'x' => {'y' => [{'z' => '10'}, {'z' => '20'}]}}, ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][z]=20'))
442
- assert_equal("10", ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][z]=20')["x"]["y"].first["z"])
443
- assert_equal("10", ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][z]=20').with_indifferent_access[:x][:y].first[:z])
444
- end
445
-
446
- def test_deep_query_string_with_array_of_hashes_with_multiple_pairs
447
- assert_equal(
448
- {'x' => {'y' => [{'z' => '10', 'w' => 'a'}, {'z' => '20', 'w' => 'b'}]}},
449
- ActionController::AbstractRequest.parse_query_parameters('x[y][][z]=10&x[y][][w]=a&x[y][][z]=20&x[y][][w]=b')
450
- )
451
- end
452
-
453
- def test_query_string_with_nil
454
- assert_equal(
455
- { "action" => "create_customer", "full_name" => ''},
456
- ActionController::AbstractRequest.parse_query_parameters(@query_string_with_empty)
457
- )
458
- end
459
-
460
- def test_query_string_with_array
461
- assert_equal(
462
- { "action" => "create_customer", "selected" => ["1", "2", "3"]},
463
- ActionController::AbstractRequest.parse_query_parameters(@query_string_with_array)
464
- )
465
- end
466
-
467
- def test_query_string_with_amps
468
- assert_equal(
469
- { "action" => "create_customer", "name" => "Don't & Does"},
470
- ActionController::AbstractRequest.parse_query_parameters(@query_string_with_amps)
471
- )
472
- end
473
-
474
- def test_query_string_with_multiple_of_same_name
475
- assert_equal(
476
- { "action" => "update_order", "full_name" => "Lau Taarnskov", "products" => "4" },
477
- ActionController::AbstractRequest.parse_query_parameters(@query_string_with_multiple_of_same_name)
478
- )
479
- end
480
-
481
- def test_query_string_with_many_equal
482
- assert_equal(
483
- { "action" => "create_customer", "full_name" => "abc=def=ghi"},
484
- ActionController::AbstractRequest.parse_query_parameters(@query_string_with_many_equal)
485
- )
486
- end
487
-
488
- def test_query_string_without_equal
489
- assert_equal(
490
- { "action" => nil },
491
- ActionController::AbstractRequest.parse_query_parameters(@query_string_without_equal)
492
- )
493
- end
494
-
495
- def test_query_string_with_empty_key
496
- assert_equal(
497
- { "action" => "create_customer", "full_name" => "David Heinemeier Hansson" },
498
- ActionController::AbstractRequest.parse_query_parameters(@query_string_with_empty_key)
499
- )
500
- end
501
-
502
- def test_query_string_with_many_ampersands
503
- assert_equal(
504
- { "action" => "create_customer", "full_name" => "David Heinemeier Hansson"},
505
- ActionController::AbstractRequest.parse_query_parameters(@query_string_with_many_ampersands)
506
- )
507
- end
508
-
509
- def test_unbalanced_query_string_with_array
510
- assert_equal(
511
- {'location' => ["1", "2"], 'age_group' => ["2"]},
512
- ActionController::AbstractRequest.parse_query_parameters("location[]=1&location[]=2&age_group[]=2")
513
- )
514
- assert_equal(
515
- {'location' => ["1", "2"], 'age_group' => ["2"]},
516
- ActionController::AbstractRequest.parse_request_parameters({'location[]' => ["1", "2"],
517
- 'age_group[]' => ["2"]})
518
- )
519
- end
520
-
521
- def test_request_hash_parsing
522
- query = {
523
- "note[viewers][viewer][][type]" => ["User", "Group"],
524
- "note[viewers][viewer][][id]" => ["1", "2"]
525
- }
526
-
527
- expected = { "note" => { "viewers"=>{"viewer"=>[{ "id"=>"1", "type"=>"User"}, {"type"=>"Group", "id"=>"2"} ]} } }
528
-
529
- assert_equal(expected, ActionController::AbstractRequest.parse_request_parameters(query))
530
- end
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
-
701
- def test_parse_params_with_array_prefix_and_hashes
702
- input = { "a[][b][c]" => %w(d) }
703
- expected = {"a" => [{"b" => {"c" => "d"}}]}
704
- assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
705
- end
706
-
707
- def test_parse_params_with_complex_nesting
708
- input = { "a[][b][c][][d][]" => %w(e) }
709
- expected = {"a" => [{"b" => {"c" => [{"d" => ["e"]}]}}]}
710
- assert_equal expected, ActionController::AbstractRequest.parse_request_parameters(input)
711
- end
712
- end
713
-
714
- class MultipartRequestParameterParsingTest < Test::Unit::TestCase
715
- FIXTURE_PATH = File.dirname(__FILE__) + '/../fixtures/multipart'
716
-
717
- def test_single_parameter
718
- params = process('single_parameter')
719
- assert_equal({ 'foo' => 'bar' }, params)
720
- end
721
-
722
- def test_bracketed_param
723
- assert_equal({ 'foo' => { 'baz' => 'bar'}}, process('bracketed_param'))
724
- end
725
-
726
- def test_text_file
727
- params = process('text_file')
728
- assert_equal %w(file foo), params.keys.sort
729
- assert_equal 'bar', params['foo']
730
-
731
- file = params['file']
732
- assert_kind_of StringIO, file
733
- assert_equal 'file.txt', file.original_filename
734
- assert_equal "text/plain", file.content_type
735
- assert_equal 'contents', file.read
736
- end
737
-
738
- def test_boundary_problem_file
739
- params = process('boundary_problem_file')
740
- assert_equal %w(file foo), params.keys.sort
741
-
742
- file = params['file']
743
- foo = params['foo']
744
-
745
- assert_kind_of Tempfile, file
746
-
747
- assert_equal 'file.txt', file.original_filename
748
- assert_equal "text/plain", file.content_type
749
-
750
- assert_equal 'bar', foo
751
- end
752
-
753
- def test_large_text_file
754
- params = process('large_text_file')
755
- assert_equal %w(file foo), params.keys.sort
756
- assert_equal 'bar', params['foo']
757
-
758
- file = params['file']
759
-
760
- assert_kind_of Tempfile, file
761
-
762
- assert_equal 'file.txt', file.original_filename
763
- assert_equal "text/plain", file.content_type
764
- assert ('a' * 20480) == file.read
765
- end
766
-
767
- uses_mocha "test_no_rewind_stream" do
768
- def test_no_rewind_stream
769
- # Ensures that parse_multipart_form_parameters works with streams that cannot be rewound
770
- file = File.open(File.join(FIXTURE_PATH, 'large_text_file'), 'rb')
771
- file.expects(:rewind).raises(Errno::ESPIPE)
772
- params = ActionController::AbstractRequest.parse_multipart_form_parameters(file, 'AaB03x', file.stat.size, {})
773
- assert_not_equal 0, file.pos # file was not rewound after reading
774
- end
775
- end
776
-
777
- def test_binary_file
778
- params = process('binary_file')
779
- assert_equal %w(file flowers foo), params.keys.sort
780
- assert_equal 'bar', params['foo']
781
-
782
- file = params['file']
783
- assert_kind_of StringIO, file
784
- assert_equal 'file.csv', file.original_filename
785
- assert_nil file.content_type
786
- assert_equal 'contents', file.read
787
-
788
- file = params['flowers']
789
- assert_kind_of StringIO, file
790
- assert_equal 'flowers.jpg', file.original_filename
791
- assert_equal "image/jpeg", file.content_type
792
- assert_equal 19512, file.size
793
- #assert_equal File.read(File.dirname(__FILE__) + '/../../../activerecord/test/fixtures/flowers.jpg'), file.read
794
- end
795
-
796
- def test_mixed_files
797
- params = process('mixed_files')
798
- assert_equal %w(files foo), params.keys.sort
799
- assert_equal 'bar', params['foo']
800
-
801
- # Ruby CGI doesn't handle multipart/mixed for us.
802
- files = params['files']
803
- assert_kind_of String, files
804
- files.force_encoding('ASCII-8BIT') if files.respond_to?(:force_encoding)
805
- assert_equal 19756, files.size
806
- end
807
-
808
- private
809
- def process(name)
810
- File.open(File.join(FIXTURE_PATH, name), 'rb') do |file|
811
- params = ActionController::AbstractRequest.parse_multipart_form_parameters(file, 'AaB03x', file.stat.size, {})
812
- assert_equal 0, file.pos # file was rewound after reading
813
- params
814
- end
815
- end
816
- end
817
-
818
- class XmlParamsParsingTest < Test::Unit::TestCase
819
- def test_hash_params
820
- person = parse_body("<person><name>David</name></person>")[:person]
821
- assert_kind_of Hash, person
822
- assert_equal 'David', person['name']
823
- end
824
-
825
- def test_single_file
826
- person = parse_body("<person><name>David</name><avatar type='file' name='me.jpg' content_type='image/jpg'>#{ActiveSupport::Base64.encode64('ABC')}</avatar></person>")
827
-
828
- assert_equal "image/jpg", person['person']['avatar'].content_type
829
- assert_equal "me.jpg", person['person']['avatar'].original_filename
830
- assert_equal "ABC", person['person']['avatar'].read
831
- end
832
-
833
- def test_multiple_files
834
- person = parse_body(<<-end_body)
835
- <person>
836
- <name>David</name>
837
- <avatars>
838
- <avatar type='file' name='me.jpg' content_type='image/jpg'>#{ActiveSupport::Base64.encode64('ABC')}</avatar>
839
- <avatar type='file' name='you.gif' content_type='image/gif'>#{ActiveSupport::Base64.encode64('DEF')}</avatar>
840
- </avatars>
841
- </person>
842
- end_body
843
-
844
- assert_equal "image/jpg", person['person']['avatars']['avatar'].first.content_type
845
- assert_equal "me.jpg", person['person']['avatars']['avatar'].first.original_filename
846
- assert_equal "ABC", person['person']['avatars']['avatar'].first.read
847
-
848
- assert_equal "image/gif", person['person']['avatars']['avatar'].last.content_type
849
- assert_equal "you.gif", person['person']['avatars']['avatar'].last.original_filename
850
- assert_equal "DEF", person['person']['avatars']['avatar'].last.read
851
- end
852
-
853
- private
854
- def parse_body(body)
855
- env = { 'rack.input' => StringIO.new(body),
856
- 'CONTENT_TYPE' => 'application/xml',
857
- 'CONTENT_LENGTH' => body.size.to_s }
858
- ActionController::RackRequest.new(env).request_parameters
859
- end
860
- end
861
-
862
- class LegacyXmlParamsParsingTest < XmlParamsParsingTest
863
- private
864
- def parse_body(body)
865
- env = { 'rack.input' => StringIO.new(body),
866
- 'HTTP_X_POST_DATA_FORMAT' => 'xml',
867
- 'CONTENT_LENGTH' => body.size.to_s }
868
- ActionController::RackRequest.new(env).request_parameters
869
- end
870
- end
871
-
872
- class JsonParamsParsingTest < Test::Unit::TestCase
873
- def test_hash_params_for_application_json
874
- person = parse_body({:person => {:name => "David"}}.to_json,'application/json')[:person]
875
- assert_kind_of Hash, person
876
- assert_equal 'David', person['name']
877
- end
878
-
879
- def test_hash_params_for_application_jsonrequest
880
- person = parse_body({:person => {:name => "David"}}.to_json,'application/jsonrequest')[:person]
881
- assert_kind_of Hash, person
882
- assert_equal 'David', person['name']
883
- end
884
-
885
- private
886
- def parse_body(body,content_type)
887
- env = { 'rack.input' => StringIO.new(body),
888
- 'CONTENT_TYPE' => content_type,
889
- 'CONTENT_LENGTH' => body.size.to_s }
890
- ActionController::RackRequest.new(env).request_parameters
405
+ @request.request_method = nil # Reset the ivar cache
891
406
  end
892
407
  end