Updated README.rdoc again
[feedcatcher.git] / vendor / rails / actionpack / test / controller / request / url_encoded_params_parsing_test.rb
1 require 'abstract_unit'
2
3 class UrlEncodedParamsParsingTest < ActionController::IntegrationTest
4 class TestController < ActionController::Base
5 class << self
6 attr_accessor :last_request_parameters, :last_request_type
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 unbalanced query string with array" do
20 assert_parses(
21 {'location' => ["1", "2"], 'age_group' => ["2"]},
22 "location[]=1&location[]=2&age_group[]=2"
23 )
24 end
25
26 test "parses nested hash" do
27 query = [
28 "note[viewers][viewer][][type]=User",
29 "note[viewers][viewer][][id]=1",
30 "note[viewers][viewer][][type]=Group",
31 "note[viewers][viewer][][id]=2"
32 ].join("&")
33
34 expected = { "note" => { "viewers"=>{"viewer"=>[{ "id"=>"1", "type"=>"User"}, {"type"=>"Group", "id"=>"2"} ]} } }
35 assert_parses(expected, query)
36 end
37
38 test "parses more complex nesting" do
39 query = [
40 "customers[boston][first][name]=David",
41 "customers[boston][first][url]=http://David",
42 "customers[boston][second][name]=Allan",
43 "customers[boston][second][url]=http://Allan",
44 "something_else=blah",
45 "something_nil=",
46 "something_empty=",
47 "products[first]=Apple Computer",
48 "products[second]=Pc",
49 "=Save"
50 ].join("&")
51
52 expected = {
53 "customers" => {
54 "boston" => {
55 "first" => {
56 "name" => "David",
57 "url" => "http://David"
58 },
59 "second" => {
60 "name" => "Allan",
61 "url" => "http://Allan"
62 }
63 }
64 },
65 "something_else" => "blah",
66 "something_empty" => "",
67 "something_nil" => "",
68 "products" => {
69 "first" => "Apple Computer",
70 "second" => "Pc"
71 }
72 }
73
74 assert_parses expected, query
75 end
76
77 test "parses params with array" do
78 query = "selected[]=1&selected[]=2&selected[]=3"
79 expected = { "selected" => [ "1", "2", "3" ] }
80 assert_parses expected, query
81 end
82
83 test "parses params with nil key" do
84 query = "=&test2=value1"
85 expected = { "test2" => "value1" }
86 assert_parses expected, query
87 end
88
89 test "parses params with array prefix and hashes" do
90 query = "a[][b][c]=d"
91 expected = {"a" => [{"b" => {"c" => "d"}}]}
92 assert_parses expected, query
93 end
94
95 test "parses params with complex nesting" do
96 query = "a[][b][c][][d][]=e"
97 expected = {"a" => [{"b" => {"c" => [{"d" => ["e"]}]}}]}
98 assert_parses expected, query
99 end
100
101 test "parses params with file path" do
102 query = [
103 "customers[boston][first][name]=David",
104 "something_else=blah",
105 "logo=#{File.expand_path(__FILE__)}"
106 ].join("&")
107
108 expected = {
109 "customers" => {
110 "boston" => {
111 "first" => {
112 "name" => "David"
113 }
114 }
115 },
116 "something_else" => "blah",
117 "logo" => File.expand_path(__FILE__),
118 }
119
120 assert_parses expected, query
121 end
122
123 test "parses params with Safari 2 trailing null character" do
124 query = "selected[]=1&selected[]=2&selected[]=3\0"
125 expected = { "selected" => [ "1", "2", "3" ] }
126 assert_parses expected, query
127 end
128
129 test "passes through rack middleware and parses params" do
130 with_muck_middleware do
131 assert_parses({ "a" => { "b" => "c" } }, "a[b]=c")
132 end
133 end
134
135 # The lint wrapper is used in integration tests
136 # instead of a normal StringIO class
137 InputWrapper = Rack::Lint::InputWrapper
138
139 test "passes through rack middleware and parses params with unwindable input" do
140 InputWrapper.any_instance.stubs(:rewind).raises(Errno::ESPIPE)
141 with_muck_middleware do
142 assert_parses({ "a" => { "b" => "c" } }, "a[b]=c")
143 end
144 end
145
146 private
147 class MuckMiddleware
148 def initialize(app)
149 @app = app
150 end
151
152 def call(env)
153 req = Rack::Request.new(env)
154 req.params # Parse params
155 @app.call(env)
156 end
157 end
158
159 def with_muck_middleware
160 original_middleware = ActionController::Dispatcher.middleware
161 middleware = original_middleware.dup
162 middleware.insert_after ActionController::RewindableInput, MuckMiddleware
163 ActionController::Dispatcher.middleware = middleware
164 yield
165 ActionController::Dispatcher.middleware = original_middleware
166 end
167
168 def with_test_routing
169 with_routing do |set|
170 set.draw do |map|
171 map.connect ':action', :controller => "url_encoded_params_parsing_test/test"
172 end
173 yield
174 end
175 end
176
177 def assert_parses(expected, actual)
178 with_test_routing do
179 post "/parse", actual
180 assert_response :ok
181 assert_equal(expected, TestController.last_request_parameters)
182 end
183 end
184 end