mechanize 1.0.1.beta.20110107104205 → 2.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of mechanize might be problematic. Click here for more details.

Files changed (89) hide show
  1. data.tar.gz.sig +2 -0
  2. data/{lib/mechanize/chain/post_connect_hook.rb → .gemtest} +0 -0
  3. data/CHANGELOG.rdoc +51 -6
  4. data/EXAMPLES.rdoc +5 -3
  5. data/GUIDE.rdoc +72 -32
  6. data/LICENSE.rdoc +20 -340
  7. data/Manifest.txt +20 -27
  8. data/README.rdoc +12 -9
  9. data/Rakefile +5 -2
  10. data/examples/spider.rb +13 -2
  11. data/lib/mechanize.rb +545 -267
  12. data/lib/mechanize/content_type_error.rb +1 -1
  13. data/lib/mechanize/cookie.rb +72 -65
  14. data/lib/mechanize/cookie_jar.rb +197 -148
  15. data/lib/mechanize/element_matcher.rb +35 -0
  16. data/lib/mechanize/file.rb +3 -1
  17. data/lib/mechanize/file_connection.rb +17 -0
  18. data/lib/mechanize/file_request.rb +26 -0
  19. data/lib/mechanize/file_response.rb +61 -47
  20. data/lib/mechanize/form.rb +57 -58
  21. data/lib/mechanize/form/image_button.rb +2 -3
  22. data/lib/mechanize/form/multi_select_list.rb +71 -55
  23. data/lib/mechanize/form/select_list.rb +34 -62
  24. data/lib/mechanize/monkey_patch.rb +13 -11
  25. data/lib/mechanize/page.rb +277 -270
  26. data/lib/mechanize/page/image.rb +6 -2
  27. data/lib/mechanize/redirect_limit_reached_error.rb +1 -1
  28. data/lib/mechanize/redirect_not_get_or_head_error.rb +1 -1
  29. data/lib/mechanize/response_code_error.rb +3 -3
  30. data/lib/mechanize/unsupported_scheme_error.rb +1 -1
  31. data/lib/mechanize/uri_resolver.rb +82 -0
  32. data/lib/mechanize/util.rb +76 -60
  33. data/test/helper.rb +35 -5
  34. data/test/htdocs/dir with spaces/foo.html +1 -0
  35. data/test/htdocs/rails_3_encoding_hack_form_test.html +27 -0
  36. data/test/htdocs/tc_base_images.html +10 -0
  37. data/test/htdocs/tc_images.html +8 -0
  38. data/test/htdocs/test_click.html +11 -0
  39. data/test/servlets.rb +3 -2
  40. data/test/test_authenticate.rb +5 -5
  41. data/test/test_errors.rb +8 -8
  42. data/test/test_follow_meta.rb +4 -4
  43. data/test/test_form_as_hash.rb +4 -4
  44. data/test/test_forms.rb +3 -7
  45. data/test/test_hash_api.rb +2 -2
  46. data/test/test_headers.rb +1 -1
  47. data/test/test_images.rb +19 -0
  48. data/test/test_mech.rb +6 -6
  49. data/test/test_mechanize.rb +687 -0
  50. data/test/{test_cookie_class.rb → test_mechanize_cookie.rb} +52 -45
  51. data/test/test_mechanize_cookie_jar.rb +400 -0
  52. data/test/test_mechanize_file.rb +7 -1
  53. data/test/test_mechanize_file_request.rb +19 -0
  54. data/test/test_mechanize_file_response.rb +21 -0
  55. data/test/test_mechanize_form_image_button.rb +12 -0
  56. data/test/test_mechanize_page.rb +165 -0
  57. data/test/test_mechanize_uri_resolver.rb +29 -0
  58. data/test/{test_util.rb → test_mechanize_util.rb} +1 -1
  59. data/test/test_multi_select.rb +12 -0
  60. data/test/test_post_form.rb +7 -0
  61. data/test/test_redirect_verb_handling.rb +6 -6
  62. data/test/test_scheme.rb +0 -7
  63. data/test/test_verbs.rb +3 -3
  64. metadata +106 -72
  65. metadata.gz.sig +0 -0
  66. data/lib/mechanize/chain.rb +0 -36
  67. data/lib/mechanize/chain/auth_headers.rb +0 -78
  68. data/lib/mechanize/chain/body_decoding_handler.rb +0 -50
  69. data/lib/mechanize/chain/connection_resolver.rb +0 -28
  70. data/lib/mechanize/chain/custom_headers.rb +0 -21
  71. data/lib/mechanize/chain/handler.rb +0 -9
  72. data/lib/mechanize/chain/header_resolver.rb +0 -48
  73. data/lib/mechanize/chain/parameter_resolver.rb +0 -22
  74. data/lib/mechanize/chain/pre_connect_hook.rb +0 -20
  75. data/lib/mechanize/chain/request_resolver.rb +0 -31
  76. data/lib/mechanize/chain/response_body_parser.rb +0 -36
  77. data/lib/mechanize/chain/response_header_handler.rb +0 -34
  78. data/lib/mechanize/chain/response_reader.rb +0 -39
  79. data/lib/mechanize/chain/ssl_resolver.rb +0 -40
  80. data/lib/mechanize/chain/uri_resolver.rb +0 -75
  81. data/test/chain/test_argument_validator.rb +0 -14
  82. data/test/chain/test_auth_headers.rb +0 -25
  83. data/test/chain/test_custom_headers.rb +0 -18
  84. data/test/chain/test_header_resolver.rb +0 -27
  85. data/test/chain/test_parameter_resolver.rb +0 -35
  86. data/test/chain/test_request_resolver.rb +0 -29
  87. data/test/chain/test_response_reader.rb +0 -24
  88. data/test/test_cookie_jar.rb +0 -324
  89. data/test/test_page.rb +0 -124
@@ -20,9 +20,9 @@ class BasicAuthTest < Test::Unit::TestCase
20
20
 
21
21
  def test_no_duplicate_headers
22
22
  block_called = false
23
- @agent.pre_connect_hooks << lambda { |params|
23
+ @agent.pre_connect_hooks << lambda { |_, request|
24
24
  block_called = true
25
- params[:request].to_hash.each do |k,v|
25
+ request.to_hash.each do |k,v|
26
26
  assert_equal(1, v.length)
27
27
  end
28
28
  }
@@ -35,10 +35,10 @@ class BasicAuthTest < Test::Unit::TestCase
35
35
  class << @agent
36
36
  alias :old_fetch_page :fetch_page
37
37
  attr_accessor :requests
38
- def fetch_page(args)
38
+ def fetch_page(uri, method, *args)
39
39
  @requests ||= []
40
- x = old_fetch_page(args)
41
- @requests << args[:verb]
40
+ x = old_fetch_page(uri, method, *args)
41
+ @requests << method
42
42
  x
43
43
  end
44
44
  end
@@ -7,9 +7,9 @@ class MechErrorsTest < Test::Unit::TestCase
7
7
 
8
8
  def test_bad_form_method
9
9
  page = @agent.get("http://localhost/bad_form_test.html")
10
- assert_raise(RuntimeError) {
10
+ assert_raise ArgumentError do
11
11
  @agent.submit(page.forms.first)
12
- }
12
+ end
13
13
  end
14
14
 
15
15
  def test_non_exist
@@ -24,21 +24,21 @@ class MechErrorsTest < Test::Unit::TestCase
24
24
  page = @agent.get("http://localhost/form_test.html")
25
25
  form = page.form_with(:name => 'post_form1')
26
26
  form.radiobuttons.each { |r| r.checked = true }
27
- assert_raise(RuntimeError) {
27
+ assert_raise Mechanize::Error do
28
28
  @agent.submit(form)
29
- }
29
+ end
30
30
  end
31
31
 
32
32
  def test_unknown_agent
33
- assert_raise(RuntimeError) {
33
+ assert_raise ArgumentError do
34
34
  @agent.user_agent_alias = "Aaron's Browser"
35
- }
35
+ end
36
36
  end
37
37
 
38
38
  def test_bad_url
39
- assert_raise(RuntimeError) {
39
+ assert_raise ArgumentError do
40
40
  @agent.get('/foo.html')
41
- }
41
+ end
42
42
  end
43
43
 
44
44
  def test_unsupported_scheme
@@ -8,8 +8,8 @@ class FollowMetaTest < Test::Unit::TestCase
8
8
  def test_dont_follow_meta_in_body
9
9
  @agent.follow_meta_refresh = true
10
10
  requests = []
11
- @agent.pre_connect_hooks << lambda { |params|
12
- requests << params[:request]
11
+ @agent.pre_connect_hooks << lambda { |_, request|
12
+ requests << request
13
13
  }
14
14
 
15
15
  @agent.get('http://localhost/tc_meta_in_body.html')
@@ -25,8 +25,8 @@ class FollowMetaTest < Test::Unit::TestCase
25
25
  def test_meta_refresh_does_not_send_referer
26
26
  @agent.follow_meta_refresh = true
27
27
  requests = []
28
- @agent.pre_connect_hooks << lambda { |params|
29
- requests << params[:request]
28
+ @agent.pre_connect_hooks << lambda { |_, request|
29
+ requests << request
30
30
  }
31
31
 
32
32
  @agent.get('http://localhost/tc_follow_meta.html')
@@ -46,13 +46,13 @@ class TestFormHash < Test::Unit::TestCase
46
46
  form = @page.forms.first
47
47
 
48
48
  assert_not_nil(form)
49
- assert_equal(false, form.has_field?('name'))
50
- assert_equal(false, form.has_value?('Aaron'))
49
+ assert(!form.has_field?('name'))
50
+ assert(!form.has_value?('Aaron'))
51
51
  assert_equal(0, form.keys.length)
52
52
  assert_equal(0, form.values.length)
53
53
  form['name'] = 'Aaron'
54
- assert_equal(true, form.has_field?('name'))
55
- assert_equal(true, form.has_value?('Aaron'))
54
+ assert(form.has_field?('name'))
55
+ assert(form.has_value?('Aaron'))
56
56
  assert_equal(1, form.keys.length)
57
57
  assert_equal(['name'], form.keys)
58
58
  assert_equal(1, form.values.length)
@@ -271,7 +271,7 @@ class FormsMechTest < Test::Unit::TestCase
271
271
  page = @agent.submit(get_form, get_form.buttons.first)
272
272
 
273
273
  # Check that the submitted fields exist
274
- assert_equal(7, page.links.size, "Not enough links")
274
+ assert_equal(6, page.links.size, "Not enough links")
275
275
  assert_not_nil(
276
276
  page.links.find { |l| l.text == "likes ham:on" },
277
277
  "likes ham check box missing"
@@ -296,10 +296,6 @@ class FormsMechTest < Test::Unit::TestCase
296
296
  page.links.find { |l| l.text == "button.x:9" },
297
297
  "Image button missing"
298
298
  )
299
- assert_not_nil(
300
- page.links.find { |l| l.text == "button:button" },
301
- "Image button missing"
302
- )
303
299
  end
304
300
 
305
301
  def test_post_with_space_in_action
@@ -572,10 +568,10 @@ class FormsMechTest < Test::Unit::TestCase
572
568
  form = page.form_with(:name => 'post_form')
573
569
 
574
570
  assert_not_nil(form)
575
- assert_equal(false, form.has_field?('intarweb'))
571
+ assert(!form.has_field?('intarweb'))
576
572
  f = form.add_field!('intarweb')
577
573
  assert_not_nil(f)
578
- assert_equal(true, form.has_field?('intarweb'))
574
+ assert(form.has_field?('intarweb'))
579
575
  end
580
576
 
581
577
  def test_field_error
@@ -26,8 +26,8 @@ class TestHashApi < Test::Unit::TestCase
26
26
 
27
27
  def test_get_with_referer
28
28
  request = nil
29
- @agent.pre_connect_hooks << lambda { |params|
30
- request = params[:request]
29
+ @agent.pre_connect_hooks << lambda { |_, req|
30
+ request = req
31
31
  }
32
32
 
33
33
  @agent.get( :url => 'http://localhost/',
@@ -25,7 +25,7 @@ class TestHeaders < Test::Unit::TestCase
25
25
  when *all_keys
26
26
  # ok
27
27
  else
28
- raise "unexpected key: #{key}"
28
+ flunk "unexpected key: #{key}"
29
29
  end
30
30
  }
31
31
  assert_equal([], keys)
@@ -0,0 +1,19 @@
1
+ require "helper"
2
+
3
+ class ImagesMechTest < Test::Unit::TestCase
4
+ def setup
5
+ @agent = Mechanize.new
6
+ end
7
+
8
+ def test_base
9
+ page = @agent.get("http://google.com/tc_base_images.html")
10
+ assert_equal page.images[0].url, "http://localhost/a.jpg"
11
+ assert_equal page.images[1].url, "http://localhost/b.gif"
12
+ end
13
+
14
+ def test_base2
15
+ page = @agent.get("http://google.com/tc_images.html")
16
+ assert_equal page.images[0].url, "http://google.com/a.jpg"
17
+ assert_equal page.images[1].url, "http://google.com/b.gif"
18
+ end
19
+ end
@@ -40,8 +40,8 @@ class TestMechMethods < Test::Unit::TestCase
40
40
 
41
41
  def test_get_no_referer
42
42
  requests = []
43
- @agent.pre_connect_hooks << lambda { |params|
44
- requests << params[:request]
43
+ @agent.pre_connect_hooks << lambda { |_, request|
44
+ requests << request
45
45
  }
46
46
 
47
47
  @agent.get('http://localhost/')
@@ -59,8 +59,8 @@ class TestMechMethods < Test::Unit::TestCase
59
59
 
60
60
  def test_post_connect_hook_gets_called
61
61
  response = nil
62
- @agent.post_connect_hooks << lambda { |params|
63
- response = params[:response]
62
+ @agent.post_connect_hooks << lambda { |_, res|
63
+ response = res
64
64
  }
65
65
 
66
66
  @agent.get('http://localhost/')
@@ -69,8 +69,8 @@ class TestMechMethods < Test::Unit::TestCase
69
69
 
70
70
  def test_get_with_referer
71
71
  request = nil
72
- @agent.pre_connect_hooks << lambda { |params|
73
- request = params[:request]
72
+ @agent.pre_connect_hooks << lambda { |_, req|
73
+ request = req
74
74
  }
75
75
 
76
76
  @agent.get('http://localhost/', URI.parse('http://google.com/'))
@@ -0,0 +1,687 @@
1
+ # coding: utf-8
2
+
3
+ require 'helper'
4
+
5
+ class TestMechanize < Test::Unit::TestCase
6
+
7
+ KEY = OpenSSL::PKey::RSA.new 512
8
+ name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
9
+ CERT = OpenSSL::X509::Certificate.new
10
+ CERT.version = 2
11
+ CERT.serial = 0
12
+ CERT.not_before = Time.now
13
+ CERT.not_after = Time.now + 60
14
+ CERT.public_key = KEY.public_key
15
+ CERT.subject = name
16
+ CERT.issuer = name
17
+ CERT.sign KEY, OpenSSL::Digest::SHA1.new
18
+
19
+ def setup
20
+ @agent = Mechanize.new
21
+ @uri = URI.parse 'http://example/'
22
+ @req = Net::HTTP::Get.new '/'
23
+
24
+ @res = Net::HTTPOK.allocate
25
+ @res.instance_variable_set :@code, 200
26
+ @res.instance_variable_set :@header, {}
27
+
28
+ @headers = if RUBY_VERSION > '1.9' then
29
+ %w[accept user-agent]
30
+ else
31
+ %w[accept]
32
+ end
33
+ end
34
+
35
+ def test_cert_key_file
36
+ Tempfile.open 'key' do |key|
37
+ Tempfile.open 'cert' do |cert|
38
+ key.write KEY.to_pem
39
+ key.rewind
40
+
41
+ cert.write CERT.to_pem
42
+ cert.rewind
43
+
44
+ agent = Mechanize.new do |a|
45
+ a.cert = cert.path
46
+ a.key = key.path
47
+ end
48
+
49
+ # Certificate#== seems broken
50
+ assert_equal CERT.to_pem, agent.http.certificate.to_pem
51
+ end
52
+ end
53
+ end
54
+
55
+ def test_cert_key_object
56
+ agent = Mechanize.new do |a|
57
+ a.cert = CERT
58
+ a.key = KEY
59
+ end
60
+
61
+ assert_equal CERT, agent.http.certificate
62
+ end
63
+
64
+ def test_connection_for_file
65
+ uri = URI.parse 'file:///nonexistent'
66
+ conn = @agent.connection_for uri
67
+
68
+ assert_equal Mechanize::FileConnection.new, conn
69
+ end
70
+
71
+ def test_connection_for_http
72
+ conn = @agent.connection_for @uri
73
+
74
+ assert_equal @agent.http, conn
75
+ end
76
+
77
+ #def test_download
78
+ # Dir.mktmpdir do |dir|
79
+ # file = "#{dir}/download"
80
+ # open file, 'w' do |io|
81
+ # @agent.download 'http://example', io
82
+ # end
83
+
84
+ # assert_equal 1, File.stat(file).size
85
+ # end
86
+ #end
87
+
88
+ def test_enable_gzip
89
+ @agent.enable_gzip @req
90
+
91
+ assert_equal 'gzip,deflate,identity', @req['accept-encoding']
92
+ end
93
+
94
+ def test_enable_gzip_no
95
+ @agent.gzip_enabled = false
96
+
97
+ @agent.enable_gzip @req
98
+
99
+ assert_equal 'identity', @req['accept-encoding']
100
+ end
101
+
102
+ def test_fetch_page_file_plus
103
+ Tempfile.open '++plus++' do |io|
104
+ content = 'plusses +++'
105
+ io.write content
106
+ io.rewind
107
+
108
+ uri = URI.parse "file://#{Mechanize::Util.uri_escape io.path}"
109
+
110
+ page = @agent.send :fetch_page, uri
111
+
112
+ assert_equal content, page.body
113
+ assert_kind_of Mechanize::File, page
114
+ end
115
+ end
116
+
117
+ def test_fetch_page_file_space
118
+ foo = File.expand_path("../htdocs/dir with spaces/foo.html", __FILE__)
119
+
120
+ uri = URI.parse "file://#{Mechanize::Util.uri_escape foo}"
121
+
122
+ page = @agent.send :fetch_page, uri
123
+
124
+ assert_equal File.read(foo), page.body
125
+ assert_kind_of Mechanize::Page, page
126
+ end
127
+
128
+ def test_fetch_page_file_nonexistent
129
+ uri = URI.parse 'file:///nonexistent'
130
+
131
+ e = assert_raises Mechanize::ResponseCodeError do
132
+ page = @agent.send :fetch_page, uri
133
+ end
134
+
135
+ assert_equal '404 => Net::HTTPNotFound', e.message
136
+ end
137
+
138
+ def test_get_yield
139
+ pages = nil
140
+
141
+ @agent.get("http://localhost/file_upload.html") { |page|
142
+ pages = page
143
+ }
144
+
145
+ assert pages
146
+ assert_equal('File Upload Form', pages.title)
147
+ end
148
+
149
+ def test_http_request_file
150
+ uri = URI.parse 'file:///nonexistent'
151
+ request = @agent.http_request uri, :get
152
+
153
+ assert_kind_of Mechanize::FileRequest, request
154
+ assert_equal '/nonexistent', request.path
155
+ end
156
+
157
+ def test_http_request_get
158
+ request = @agent.http_request @uri, :get
159
+
160
+ assert_kind_of Net::HTTP::Get, request
161
+ assert_equal '/', request.path
162
+ end
163
+
164
+ def test_http_request_post
165
+ request = @agent.http_request @uri, :post
166
+
167
+ assert_kind_of Net::HTTP::Post, request
168
+ assert_equal '/', request.path
169
+ end
170
+
171
+ def test_post_connect
172
+ @agent.post_connect_hooks << proc { |agent, response|
173
+ assert_equal @agent, agent
174
+ assert_kind_of Net::HTTPResponse, response
175
+ throw :called
176
+ }
177
+
178
+ assert_throws :called do
179
+ @agent.post_connect @res
180
+ end
181
+ end
182
+
183
+ def test_pre_connect
184
+ @agent.pre_connect_hooks << proc { |agent, request|
185
+ assert_equal @agent, agent
186
+ assert_kind_of Net::HTTPRequest, request
187
+ throw :called
188
+ }
189
+
190
+ assert_throws :called do
191
+ @agent.pre_connect @req
192
+ end
193
+ end
194
+
195
+ def test_request_cookies
196
+ uri = URI.parse 'http://host.example.com'
197
+ Mechanize::Cookie.parse uri, 'hello=world domain=.example.com' do |cookie|
198
+ @agent.cookie_jar.add uri, cookie
199
+ end
200
+
201
+ @agent.request_cookies @req, uri
202
+
203
+ assert_equal 'hello=world domain=.example.com', @req['Cookie']
204
+ end
205
+
206
+ def test_request_cookies_none
207
+ @agent.request_cookies @req, @uri
208
+
209
+ assert_nil @req['Cookie']
210
+ end
211
+
212
+ def test_request_cookies_many
213
+ uri = URI.parse 'http://host.example.com'
214
+ cookie_str = 'a=b domain=.example.com, c=d domain=.example.com'
215
+ Mechanize::Cookie.parse uri, cookie_str do |cookie|
216
+ @agent.cookie_jar.add uri, cookie
217
+ end
218
+
219
+ @agent.request_cookies @req, uri
220
+
221
+ expected = cookie_str.sub ', ', '; '
222
+
223
+ assert_equal expected, @req['Cookie']
224
+ end
225
+
226
+ def test_request_cookies_wrong_domain
227
+ uri = URI.parse 'http://host.example.com'
228
+ Mechanize::Cookie.parse uri, 'hello=world domain=.example.com' do |cookie|
229
+ @agent.cookie_jar.add uri, cookie
230
+ end
231
+
232
+ @agent.request_cookies @req, @uri
233
+
234
+ assert_nil @req['Cookie']
235
+ end
236
+
237
+ def test_request_host
238
+ @agent.request_host @req, @uri
239
+
240
+ assert_equal 'example', @req['host']
241
+ end
242
+
243
+ def test_request_host_nonstandard
244
+ @uri.port = 81
245
+
246
+ @agent.request_host @req, @uri
247
+
248
+ assert_equal 'example:81', @req['host']
249
+ end
250
+
251
+ def test_request_language_charset
252
+ @agent.request_language_charset @req
253
+
254
+ assert_equal 'en-us,en;q=0.5', @req['accept-language']
255
+ assert_equal 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', @req['accept-charset']
256
+ end
257
+
258
+ def test_request_add_headers
259
+ @agent.request_add_headers @req, 'Content-Length' => 300
260
+
261
+ assert_equal '300', @req['content-length']
262
+ end
263
+
264
+ def test_request_add_headers_etag
265
+ @agent.request_add_headers @req, :etag => '300'
266
+
267
+ assert_equal '300', @req['etag']
268
+ end
269
+
270
+ def test_request_add_headers_if_modified_since
271
+ @agent.request_add_headers @req, :if_modified_since => 'some_date'
272
+
273
+ assert_equal 'some_date', @req['if-modified-since']
274
+ end
275
+
276
+ def test_request_add_headers_none
277
+ @agent.request_add_headers @req
278
+
279
+ assert_equal @headers, @req.to_hash.keys.sort
280
+ end
281
+
282
+ def test_request_add_headers_request_headers
283
+ @agent.request_headers['X-Foo'] = 'bar'
284
+
285
+ @agent.request_add_headers @req
286
+
287
+ assert_equal @headers + %w[x-foo], @req.to_hash.keys.sort
288
+ end
289
+
290
+ def test_request_add_headers_symbol
291
+ e = assert_raises ArgumentError do
292
+ @agent.request_add_headers @req, :content_length => 300
293
+ end
294
+
295
+ assert_equal 'unknown header symbol content_length', e.message
296
+ end
297
+
298
+ def test_request_referer
299
+ referer = URI.parse 'http://old.example'
300
+
301
+ @agent.request_referer @req, @uri, referer
302
+
303
+ assert_equal 'http://old.example', @req['referer']
304
+ end
305
+
306
+ def test_request_referer_https
307
+ uri = URI.parse 'https://example'
308
+ referer = URI.parse 'https://old.example'
309
+
310
+ @agent.request_referer @req, uri, referer
311
+
312
+ assert_equal 'https://old.example', @req['referer']
313
+ end
314
+
315
+ def test_request_referer_https_downgrade
316
+ referer = URI.parse 'https://old.example'
317
+
318
+ @agent.request_referer @req, @uri, referer
319
+
320
+ assert_nil @req['referer']
321
+ end
322
+
323
+ def test_request_referer_https_downgrade_case
324
+ uri = URI.parse 'http://example'
325
+ referer = URI.parse 'httpS://old.example'
326
+
327
+ @agent.request_referer @req, uri, referer
328
+
329
+ assert_nil @req['referer']
330
+ end
331
+
332
+ def test_request_referer_none
333
+ @agent.request_referer @req, @uri, nil
334
+
335
+ assert_nil @req['referer']
336
+ end
337
+
338
+ def test_request_user_agent
339
+ @agent.request_user_agent @req
340
+
341
+ assert_match %r%^Mechanize/#{Mechanize::VERSION}%, @req['user-agent']
342
+
343
+ ruby_version = if RUBY_PATCHLEVEL >= 0 then
344
+ "#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
345
+ else
346
+ "#{RUBY_VERSION}dev#{RUBY_REVISION}"
347
+ end
348
+
349
+ assert_match %r%Ruby/#{ruby_version}%, @req['user-agent']
350
+ end
351
+
352
+ def test_resolve_parameters_body
353
+ input_params = { :q => 'hello' }
354
+
355
+ uri, params = @agent.resolve_parameters @uri, :post, input_params
356
+
357
+ assert_equal 'http://example/', uri.to_s
358
+ assert_equal input_params, params
359
+ end
360
+
361
+ def test_resolve_parameters_query
362
+ uri, params = @agent.resolve_parameters @uri, :get, :q => 'hello'
363
+
364
+ assert_equal 'http://example/?q=hello', uri.to_s
365
+ assert_nil params
366
+ end
367
+
368
+ def test_resolve_parameters_query_append
369
+ input_params = { :q => 'hello' }
370
+ @uri.query = 'a=b'
371
+
372
+ uri, params = @agent.resolve_parameters @uri, :get, input_params
373
+
374
+ assert_equal 'http://example/?a=b&q=hello', uri.to_s
375
+ assert_nil params
376
+ end
377
+
378
+ def test_response_cookies
379
+ uri = URI.parse 'http://host.example.com'
380
+ cookie_str = 'a=b domain=.example.com'
381
+ @res.instance_variable_set(:@header,
382
+ 'set-cookie' => [cookie_str],
383
+ 'content-type' => %w[text/html])
384
+ page = Mechanize::Page.new uri, @res, '', 200, @agent
385
+
386
+ @agent.response_cookies @res, uri, page
387
+
388
+ assert_equal ['a=b domain=.example.com'],
389
+ @agent.cookie_jar.cookies(uri).map { |c| c.to_s }
390
+ end
391
+
392
+ def test_response_cookies_meta
393
+ uri = URI.parse 'http://host.example.com'
394
+ cookie_str = 'a=b domain=.example.com'
395
+
396
+ body = <<-BODY
397
+ <head>
398
+ <meta http-equiv="Set-Cookie" content="#{cookie_str}">
399
+ </head>"
400
+ BODY
401
+
402
+ @res.instance_variable_set(:@header,
403
+ 'content-type' => %w[text/html])
404
+ page = Mechanize::Page.new uri, @res, body, 200, @agent
405
+
406
+ @agent.response_cookies @res, uri, page
407
+
408
+ assert_equal ['a=b domain=.example.com'],
409
+ @agent.cookie_jar.cookies(uri).map { |c| c.to_s }
410
+ end
411
+
412
+ def test_response_follow_meta_refresh
413
+ uri = URI.parse 'http://example/#id+1'
414
+
415
+ body = <<-BODY
416
+ <title></title>
417
+ <meta http-equiv="refresh" content="0">
418
+ BODY
419
+
420
+ page = Mechanize::Page.new(uri, {'content-type' => 'text/html'}, body,
421
+ 200, @agent)
422
+
423
+ @agent.follow_meta_refresh = true
424
+
425
+ page = @agent.response_follow_meta_refresh @res, uri, page, 0
426
+
427
+ assert_equal uri, page.uri
428
+ end
429
+
430
+ def test_response_read
431
+ def @res.read_body() yield 'part' end
432
+ def @res.content_length() 4 end
433
+
434
+ body = @agent.response_read @res, @req
435
+
436
+ assert_equal 'part', body
437
+ end
438
+
439
+ def test_response_read_content_length_head
440
+ req = Net::HTTP::Head.new '/'
441
+
442
+ def @res.content_length() end
443
+ def @res.read_body() end
444
+
445
+ body = @agent.response_read @res, req
446
+
447
+ assert_equal '', body
448
+ end
449
+
450
+ def test_response_read_content_length_mismatch
451
+ def @res.content_length() 5 end
452
+ def @res.read_body() yield 'part' end
453
+
454
+ e = assert_raises EOFError do
455
+ @agent.response_read @res, @req
456
+ end
457
+
458
+ assert_equal 'Content-Length (5) does not match response body length (4)',
459
+ e.message
460
+ end
461
+
462
+ def test_response_read_content_length_redirect
463
+ res = Net::HTTPFound.allocate
464
+ def res.content_length() 5 end
465
+ def res.code() 302 end
466
+ def res.read_body() yield 'part' end
467
+ res.instance_variable_set :@header, {}
468
+
469
+ body = @agent.response_read res, @req
470
+
471
+ assert_equal 'part', body
472
+ end
473
+
474
+ def test_response_read_encoding_7_bit
475
+ def @res.read_body() yield 'part' end
476
+ def @res.content_length() 4 end
477
+ @res.instance_variable_set :@header, 'content-encoding' => %w[7bit]
478
+
479
+ body = @agent.response_read @res, @req
480
+
481
+ assert_equal 'part', body
482
+ end
483
+
484
+ def test_response_read_encoding_deflate
485
+ def @res.read_body()
486
+ yield "x\x9C+H,*\x01\x00\x04?\x01\xB8"
487
+ end
488
+ def @res.content_length() 12 end
489
+ @res.instance_variable_set :@header, 'content-encoding' => %w[deflate]
490
+
491
+ body = @agent.response_read @res, @req
492
+
493
+ assert_equal 'part', body
494
+ end
495
+
496
+ # IIS/6.0 ASP.NET/2.0.50727 does not wrap deflate with zlib, WTF?
497
+ def test_response_read_encoding_deflate_no_zlib
498
+ def @res.read_body()
499
+ yield "+H,*\001\000"
500
+ end
501
+ def @res.content_length() 6 end
502
+ @res.instance_variable_set :@header, 'content-encoding' => %w[deflate]
503
+
504
+ body = @agent.response_read @res, @req
505
+
506
+ assert_equal 'part', body
507
+ end
508
+
509
+ def test_response_read_encoding_gzip
510
+ def @res.read_body()
511
+ yield "\037\213\b\0002\002\225M\000\003"
512
+ yield "+H,*\001\000\306p\017I\004\000\000\000"
513
+ end
514
+ def @res.content_length() 24 end
515
+ @res.instance_variable_set :@header, 'content-encoding' => %w[gzip]
516
+
517
+ body = @agent.response_read @res, @req
518
+
519
+ assert_equal 'part', body
520
+ end
521
+
522
+ def test_response_read_encoding_none
523
+ def @res.read_body() yield 'part' end
524
+ def @res.content_length() 4 end
525
+ @res.instance_variable_set :@header, 'content-encoding' => %w[none]
526
+
527
+ body = @agent.response_read @res, @req
528
+
529
+ assert_equal 'part', body
530
+ end
531
+
532
+ def test_response_read_encoding_x_gzip
533
+ def @res.read_body()
534
+ yield "\037\213\b\0002\002\225M\000\003"
535
+ yield "+H,*\001\000\306p\017I\004\000\000\000"
536
+ end
537
+ def @res.content_length() 24 end
538
+ @res.instance_variable_set :@header, 'content-encoding' => %w[x-gzip]
539
+
540
+ body = @agent.response_read @res, @req
541
+
542
+ assert_equal 'part', body
543
+ end
544
+
545
+ def test_response_read_encoding_unknown
546
+ def @res.read_body() yield 'part' end
547
+ def @res.content_length() 4 end
548
+ @res.instance_variable_set :@header, 'content-encoding' => %w[unknown]
549
+
550
+ e = assert_raises Mechanize::Error do
551
+ @agent.response_read @res, @req
552
+ end
553
+
554
+ assert_equal 'Unsupported Content-Encoding: unknown', e.message
555
+ end
556
+
557
+ def test_response_read_file
558
+ Tempfile.open 'pi.txt' do |tempfile|
559
+ tempfile.write "π\n"
560
+ tempfile.flush
561
+ tempfile.rewind
562
+
563
+ uri = URI.parse "file://#{tempfile.path}"
564
+ req = Mechanize::FileRequest.new uri
565
+ res = Mechanize::FileResponse.new tempfile.path
566
+
567
+ body = @agent.response_read res, req
568
+
569
+ expected = "π\n"
570
+ expected.force_encoding Encoding::BINARY if expected.respond_to? :encoding
571
+
572
+ assert_equal expected, body
573
+ assert_equal Encoding::BINARY, body.encoding if body.respond_to? :encoding
574
+ end
575
+ end
576
+
577
+ def test_response_read_no_body
578
+ req = Net::HTTP::Options.new '/'
579
+
580
+ def @res.content_length() end
581
+ def @res.read_body() end
582
+
583
+ body = @agent.response_read @res, req
584
+
585
+ assert_equal '', body
586
+ end
587
+
588
+ def test_response_read_unknown_code
589
+ res = Net::HTTPUnknownResponse.allocate
590
+ res.instance_variable_set :@code, 9999
591
+ def res.read_body() yield 'part' end
592
+
593
+ e = assert_raises Mechanize::ResponseCodeError do
594
+ @agent.response_read res, @req
595
+ end
596
+
597
+ assert_equal res, e.page
598
+ end
599
+
600
+ def test_response_parse
601
+ body = '<title>hi</title>'
602
+ @res.instance_variable_set :@header, 'content-type' => %w[text/html]
603
+
604
+ page = @agent.response_parse @res, body, @uri
605
+
606
+ assert_instance_of Mechanize::Page, page
607
+ assert_equal @agent, page.mech
608
+ end
609
+
610
+ def test_response_parse_content_type_case
611
+ body = '<title>hi</title>'
612
+ @res.instance_variable_set(:@header, 'content-type' => %w[text/HTML])
613
+
614
+ page = @agent.response_parse @res, body, @uri
615
+
616
+ assert_instance_of Mechanize::Page, page
617
+
618
+ assert_equal 'text/HTML', page.content_type
619
+ end
620
+
621
+ def test_response_parse_content_type_encoding
622
+ body = '<title>hi</title>'
623
+ @res.instance_variable_set(:@header,
624
+ 'content-type' =>
625
+ %w[text/html;charset=ISO-8859-1])
626
+
627
+ page = @agent.response_parse @res, body, @uri
628
+
629
+ assert_instance_of Mechanize::Page, page
630
+ assert_equal @agent, page.mech
631
+
632
+ assert_equal 'ISO-8859-1', page.encoding
633
+ assert_equal 'ISO-8859-1', page.parser.encoding
634
+ end
635
+
636
+ def test_response_parse_content_type_encoding_garbage
637
+ body = '<title>hi</title>'
638
+ @res.instance_variable_set(:@header,
639
+ 'content-type' =>
640
+ %w[text/html; charset=garbage_charset])
641
+
642
+ page = @agent.response_parse @res, body, @uri
643
+
644
+ assert_instance_of Mechanize::Page, page
645
+ assert_equal @agent, page.mech
646
+ end
647
+
648
+ def test_response_parse_content_type_encoding_broken_iso_8859_1
649
+ body = '<title>hi</title>'
650
+ @res.instance_variable_set(:@header,
651
+ 'content-type' =>
652
+ %w[text/html; charset=ISO_8859-1])
653
+
654
+ page = @agent.response_parse @res, body, @uri
655
+
656
+ assert_instance_of Mechanize::Page, page
657
+ assert_equal 'ISO_8859-1', page.encoding
658
+ end
659
+
660
+ def test_response_parse_content_type_encoding_broken_utf_8
661
+ body = '<title>hi</title>'
662
+ @res.instance_variable_set(:@header,
663
+ 'content-type' =>
664
+ %w[text/html; charset=UTF8])
665
+
666
+ page = @agent.response_parse @res, body, @uri
667
+
668
+ assert_instance_of Mechanize::Page, page
669
+ assert_equal 'UTF8', page.encoding
670
+ assert_equal 'UTF8', page.parser.encoding
671
+ end
672
+
673
+ def test_response_parse_content_type_encoding_semicolon
674
+ body = '<title>hi</title>'
675
+ @res.instance_variable_set(:@header,
676
+ 'content-type' =>
677
+ %w[text/html;charset=UTF-8;])
678
+
679
+ page = @agent.response_parse @res, body, @uri
680
+
681
+ assert_instance_of Mechanize::Page, page
682
+
683
+ assert_equal 'UTF-8', page.encoding
684
+ end
685
+
686
+ end
687
+