mechanize 2.0.1 → 2.1.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.
- data.tar.gz.sig +0 -0
- data/CHANGELOG.rdoc +82 -0
- data/EXAMPLES.rdoc +1 -1
- data/FAQ.rdoc +9 -9
- data/Manifest.txt +35 -48
- data/README.rdoc +2 -1
- data/Rakefile +16 -3
- data/lib/mechanize.rb +809 -392
- data/lib/mechanize/content_type_error.rb +10 -11
- data/lib/mechanize/cookie.rb +193 -60
- data/lib/mechanize/cookie_jar.rb +39 -86
- data/lib/mechanize/download.rb +59 -0
- data/lib/mechanize/element_matcher.rb +1 -0
- data/lib/mechanize/file.rb +61 -76
- data/lib/mechanize/file_saver.rb +37 -35
- data/lib/mechanize/form.rb +475 -410
- data/lib/mechanize/form/button.rb +4 -7
- data/lib/mechanize/form/check_box.rb +10 -9
- data/lib/mechanize/form/field.rb +52 -42
- data/lib/mechanize/form/file_upload.rb +17 -19
- data/lib/mechanize/form/hidden.rb +3 -0
- data/lib/mechanize/form/image_button.rb +15 -16
- data/lib/mechanize/form/keygen.rb +34 -0
- data/lib/mechanize/form/multi_select_list.rb +20 -9
- data/lib/mechanize/form/option.rb +48 -47
- data/lib/mechanize/form/radio_button.rb +52 -45
- data/lib/mechanize/form/reset.rb +3 -0
- data/lib/mechanize/form/select_list.rb +10 -6
- data/lib/mechanize/form/submit.rb +3 -0
- data/lib/mechanize/form/text.rb +3 -0
- data/lib/mechanize/form/textarea.rb +3 -0
- data/lib/mechanize/headers.rb +17 -19
- data/lib/mechanize/history.rb +60 -61
- data/lib/mechanize/http.rb +5 -0
- data/lib/mechanize/http/agent.rb +485 -218
- data/lib/mechanize/http/auth_challenge.rb +59 -0
- data/lib/mechanize/http/auth_realm.rb +31 -0
- data/lib/mechanize/http/content_disposition_parser.rb +188 -0
- data/lib/mechanize/http/www_authenticate_parser.rb +155 -0
- data/lib/mechanize/monkey_patch.rb +14 -35
- data/lib/mechanize/page.rb +34 -2
- data/lib/mechanize/page/base.rb +6 -7
- data/lib/mechanize/page/frame.rb +5 -5
- data/lib/mechanize/page/image.rb +23 -23
- data/lib/mechanize/page/label.rb +16 -16
- data/lib/mechanize/page/link.rb +16 -0
- data/lib/mechanize/page/meta_refresh.rb +19 -7
- data/lib/mechanize/parser.rb +173 -0
- data/lib/mechanize/pluggable_parsers.rb +126 -83
- data/lib/mechanize/redirect_limit_reached_error.rb +16 -13
- data/lib/mechanize/redirect_not_get_or_head_error.rb +18 -16
- data/lib/mechanize/response_code_error.rb +16 -17
- data/lib/mechanize/robots_disallowed_error.rb +22 -23
- data/lib/mechanize/test_case.rb +659 -0
- data/lib/mechanize/unauthorized_error.rb +3 -0
- data/lib/mechanize/unsupported_scheme_error.rb +4 -6
- data/lib/mechanize/util.rb +0 -12
- data/test/htdocs/form_order_test.html +11 -0
- data/test/htdocs/form_test.html +2 -2
- data/test/htdocs/tc_links.html +1 -0
- data/test/test_mechanize.rb +367 -59
- data/test/test_mechanize_cookie.rb +69 -4
- data/test/test_mechanize_cookie_jar.rb +200 -124
- data/test/test_mechanize_download.rb +43 -0
- data/test/test_mechanize_file.rb +53 -45
- data/test/{test_mechanize_file_response.rb → test_mechanize_file_connection.rb} +2 -2
- data/test/test_mechanize_file_request.rb +2 -2
- data/test/test_mechanize_file_saver.rb +21 -0
- data/test/test_mechanize_form.rb +345 -46
- data/test/test_mechanize_form_check_box.rb +5 -4
- data/test/test_mechanize_form_encoding.rb +10 -16
- data/test/test_mechanize_form_field.rb +45 -3
- data/test/test_mechanize_form_file_upload.rb +20 -0
- data/test/test_mechanize_form_image_button.rb +2 -2
- data/test/test_mechanize_form_keygen.rb +32 -0
- data/test/test_mechanize_form_multi_select_list.rb +84 -0
- data/test/test_mechanize_form_option.rb +55 -0
- data/test/test_mechanize_form_radio_button.rb +78 -0
- data/test/test_mechanize_form_select_list.rb +76 -0
- data/test/test_mechanize_form_textarea.rb +8 -7
- data/test/{test_headers.rb → test_mechanize_headers.rb} +4 -2
- data/test/test_mechanize_history.rb +103 -0
- data/test/test_mechanize_http_agent.rb +525 -17
- data/test/test_mechanize_http_auth_challenge.rb +39 -0
- data/test/test_mechanize_http_auth_realm.rb +49 -0
- data/test/test_mechanize_http_content_disposition_parser.rb +118 -0
- data/test/test_mechanize_http_www_authenticate_parser.rb +146 -0
- data/test/test_mechanize_link.rb +10 -14
- data/test/test_mechanize_page.rb +118 -0
- data/test/test_mechanize_page_encoding.rb +48 -13
- data/test/test_mechanize_page_frame.rb +16 -0
- data/test/test_mechanize_page_link.rb +27 -19
- data/test/test_mechanize_page_meta_refresh.rb +26 -14
- data/test/test_mechanize_parser.rb +289 -0
- data/test/test_mechanize_pluggable_parser.rb +52 -0
- data/test/test_mechanize_redirect_limit_reached_error.rb +24 -0
- data/test/test_mechanize_redirect_not_get_or_head_error.rb +3 -7
- data/test/test_mechanize_subclass.rb +2 -2
- data/test/test_mechanize_util.rb +24 -13
- data/test/test_multi_select.rb +23 -22
- metadata +145 -114
- metadata.gz.sig +0 -0
- data/lib/mechanize/inspect.rb +0 -88
- data/test/helper.rb +0 -175
- data/test/htdocs/form_select_all.html +0 -16
- data/test/htdocs/form_select_none.html +0 -17
- data/test/htdocs/form_select_noopts.html +0 -10
- data/test/htdocs/iframe_test.html +0 -16
- data/test/htdocs/nofollow.html +0 -9
- data/test/htdocs/norobots.html +0 -8
- data/test/htdocs/rel_nofollow.html +0 -8
- data/test/htdocs/tc_base_images.html +0 -10
- data/test/htdocs/tc_images.html +0 -8
- data/test/htdocs/tc_no_attributes.html +0 -16
- data/test/htdocs/tc_radiobuttons.html +0 -17
- data/test/htdocs/test_bad_encoding.html +0 -52
- data/test/servlets.rb +0 -402
- data/test/ssl_server.rb +0 -48
- data/test/test_cookies.rb +0 -129
- data/test/test_form_action.rb +0 -52
- data/test/test_form_as_hash.rb +0 -59
- data/test/test_form_button.rb +0 -46
- data/test/test_frames.rb +0 -34
- data/test/test_history.rb +0 -118
- data/test/test_history_added.rb +0 -16
- data/test/test_html_unscape_forms.rb +0 -46
- data/test/test_if_modified_since.rb +0 -20
- data/test/test_images.rb +0 -19
- data/test/test_no_attributes.rb +0 -13
- data/test/test_option.rb +0 -18
- data/test/test_pluggable_parser.rb +0 -136
- data/test/test_post_form.rb +0 -37
- data/test/test_pretty_print.rb +0 -22
- data/test/test_radiobutton.rb +0 -75
- data/test/test_redirect_limit_reached.rb +0 -39
- data/test/test_referer.rb +0 -81
- data/test/test_relative_links.rb +0 -40
- data/test/test_request.rb +0 -13
- data/test/test_response_code.rb +0 -53
- data/test/test_robots.rb +0 -72
- data/test/test_save_file.rb +0 -48
- data/test/test_scheme.rb +0 -48
- data/test/test_select.rb +0 -119
- data/test/test_select_all.rb +0 -15
- data/test/test_select_none.rb +0 -15
- data/test/test_select_noopts.rb +0 -18
- data/test/test_set_fields.rb +0 -44
- data/test/test_ssl_server.rb +0 -20
@@ -1,8 +1,6 @@
|
|
1
|
-
class Mechanize
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
@scheme = scheme
|
6
|
-
end
|
1
|
+
class Mechanize::UnsupportedSchemeError < Mechanize::Error
|
2
|
+
attr_accessor :scheme
|
3
|
+
def initialize(scheme)
|
4
|
+
@scheme = scheme
|
7
5
|
end
|
8
6
|
end
|
data/lib/mechanize/util.rb
CHANGED
@@ -24,18 +24,6 @@ class Mechanize::Util
|
|
24
24
|
}.compact.join('&')
|
25
25
|
end
|
26
26
|
|
27
|
-
def self.to_native_charset(s, code=nil)
|
28
|
-
location = Gem.location_of_caller.join ':'
|
29
|
-
warn "#{location}: Mechanize::Util::to_native_charset is deprecated and will be removed October 2011"
|
30
|
-
if Mechanize.html_parser == Nokogiri::HTML
|
31
|
-
return unless s
|
32
|
-
code ||= detect_charset(s)
|
33
|
-
Iconv.iconv("UTF-8", code, s).join("")
|
34
|
-
else
|
35
|
-
s
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
27
|
# Converts string +s+ from +code+ to UTF-8.
|
40
28
|
def self.from_native_charset(s, code, ignore_encoding_error=false, log=nil)
|
41
29
|
return s unless s && code
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<html>
|
2
|
+
<head><title>Page Title</title></head>
|
3
|
+
<body>
|
4
|
+
<form name="post_form1">
|
5
|
+
<input type="radio" name="1" value="RADIO" checked>
|
6
|
+
<input type="email" name="3" value="nobody@example">
|
7
|
+
<input type="text" name="2" value="TEXT">
|
8
|
+
<input type="month" name="3" value="2011-10">
|
9
|
+
</form>
|
10
|
+
</body>
|
11
|
+
</html>
|
data/test/htdocs/form_test.html
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
<head><title>Page Title</title></head>
|
3
3
|
<body>
|
4
4
|
<h1>Post Form 1</h1>
|
5
|
-
<form name="post_form1" method="post" action="/form_post" id="generic_form" >
|
5
|
+
<form name="post_form1" method="post" action="/form_post" id="generic_form" class="really_generic_form" >
|
6
6
|
<table>
|
7
7
|
<tr>
|
8
8
|
<td>First Name</td>
|
9
|
-
<td><input type="text" name="first_name" id="name_first" /></td>
|
9
|
+
<td><input type="text" name="first_name" id="name_first" class="text_input"/></td>
|
10
10
|
</tr>
|
11
11
|
<tr>
|
12
12
|
<td>Gender</td>
|
data/test/htdocs/tc_links.html
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
<a href="thing.html" rel="nofollow">Dude</a>
|
5
5
|
<a href="thing.html" rel="me">Aaron <b>James</b> Patterson</a>
|
6
6
|
<a href="thing.html" id="bold_aaron_link" rel="me nofollow"><b>Aaron</b> Patterson</a>
|
7
|
+
<a href="thing.html" class="thing_link">Thing!</a>
|
7
8
|
<a href="thing.html">Ruby <b>Rocks!</b></a>
|
8
9
|
<!-- Testing a bug with escaped stuff in links:
|
9
10
|
http://rubyforge.org/pipermail/mechanize-users/2006-September/000002.html
|
data/test/test_mechanize.rb
CHANGED
@@ -1,25 +1,13 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
require '
|
4
|
-
|
5
|
-
class TestMechanize <
|
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
|
3
|
+
require 'mechanize/test_case'
|
4
|
+
|
5
|
+
class TestMechanize < Mechanize::TestCase
|
18
6
|
|
19
7
|
def setup
|
20
|
-
|
21
|
-
|
22
|
-
@uri = URI
|
8
|
+
super
|
9
|
+
|
10
|
+
@uri = URI 'http://example/'
|
23
11
|
@req = Net::HTTP::Get.new '/'
|
24
12
|
|
25
13
|
@res = Net::HTTPOK.allocate
|
@@ -59,32 +47,36 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
59
47
|
end
|
60
48
|
|
61
49
|
def test_cert_key_file
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
key.rewind
|
66
|
-
|
67
|
-
cert.write CERT.to_pem
|
68
|
-
cert.rewind
|
50
|
+
in_tmpdir do
|
51
|
+
open 'key.pem', 'w' do |io| io.write ssl_private_key.to_pem end
|
52
|
+
open 'cert.pem', 'w' do |io| io.write ssl_certificate.to_pem end
|
69
53
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
74
|
-
|
75
|
-
# Certificate#== seems broken
|
76
|
-
assert_equal CERT.to_pem, mech.certificate.to_pem
|
54
|
+
mech = Mechanize.new do |a|
|
55
|
+
a.cert = 'cert.pem'
|
56
|
+
a.key = 'key.pem'
|
77
57
|
end
|
58
|
+
|
59
|
+
# Certificate#== seems broken
|
60
|
+
assert_equal ssl_certificate.to_pem, mech.certificate.to_pem
|
78
61
|
end
|
79
62
|
end
|
80
63
|
|
81
64
|
def test_cert_key_object
|
82
65
|
mech = Mechanize.new do |a|
|
83
|
-
a.cert =
|
84
|
-
a.key =
|
66
|
+
a.cert = ssl_certificate
|
67
|
+
a.key = ssl_private_key
|
85
68
|
end
|
86
69
|
|
87
|
-
assert_equal
|
70
|
+
assert_equal ssl_certificate, mech.certificate
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_cert_store
|
74
|
+
assert_nil @mech.cert_store
|
75
|
+
|
76
|
+
store = OpenSSL::X509::Store.new
|
77
|
+
@mech.cert_store = store
|
78
|
+
|
79
|
+
assert_equal store, @mech.cert_store
|
88
80
|
end
|
89
81
|
|
90
82
|
def test_click
|
@@ -98,6 +90,15 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
98
90
|
@mech.history.last.uri.to_s)
|
99
91
|
end
|
100
92
|
|
93
|
+
def test_click_frame
|
94
|
+
frame = node 'frame', 'src' => '/index.html'
|
95
|
+
frame = Mechanize::Page::Frame.new frame, @mech, fake_page
|
96
|
+
|
97
|
+
@mech.click frame
|
98
|
+
|
99
|
+
assert_equal '/index.html', requests.first.path
|
100
|
+
end
|
101
|
+
|
101
102
|
def test_click_frame_hpricot_style
|
102
103
|
page = @mech.get("http://localhost/frame_test.html")
|
103
104
|
link = (page/"//frame[@name='frame2']").first
|
@@ -119,15 +120,81 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
119
120
|
end
|
120
121
|
|
121
122
|
def test_click_link
|
122
|
-
|
123
|
-
|
124
|
-
page = agent.get("http://localhost/frame_test.html")
|
125
|
-
link = page.link_with(:text => "Form Test")
|
123
|
+
link = node 'a', 'href' => '/index.html'
|
124
|
+
link = Mechanize::Page::Link.new link, @mech, fake_page
|
126
125
|
|
127
|
-
|
126
|
+
@mech.click link
|
128
127
|
|
129
|
-
assert_equal
|
130
|
-
|
128
|
+
assert_equal '/index.html', requests.first.path
|
129
|
+
assert_equal 'http://fake.example/', requests.first['Referer']
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_click_link_nofollow
|
133
|
+
page = html_page <<-BODY
|
134
|
+
<meta name="ROBOTS" content="nofollow">
|
135
|
+
|
136
|
+
<p>Do not follow <a href="/index.html">this</a> or <a href="/">this</a>!
|
137
|
+
BODY
|
138
|
+
|
139
|
+
page.links[0].click
|
140
|
+
page.links[1].click
|
141
|
+
|
142
|
+
@mech.robots = true
|
143
|
+
|
144
|
+
assert_raises Mechanize::RobotsDisallowedError do
|
145
|
+
page.links[0].click
|
146
|
+
end
|
147
|
+
|
148
|
+
assert_raises Mechanize::RobotsDisallowedError do
|
149
|
+
page.links[1].click
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_click_link_noreferrer
|
154
|
+
link = node 'a', 'href' => '/index.html', 'rel' => 'noreferrer'
|
155
|
+
link = Mechanize::Page::Link.new link, @mech, fake_page
|
156
|
+
|
157
|
+
@mech.click link
|
158
|
+
|
159
|
+
assert_nil requests.first['referer']
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_click_link_rel_nofollow
|
163
|
+
page = html_page <<-BODY
|
164
|
+
<p>You can follow <a href="/index.html">this link</a>
|
165
|
+
but not <a href="/" rel="me nofollow">this</a>!
|
166
|
+
BODY
|
167
|
+
|
168
|
+
page.links[0].click
|
169
|
+
page.links[1].click
|
170
|
+
|
171
|
+
@mech.robots = true
|
172
|
+
|
173
|
+
page.links[0].click
|
174
|
+
|
175
|
+
assert_raises Mechanize::RobotsDisallowedError do
|
176
|
+
page.links[1].click
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_click_link_parent
|
181
|
+
page = page URI 'http://example/a/index.html'
|
182
|
+
link = node 'a', 'href' => '../index.html'
|
183
|
+
link = Mechanize::Page::Link.new link, @mech, page
|
184
|
+
|
185
|
+
@mech.click link
|
186
|
+
|
187
|
+
assert_equal '/index.html', requests.first.path
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_click_link_parent_extra
|
191
|
+
page = page URI 'http://example/a/index.html'
|
192
|
+
link = node 'a', 'href' => '../../index.html'
|
193
|
+
link = Mechanize::Page::Link.new link, @mech, page
|
194
|
+
|
195
|
+
@mech.click link
|
196
|
+
|
197
|
+
assert_equal '/index.html', requests.first.path
|
131
198
|
end
|
132
199
|
|
133
200
|
def test_click_link_hpricot_style # HACK move to test_search in Page
|
@@ -172,6 +239,28 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
172
239
|
@mech.page.uri.to_s
|
173
240
|
end
|
174
241
|
|
242
|
+
def test_cookies
|
243
|
+
uri = URI 'http://example'
|
244
|
+
jar = Mechanize::CookieJar.new
|
245
|
+
Mechanize::Cookie.parse uri, 'a=b' do |cookie|
|
246
|
+
jar.add uri, cookie
|
247
|
+
end
|
248
|
+
|
249
|
+
@mech.cookie_jar = jar
|
250
|
+
|
251
|
+
refute_empty @mech.cookies
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_cookie_jar
|
255
|
+
assert_kind_of Mechanize::CookieJar, @mech.cookie_jar
|
256
|
+
|
257
|
+
jar = Mechanize::CookieJar.new
|
258
|
+
|
259
|
+
@mech.cookie_jar = jar
|
260
|
+
|
261
|
+
assert_equal jar, @mech.cookie_jar
|
262
|
+
end
|
263
|
+
|
175
264
|
def test_delete
|
176
265
|
page = @mech.delete('http://localhost/verb', { 'q' => 'foo' })
|
177
266
|
assert_equal 1, @mech.history.length
|
@@ -198,10 +287,12 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
198
287
|
#end
|
199
288
|
|
200
289
|
def test_get
|
201
|
-
|
202
|
-
{ 'X-H' => 'v' })
|
290
|
+
uri = URI 'http://localhost'
|
203
291
|
|
204
|
-
|
292
|
+
page = @mech.get uri, { :q => 'h' }, 'http://example', { 'X-H' => 'v' }
|
293
|
+
|
294
|
+
assert_equal URI('http://localhost/?q=h'), page.uri
|
295
|
+
assert_equal URI('http://localhost'), uri
|
205
296
|
end
|
206
297
|
|
207
298
|
def test_get_HTTP
|
@@ -223,7 +314,7 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
223
314
|
def test_get_basic_auth_bad
|
224
315
|
@mech.basic_auth('aaron', 'aaron')
|
225
316
|
|
226
|
-
e = assert_raises Mechanize::
|
317
|
+
e = assert_raises Mechanize::UnauthorizedError do
|
227
318
|
@mech.get("http://localhost/basic_auth")
|
228
319
|
end
|
229
320
|
|
@@ -231,13 +322,26 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
231
322
|
end
|
232
323
|
|
233
324
|
def test_get_basic_auth_none
|
234
|
-
e = assert_raises Mechanize::
|
325
|
+
e = assert_raises Mechanize::UnauthorizedError do
|
235
326
|
@mech.get("http://localhost/basic_auth")
|
236
327
|
end
|
237
328
|
|
238
329
|
assert_equal("401", e.response_code)
|
239
330
|
end
|
240
331
|
|
332
|
+
def test_get_conditional
|
333
|
+
assert_empty @mech.history
|
334
|
+
|
335
|
+
page = @mech.get 'http://localhost/if_modified_since'
|
336
|
+
assert_match(/You did not send/, page.body)
|
337
|
+
|
338
|
+
assert_equal 1, @mech.history.length
|
339
|
+
page2 = @mech.get 'http://localhost/if_modified_since'
|
340
|
+
|
341
|
+
assert_equal 2, @mech.history.length
|
342
|
+
assert_equal page.object_id, page2.object_id
|
343
|
+
end
|
344
|
+
|
241
345
|
def test_get_digest_auth
|
242
346
|
block_called = false
|
243
347
|
|
@@ -294,6 +398,7 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
294
398
|
|
295
399
|
def test_get_follow_meta_refresh_empty_url
|
296
400
|
@mech.follow_meta_refresh = true
|
401
|
+
@mech.follow_meta_refresh_self = true
|
297
402
|
|
298
403
|
page = @mech.get('http://localhost/refresh_with_empty_url')
|
299
404
|
|
@@ -319,6 +424,7 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
319
424
|
|
320
425
|
def test_get_follow_meta_refresh_no_url
|
321
426
|
@mech.follow_meta_refresh = true
|
427
|
+
@mech.follow_meta_refresh_self = true
|
322
428
|
|
323
429
|
page = @mech.get('http://localhost/refresh_without_url')
|
324
430
|
|
@@ -346,6 +452,24 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
346
452
|
assert_nil requests.last['referer']
|
347
453
|
end
|
348
454
|
|
455
|
+
def test_get_robots
|
456
|
+
@mech.robots = true
|
457
|
+
|
458
|
+
assert_equal "Page Title", @mech.get("http://localhost/index.html").title
|
459
|
+
|
460
|
+
assert_raises Mechanize::RobotsDisallowedError do
|
461
|
+
@mech.get "http://localhost/norobots.html"
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
def test_follow_meta_refresh_self
|
466
|
+
refute @mech.agent.follow_meta_refresh_self
|
467
|
+
|
468
|
+
@mech.follow_meta_refresh_self = true
|
469
|
+
|
470
|
+
assert @mech.agent.follow_meta_refresh_self
|
471
|
+
end
|
472
|
+
|
349
473
|
def test_get_gzip
|
350
474
|
page = @mech.get("http://localhost/gzip?file=index.html")
|
351
475
|
|
@@ -354,11 +478,52 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
354
478
|
assert_match('Hello World', page.body)
|
355
479
|
end
|
356
480
|
|
481
|
+
def test_content_encoding_hooks_header
|
482
|
+
h = {'X-ResponseContentEncoding' => 'agzip'}
|
483
|
+
|
484
|
+
# test of X-ResponseContentEncoding feature
|
485
|
+
assert_raises(Mechanize::Error, 'Unsupported Content-Encoding: agzip') do
|
486
|
+
@mech.get("http://localhost/gzip?file=index.html", nil, nil, h)
|
487
|
+
end
|
488
|
+
|
489
|
+
@mech.content_encoding_hooks << lambda{|agent, uri, response, response_body_io|
|
490
|
+
response['content-encoding'] = 'gzip' if response['content-encoding'] == 'agzip'}
|
491
|
+
|
492
|
+
page = @mech.get("http://localhost/gzip?file=index.html", nil, nil, h)
|
493
|
+
|
494
|
+
assert_match('Hello World', page.body)
|
495
|
+
end
|
496
|
+
|
497
|
+
def external_cmd(io); Zlib::GzipReader.new(io).read; end
|
498
|
+
|
499
|
+
def test_content_encoding_hooks_body_io
|
500
|
+
h = {'X-ResponseContentEncoding' => 'unsupported_content_encoding'}
|
501
|
+
|
502
|
+
@mech.content_encoding_hooks << lambda{|agent, uri, response, response_body_io|
|
503
|
+
if response['content-encoding'] == 'unsupported_content_encoding'
|
504
|
+
response['content-encoding'] = 'none'
|
505
|
+
response_body_io.string = external_cmd(response_body_io)
|
506
|
+
end}
|
507
|
+
|
508
|
+
page = @mech.get("http://localhost/gzip?file=index.html", nil, nil, h)
|
509
|
+
|
510
|
+
assert_match('Hello World', page.body)
|
511
|
+
end
|
512
|
+
|
357
513
|
def test_get_http_refresh
|
358
514
|
@mech.follow_meta_refresh = true
|
515
|
+
|
516
|
+
requests = []
|
517
|
+
|
518
|
+
@mech.pre_connect_hooks << lambda { |_, request|
|
519
|
+
requests << request
|
520
|
+
}
|
521
|
+
|
359
522
|
page = @mech.get('http://localhost/http_refresh?refresh_time=0')
|
523
|
+
|
360
524
|
assert_equal('http://localhost/index.html', page.uri.to_s)
|
361
525
|
assert_equal(2, @mech.history.length)
|
526
|
+
assert_nil requests.last['referer']
|
362
527
|
end
|
363
528
|
|
364
529
|
def test_get_http_refresh_delay
|
@@ -426,7 +591,7 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
426
591
|
end
|
427
592
|
|
428
593
|
def test_get_referer_file
|
429
|
-
uri = URI
|
594
|
+
uri = URI 'http://tenderlovemaking.com/crossdomain.xml'
|
430
595
|
file = Mechanize::File.new uri
|
431
596
|
|
432
597
|
@mech.get('http://localhost', [], file)
|
@@ -523,6 +688,16 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
523
688
|
assert @mech.visited?(page.links.first)
|
524
689
|
end
|
525
690
|
|
691
|
+
def test_history_added_gets_called
|
692
|
+
added_page = nil
|
693
|
+
|
694
|
+
@mech.history_added = lambda { |page|
|
695
|
+
added_page = page
|
696
|
+
}
|
697
|
+
|
698
|
+
assert_equal @mech.get('http://localhost/tc_blank_form.html'), added_page
|
699
|
+
end
|
700
|
+
|
526
701
|
def test_history_order
|
527
702
|
@mech.max_history = 2
|
528
703
|
assert_equal(0, @mech.history.length)
|
@@ -547,6 +722,20 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
547
722
|
}
|
548
723
|
end
|
549
724
|
|
725
|
+
def test_idle_timeout_equals
|
726
|
+
@mech.idle_timeout = 5
|
727
|
+
|
728
|
+
assert_equal 5, @mech.idle_timeout
|
729
|
+
end
|
730
|
+
|
731
|
+
def test_keep_alive_equals
|
732
|
+
assert @mech.keep_alive
|
733
|
+
|
734
|
+
@mech.keep_alive = false
|
735
|
+
|
736
|
+
refute @mech.keep_alive
|
737
|
+
end
|
738
|
+
|
550
739
|
def test_keep_alive_time
|
551
740
|
assert_equal 0, @mech.keep_alive_time
|
552
741
|
|
@@ -555,6 +744,23 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
555
744
|
assert_equal 1, @mech.keep_alive_time
|
556
745
|
end
|
557
746
|
|
747
|
+
def test_log
|
748
|
+
assert_nil @mech.log
|
749
|
+
end
|
750
|
+
|
751
|
+
def test_log_equals
|
752
|
+
@mech.log = Logger.new $stderr
|
753
|
+
|
754
|
+
refute_nil @mech.log
|
755
|
+
assert_nil Mechanize.log
|
756
|
+
end
|
757
|
+
|
758
|
+
def test_max_file_buffer_equals
|
759
|
+
@mech.max_file_buffer = 1024
|
760
|
+
|
761
|
+
assert_equal 1024, @mech.agent.max_file_buffer
|
762
|
+
end
|
763
|
+
|
558
764
|
def test_max_history_equals
|
559
765
|
@mech.max_history = 10
|
560
766
|
0.upto(10) do |i|
|
@@ -574,6 +780,34 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
574
780
|
assert_equal 5, @mech.open_timeout
|
575
781
|
end
|
576
782
|
|
783
|
+
def test_parse_download
|
784
|
+
@mech.pluggable_parser['application/octet-stream'] = Mechanize::Download
|
785
|
+
|
786
|
+
response = Net::HTTPOK.allocate
|
787
|
+
response.instance_variable_set(:@header,
|
788
|
+
'content-type' =>
|
789
|
+
['application/octet-stream'])
|
790
|
+
|
791
|
+
download = @mech.parse @uri, response, StringIO.new('raw')
|
792
|
+
|
793
|
+
assert_kind_of Mechanize::Download, download
|
794
|
+
end
|
795
|
+
|
796
|
+
def test_parse_html
|
797
|
+
response = Net::HTTPOK.allocate
|
798
|
+
response.instance_variable_set :@header, 'content-type' => ['text/html']
|
799
|
+
|
800
|
+
page = @mech.parse URI('http://example/'), response, ''
|
801
|
+
|
802
|
+
assert_kind_of Mechanize::Page, page
|
803
|
+
end
|
804
|
+
|
805
|
+
def test_post
|
806
|
+
@mech.post "http://example", 'gender' => 'female'
|
807
|
+
|
808
|
+
assert_equal "gender=female", requests.first.body
|
809
|
+
end
|
810
|
+
|
577
811
|
def test_post_basic_auth
|
578
812
|
requests = []
|
579
813
|
|
@@ -590,6 +824,19 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
590
824
|
assert_equal(r1, r2)
|
591
825
|
end
|
592
826
|
|
827
|
+
def test_post_entity
|
828
|
+
@mech.post "http://localhost/form_post", 'json' => '["""]'
|
829
|
+
|
830
|
+
assert_equal "json=%5B%22%22%22%5D", requests.first.body
|
831
|
+
end
|
832
|
+
|
833
|
+
def test_post_multiple_values
|
834
|
+
@mech.post "http://localhost/form_post",
|
835
|
+
[%w[gender female], %w[gender male]]
|
836
|
+
|
837
|
+
assert_equal "gender=female&gender=male", requests.first.body
|
838
|
+
end
|
839
|
+
|
593
840
|
def test_post_multipart
|
594
841
|
page = @mech.post('http://localhost/file_upload', {
|
595
842
|
:name => 'Some file',
|
@@ -632,6 +879,14 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
632
879
|
assert_equal 5, @mech.read_timeout
|
633
880
|
end
|
634
881
|
|
882
|
+
def test_retry_change_requests_equals
|
883
|
+
refute @mech.retry_change_requests
|
884
|
+
|
885
|
+
@mech.retry_change_requests = true
|
886
|
+
|
887
|
+
assert @mech.retry_change_requests
|
888
|
+
end
|
889
|
+
|
635
890
|
def test_set_proxy
|
636
891
|
http = @mech.agent.http
|
637
892
|
|
@@ -681,14 +936,16 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
681
936
|
assert_equal('multipart/form-data', page.forms[0].enctype)
|
682
937
|
|
683
938
|
form = page.forms.first
|
684
|
-
form.file_uploads.first.file_name =
|
939
|
+
form.file_uploads.first.file_name = __FILE__
|
685
940
|
form.file_uploads.first.mime_type = "text/plain"
|
686
941
|
form.file_uploads.first.file_data = "Hello World\n\n"
|
687
942
|
|
688
943
|
page = @mech.submit(form)
|
689
944
|
|
945
|
+
basename = File.basename __FILE__
|
946
|
+
|
690
947
|
assert_match(
|
691
|
-
"Content-Disposition: form-data; name=\"userfile1\"; filename=\"
|
948
|
+
"Content-Disposition: form-data; name=\"userfile1\"; filename=\"#{basename}\"",
|
692
949
|
page.body
|
693
950
|
)
|
694
951
|
assert_match(
|
@@ -705,16 +962,19 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
705
962
|
assert_equal('multipart/form-data', page.forms[1].enctype)
|
706
963
|
|
707
964
|
form = page.forms[1]
|
708
|
-
form.file_uploads.first.file_name =
|
709
|
-
form.file_uploads.first.file_data = File.
|
965
|
+
form.file_uploads.first.file_name = __FILE__
|
966
|
+
form.file_uploads.first.file_data = File.read __FILE__
|
710
967
|
|
711
968
|
page = @mech.submit(form)
|
712
969
|
|
713
|
-
contents = File.
|
970
|
+
contents = File.read __FILE__
|
971
|
+
basename = File.basename __FILE__
|
972
|
+
|
714
973
|
assert_match(
|
715
|
-
"Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"
|
974
|
+
"Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"#{basename}\"",
|
716
975
|
page.body
|
717
976
|
)
|
977
|
+
|
718
978
|
assert_match(contents, page.body)
|
719
979
|
end
|
720
980
|
|
@@ -723,18 +983,28 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
723
983
|
assert_equal('multipart/form-data', page.forms[1].enctype)
|
724
984
|
|
725
985
|
form = page.forms[1]
|
726
|
-
form.file_uploads.first.file_name =
|
986
|
+
form.file_uploads.first.file_name = __FILE__
|
727
987
|
|
728
988
|
page = @mech.submit(form)
|
729
989
|
|
730
|
-
contents = File.
|
990
|
+
contents = File.read __FILE__
|
991
|
+
basename = File.basename __FILE__
|
731
992
|
assert_match(
|
732
|
-
"Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"
|
993
|
+
"Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"#{basename}\"",
|
733
994
|
page.body
|
734
995
|
)
|
735
996
|
assert_match(contents, page.body)
|
736
997
|
end
|
737
998
|
|
999
|
+
def test_submit_get
|
1000
|
+
form = node 'form', 'method' => 'GET', 'action' => '/?a=b'
|
1001
|
+
form = Mechanize::Form.new form, @mech, fake_page
|
1002
|
+
|
1003
|
+
@mech.submit form
|
1004
|
+
|
1005
|
+
assert_equal '/', requests.first.path
|
1006
|
+
end
|
1007
|
+
|
738
1008
|
def test_submit_headers
|
739
1009
|
page = @mech.get 'http://localhost:2000/form_no_action.html'
|
740
1010
|
|
@@ -755,14 +1025,16 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
755
1025
|
assert_equal('multipart/form-data', page.forms[1].enctype)
|
756
1026
|
|
757
1027
|
form = page.forms[1]
|
758
|
-
form.file_uploads.first.file_name =
|
1028
|
+
form.file_uploads.first.file_name = __FILE__
|
759
1029
|
form.file_uploads.first.mime_type = "text/plain"
|
760
1030
|
form.file_uploads.first.file_data = "Hello World\n\n"
|
761
1031
|
|
762
1032
|
page = @mech.submit(form)
|
763
1033
|
|
1034
|
+
basename = File.basename __FILE__
|
1035
|
+
|
764
1036
|
assert_match(
|
765
|
-
"Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"
|
1037
|
+
"Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"#{basename}\"",
|
766
1038
|
page.body
|
767
1039
|
)
|
768
1040
|
end
|
@@ -779,6 +1051,24 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
779
1051
|
)
|
780
1052
|
end
|
781
1053
|
|
1054
|
+
def test_submit_post
|
1055
|
+
form = node 'form', 'method' => 'POST', 'action' => '/?a=b'
|
1056
|
+
form = Mechanize::Form.new form, @mech, fake_page
|
1057
|
+
|
1058
|
+
@mech.submit form
|
1059
|
+
|
1060
|
+
assert_equal '/?a=b', requests.first.path
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
def test_submit_post_pound
|
1064
|
+
form = node 'form', 'method' => 'POST', 'action' => '/#1'
|
1065
|
+
form = Mechanize::Form.new form, @mech, fake_page
|
1066
|
+
|
1067
|
+
@mech.submit form
|
1068
|
+
|
1069
|
+
assert_equal '/', requests.first.path
|
1070
|
+
end
|
1071
|
+
|
782
1072
|
def test_submit_too_many_radiobuttons
|
783
1073
|
page = @mech.get("http://localhost/form_test.html")
|
784
1074
|
form = page.form_with(:name => 'post_form1')
|
@@ -807,6 +1097,14 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
807
1097
|
end
|
808
1098
|
end
|
809
1099
|
|
1100
|
+
def test_verify_mode
|
1101
|
+
assert_equal OpenSSL::SSL::VERIFY_PEER, @mech.verify_mode
|
1102
|
+
|
1103
|
+
@mech.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
1104
|
+
|
1105
|
+
assert_equal OpenSSL::SSL::VERIFY_NONE, @mech.verify_mode
|
1106
|
+
end
|
1107
|
+
|
810
1108
|
def test_visited_eh
|
811
1109
|
@mech.get("http://localhost/content_type_test?ct=application/pdf")
|
812
1110
|
|
@@ -818,6 +1116,16 @@ class TestMechanize < MiniTest::Unit::TestCase
|
|
818
1116
|
!@mech.visited?("http://localhost/content_type_test?ct=text/html")
|
819
1117
|
end
|
820
1118
|
|
1119
|
+
def test_visited_eh_link
|
1120
|
+
@mech.get("http://example/index.html")
|
1121
|
+
|
1122
|
+
page = page URI 'http://example'
|
1123
|
+
link = node 'a', 'href' => '/index.html'
|
1124
|
+
link = Mechanize::Page::Link.new link, page, @mech
|
1125
|
+
|
1126
|
+
assert @mech.visited? link
|
1127
|
+
end
|
1128
|
+
|
821
1129
|
def test_visited_eh_redirect
|
822
1130
|
@mech.get("http://localhost/response_code?code=302")
|
823
1131
|
|