mechanize 2.0.pre.2 → 2.0
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.
- data.tar.gz.sig +0 -0
- data/CHANGELOG.rdoc +22 -0
- data/Manifest.txt +11 -8
- data/Rakefile +2 -2
- data/examples/flickr_upload.rb +6 -7
- data/examples/mech-dump.rb +0 -2
- data/examples/proxy_req.rb +0 -2
- data/examples/rubyforge.rb +1 -3
- data/examples/spider.rb +2 -3
- data/lib/mechanize.rb +228 -680
- data/lib/mechanize/form/field.rb +1 -1
- data/lib/mechanize/history.rb +23 -5
- data/lib/mechanize/http.rb +3 -0
- data/lib/mechanize/http/agent.rb +738 -0
- data/lib/mechanize/inspect.rb +2 -2
- data/lib/mechanize/page.rb +101 -42
- data/lib/mechanize/page/frame.rb +24 -17
- data/lib/mechanize/page/link.rb +72 -54
- data/lib/mechanize/page/meta_refresh.rb +56 -0
- data/lib/mechanize/response_read_error.rb +27 -0
- data/test/htdocs/frame_referer_test.html +10 -0
- data/test/htdocs/tc_referer.html +4 -0
- data/test/test_frames.rb +9 -0
- data/test/test_history.rb +74 -98
- data/test/test_mechanize.rb +334 -812
- data/test/test_mechanize_form.rb +32 -3
- data/test/{test_textarea.rb → test_mechanize_form_textarea.rb} +1 -1
- data/test/test_mechanize_http_agent.rb +697 -0
- data/test/test_mechanize_link.rb +83 -0
- data/test/test_mechanize_page_encoding.rb +147 -0
- data/test/test_mechanize_page_link.rb +379 -0
- data/test/test_mechanize_page_meta_refresh.rb +115 -0
- data/test/test_pretty_print.rb +1 -1
- data/test/test_referer.rb +29 -5
- data/test/test_response_code.rb +21 -20
- data/test/test_robots.rb +13 -17
- data/test/test_scheme.rb +1 -1
- metadata +30 -31
- metadata.gz.sig +0 -0
- data/lib/mechanize/page/meta.rb +0 -48
- data/test/test_form_no_inputname.rb +0 -15
- data/test/test_links.rb +0 -146
- data/test/test_mechanize_page.rb +0 -224
- data/test/test_meta.rb +0 -67
- data/test/test_upload.rb +0 -109
- data/test/test_verbs.rb +0 -25
data/test/test_mechanize_form.rb
CHANGED
@@ -14,6 +14,13 @@ class TestMechanizeForm < Test::Unit::TestCase
|
|
14
14
|
assert query.all? { |x| x[1] == '' }
|
15
15
|
end
|
16
16
|
|
17
|
+
def test_checkboxes_no_input_name
|
18
|
+
page = @agent.get('http://localhost/form_no_input_name.html')
|
19
|
+
form = page.forms.first
|
20
|
+
|
21
|
+
assert_equal(0, form.checkboxes.length)
|
22
|
+
end
|
23
|
+
|
17
24
|
def test_field_with
|
18
25
|
page = @agent.get("http://localhost/google.html")
|
19
26
|
search = page.forms.find { |f| f.name == "f" }
|
@@ -23,6 +30,27 @@ class TestMechanizeForm < Test::Unit::TestCase
|
|
23
30
|
assert_not_nil(search.fields.find { |f| f.name == 'ie' })
|
24
31
|
end
|
25
32
|
|
33
|
+
def test_fields_no_input_name
|
34
|
+
page = @agent.get('http://localhost/form_no_input_name.html')
|
35
|
+
form = page.forms.first
|
36
|
+
|
37
|
+
assert_equal(0, form.fields.length)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_file_uploads_no_value
|
41
|
+
page = @agent.get("http://localhost/file_upload.html")
|
42
|
+
form = page.form('value_test')
|
43
|
+
assert_nil(form.file_uploads.first.value)
|
44
|
+
assert_nil(form.file_uploads.first.file_name)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_forms_no_input_name
|
48
|
+
page = @agent.get('http://localhost/form_no_input_name.html')
|
49
|
+
form = page.forms.first
|
50
|
+
|
51
|
+
assert_equal(0, form.radiobuttons.length)
|
52
|
+
end
|
53
|
+
|
26
54
|
def test_parse_textarea
|
27
55
|
form = Nokogiri::HTML <<-FORM
|
28
56
|
<form>
|
@@ -74,9 +102,10 @@ class TestMechanizeForm < Test::Unit::TestCase
|
|
74
102
|
assert form = page.forms.first
|
75
103
|
form.action = '/http_headers'
|
76
104
|
page = @agent.submit(form, nil, { 'foo' => 'bar' })
|
77
|
-
|
78
|
-
|
79
|
-
|
105
|
+
|
106
|
+
headers = page.body.split("\n").map { |x| x.split('|', 2) }.flatten
|
107
|
+
headers = Hash[*headers]
|
108
|
+
|
80
109
|
assert_equal 'bar', headers['foo']
|
81
110
|
end
|
82
111
|
|
@@ -0,0 +1,697 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'helper'
|
3
|
+
|
4
|
+
class TestMechanizeHttpAgent < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@mech = Mechanize.new
|
8
|
+
@agent = @mech.agent
|
9
|
+
|
10
|
+
@uri = URI.parse 'http://example/'
|
11
|
+
|
12
|
+
@req = Net::HTTP::Get.new '/'
|
13
|
+
@res = Net::HTTPOK.allocate
|
14
|
+
@res.instance_variable_set :@code, 200
|
15
|
+
@res.instance_variable_set :@header, {}
|
16
|
+
|
17
|
+
@headers = if RUBY_VERSION > '1.9' then
|
18
|
+
%w[accept user-agent]
|
19
|
+
else
|
20
|
+
%w[accept]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_connection_for_file
|
25
|
+
uri = URI.parse 'file:///nonexistent'
|
26
|
+
conn = @agent.connection_for uri
|
27
|
+
|
28
|
+
assert_equal Mechanize::FileConnection.new, conn
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_connection_for_http
|
32
|
+
conn = @agent.connection_for @uri
|
33
|
+
|
34
|
+
assert_equal @agent.http, conn
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_enable_gzip
|
38
|
+
@agent.enable_gzip @req
|
39
|
+
|
40
|
+
assert_equal 'gzip,deflate,identity', @req['accept-encoding']
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_enable_gzip_no
|
44
|
+
@agent.gzip_enabled = false
|
45
|
+
|
46
|
+
@agent.enable_gzip @req
|
47
|
+
|
48
|
+
assert_equal 'identity', @req['accept-encoding']
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_fetch_file_plus
|
52
|
+
Tempfile.open '++plus++' do |io|
|
53
|
+
content = 'plusses +++'
|
54
|
+
io.write content
|
55
|
+
io.rewind
|
56
|
+
|
57
|
+
uri = URI.parse "file://#{Mechanize::Util.uri_escape io.path}"
|
58
|
+
|
59
|
+
page = @agent.fetch uri
|
60
|
+
|
61
|
+
assert_equal content, page.body
|
62
|
+
assert_kind_of Mechanize::File, page
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_fetch_file_space
|
67
|
+
foo = File.expand_path("../htdocs/dir with spaces/foo.html", __FILE__)
|
68
|
+
|
69
|
+
uri = URI.parse "file://#{Mechanize::Util.uri_escape foo}"
|
70
|
+
|
71
|
+
page = @agent.fetch uri
|
72
|
+
|
73
|
+
assert_equal File.read(foo), page.body
|
74
|
+
assert_kind_of Mechanize::Page, page
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_fetch_file_nonexistent
|
78
|
+
uri = URI.parse 'file:///nonexistent'
|
79
|
+
|
80
|
+
e = assert_raises Mechanize::ResponseCodeError do
|
81
|
+
@agent.fetch uri
|
82
|
+
end
|
83
|
+
|
84
|
+
assert_equal '404 => Net::HTTPNotFound', e.message
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_fetch_post_connect_hook
|
88
|
+
response = nil
|
89
|
+
@agent.post_connect_hooks << lambda { |_, _, res, _| response = res }
|
90
|
+
|
91
|
+
@agent.fetch 'http://localhost/'
|
92
|
+
|
93
|
+
assert response
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_get_robots
|
97
|
+
robotstxt = @agent.get_robots 'http://localhost/robots.txt'
|
98
|
+
assert_not_equal '', robotstxt
|
99
|
+
|
100
|
+
robotstxt = @agent.get_robots 'http://localhost/response_code?code=404'
|
101
|
+
assert_equal '', robotstxt
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_http_request_file
|
105
|
+
uri = URI.parse 'file:///nonexistent'
|
106
|
+
request = @agent.http_request uri, :get
|
107
|
+
|
108
|
+
assert_kind_of Mechanize::FileRequest, request
|
109
|
+
assert_equal '/nonexistent', request.path
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_http_request_get
|
113
|
+
request = @agent.http_request @uri, :get
|
114
|
+
|
115
|
+
assert_kind_of Net::HTTP::Get, request
|
116
|
+
assert_equal '/', request.path
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_http_request_post
|
120
|
+
request = @agent.http_request @uri, :post
|
121
|
+
|
122
|
+
assert_kind_of Net::HTTP::Post, request
|
123
|
+
assert_equal '/', request.path
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_post_connect
|
127
|
+
@agent.post_connect_hooks << proc { |agent, uri, response, body|
|
128
|
+
assert_equal @agent, agent
|
129
|
+
assert_equal @res, response
|
130
|
+
assert_equal 'body', body
|
131
|
+
throw :called
|
132
|
+
}
|
133
|
+
|
134
|
+
assert_throws :called do
|
135
|
+
@agent.post_connect @uri, @res, 'body'
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_pre_connect
|
140
|
+
@agent.pre_connect_hooks << proc { |agent, request|
|
141
|
+
assert_equal @agent, agent
|
142
|
+
assert_equal @req, request
|
143
|
+
throw :called
|
144
|
+
}
|
145
|
+
|
146
|
+
assert_throws :called do
|
147
|
+
@agent.pre_connect @req
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_request_cookies
|
152
|
+
uri = URI.parse 'http://host.example.com'
|
153
|
+
Mechanize::Cookie.parse uri, 'hello=world domain=.example.com' do |cookie|
|
154
|
+
@agent.cookie_jar.add uri, cookie
|
155
|
+
end
|
156
|
+
|
157
|
+
@agent.request_cookies @req, uri
|
158
|
+
|
159
|
+
assert_equal 'hello=world domain=.example.com', @req['Cookie']
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_request_cookies_none
|
163
|
+
@agent.request_cookies @req, @uri
|
164
|
+
|
165
|
+
assert_nil @req['Cookie']
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_request_cookies_many
|
169
|
+
uri = URI.parse 'http://host.example.com'
|
170
|
+
cookie_str = 'a=b domain=.example.com, c=d domain=.example.com'
|
171
|
+
Mechanize::Cookie.parse uri, cookie_str do |cookie|
|
172
|
+
@agent.cookie_jar.add uri, cookie
|
173
|
+
end
|
174
|
+
|
175
|
+
@agent.request_cookies @req, uri
|
176
|
+
|
177
|
+
expected = cookie_str.sub ', ', '; '
|
178
|
+
|
179
|
+
assert_equal expected, @req['Cookie']
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_request_cookies_wrong_domain
|
183
|
+
uri = URI.parse 'http://host.example.com'
|
184
|
+
Mechanize::Cookie.parse uri, 'hello=world domain=.example.com' do |cookie|
|
185
|
+
@agent.cookie_jar.add uri, cookie
|
186
|
+
end
|
187
|
+
|
188
|
+
@agent.request_cookies @req, @uri
|
189
|
+
|
190
|
+
assert_nil @req['Cookie']
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_request_host
|
194
|
+
@agent.request_host @req, @uri
|
195
|
+
|
196
|
+
assert_equal 'example', @req['host']
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_request_host_nonstandard
|
200
|
+
@uri.port = 81
|
201
|
+
|
202
|
+
@agent.request_host @req, @uri
|
203
|
+
|
204
|
+
assert_equal 'example:81', @req['host']
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_request_language_charset
|
208
|
+
@agent.request_language_charset @req
|
209
|
+
|
210
|
+
assert_equal 'en-us,en;q=0.5', @req['accept-language']
|
211
|
+
assert_equal 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', @req['accept-charset']
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_request_add_headers
|
215
|
+
@agent.request_add_headers @req, 'Content-Length' => 300
|
216
|
+
|
217
|
+
assert_equal '300', @req['content-length']
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_request_add_headers_etag
|
221
|
+
@agent.request_add_headers @req, :etag => '300'
|
222
|
+
|
223
|
+
assert_equal '300', @req['etag']
|
224
|
+
end
|
225
|
+
|
226
|
+
def test_request_add_headers_if_modified_since
|
227
|
+
@agent.request_add_headers @req, :if_modified_since => 'some_date'
|
228
|
+
|
229
|
+
assert_equal 'some_date', @req['if-modified-since']
|
230
|
+
end
|
231
|
+
|
232
|
+
def test_request_add_headers_none
|
233
|
+
@agent.request_add_headers @req
|
234
|
+
|
235
|
+
assert_equal @headers, @req.to_hash.keys.sort
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_request_add_headers_request_headers
|
239
|
+
@agent.request_headers['X-Foo'] = 'bar'
|
240
|
+
|
241
|
+
@agent.request_add_headers @req
|
242
|
+
|
243
|
+
assert_equal @headers + %w[x-foo], @req.to_hash.keys.sort
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_request_add_headers_symbol
|
247
|
+
e = assert_raises ArgumentError do
|
248
|
+
@agent.request_add_headers @req, :content_length => 300
|
249
|
+
end
|
250
|
+
|
251
|
+
assert_equal 'unknown header symbol content_length', e.message
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_request_referer
|
255
|
+
referer = URI.parse 'http://old.example'
|
256
|
+
|
257
|
+
@agent.request_referer @req, @uri, referer
|
258
|
+
|
259
|
+
assert_equal 'http://old.example', @req['referer']
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_request_referer_https
|
263
|
+
uri = URI.parse 'https://example'
|
264
|
+
referer = URI.parse 'https://old.example'
|
265
|
+
|
266
|
+
@agent.request_referer @req, uri, referer
|
267
|
+
|
268
|
+
assert_equal 'https://old.example', @req['referer']
|
269
|
+
end
|
270
|
+
|
271
|
+
def test_request_referer_https_downgrade
|
272
|
+
referer = URI.parse 'https://old.example'
|
273
|
+
|
274
|
+
@agent.request_referer @req, @uri, referer
|
275
|
+
|
276
|
+
assert_nil @req['referer']
|
277
|
+
end
|
278
|
+
|
279
|
+
def test_request_referer_https_downgrade_case
|
280
|
+
uri = URI.parse 'http://example'
|
281
|
+
referer = URI.parse 'httpS://old.example'
|
282
|
+
|
283
|
+
@agent.request_referer @req, uri, referer
|
284
|
+
|
285
|
+
assert_nil @req['referer']
|
286
|
+
end
|
287
|
+
|
288
|
+
def test_request_referer_none
|
289
|
+
@agent.request_referer @req, @uri, nil
|
290
|
+
|
291
|
+
assert_nil @req['referer']
|
292
|
+
end
|
293
|
+
|
294
|
+
def test_request_user_agent
|
295
|
+
@agent.request_user_agent @req
|
296
|
+
|
297
|
+
assert_match %r%^Mechanize/#{Mechanize::VERSION}%, @req['user-agent']
|
298
|
+
|
299
|
+
ruby_version = if RUBY_PATCHLEVEL >= 0 then
|
300
|
+
"#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
|
301
|
+
else
|
302
|
+
"#{RUBY_VERSION}dev#{RUBY_REVISION}"
|
303
|
+
end
|
304
|
+
|
305
|
+
assert_match %r%Ruby/#{ruby_version}%, @req['user-agent']
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_resolve_bad_uri
|
309
|
+
e = assert_raises ArgumentError do
|
310
|
+
@agent.resolve 'google'
|
311
|
+
end
|
312
|
+
|
313
|
+
assert_equal 'absolute URL needed (not google)', e.message
|
314
|
+
end
|
315
|
+
|
316
|
+
def test_resolve_utf8
|
317
|
+
uri = 'http://example?q=ü'
|
318
|
+
|
319
|
+
resolved = @agent.resolve uri
|
320
|
+
|
321
|
+
assert_equal '/?q=%C3%BC', resolved.request_uri
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_resolve_parameters_body
|
325
|
+
input_params = { :q => 'hello' }
|
326
|
+
|
327
|
+
uri, params = @agent.resolve_parameters @uri, :post, input_params
|
328
|
+
|
329
|
+
assert_equal 'http://example/', uri.to_s
|
330
|
+
assert_equal input_params, params
|
331
|
+
end
|
332
|
+
|
333
|
+
def test_resolve_parameters_query
|
334
|
+
uri, params = @agent.resolve_parameters @uri, :get, :q => 'hello'
|
335
|
+
|
336
|
+
assert_equal 'http://example/?q=hello', uri.to_s
|
337
|
+
assert_nil params
|
338
|
+
end
|
339
|
+
|
340
|
+
def test_resolve_parameters_query_append
|
341
|
+
input_params = { :q => 'hello' }
|
342
|
+
@uri.query = 'a=b'
|
343
|
+
|
344
|
+
uri, params = @agent.resolve_parameters @uri, :get, input_params
|
345
|
+
|
346
|
+
assert_equal 'http://example/?a=b&q=hello', uri.to_s
|
347
|
+
assert_nil params
|
348
|
+
end
|
349
|
+
|
350
|
+
def test_response_content_encoding_7_bit
|
351
|
+
def @res.content_length() 4 end
|
352
|
+
@res.instance_variable_set :@header, 'content-encoding' => %w[7bit]
|
353
|
+
|
354
|
+
body = @agent.response_content_encoding @res, StringIO.new('part')
|
355
|
+
|
356
|
+
assert_equal 'part', body
|
357
|
+
end
|
358
|
+
|
359
|
+
def test_response_content_encoding_deflate
|
360
|
+
def @res.content_length() 12 end
|
361
|
+
@res.instance_variable_set :@header, 'content-encoding' => %w[deflate]
|
362
|
+
body_io = StringIO.new "x\x9C+H,*\x01\x00\x04?\x01\xB8"
|
363
|
+
|
364
|
+
body = @agent.response_content_encoding @res, body_io
|
365
|
+
|
366
|
+
assert_equal 'part', body
|
367
|
+
end
|
368
|
+
|
369
|
+
def test_response_content_encoding_deflate_chunked
|
370
|
+
def @res.content_length() nil end
|
371
|
+
@res.instance_variable_set :@header, 'content-encoding' => %w[deflate]
|
372
|
+
body_io = StringIO.new "x\x9C+H,*\x01\x00\x04?\x01\xB8"
|
373
|
+
|
374
|
+
body = @agent.response_content_encoding @res, body_io
|
375
|
+
|
376
|
+
assert_equal 'part', body
|
377
|
+
end
|
378
|
+
|
379
|
+
# IIS/6.0 ASP.NET/2.0.50727 does not wrap deflate with zlib, WTF?
|
380
|
+
def test_response_content_encoding_deflate_no_zlib
|
381
|
+
def @res.content_length() 6 end
|
382
|
+
@res.instance_variable_set :@header, 'content-encoding' => %w[deflate]
|
383
|
+
|
384
|
+
body = @agent.response_content_encoding @res, StringIO.new("+H,*\001\000")
|
385
|
+
|
386
|
+
assert_equal 'part', body
|
387
|
+
end
|
388
|
+
|
389
|
+
def test_response_content_encoding_gzip
|
390
|
+
def @res.content_length() 24 end
|
391
|
+
@res.instance_variable_set :@header, 'content-encoding' => %w[gzip]
|
392
|
+
body_io = StringIO.new \
|
393
|
+
"\037\213\b\0002\002\225M\000\003+H,*\001\000\306p\017I\004\000\000\000"
|
394
|
+
|
395
|
+
body = @agent.response_content_encoding @res, body_io
|
396
|
+
|
397
|
+
assert_equal 'part', body
|
398
|
+
end
|
399
|
+
|
400
|
+
def test_response_content_encoding_gzip_chunked
|
401
|
+
def @res.content_length() nil end
|
402
|
+
@res.instance_variable_set :@header, 'content-encoding' => %w[gzip]
|
403
|
+
body_io = StringIO.new \
|
404
|
+
"\037\213\b\0002\002\225M\000\003+H,*\001\000\306p\017I\004\000\000\000"
|
405
|
+
|
406
|
+
body = @agent.response_content_encoding @res, body_io
|
407
|
+
|
408
|
+
assert_equal 'part', body
|
409
|
+
end
|
410
|
+
|
411
|
+
def test_response_content_encoding_none
|
412
|
+
def @res.content_length() 4 end
|
413
|
+
@res.instance_variable_set :@header, 'content-encoding' => %w[none]
|
414
|
+
|
415
|
+
body = @agent.response_content_encoding @res, StringIO.new('part')
|
416
|
+
|
417
|
+
assert_equal 'part', body
|
418
|
+
end
|
419
|
+
|
420
|
+
def test_response_content_encoding_x_gzip
|
421
|
+
def @res.content_length() 24 end
|
422
|
+
@res.instance_variable_set :@header, 'content-encoding' => %w[x-gzip]
|
423
|
+
body_io = StringIO.new \
|
424
|
+
"\037\213\b\0002\002\225M\000\003+H,*\001\000\306p\017I\004\000\000\000"
|
425
|
+
|
426
|
+
body = @agent.response_content_encoding @res, body_io
|
427
|
+
|
428
|
+
assert_equal 'part', body
|
429
|
+
end
|
430
|
+
|
431
|
+
def test_response_content_encoding_unknown
|
432
|
+
def @res.content_length() 4 end
|
433
|
+
@res.instance_variable_set :@header, 'content-encoding' => %w[unknown]
|
434
|
+
body = StringIO.new 'part'
|
435
|
+
|
436
|
+
e = assert_raises Mechanize::Error do
|
437
|
+
@agent.response_content_encoding @res, body
|
438
|
+
end
|
439
|
+
|
440
|
+
assert_equal 'Unsupported Content-Encoding: unknown', e.message
|
441
|
+
end
|
442
|
+
|
443
|
+
def test_response_cookies
|
444
|
+
uri = URI.parse 'http://host.example.com'
|
445
|
+
cookie_str = 'a=b domain=.example.com'
|
446
|
+
@res.instance_variable_set(:@header,
|
447
|
+
'set-cookie' => [cookie_str],
|
448
|
+
'content-type' => %w[text/html])
|
449
|
+
page = Mechanize::Page.new uri, @res, '', 200, @mech
|
450
|
+
|
451
|
+
@agent.response_cookies @res, uri, page
|
452
|
+
|
453
|
+
assert_equal ['a=b domain=.example.com'],
|
454
|
+
@agent.cookie_jar.cookies(uri).map { |c| c.to_s }
|
455
|
+
end
|
456
|
+
|
457
|
+
def test_response_cookies_meta
|
458
|
+
uri = URI.parse 'http://host.example.com'
|
459
|
+
cookie_str = 'a=b domain=.example.com'
|
460
|
+
|
461
|
+
body = <<-BODY
|
462
|
+
<head>
|
463
|
+
<meta http-equiv="Set-Cookie" content="#{cookie_str}">
|
464
|
+
</head>"
|
465
|
+
BODY
|
466
|
+
|
467
|
+
@res.instance_variable_set(:@header,
|
468
|
+
'content-type' => %w[text/html])
|
469
|
+
page = Mechanize::Page.new uri, @res, body, 200, @mech
|
470
|
+
|
471
|
+
@agent.response_cookies @res, uri, page
|
472
|
+
|
473
|
+
assert_equal ['a=b domain=.example.com'],
|
474
|
+
@agent.cookie_jar.cookies(uri).map { |c| c.to_s }
|
475
|
+
end
|
476
|
+
|
477
|
+
def test_response_follow_meta_refresh
|
478
|
+
uri = URI.parse 'http://example/#id+1'
|
479
|
+
|
480
|
+
body = <<-BODY
|
481
|
+
<title></title>
|
482
|
+
<meta http-equiv="refresh" content="0">
|
483
|
+
BODY
|
484
|
+
|
485
|
+
page = Mechanize::Page.new(uri, {'content-type' => 'text/html'}, body,
|
486
|
+
200, @mech)
|
487
|
+
|
488
|
+
@agent.follow_meta_refresh = true
|
489
|
+
|
490
|
+
page = @agent.response_follow_meta_refresh @res, uri, page, 0
|
491
|
+
|
492
|
+
assert_equal uri, page.uri
|
493
|
+
end
|
494
|
+
|
495
|
+
def test_response_read
|
496
|
+
def @res.read_body() yield 'part' end
|
497
|
+
def @res.content_length() 4 end
|
498
|
+
|
499
|
+
io = @agent.response_read @res, @req
|
500
|
+
|
501
|
+
body = io.read
|
502
|
+
|
503
|
+
assert_equal 'part', body
|
504
|
+
assert_equal Encoding::BINARY, body.encoding if body.respond_to? :encoding
|
505
|
+
end
|
506
|
+
|
507
|
+
def test_response_read_content_length_head
|
508
|
+
req = Net::HTTP::Head.new '/'
|
509
|
+
|
510
|
+
def @res.content_length() end
|
511
|
+
def @res.read_body() end
|
512
|
+
|
513
|
+
io = @agent.response_read @res, req
|
514
|
+
|
515
|
+
assert_equal '', io.read
|
516
|
+
end
|
517
|
+
|
518
|
+
def test_response_read_content_length_mismatch
|
519
|
+
def @res.content_length() 5 end
|
520
|
+
def @res.read_body() yield 'part' end
|
521
|
+
|
522
|
+
e = assert_raises EOFError do
|
523
|
+
@agent.response_read @res, @req
|
524
|
+
end
|
525
|
+
|
526
|
+
assert_equal 'Content-Length (5) does not match response body length (4)',
|
527
|
+
e.message
|
528
|
+
end
|
529
|
+
|
530
|
+
def test_response_read_content_length_redirect
|
531
|
+
res = Net::HTTPFound.allocate
|
532
|
+
def res.content_length() 5 end
|
533
|
+
def res.code() 302 end
|
534
|
+
def res.read_body() yield 'part' end
|
535
|
+
res.instance_variable_set :@header, {}
|
536
|
+
|
537
|
+
io = @agent.response_read res, @req
|
538
|
+
|
539
|
+
assert_equal 'part', io.read
|
540
|
+
end
|
541
|
+
|
542
|
+
def test_response_read_error
|
543
|
+
def @res.read_body()
|
544
|
+
yield 'part'
|
545
|
+
raise Net::HTTP::Persistent::Error
|
546
|
+
end
|
547
|
+
|
548
|
+
e = assert_raises Mechanize::ResponseReadError do
|
549
|
+
@agent.response_read @res, @req
|
550
|
+
end
|
551
|
+
|
552
|
+
assert_equal @res, e.response
|
553
|
+
assert_equal 'part', e.body_io.read
|
554
|
+
assert_kind_of Net::HTTP::Persistent::Error, e.error
|
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
|
+
io = @agent.response_read res, req
|
568
|
+
|
569
|
+
expected = "π\n"
|
570
|
+
expected.force_encoding Encoding::BINARY if expected.respond_to? :encoding
|
571
|
+
|
572
|
+
body = io.read
|
573
|
+
assert_equal expected, body
|
574
|
+
assert_equal Encoding::BINARY, body.encoding if body.respond_to? :encoding
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
def test_response_read_no_body
|
579
|
+
req = Net::HTTP::Options.new '/'
|
580
|
+
|
581
|
+
def @res.content_length() end
|
582
|
+
def @res.read_body() end
|
583
|
+
|
584
|
+
io = @agent.response_read @res, req
|
585
|
+
|
586
|
+
assert_equal '', io.read
|
587
|
+
end
|
588
|
+
|
589
|
+
def test_response_read_unknown_code
|
590
|
+
res = Net::HTTPUnknownResponse.allocate
|
591
|
+
res.instance_variable_set :@code, 9999
|
592
|
+
def res.read_body() yield 'part' end
|
593
|
+
|
594
|
+
e = assert_raises Mechanize::ResponseCodeError do
|
595
|
+
@agent.response_read res, @req
|
596
|
+
end
|
597
|
+
|
598
|
+
assert_equal res, e.page
|
599
|
+
end
|
600
|
+
|
601
|
+
def test_response_parse
|
602
|
+
body = '<title>hi</title>'
|
603
|
+
@res.instance_variable_set :@header, 'content-type' => %w[text/html]
|
604
|
+
|
605
|
+
page = @agent.response_parse @res, body, @uri
|
606
|
+
|
607
|
+
assert_instance_of Mechanize::Page, page
|
608
|
+
assert_equal @mech, page.mech
|
609
|
+
end
|
610
|
+
|
611
|
+
def test_response_parse_content_type_case
|
612
|
+
body = '<title>hi</title>'
|
613
|
+
@res.instance_variable_set(:@header, 'content-type' => %w[text/HTML])
|
614
|
+
|
615
|
+
page = @agent.response_parse @res, body, @uri
|
616
|
+
|
617
|
+
assert_instance_of Mechanize::Page, page
|
618
|
+
|
619
|
+
assert_equal 'text/HTML', page.content_type
|
620
|
+
end
|
621
|
+
|
622
|
+
def test_response_parse_content_type_encoding
|
623
|
+
body = '<title>hi</title>'
|
624
|
+
@res.instance_variable_set(:@header,
|
625
|
+
'content-type' =>
|
626
|
+
%w[text/html;charset=ISO-8859-1])
|
627
|
+
|
628
|
+
page = @agent.response_parse @res, body, @uri
|
629
|
+
|
630
|
+
assert_instance_of Mechanize::Page, page
|
631
|
+
assert_equal @mech, page.mech
|
632
|
+
|
633
|
+
assert_equal 'ISO-8859-1', page.encoding
|
634
|
+
assert_equal 'ISO-8859-1', page.parser.encoding
|
635
|
+
end
|
636
|
+
|
637
|
+
def test_response_parse_content_type_encoding_garbage
|
638
|
+
body = '<title>hi</title>'
|
639
|
+
@res.instance_variable_set(:@header,
|
640
|
+
'content-type' =>
|
641
|
+
%w[text/html; charset=garbage_charset])
|
642
|
+
|
643
|
+
page = @agent.response_parse @res, body, @uri
|
644
|
+
|
645
|
+
assert_instance_of Mechanize::Page, page
|
646
|
+
assert_equal @mech, page.mech
|
647
|
+
end
|
648
|
+
|
649
|
+
def test_response_parse_content_type_encoding_broken_iso_8859_1
|
650
|
+
body = '<title>hi</title>'
|
651
|
+
@res.instance_variable_set(:@header,
|
652
|
+
'content-type' =>
|
653
|
+
%w[text/html; charset=ISO_8859-1])
|
654
|
+
|
655
|
+
page = @agent.response_parse @res, body, @uri
|
656
|
+
|
657
|
+
assert_instance_of Mechanize::Page, page
|
658
|
+
assert_equal 'ISO_8859-1', page.encoding
|
659
|
+
end
|
660
|
+
|
661
|
+
def test_response_parse_content_type_encoding_broken_utf_8
|
662
|
+
body = '<title>hi</title>'
|
663
|
+
@res.instance_variable_set(:@header,
|
664
|
+
'content-type' =>
|
665
|
+
%w[text/html; charset=UTF8])
|
666
|
+
|
667
|
+
page = @agent.response_parse @res, body, @uri
|
668
|
+
|
669
|
+
assert_instance_of Mechanize::Page, page
|
670
|
+
assert_equal 'UTF8', page.encoding
|
671
|
+
assert_equal 'UTF8', page.parser.encoding
|
672
|
+
end
|
673
|
+
|
674
|
+
def test_response_parse_content_type_encoding_semicolon
|
675
|
+
body = '<title>hi</title>'
|
676
|
+
@res.instance_variable_set(:@header,
|
677
|
+
'content-type' =>
|
678
|
+
%w[text/html;charset=UTF-8;])
|
679
|
+
|
680
|
+
page = @agent.response_parse @res, body, @uri
|
681
|
+
|
682
|
+
assert_instance_of Mechanize::Page, page
|
683
|
+
|
684
|
+
assert_equal 'UTF-8', page.encoding
|
685
|
+
end
|
686
|
+
|
687
|
+
def test_set_proxy
|
688
|
+
@agent.set_proxy('www.example.com', 9001, 'joe', 'lol')
|
689
|
+
|
690
|
+
assert_equal(@agent.proxy_uri.host, 'www.example.com')
|
691
|
+
assert_equal(@agent.proxy_uri.port, 9001)
|
692
|
+
assert_equal(@agent.proxy_uri.user, 'joe')
|
693
|
+
assert_equal(@agent.proxy_uri.password, 'lol')
|
694
|
+
end
|
695
|
+
|
696
|
+
end
|
697
|
+
|