mosquito 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'camping'
3
+
4
+ Camping.goes :ParsingArrays
5
+
6
+ class ParsingArrays::Controllers::Klonk < ParsingArrays::Controllers::R('/')
7
+ def get; render :foam; end
8
+ def post; input.inspect; end
9
+ end
10
+
11
+ module ParsingArrays::Views
12
+ def foam
13
+ h2 "This is multipart with arrays"
14
+ form(:method => :post, :enctype => 'multipart/form-data') { _inputs }
15
+ h2 "This is urlencoded with arrays"
16
+ form(:method => :post, :enctype => 'application/x-www-form-urlencoded') { _inputs }
17
+ end
18
+
19
+ def _inputs
20
+ input :type => :text, :name => "array", :value => '1'
21
+ input :type => :text, :name => "array", :value => '2'
22
+ input :type => :text, :name => "array", :value => '3'
23
+ input :type => :submit, :name => 'flush', :value => 'Observe'
24
+ end
25
+ end
data/test/test_bare.rb ADDED
@@ -0,0 +1,66 @@
1
+ require File.dirname(__FILE__) + "/../lib/mosquito"
2
+ require File.dirname(__FILE__) + "/../public/bare"
3
+
4
+ # When you got a few Camping apps in one process you actually install the session
5
+ # for all of them simply by including. We want to test operation without sessions so we
6
+ # call this app Bare, which comes before Blog.
7
+ class TestBare < Camping::FunctionalTest
8
+
9
+ test "should get index with success" do
10
+ get '/'
11
+ assert_response :success
12
+ assert_no_session
13
+ assert_match_body %r!Charles!
14
+ end
15
+
16
+ def test_get_without_arguments_should_give_us_the_index_page
17
+ get
18
+ assert_response :success
19
+ assert_match_body %r!Charles!
20
+ end
21
+
22
+ test "should get page with success" do
23
+ get '/sample'
24
+ assert_response :success
25
+ assert_no_session
26
+ assert_match_body %r!<p>A sample page</p>!
27
+ end
28
+
29
+ def test_request_uri_preserves_query_vars
30
+ get '/sample', :somevar => 10
31
+ assert_equal '/bare/sample?somevar=10', @request['REQUEST_URI']
32
+ end
33
+
34
+ test "should assert_no_match_body" do
35
+ get '/sample'
36
+ assert_no_match_body /Rubber\s+Bubblegum\s+Burt Reynolds\s+Hippopotamus/
37
+ end
38
+
39
+ test "should return error" do
40
+ get '/error'
41
+ assert_response :error
42
+ end
43
+
44
+ test "should return 404 error" do
45
+ get '/error404'
46
+ assert_response 404
47
+ end
48
+
49
+ def test_assigning_verbatim_post_payload
50
+ post '/sample', 'foo=bar&plain=flat'
51
+ @request.body.rewind
52
+ assert_equal 'foo=bar&plain=flat', @request.body.read
53
+ end
54
+
55
+ test "should redirect" do
56
+ get '/redirect'
57
+ assert_redirected_to '/faq'
58
+ end
59
+
60
+ # test "should send file" do
61
+ # get '/file'
62
+ # assert_response :success
63
+ # # TODO
64
+ # end
65
+
66
+ end
data/test/test_blog.rb CHANGED
@@ -1,31 +1,51 @@
1
1
  require File.dirname(__FILE__) + "/../lib/mosquito"
2
2
  require File.dirname(__FILE__) + "/../public/blog"
3
-
4
3
  Blog.create
5
4
  include Blog::Models
6
5
 
7
6
  class TestBlog < Camping::FunctionalTest
8
-
9
7
  fixtures :blog_posts, :blog_users, :blog_comments
10
-
8
+
11
9
  def setup
12
10
  super
13
- # Do other stuff here
11
+ # We inject the session into the blog here to prevent it from attaching to Bare as well. Normally this
12
+ # should not happen but we need to take sides to test for sessioneless Camping compliance.
13
+ unless @sesion_set
14
+ Blog.send(:include, Camping::Session)
15
+ ActiveRecord::Migration.suppress_messages do
16
+ ::Camping::Models::Session.create_schema
17
+ end
18
+ @sesion_set = true
19
+ end
14
20
  end
15
-
21
+
16
22
  def test_cookies
17
23
  get '/cookies'
18
- assert_cookie 'awesome_cookie', 'camping+for+good'
24
+ assert_cookie 'awesome_cookie', 'camping for good'
25
+ assert_equal @state.awesome_data, 'camping for good'
26
+ get '/'
19
27
  assert_equal @state.awesome_data, 'camping for good'
28
+ end
29
+
30
+ def test_cookies_persisted_across_requests_and_escaping_properly_handled
31
+ @cookies["asgård"] = 'Wøbble'
32
+ get '/cookies'
33
+ assert_equal 'asgård=W%C3%B8bble', @request['HTTP_COOKIE'], "The cookie val shouldbe escaped"
34
+ assert_response :success
35
+ assert_equal 'Wøbble', @cookies["asgård"]
36
+
20
37
  get '/'
21
38
  assert_equal @state.awesome_data, 'camping for good'
39
+ assert_equal 'Wøbble', @cookies["asgård"]
22
40
  end
23
-
41
+
24
42
  def test_index
25
43
  get
26
44
  assert_response :success
27
45
  assert_match_body %r!>blog<!
28
46
  assert_not_equal @state.awesome_data, 'camping for good'
47
+ assert_kind_of Array, @assigns[:posts]
48
+ assert_kind_of Post, assigns[:posts].first
29
49
  end
30
50
 
31
51
  def test_view
@@ -33,7 +53,7 @@ class TestBlog < Camping::FunctionalTest
33
53
  assert_response :success
34
54
  assert_match_body %r!The quick fox jumped over the lazy dog!
35
55
  end
36
-
56
+
37
57
  def test_styles
38
58
  get 'styles.css'
39
59
  assert_match_body %r!Utopia!
@@ -52,20 +72,105 @@ class TestBlog < Camping::FunctionalTest
52
72
 
53
73
  def test_comment
54
74
  assert_difference(Comment) {
55
- post 'comment', :post_username => 'jim',
56
- :post_body => 'Nice article.',
57
- :post_id => 1
75
+ post 'comment', {
76
+ :post_username => 'jim',
77
+ :post_body => 'Nice article.',
78
+ :post_id => 1
79
+ }
58
80
  assert_response :redirect
59
81
  assert_redirected_to '/view/1'
60
82
  }
61
83
  end
62
84
 
85
+ def test_sage_advice_raised_when_getting_with_files
86
+ assert_raise(Mosquito::SageAdvice) do
87
+ get '/view/1', :afile => Mosquito::MockUpload.new("apic.jpg")
88
+ end
89
+ end
90
+
91
+ def test_session_roundtrip_across_successive_requests
92
+ get '/session-roundtrip'
93
+ assert @state.has_key?(:flag_in_session)
94
+
95
+ assert_session_started
96
+ post '/session-roundtrip'
97
+ assert @state.has_key?(:second_flag), "The :second_flag key in the session gets set only if the previous flag was present"
98
+ assert_session_started
99
+ end
100
+
101
+ def test_request_uri_has_no_double_slashes
102
+ get '/session-roundtrip'
103
+ assert_equal "/blog/session-roundtrip", @request['REQUEST_URI']
104
+ end
105
+
106
+ def test_follow_redirect
107
+ get '/redirector'
108
+ assert_response :redirect
109
+
110
+ assert_redirected_to '/sniffer?one=two'
111
+
112
+ follow_redirect
113
+ roundtipped_params = YAML::load(StringIO.new(@response.body))
114
+ ref = {"one" => "two"}.with_indifferent_access
115
+ assert_equal ref, roundtipped_params
116
+ end
117
+
118
+ def test_request_honors_verbatim_query_string_and_passed_params
119
+ assert_nothing_raised do
120
+ get '/sniffer?one=2&foo=baz', :taing => 44
121
+ end
122
+
123
+ roundtripped = YAML::load(StringIO.new(@response.body.to_s))
124
+ ref = {"taing"=>"44", "one" => "2", "foo" => "baz"}
125
+ assert_equal ref, roundtripped
126
+ end
127
+
128
+ def test_uplaod_gets_a_quick_uplaod_handle
129
+ file = upload("pic.jpg")
130
+ assert_kind_of Mosquito::MockUpload, file
131
+ end
132
+
133
+ def test_intrinsic_methods
134
+ # This WILL use mocks when we get to it from more pressing matters
135
+ delete '/rest'
136
+ assert_equal 'Called delete', @response.body
137
+
138
+ put '/rest'
139
+ assert_equal 'Called put', @response.body
140
+ end
141
+
142
+ def calling_with_an_absolute_url_should_relativize
143
+ assert_equal 'test.host', @request.domain
144
+ put 'http://test.host/blog/rest'
145
+ assert_nothing_raised do
146
+ assert_equal 'Called put', @response.body
147
+ end
148
+ end
149
+
150
+ def test_calling_with_an_absolute_url_outside_of_the_default_test_host_must_raise
151
+ assert_equal 'test.host', @request.domain
152
+ assert_raise(Mosquito::NonLocalRequest) do
153
+ put 'http://yahoo.com/blog/rest'
154
+ end
155
+ end
156
+
157
+ def test_calling_with_an_absolute_url_outside_of_the_custom_test_host_must_raise
158
+ @request.domain = 'foo.bar'
159
+ assert_raise(Mosquito::NonLocalRequest) do
160
+ put 'http://test.host/blog/rest'
161
+ end
162
+ end
163
+
63
164
  end
64
165
 
65
- class TestPost < Camping::UnitTest
166
+ class TestPost < Camping::ModelTest
66
167
 
67
168
  fixtures :blog_posts, :blog_users, :blog_comments
68
-
169
+
170
+ def test_fixtures_path_is_relative_to_the_testcase
171
+ assert_equal 'test/fixtures/', self.class.fixture_path
172
+ end
173
+
69
174
  def test_create
70
175
  post = create
71
176
  assert post.valid?
@@ -83,19 +188,21 @@ class TestPost < Camping::UnitTest
83
188
  assert_equal original_count - 1, Post.count
84
189
  end
85
190
 
86
- private
191
+ private
87
192
 
88
193
  def create(options={})
89
- Post.create({ :user_id => 1,
90
- :title => "Title",
91
- :body => "Body"}.merge(options))
194
+ Post.create({
195
+ :user_id => 1,
196
+ :title => "Title",
197
+ :body => "Body"
198
+ }.merge(options))
92
199
  end
93
-
200
+
94
201
  end
95
202
 
96
- class TestUser < Camping::UnitTest
203
+ class TestUser < Camping::ModelTest
97
204
 
98
- fixtures :blog_posts, :blog_users, :blog_comments
205
+ fixtures :blog_posts, :blog_users, :blog_comments
99
206
 
100
207
  def test_create
101
208
  user = create
@@ -108,12 +215,19 @@ class TestUser < Camping::UnitTest
108
215
  assert_not_nil user.errors.on(:username)
109
216
  end
110
217
 
111
- private
112
-
218
+ test "should require username" do
219
+ assert_no_difference(User, :count) do
220
+ User.create(:username => nil)
221
+ end
222
+ end
223
+
224
+ private
225
+
113
226
  def create(options={})
114
- User.create({ :username => 'godfrey',
115
- :password => 'password' }.merge(options))
227
+ User.create({
228
+ :username => 'godfrey',
229
+ :password => 'password'
230
+ }.merge(options))
116
231
  end
117
-
118
- end
119
232
 
233
+ end
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + "/../lib/mosquito"
2
+
3
+ class TestHelpers < Camping::ModelTest
4
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=8921&group_id=351&atid=1416
5
+ def test_supports_old_style_and_new_style_fixture_generation
6
+ assert self.respond_to?(:create_fixtures), "Oldstyle method should work"
7
+ assert self.class.respond_to?(:fixtures), "Newstyle method should work"
8
+ end
9
+
10
+ def test_stash_and_unstash
11
+ someval = {:foo => "bar"}
12
+ assert_nothing_raised do
13
+ assert_equal someval, Mosquito::stash(someval)
14
+ end
15
+
16
+ retr = Mosquito.unstash
17
+ assert_nil Mosquito.unstash, "There is nothing stashed now"
18
+ assert_equal retr, someval, "The value should be retrieved"
19
+ end
20
+ end
@@ -0,0 +1,292 @@
1
+ require File.dirname(__FILE__) + "/../lib/mosquito"
2
+
3
+ $KCODE = 'u'
4
+ # Sadly, Camping does not mandate UTF-8 - but we will use it here to torment the
5
+ # URL-escaping routines wïs ze ümlåuts.
6
+
7
+ # We use Sniffer to check if our request is parsed properly. After being called Sniffer
8
+ # will raise a Messenger exception with the @input inside.
9
+ Camping.goes :Sniffer
10
+ class Sniffer::Controllers::ParamPeeker < Sniffer::Controllers::R('/')
11
+ class Messenger < RuntimeError
12
+ attr_reader :packet
13
+ def initialize(packet)
14
+ @packet = packet
15
+ end
16
+ end
17
+
18
+ def post
19
+ raise Messenger.new(input.dup)
20
+ end
21
+ alias_method :get, :post
22
+ end
23
+
24
+ class Sniffer::Controllers::ServerError
25
+ def get(*a)
26
+ raise a.pop
27
+ end
28
+ end
29
+
30
+ class TestMockRequest < Test::Unit::TestCase
31
+ include Mosquito
32
+
33
+ def setup
34
+ @parsed_input = nil
35
+ @req = MockRequest.new
36
+ end
37
+
38
+ def test_default_domain_and_port
39
+ assert_equal 'test.host', @req.to_hash['SERVER_NAME']
40
+ assert_equal 'test.host', @req.to_hash['HTTP_HOST']
41
+ end
42
+
43
+ def test_envars_translate_to_readers
44
+ %w( server_name path_info accept_encoding user_agent
45
+ script_name server_protocol cache_control accept_language
46
+ host remote_addr server_software keep_alive referer accept_charset
47
+ version request_uri server_port gateway_interface accept connection
48
+ request_method).map do | envar |
49
+ true_value = (@req[envar.upcase] || @req["HTTP_" + envar.upcase])
50
+ assert_not_nil true_value,
51
+ "The environment of the default request should provide #{envar.upcase} or HTTP_#{envar.upcase}"
52
+ assert_nothing_raised do
53
+ assert_equal true_value, @req.send(envar), "The request should understand the reader for #{envar}"
54
+ assert_equal true_value, @req.send(envar.upcase), "The request should understand the reader for #{envar.upcase} " +
55
+ "for backwards compatibility"
56
+ end
57
+ end
58
+ end
59
+
60
+ def test_accessor_for_query_string
61
+ assert @req.respond_to?(:query_string), "The request must have a reader for query string"
62
+ assert @req.respond_to?(:query_string=), "The request must have a writer for query string"
63
+
64
+ qs = "one=two&foo=bar"
65
+ assert_nothing_raised { @req.query_string = qs }
66
+ assert_equal "?one=two&foo=bar", @req.query_string,
67
+ "The request should return the query string segment with a question mark"
68
+
69
+ qs = "?one=two&foo=bar"
70
+ assert_equal "?one=two&foo=bar", @req.query_string,
71
+ "The request should return the query string segment with one and only one question mark"
72
+
73
+ assert_equal '/?one=two&foo=bar', @req['REQUEST_URI'],
74
+ "The assigned query string should be propargated to REQUEST_URI"
75
+
76
+ assert_equal 'one=two&foo=bar', @req['QUERY_STRING'],
77
+ "The assigned query string should be propargated to QUERY_STRING"
78
+
79
+ @req.query_string = ''
80
+ assert_equal '/', @req['REQUEST_URI'], "The query part should be removed from the REQUEST_URI along with the qmark"
81
+ end
82
+
83
+ def test_query_string_composition_from_params
84
+ composable_hash = {
85
+ :foo => "bar",
86
+ :user => {
87
+ :login => "boss",
88
+ :password => "secret",
89
+ :friend_ids => [1, 2, 3]
90
+ }
91
+ }
92
+
93
+ assert @req.respond_to?(:query_string_params=)
94
+ @req.query_string_params = composable_hash
95
+
96
+ ref = '?foo=bar&user[friend_ids]=1&user[friend_ids]=2&user[friend_ids]=3&user[login]=boss&user[password]=secret'
97
+ assert_equal normalize_qs(ref), normalize_qs(@req.query_string)
98
+ assert_equal "/"+ref, @req['REQUEST_URI'], "The query string parameters should be propagated to the " +
99
+ "request uri and be in their sorted form"
100
+ assert_equal normalize_qs(ref), normalize_qs(@req["QUERY_STRING"]), "The query string should also land in QUERY_STRING"
101
+ end
102
+
103
+ def test_qs_assignment_with_empty_hash_unsets_envar
104
+ @req.query_string_params = {}
105
+ assert_equal '', @req.query_string, "When an empty hash is assigned the query string should be empty"
106
+ assert_nil @req.to_hash['QUERY_STRING'], "The key for QUERY_STRING should be unset in the environment"
107
+ end
108
+
109
+ def test_multipart_boundary_generation
110
+ boundaries = (1..40).map do
111
+ @req.generate_boundary
112
+ end
113
+ assert_equal boundaries.uniq.length, boundaries.length, "All boundaries generated should be unique"
114
+ assert_equal boundaries, boundaries.grep(/^msqto\-/), "All boundaries should be prepended with msqto-"
115
+ end
116
+
117
+ def test_method_missing_is_indeed_missing
118
+ assert_raise(NoMethodError) { @req.kaboodle! }
119
+ end
120
+
121
+ def test_extract_values
122
+ t = {
123
+ :foo => "bar",
124
+ :bar => {
125
+ :baz => [1,2,3],
126
+ :bam => "trunk",
127
+ },
128
+ :sequence => "xyz"
129
+ }
130
+ assert_equal ["bar", "1", "2" , "3", "trunk", "xyz"].sort, @req.send(:extract_values, t).map(&:to_s).sort,
131
+ "should properly extract infinitely deeply nested values"
132
+ end
133
+
134
+ def test_post_composition_with_urlencoding
135
+ assert_equal 'GET', @req['REQUEST_METHOD'], "The default request method is GET"
136
+
137
+ @req.post_params = {:hello => "welæcome", :name => "john", :data => {:values => [1,2,3] } }
138
+ assert_kind_of StringIO, @req.body, "The request body is an IO"
139
+ assert_equal 'POST', @req['REQUEST_METHOD'],
140
+ "When the parameters are assigned the request should be switched to POST"
141
+ assert_equal "application/x-www-form-urlencoded", @req['CONTENT_TYPE'],
142
+ "The content-type should be switched accordingly"
143
+ assert_equal normalize_qs('data[values]=1&data[values]=2&data[values]=3&hello=wel%C3%A6come&name=john'), normalize_qs(@req.body.read),
144
+ "The body should now contain URL-encoded form parameters"
145
+ end
146
+
147
+ def test_post_composition_accepts_verbatim_strings_as_payload
148
+ assert_equal 'GET', @req['REQUEST_METHOD'], "The default request method is GET"
149
+ @req.post_params = 'foo=bar&baz=bad'
150
+ assert_equal 'POST', @req['REQUEST_METHOD']
151
+ assert_equal "application/x-www-form-urlencoded", @req['CONTENT_TYPE'],
152
+ "The content-type should be switched accordingly"
153
+ assert_equal 'foo=bar&baz=bad', @req.body.read, "The payload should have been assigned directly"
154
+ end
155
+
156
+ def test_append_to_query_string
157
+ @req.append_to_query_string "x=y&boo=2"
158
+ @req.append_to_query_string "zaz=taing&schmoo=tweed"
159
+ assert_equal "x=y&boo=2&zaz=taing&schmoo=tweed", @req["QUERY_STRING"]
160
+ end
161
+
162
+ # We could let that one slip but why? If someone does TDD he deserves gratification
163
+ def test_post_composition_requiring_multipart_with_arrays_warns_the_noble_developer_and_everyone_stays_happy
164
+ assert_raise(Mosquito::SageAdvice) do
165
+ @req.post_params = {:hello => "welcome", :name => "john", :arrayed => [1, 2, 3], :somefile => MockUpload.new("pic.jpg") }
166
+ end
167
+
168
+ assert_nothing_raised do
169
+ @req.post_params = {:hello => "welcome", :name => "john", :arrayed => [1, 2, 3], :not_a_file => "shtaink" }
170
+ end
171
+ end
172
+
173
+ # We could let that one slip but why? If someone does TDD he deserves gratification
174
+ def test_get_composition_with_files_warns_the_noble_developer_and_he_quickly_corrects_himself
175
+ assert_raise(Mosquito::SageAdvice) do
176
+ @req.query_string_params = {:hello => "welcome", :somefile => MockUpload.new("pic.jpg") }
177
+ end
178
+ end
179
+
180
+ def test_post_composition_from_values_requiring_multipart
181
+ assert_equal 'GET', @req['REQUEST_METHOD'], "The default request method is GET"
182
+
183
+ @req.post_params = {:hello => "welcome", :name => "john", :somefile => MockUpload.new("pic.jpg") }
184
+
185
+ assert_kind_of StringIO, @req.body, "The request body is an IO"
186
+ assert_equal 'POST', @req['REQUEST_METHOD'], "When the parameters are assigned the request should be switched to POST"
187
+ ctype, boundary = @req['CONTENT_TYPE'].split(/=/)
188
+ boundary_with_prefix = "--" + boundary
189
+ assert_equal "multipart/form-data; boundary", ctype, "The content-type should be switched accordingly"
190
+
191
+ @req.body.rewind
192
+ output = @req.body.read.split("\r")
193
+ ref_segments = [
194
+ "--#{boundary}",
195
+ "\nContent-Disposition: form-data; name=\"hello\"",
196
+ "\n", "\nwelcome", "\n--#{boundary}",
197
+ "\nContent-Disposition: form-data; name=\"name\"",
198
+ "\n",
199
+ "\njohn",
200
+ "\n--#{boundary}",
201
+ "\nContent-Disposition: form-data; name=\"somefile\"; filename=\"pic.jpg\"",
202
+ "\nContent-Type: image/jpeg", "\nContent-Length: 120",
203
+ "\n",
204
+ /\nStub file pic\.jpg \n([AZ-az]{120})\n/,
205
+ "\n--#{boundary}--"
206
+ ]
207
+
208
+ ref_segments.each_with_index do | ref, idx |
209
+ if ref == String
210
+ assert_equal ref, output[idx], "The segment #{idx} should be #{ref}"
211
+ elsif ref == Regexp
212
+ assert_match ref, output[idx], "The segment #{idx} should match #{ref}"
213
+ end
214
+ end
215
+ end
216
+
217
+ private
218
+ # Remove the question mark, sort the pairs
219
+ def normalize_qs(query_string)
220
+ "?" + query_string.to_s.gsub(/^\?/, '').split(/&/).sort.join('&')
221
+ end
222
+ end
223
+
224
+
225
+ class TestMockRequestWithRoundtrip < Test::Unit::TestCase
226
+ include Mosquito
227
+ def setup
228
+ @parsed_input = nil
229
+ @req = MockRequest.new
230
+ end
231
+
232
+ def test_multipart_post_properly_roundtripped
233
+ @req.post_params = {:hello => "welcome", :name => "john", :somefile => MockUpload.new("pic.jpg") }
234
+
235
+ run_request!
236
+
237
+ # Reference is something like this
238
+ # {"name"=>"john", "somefile"=>{"name"=>"somefile", "type"=>"image/jpeg",
239
+ # "tempfile"=>#<File:/tmp/C.9366.0>, "filename"=>"pic.jpg"}, "hello"=>"welcome"}
240
+
241
+ assert_equal "john", @parsed_input["name"]
242
+ assert_kind_of Hash, @parsed_input["somefile"]
243
+ assert_equal "somefile", @parsed_input["somefile"]["name"]
244
+ assert_equal "pic.jpg", @parsed_input["somefile"]["filename"]
245
+ assert_equal "image/jpeg", @parsed_input["somefile"]["type"]
246
+ assert_kind_of Tempfile, @parsed_input["somefile"]["tempfile"]
247
+
248
+
249
+ @req.post_params = {:hello => "welcome", :name => "john", :arrayed => [1, 2, 3], :somefile => "instead" }
250
+ assert_kind_of StringIO, @req.body, "The request body is an IO"
251
+ assert_match /urlencoded/, @req['CONTENT_TYPE'], "The ctype should have been switched back to urlencoded"
252
+
253
+ run_request!
254
+
255
+ ref = {"name"=>"john", "arrayed"=>["1", "2", "3"], "somefile"=>"instead", "hello"=>"welcome"}
256
+ assert_equal ref, @parsed_input, "Camping should have parsed our params just like so"
257
+ end
258
+
259
+ def test_reader_and_writer_for_domain
260
+ assert_nothing_raised { assert_equal 'test.host', @req.domain }
261
+ assert_nothing_raised { @req.domain = "foo.dzing" }
262
+
263
+ assert_equal 'foo.dzing', @req.domain
264
+ assert_equal 'foo.dzing', @req['SERVER_NAME']
265
+ assert_equal 'foo.dzing', @req['HTTP_HOST']
266
+ end
267
+
268
+ def test_query_string_properly_roundtripped
269
+ parsed = {"user"=> {"friend_äidéis"=>["1", "2", "3"], "paßwort"=>"secret", "login"=>"boss"}, "foo"=>"bar"}
270
+ @req.query_string_params = parsed
271
+ run_request!
272
+ assert_equal parsed, @parsed_input
273
+ end
274
+
275
+ def test_urlencoded_post_properly_roundtripped
276
+ assert_equal 'GET', @req['REQUEST_METHOD'], "The default request method is GET"
277
+
278
+ @req.post_params = {:hello => "welæcome", :name => "john", :data => {:values => [1,2,3] } }
279
+ run_request!
280
+ ref = {"name"=>"john", "hello"=>"welæcome", "data"=>{"values"=>["1", "2", "3"]}}
281
+ assert_equal ref, @parsed_input, "Camping should have parsed our input like so"
282
+ end
283
+ private
284
+ def run_request!
285
+ @req.body.rewind
286
+ begin
287
+ Sniffer.run(@req.body, @req.to_hash)
288
+ rescue Sniffer::Controllers::ParamPeeker::Messenger => e
289
+ @parsed_input = e.packet
290
+ end
291
+ end
292
+ end