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.

Files changed (148) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG.rdoc +82 -0
  3. data/EXAMPLES.rdoc +1 -1
  4. data/FAQ.rdoc +9 -9
  5. data/Manifest.txt +35 -48
  6. data/README.rdoc +2 -1
  7. data/Rakefile +16 -3
  8. data/lib/mechanize.rb +809 -392
  9. data/lib/mechanize/content_type_error.rb +10 -11
  10. data/lib/mechanize/cookie.rb +193 -60
  11. data/lib/mechanize/cookie_jar.rb +39 -86
  12. data/lib/mechanize/download.rb +59 -0
  13. data/lib/mechanize/element_matcher.rb +1 -0
  14. data/lib/mechanize/file.rb +61 -76
  15. data/lib/mechanize/file_saver.rb +37 -35
  16. data/lib/mechanize/form.rb +475 -410
  17. data/lib/mechanize/form/button.rb +4 -7
  18. data/lib/mechanize/form/check_box.rb +10 -9
  19. data/lib/mechanize/form/field.rb +52 -42
  20. data/lib/mechanize/form/file_upload.rb +17 -19
  21. data/lib/mechanize/form/hidden.rb +3 -0
  22. data/lib/mechanize/form/image_button.rb +15 -16
  23. data/lib/mechanize/form/keygen.rb +34 -0
  24. data/lib/mechanize/form/multi_select_list.rb +20 -9
  25. data/lib/mechanize/form/option.rb +48 -47
  26. data/lib/mechanize/form/radio_button.rb +52 -45
  27. data/lib/mechanize/form/reset.rb +3 -0
  28. data/lib/mechanize/form/select_list.rb +10 -6
  29. data/lib/mechanize/form/submit.rb +3 -0
  30. data/lib/mechanize/form/text.rb +3 -0
  31. data/lib/mechanize/form/textarea.rb +3 -0
  32. data/lib/mechanize/headers.rb +17 -19
  33. data/lib/mechanize/history.rb +60 -61
  34. data/lib/mechanize/http.rb +5 -0
  35. data/lib/mechanize/http/agent.rb +485 -218
  36. data/lib/mechanize/http/auth_challenge.rb +59 -0
  37. data/lib/mechanize/http/auth_realm.rb +31 -0
  38. data/lib/mechanize/http/content_disposition_parser.rb +188 -0
  39. data/lib/mechanize/http/www_authenticate_parser.rb +155 -0
  40. data/lib/mechanize/monkey_patch.rb +14 -35
  41. data/lib/mechanize/page.rb +34 -2
  42. data/lib/mechanize/page/base.rb +6 -7
  43. data/lib/mechanize/page/frame.rb +5 -5
  44. data/lib/mechanize/page/image.rb +23 -23
  45. data/lib/mechanize/page/label.rb +16 -16
  46. data/lib/mechanize/page/link.rb +16 -0
  47. data/lib/mechanize/page/meta_refresh.rb +19 -7
  48. data/lib/mechanize/parser.rb +173 -0
  49. data/lib/mechanize/pluggable_parsers.rb +126 -83
  50. data/lib/mechanize/redirect_limit_reached_error.rb +16 -13
  51. data/lib/mechanize/redirect_not_get_or_head_error.rb +18 -16
  52. data/lib/mechanize/response_code_error.rb +16 -17
  53. data/lib/mechanize/robots_disallowed_error.rb +22 -23
  54. data/lib/mechanize/test_case.rb +659 -0
  55. data/lib/mechanize/unauthorized_error.rb +3 -0
  56. data/lib/mechanize/unsupported_scheme_error.rb +4 -6
  57. data/lib/mechanize/util.rb +0 -12
  58. data/test/htdocs/form_order_test.html +11 -0
  59. data/test/htdocs/form_test.html +2 -2
  60. data/test/htdocs/tc_links.html +1 -0
  61. data/test/test_mechanize.rb +367 -59
  62. data/test/test_mechanize_cookie.rb +69 -4
  63. data/test/test_mechanize_cookie_jar.rb +200 -124
  64. data/test/test_mechanize_download.rb +43 -0
  65. data/test/test_mechanize_file.rb +53 -45
  66. data/test/{test_mechanize_file_response.rb → test_mechanize_file_connection.rb} +2 -2
  67. data/test/test_mechanize_file_request.rb +2 -2
  68. data/test/test_mechanize_file_saver.rb +21 -0
  69. data/test/test_mechanize_form.rb +345 -46
  70. data/test/test_mechanize_form_check_box.rb +5 -4
  71. data/test/test_mechanize_form_encoding.rb +10 -16
  72. data/test/test_mechanize_form_field.rb +45 -3
  73. data/test/test_mechanize_form_file_upload.rb +20 -0
  74. data/test/test_mechanize_form_image_button.rb +2 -2
  75. data/test/test_mechanize_form_keygen.rb +32 -0
  76. data/test/test_mechanize_form_multi_select_list.rb +84 -0
  77. data/test/test_mechanize_form_option.rb +55 -0
  78. data/test/test_mechanize_form_radio_button.rb +78 -0
  79. data/test/test_mechanize_form_select_list.rb +76 -0
  80. data/test/test_mechanize_form_textarea.rb +8 -7
  81. data/test/{test_headers.rb → test_mechanize_headers.rb} +4 -2
  82. data/test/test_mechanize_history.rb +103 -0
  83. data/test/test_mechanize_http_agent.rb +525 -17
  84. data/test/test_mechanize_http_auth_challenge.rb +39 -0
  85. data/test/test_mechanize_http_auth_realm.rb +49 -0
  86. data/test/test_mechanize_http_content_disposition_parser.rb +118 -0
  87. data/test/test_mechanize_http_www_authenticate_parser.rb +146 -0
  88. data/test/test_mechanize_link.rb +10 -14
  89. data/test/test_mechanize_page.rb +118 -0
  90. data/test/test_mechanize_page_encoding.rb +48 -13
  91. data/test/test_mechanize_page_frame.rb +16 -0
  92. data/test/test_mechanize_page_link.rb +27 -19
  93. data/test/test_mechanize_page_meta_refresh.rb +26 -14
  94. data/test/test_mechanize_parser.rb +289 -0
  95. data/test/test_mechanize_pluggable_parser.rb +52 -0
  96. data/test/test_mechanize_redirect_limit_reached_error.rb +24 -0
  97. data/test/test_mechanize_redirect_not_get_or_head_error.rb +3 -7
  98. data/test/test_mechanize_subclass.rb +2 -2
  99. data/test/test_mechanize_util.rb +24 -13
  100. data/test/test_multi_select.rb +23 -22
  101. metadata +145 -114
  102. metadata.gz.sig +0 -0
  103. data/lib/mechanize/inspect.rb +0 -88
  104. data/test/helper.rb +0 -175
  105. data/test/htdocs/form_select_all.html +0 -16
  106. data/test/htdocs/form_select_none.html +0 -17
  107. data/test/htdocs/form_select_noopts.html +0 -10
  108. data/test/htdocs/iframe_test.html +0 -16
  109. data/test/htdocs/nofollow.html +0 -9
  110. data/test/htdocs/norobots.html +0 -8
  111. data/test/htdocs/rel_nofollow.html +0 -8
  112. data/test/htdocs/tc_base_images.html +0 -10
  113. data/test/htdocs/tc_images.html +0 -8
  114. data/test/htdocs/tc_no_attributes.html +0 -16
  115. data/test/htdocs/tc_radiobuttons.html +0 -17
  116. data/test/htdocs/test_bad_encoding.html +0 -52
  117. data/test/servlets.rb +0 -402
  118. data/test/ssl_server.rb +0 -48
  119. data/test/test_cookies.rb +0 -129
  120. data/test/test_form_action.rb +0 -52
  121. data/test/test_form_as_hash.rb +0 -59
  122. data/test/test_form_button.rb +0 -46
  123. data/test/test_frames.rb +0 -34
  124. data/test/test_history.rb +0 -118
  125. data/test/test_history_added.rb +0 -16
  126. data/test/test_html_unscape_forms.rb +0 -46
  127. data/test/test_if_modified_since.rb +0 -20
  128. data/test/test_images.rb +0 -19
  129. data/test/test_no_attributes.rb +0 -13
  130. data/test/test_option.rb +0 -18
  131. data/test/test_pluggable_parser.rb +0 -136
  132. data/test/test_post_form.rb +0 -37
  133. data/test/test_pretty_print.rb +0 -22
  134. data/test/test_radiobutton.rb +0 -75
  135. data/test/test_redirect_limit_reached.rb +0 -39
  136. data/test/test_referer.rb +0 -81
  137. data/test/test_relative_links.rb +0 -40
  138. data/test/test_request.rb +0 -13
  139. data/test/test_response_code.rb +0 -53
  140. data/test/test_robots.rb +0 -72
  141. data/test/test_save_file.rb +0 -48
  142. data/test/test_scheme.rb +0 -48
  143. data/test/test_select.rb +0 -119
  144. data/test/test_select_all.rb +0 -15
  145. data/test/test_select_none.rb +0 -15
  146. data/test/test_select_noopts.rb +0 -18
  147. data/test/test_set_fields.rb +0 -44
  148. data/test/test_ssl_server.rb +0 -20
@@ -0,0 +1,76 @@
1
+ require 'mechanize/test_case'
2
+
3
+ class TestMechanizeFormSelectList < Mechanize::TestCase
4
+
5
+ def setup
6
+ super
7
+
8
+ page = html_page <<-BODY
9
+ <form name="form1" method="post" action="/form_post">
10
+ <select name="select">
11
+ <option value="1">Option 1</option>
12
+ <option value="2" selected>Option 2</option>
13
+ <option value="3">Option 3</option>
14
+ <option value="4">Option 4</option>
15
+ <option value="5">Option 5</option>
16
+ <option value="6">Option 6</option>
17
+ </select>
18
+ </form>
19
+ BODY
20
+
21
+ form = page.forms.first
22
+ @select = form.fields.first
23
+ end
24
+
25
+ def test_option_with
26
+ option = @select.option_with :value => '1'
27
+
28
+ assert_equal '1', option.value
29
+ end
30
+
31
+ def test_options_with
32
+ options = @select.options_with :value => /[12]/
33
+
34
+ assert_equal 2, options.length
35
+ end
36
+
37
+ def test_query_value
38
+ assert_equal [%w[select 2]], @select.query_value
39
+
40
+ @select.select_all
41
+
42
+ assert_equal [%w[select 6]], @select.query_value
43
+ end
44
+
45
+ def test_select_all
46
+ @select.select_all
47
+
48
+ assert_equal "6", @select.value
49
+ end
50
+
51
+ def test_select_none
52
+ @select.select_none
53
+
54
+ assert_equal "1", @select.value
55
+ end
56
+
57
+ def test_selected_options
58
+ assert_equal [@select.options[1]], @select.selected_options
59
+
60
+ @select.options.last.click
61
+
62
+ assert_equal [@select.options.last], @select.selected_options
63
+ end
64
+
65
+ def test_value
66
+ assert_equal "2", @select.value
67
+ end
68
+
69
+ def test_value_equals
70
+ @select.value = %w[a 1 2]
71
+
72
+ assert_equal "a", @select.value
73
+ end
74
+
75
+ end
76
+
@@ -1,9 +1,10 @@
1
- require "helper"
1
+ require 'mechanize/test_case'
2
2
 
3
- class TestMechanizeFormTextarea < MiniTest::Unit::TestCase
3
+ class TestMechanizeFormTextarea < Mechanize::TestCase
4
4
  def setup
5
- @agent = Mechanize.new
6
- @page = @agent.get("http://localhost/tc_textarea.html")
5
+ super
6
+
7
+ @page = @mech.get("http://localhost/tc_textarea.html")
7
8
  end
8
9
 
9
10
  def test_empty_text_area
@@ -11,7 +12,7 @@ class TestMechanizeFormTextarea < MiniTest::Unit::TestCase
11
12
  assert_equal('', form.field_with(:name => 'text1').value)
12
13
  form.text1 = 'Hello World'
13
14
  assert_equal('Hello World', form.field_with(:name => 'text1').value)
14
- page = @agent.submit(form)
15
+ page = @mech.submit(form)
15
16
  assert_equal(1, page.links.length)
16
17
  assert_equal('text1:Hello World', page.links[0].text)
17
18
  end
@@ -19,7 +20,7 @@ class TestMechanizeFormTextarea < MiniTest::Unit::TestCase
19
20
  def test_non_empty_textfield
20
21
  form = @page.forms_with(:name => 'form2').first
21
22
  assert_equal('sample text', form.field_with(:name => 'text1').value)
22
- page = @agent.submit(form)
23
+ page = @mech.submit(form)
23
24
  assert_equal(1, page.links.length)
24
25
  assert_equal('text1:sample text', page.links[0].text)
25
26
  end
@@ -36,7 +37,7 @@ class TestMechanizeFormTextarea < MiniTest::Unit::TestCase
36
37
  assert_equal('Hello World', form.fields_with(:name => 'text1')[0].value)
37
38
  assert_equal('sample text', form.fields_with(:name => 'text1')[1].value)
38
39
 
39
- page = @agent.submit(form)
40
+ page = @mech.submit(form)
40
41
 
41
42
  assert_equal(2, page.links.length)
42
43
 
@@ -1,7 +1,9 @@
1
- require "helper"
1
+ require 'mechanize/test_case'
2
2
 
3
- class TestHeaders < MiniTest::Unit::TestCase
3
+ class TestMechanizeHeaders < Mechanize::TestCase
4
4
  def setup
5
+ super
6
+
5
7
  @headers = Mechanize::Headers.new
6
8
  @headers['content-type'] = 'text/html'
7
9
  @headers['Content-encoding'] = 'gzip'
@@ -0,0 +1,103 @@
1
+ require 'mechanize/test_case'
2
+
3
+ class TestMechanizeHistory < Mechanize::TestCase
4
+
5
+ def setup
6
+ super
7
+
8
+ @uri = URI 'http://example/'
9
+ @uri2 = @uri + '/a'
10
+ @history = Mechanize::History.new
11
+ end
12
+
13
+ def test_initialize
14
+ assert_empty @history
15
+ end
16
+
17
+ def test_clear
18
+ @history.push :page, @uri
19
+
20
+ @history.clear
21
+
22
+ assert_empty @history
23
+ end
24
+
25
+ def test_pop
26
+ assert_nil @history.pop
27
+
28
+ @history.push :page1, @uri
29
+ @history.push :page2, @uri2
30
+
31
+ assert_equal :page2, @history.pop
32
+ refute_empty @history
33
+ end
34
+
35
+ def test_push
36
+ p1 = page @uri
37
+
38
+ obj = @history.push p1
39
+
40
+ assert_same @history, obj
41
+ assert_equal 1, @history.length
42
+
43
+ p2 = page @uri2
44
+
45
+ @history.push p2
46
+
47
+ assert_equal 2, @history.length
48
+ end
49
+
50
+ def test_push_max_size
51
+ @history = Mechanize::History.new 2
52
+
53
+ @history.push :page1, @uri
54
+
55
+ assert_equal 1, @history.length
56
+
57
+ @history.push :page2, @uri
58
+
59
+ assert_equal 2, @history.length
60
+
61
+ @history.push :page3, @uri
62
+
63
+ assert_equal 2, @history.length
64
+ end
65
+
66
+ def test_push_uri
67
+ obj = @history.push :page, @uri
68
+
69
+ assert_same @history, obj
70
+ assert_equal 1, @history.length
71
+
72
+ @history.push :page2, @uri
73
+
74
+ assert_equal 2, @history.length
75
+ end
76
+
77
+ def test_shift
78
+ assert_nil @history.shift
79
+
80
+ @history.push :page1, @uri
81
+ @history.push :page2, @uri2
82
+
83
+ page = @history.shift
84
+
85
+ assert_equal :page1, page
86
+ refute_empty @history
87
+
88
+ @history.shift
89
+
90
+ assert_empty @history
91
+ end
92
+
93
+ def test_visited_eh
94
+ refute @history.visited? @uri
95
+
96
+ @history.push page @uri
97
+
98
+ assert @history.visited? URI('http://example')
99
+ assert @history.visited? URI('http://example/')
100
+ end
101
+
102
+ end
103
+
@@ -1,10 +1,12 @@
1
1
  # coding: utf-8
2
- require 'helper'
3
2
 
4
- class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
3
+ require 'mechanize/test_case'
4
+
5
+ class TestMechanizeHttpAgent < Mechanize::TestCase
5
6
 
6
7
  def setup
7
- @mech = Mechanize.new
8
+ super
9
+
8
10
  @agent = @mech.agent
9
11
 
10
12
  @uri = URI.parse 'http://example/'
@@ -21,6 +23,14 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
21
23
  end
22
24
  end
23
25
 
26
+ def auth_realm uri, scheme, type
27
+ base_uri = uri + '/'
28
+ realm = Mechanize::HTTP::AuthRealm.new scheme, base_uri, 'r'
29
+ @agent.authenticate_methods[base_uri][type] << realm
30
+
31
+ realm
32
+ end
33
+
24
34
  def test_connection_for_file
25
35
  uri = URI.parse 'file:///nonexistent'
26
36
  conn = @agent.connection_for uri
@@ -34,6 +44,20 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
34
44
  assert_equal @agent.http, conn
35
45
  end
36
46
 
47
+ def test_disable_keep_alive
48
+ @agent.disable_keep_alive @req
49
+
50
+ refute @req['connection']
51
+ end
52
+
53
+ def test_disable_keep_alive_no
54
+ @agent.keep_alive = false
55
+
56
+ @agent.disable_keep_alive @req
57
+
58
+ assert_equal 'close', @req['connection']
59
+ end
60
+
37
61
  def test_enable_gzip
38
62
  @agent.enable_gzip @req
39
63
 
@@ -48,6 +72,22 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
48
72
  assert_equal 'identity', @req['accept-encoding']
49
73
  end
50
74
 
75
+ def test_fetch_hooks
76
+ @agent.pre_connect_hooks << proc do |agent, request|
77
+ assert_equal '/index.html', request.path
78
+ assert_equal @agent, agent
79
+ end
80
+
81
+ @agent.post_connect_hooks << proc do |agent, uri, response, body|
82
+ assert_equal @agent, agent
83
+ assert_equal URI('http://example/index.html'), uri
84
+ assert_equal '200', response.code
85
+ assert_kind_of String, body
86
+ end
87
+
88
+ @agent.fetch URI 'http://example/index.html'
89
+ end
90
+
51
91
  def test_fetch_file_plus
52
92
  Tempfile.open '++plus++' do |io|
53
93
  content = 'plusses +++'
@@ -93,6 +133,14 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
93
133
  assert response
94
134
  end
95
135
 
136
+ def test_fetch_server_error
137
+ e = assert_raises Mechanize::ResponseCodeError do
138
+ @mech.get 'http://localhost/response_code?code=500'
139
+ end
140
+
141
+ assert_equal '500', e.response_code
142
+ end
143
+
96
144
  def test_get_robots
97
145
  robotstxt = @agent.get_robots 'http://localhost/robots.txt'
98
146
  refute_equal '', robotstxt
@@ -123,6 +171,13 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
123
171
  assert_equal '/', request.path
124
172
  end
125
173
 
174
+ def test_idle_timeout_equals
175
+ @agent.set_http
176
+ @agent.idle_timeout = 1
177
+
178
+ assert_equal 1, @agent.http.idle_timeout
179
+ end
180
+
126
181
  def test_post_connect
127
182
  @agent.post_connect_hooks << proc { |agent, uri, response, body|
128
183
  assert_equal @agent, agent
@@ -131,9 +186,13 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
131
186
  throw :called
132
187
  }
133
188
 
189
+ io = StringIO.new 'body'
190
+
134
191
  assert_throws :called do
135
- @agent.post_connect @uri, @res, 'body'
192
+ @agent.post_connect @uri, @res, io
136
193
  end
194
+
195
+ assert_equal 0, io.pos
137
196
  end
138
197
 
139
198
  def test_pre_connect
@@ -251,6 +310,49 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
251
310
  assert_equal 'unknown header symbol content_length', e.message
252
311
  end
253
312
 
313
+ def test_request_auth_none
314
+ @agent.request_auth @req, @uri
315
+
316
+ assert_nil @req['Authorization']
317
+ end
318
+
319
+ def test_request_auth_basic
320
+ @agent.user = 'user'
321
+ @agent.password = 'password'
322
+
323
+ auth_realm @uri, 'Basic', :basic
324
+
325
+ @agent.request_auth @req, @uri
326
+
327
+ assert_match %r%^Basic %, @req['Authorization']
328
+ end
329
+
330
+ def test_request_auth_digest
331
+ @agent.user = 'user'
332
+ @agent.password = 'password'
333
+
334
+ realm = auth_realm @uri, 'Digest', :digest
335
+ @agent.digest_challenges[realm] = 'Digest realm=r, qop="auth"'
336
+
337
+ @agent.request_auth @req, @uri
338
+
339
+ assert_match %r%^Digest %, @req['Authorization']
340
+ assert_match %r%qop=auth%, @req['Authorization']
341
+ end
342
+
343
+ def test_request_auth_iis_digest
344
+ @agent.user = 'user'
345
+ @agent.password = 'password'
346
+
347
+ realm = auth_realm @uri, 'Digest', :digest
348
+ @agent.digest_challenges[realm] = 'Digest realm=r, qop="auth"'
349
+
350
+ @agent.request_auth @req, @uri
351
+
352
+ assert_match %r%^Digest %, @req['Authorization']
353
+ assert_match %r%qop=auth%, @req['Authorization']
354
+ end
355
+
254
356
  def test_request_referer
255
357
  referer = URI.parse 'http://old.example'
256
358
 
@@ -285,6 +387,15 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
285
387
  assert_nil @req['referer']
286
388
  end
287
389
 
390
+ def test_request_referer_https_upgrade
391
+ uri = URI.parse 'https://example'
392
+ referer = URI.parse 'http://old.example'
393
+
394
+ @agent.request_referer @req, uri, referer
395
+
396
+ assert_equal 'http://old.example', @req['referer']
397
+ end
398
+
288
399
  def test_request_referer_none
289
400
  @agent.request_referer @req, @uri, nil
290
401
 
@@ -347,13 +458,95 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
347
458
  assert_nil params
348
459
  end
349
460
 
461
+ def test_response_authenticate
462
+ @res.instance_variable_set :@header, 'www-authenticate' => ['Basic realm=r']
463
+ @agent.user = 'user'
464
+ @agent.password = 'password'
465
+
466
+ @agent.response_authenticate @res, nil, @uri, @req, {}, nil, nil
467
+
468
+ base_uri = @uri + '/'
469
+ realm = Mechanize::HTTP::AuthRealm.new 'Basic', base_uri, 'r'
470
+ assert_equal [realm], @agent.authenticate_methods[base_uri][:basic]
471
+ end
472
+
473
+ def test_response_authenticate_digest
474
+ @res.instance_variable_set(:@header,
475
+ 'www-authenticate' => ['Digest realm=r'])
476
+ @agent.user = 'user'
477
+ @agent.password = 'password'
478
+
479
+ @agent.response_authenticate @res, nil, @uri, @req, {}, nil, nil
480
+
481
+ base_uri = @uri + '/'
482
+ realm = Mechanize::HTTP::AuthRealm.new 'Digest', base_uri, 'r'
483
+ assert_equal [realm], @agent.authenticate_methods[base_uri][:digest]
484
+
485
+ challenge = Mechanize::HTTP::AuthChallenge.new 'Digest', 'realm' => 'r'
486
+ assert_equal challenge, @agent.digest_challenges[realm]
487
+ end
488
+
489
+ def test_response_authenticate_digest_iis
490
+ @res.instance_variable_set(:@header,
491
+ 'www-authenticate' => ['Digest realm=r'],
492
+ 'server' => ['Microsoft-IIS'])
493
+ @agent.user = 'user'
494
+ @agent.password = 'password'
495
+
496
+ @agent.response_authenticate @res, nil, @uri, @req, {}, nil, nil
497
+
498
+ base_uri = @uri + '/'
499
+ realm = Mechanize::HTTP::AuthRealm.new 'Digest', base_uri, 'r'
500
+ assert_equal [realm], @agent.authenticate_methods[base_uri][:iis_digest]
501
+ end
502
+
503
+ def test_response_authenticate_multiple
504
+ @res.instance_variable_set(:@header,
505
+ 'www-authenticate' =>
506
+ ['Basic realm=r, Digest realm=r'])
507
+ @agent.user = 'user'
508
+ @agent.password = 'password'
509
+
510
+ @agent.response_authenticate @res, nil, @uri, @req, {}, nil, nil
511
+
512
+ base_uri = @uri + '/'
513
+ realm = Mechanize::HTTP::AuthRealm.new 'Digest', base_uri, 'r'
514
+ assert_equal [realm], @agent.authenticate_methods[base_uri][:digest]
515
+
516
+ assert_empty @agent.authenticate_methods[base_uri][:basic]
517
+ end
518
+
519
+ def test_response_authenticate_ntlm
520
+ @uri += '/ntlm'
521
+ @res.instance_variable_set(:@header,
522
+ 'www-authenticate' => ['NTLM'])
523
+ @agent.user = 'user'
524
+ @agent.password = 'password'
525
+
526
+ page = @agent.response_authenticate @res, nil, @uri, @req, {}, nil, nil
527
+
528
+ assert_equal 'ok', page.body # lame test
529
+ end
530
+
531
+ def test_response_authenticate_unknown
532
+ @agent.user = 'user'
533
+ @agent.password = 'password'
534
+ page = Mechanize::File.new nil, nil, nil, 401
535
+ @res.instance_variable_set(:@header,
536
+ 'www-authenticate' => ['Unknown realm=r'])
537
+
538
+ assert_raises Mechanize::UnauthorizedError do
539
+ @agent.response_authenticate @res, page, @uri, @req, nil, nil, nil
540
+ end
541
+ end
542
+
350
543
  def test_response_content_encoding_7_bit
351
544
  def @res.content_length() 4 end
352
545
  @res.instance_variable_set :@header, 'content-encoding' => %w[7bit]
353
546
 
354
547
  body = @agent.response_content_encoding @res, StringIO.new('part')
355
548
 
356
- assert_equal 'part', body
549
+ assert_equal 'part', body.read
357
550
  end
358
551
 
359
552
  def test_response_content_encoding_deflate
@@ -363,7 +556,7 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
363
556
 
364
557
  body = @agent.response_content_encoding @res, body_io
365
558
 
366
- assert_equal 'part', body
559
+ assert_equal 'part', body.read
367
560
  end
368
561
 
369
562
  def test_response_content_encoding_deflate_chunked
@@ -373,7 +566,7 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
373
566
 
374
567
  body = @agent.response_content_encoding @res, body_io
375
568
 
376
- assert_equal 'part', body
569
+ assert_equal 'part', body.read
377
570
  end
378
571
 
379
572
  # IIS/6.0 ASP.NET/2.0.50727 does not wrap deflate with zlib, WTF?
@@ -383,7 +576,7 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
383
576
 
384
577
  body = @agent.response_content_encoding @res, StringIO.new("+H,*\001\000")
385
578
 
386
- assert_equal 'part', body
579
+ assert_equal 'part', body.read
387
580
  end
388
581
 
389
582
  def test_response_content_encoding_gzip
@@ -394,7 +587,7 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
394
587
 
395
588
  body = @agent.response_content_encoding @res, body_io
396
589
 
397
- assert_equal 'part', body
590
+ assert_equal 'part', body.read
398
591
  end
399
592
 
400
593
  def test_response_content_encoding_gzip_chunked
@@ -405,7 +598,7 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
405
598
 
406
599
  body = @agent.response_content_encoding @res, body_io
407
600
 
408
- assert_equal 'part', body
601
+ assert_equal 'part', body.read
409
602
  end
410
603
 
411
604
  def test_response_content_encoding_none
@@ -414,7 +607,7 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
414
607
 
415
608
  body = @agent.response_content_encoding @res, StringIO.new('part')
416
609
 
417
- assert_equal 'part', body
610
+ assert_equal 'part', body.read
418
611
  end
419
612
 
420
613
  def test_response_content_encoding_x_gzip
@@ -425,7 +618,7 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
425
618
 
426
619
  body = @agent.response_content_encoding @res, body_io
427
620
 
428
- assert_equal 'part', body
621
+ assert_equal 'part', body.read
429
622
  end
430
623
 
431
624
  def test_response_content_encoding_unknown
@@ -440,6 +633,99 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
440
633
  assert_equal 'Unsupported Content-Encoding: unknown', e.message
441
634
  end
442
635
 
636
+ def test_get_meta_refresh_header_follow_self
637
+ @agent.follow_meta_refresh = true
638
+ @agent.follow_meta_refresh_self = true
639
+
640
+ page = Mechanize::Page.new(@uri, {'content-type' => 'text/html'}, '',
641
+ 200, @mech)
642
+ @res.instance_variable_set :@header, 'refresh' => ['0']
643
+
644
+ refresh = @agent.get_meta_refresh @res, @uri, page
645
+
646
+ assert_equal [0.0, URI('http://example/')], refresh
647
+ end
648
+
649
+ def test_get_meta_refresh_header_no_follow
650
+ page = Mechanize::Page.new(@uri, {'content-type' => 'text/html'}, '',
651
+ 200, @mech)
652
+ @res.instance_variable_set :@header, 'refresh' => ['0']
653
+
654
+ refresh = @agent.get_meta_refresh @res, @uri, page
655
+
656
+ assert_nil refresh
657
+ end
658
+
659
+ def test_get_meta_refresh_header_no_follow_self
660
+ @agent.follow_meta_refresh = true
661
+
662
+ page = Mechanize::Page.new(@uri, {'content-type' => 'text/html'}, '',
663
+ 200, @mech)
664
+ @res.instance_variable_set :@header, 'refresh' => ['0']
665
+
666
+ refresh = @agent.get_meta_refresh @res, @uri, page
667
+
668
+ assert_nil refresh
669
+ end
670
+
671
+ def test_get_meta_refresh_meta_follow_self
672
+ @agent.follow_meta_refresh = true
673
+ @agent.follow_meta_refresh_self = true
674
+
675
+ body = <<-BODY
676
+ <title></title>
677
+ <meta http-equiv="refresh" content="0">
678
+ BODY
679
+
680
+ page = Mechanize::Page.new(@uri, {'content-type' => 'text/html'}, body,
681
+ 200, @mech)
682
+
683
+ refresh = @agent.get_meta_refresh @res, @uri, page
684
+
685
+ assert_equal [0, 'http://example/'], refresh
686
+ end
687
+
688
+ def test_get_meta_refresh_meta_no_follow
689
+ body = <<-BODY
690
+ <title></title>
691
+ <meta http-equiv="refresh" content="0">
692
+ BODY
693
+
694
+ page = Mechanize::Page.new(@uri, {'content-type' => 'text/html'}, body,
695
+ 200, @mech)
696
+
697
+ refresh = @agent.get_meta_refresh @res, @uri, page
698
+
699
+ assert_nil refresh
700
+ end
701
+
702
+ def test_get_meta_refresh_meta_no_follow_self
703
+ @agent.follow_meta_refresh = true
704
+
705
+ body = <<-BODY
706
+ <title></title>
707
+ <meta http-equiv="refresh" content="0">
708
+ BODY
709
+
710
+ page = Mechanize::Page.new(@uri, {'content-type' => 'text/html'}, body,
711
+ 200, @mech)
712
+
713
+ refresh = @agent.get_meta_refresh @res, @uri, page
714
+
715
+ assert_nil refresh
716
+ end
717
+
718
+ def test_hook_content_encoding_response
719
+ @mech.content_encoding_hooks << lambda{|agent, uri, response, response_body_io|
720
+ response['content-encoding'] = 'gzip' if response['content-encoding'] == 'agzip'}
721
+
722
+ @res.instance_variable_set :@header, 'content-encoding' => %w[agzip]
723
+ body_io = StringIO.new 'part'
724
+ @agent.hook_content_encoding @res, @uri, body_io
725
+
726
+ assert_equal 'gzip', @res['content-encoding']
727
+ end
728
+
443
729
  def test_response_cookies
444
730
  uri = URI.parse 'http://host.example.com'
445
731
  cookie_str = 'a=b domain=.example.com'
@@ -454,6 +740,21 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
454
740
  @agent.cookie_jar.cookies(uri).map { |c| c.to_s }
455
741
  end
456
742
 
743
+ def test_response_cookies_many
744
+ uri = URI.parse 'http://host.example.com'
745
+ cookie1 = 'a=b domain=.example.com'
746
+ cookie2 = 'c=d domain=.example.com'
747
+ @res.instance_variable_set(:@header,
748
+ 'set-cookie' => [cookie1, cookie2],
749
+ 'content-type' => %w[text/html])
750
+ page = Mechanize::Page.new uri, @res, '', 200, @mech
751
+
752
+ @agent.response_cookies @res, uri, page
753
+
754
+ assert_equal ['a=b domain=.example.com', 'c=d domain=.example.com'],
755
+ @agent.cookie_jar.cookies(uri).map { |c| c.to_s }
756
+ end
757
+
457
758
  def test_response_cookies_meta
458
759
  uri = URI.parse 'http://host.example.com'
459
760
  cookie_str = 'a=b domain=.example.com'
@@ -486,12 +787,33 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
486
787
  200, @mech)
487
788
 
488
789
  @agent.follow_meta_refresh = true
790
+ @agent.follow_meta_refresh_self = true
489
791
 
490
792
  page = @agent.response_follow_meta_refresh @res, uri, page, 0
491
793
 
492
794
  assert_equal uri, page.uri
493
795
  end
494
796
 
797
+ def test_response_follow_meta_refresh_limit
798
+ uri = URI.parse 'http://example/#id+1'
799
+
800
+ body = <<-BODY
801
+ <title></title>
802
+ <meta http-equiv="refresh" content="0">
803
+ BODY
804
+
805
+ page = Mechanize::Page.new(uri, {'content-type' => 'text/html'}, body,
806
+ 200, @mech)
807
+
808
+ @agent.follow_meta_refresh = true
809
+ @agent.follow_meta_refresh_self = true
810
+
811
+ assert_raises Mechanize::RedirectLimitReachedError do
812
+ @agent.response_follow_meta_refresh(@res, uri, page,
813
+ @agent.redirection_limit)
814
+ end
815
+ end
816
+
495
817
  def test_response_read
496
818
  def @res.read_body() yield 'part' end
497
819
  def @res.content_length() 4 end
@@ -504,6 +826,28 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
504
826
  assert_equal Encoding::BINARY, body.encoding if body.respond_to? :encoding
505
827
  end
506
828
 
829
+ def test_response_read_large
830
+ def @res.read_body() yield 'a' * 10241 end
831
+ def @res.content_length() 10241 end
832
+
833
+ io = @agent.response_read @res, @req
834
+
835
+ assert_kind_of Tempfile, io
836
+ assert_equal 10241, io.stat.size
837
+ end
838
+
839
+ def test_response_read_large_chunked
840
+ def @res.read_body
841
+ 11.times do yield 'a' * 1024 end
842
+ end
843
+ def @res.content_length() end
844
+
845
+ io = @agent.response_read @res, @req
846
+
847
+ assert_kind_of Tempfile, io
848
+ assert_equal 11264, io.stat.size
849
+ end
850
+
507
851
  def test_response_read_content_length_head
508
852
  req = Net::HTTP::Head.new '/'
509
853
 
@@ -589,6 +933,7 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
589
933
  def test_response_read_unknown_code
590
934
  res = Net::HTTPUnknownResponse.allocate
591
935
  res.instance_variable_set :@code, 9999
936
+ res.instance_variable_set :@header, {}
592
937
  def res.read_body() yield 'part' end
593
938
 
594
939
  e = assert_raises Mechanize::ResponseCodeError do
@@ -598,6 +943,63 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
598
943
  assert_equal res, e.page
599
944
  end
600
945
 
946
+ def test_response_redirect
947
+ @agent.redirect_ok = true
948
+ referer = page 'http://example/referer'
949
+
950
+ page = fake_page
951
+ page = @agent.response_redirect({ 'Location' => '/index.html' }, :get,
952
+ page, 0, referer)
953
+
954
+ assert_equal URI('http://fake.example/index.html'), page.uri
955
+
956
+ assert_equal 'http://example/referer', requests.first['Referer']
957
+ end
958
+
959
+ def test_response_redirect_limit
960
+ @agent.redirect_ok = true
961
+ referer = page 'http://example/referer'
962
+
963
+ assert_raises Mechanize::RedirectLimitReachedError do
964
+ @agent.response_redirect({ 'Location' => '/index.html' }, :get,
965
+ fake_page, @agent.redirection_limit, referer)
966
+ end
967
+ end
968
+
969
+ def test_response_redirect_not_ok
970
+ @agent.redirect_ok = false
971
+
972
+ page = fake_page
973
+ page = @agent.response_redirect({ 'Location' => '/other' }, :get, page, 0,
974
+ page)
975
+
976
+ assert_equal URI('http://fake.example'), page.uri
977
+ end
978
+
979
+ def test_response_redirect_permanent
980
+ @agent.redirect_ok = :permanent
981
+
982
+ response = Net::HTTPMovedPermanently.allocate
983
+ response.instance_variable_set :@header, { 'location' => %w[/index.html] }
984
+
985
+ page = fake_page
986
+ page = @agent.response_redirect response, :get, page, 0, page
987
+
988
+ assert_equal URI('http://fake.example/index.html'), page.uri
989
+ end
990
+
991
+ def test_response_redirect_permanent_temporary
992
+ @agent.redirect_ok = :permanent
993
+
994
+ response = Net::HTTPMovedTemporarily.allocate
995
+ response.instance_variable_set :@header, { 'location' => %w[/index.html] }
996
+
997
+ page = fake_page
998
+ page = @agent.response_redirect response, :get, page, 0, page
999
+
1000
+ assert_equal URI('http://fake.example/'), page.uri
1001
+ end
1002
+
601
1003
  def test_response_parse
602
1004
  body = '<title>hi</title>'
603
1005
  @res.instance_variable_set :@header, 'content-type' => %w[text/html]
@@ -684,13 +1086,119 @@ class TestMechanizeHttpAgent < MiniTest::Unit::TestCase
684
1086
  assert_equal 'UTF-8', page.encoding
685
1087
  end
686
1088
 
1089
+ def test_robots_allowed_eh
1090
+ allowed = URI 'http://localhost/index.html'
1091
+ disallowed = URI 'http://localhost/norobots.html'
1092
+
1093
+ assert @agent.robots_allowed? allowed
1094
+ refute @agent.robots_allowed? disallowed
1095
+
1096
+ refute @agent.robots_disallowed? allowed
1097
+ assert @agent.robots_disallowed? disallowed
1098
+ end
1099
+
1100
+ def test_robots_allowed_eh_noindex
1101
+ @agent.robots = true
1102
+
1103
+ noindex = URI 'http://localhost/noindex.html'
1104
+
1105
+ assert @agent.robots_allowed? noindex
1106
+
1107
+ assert_raises Mechanize::RobotsDisallowedError do
1108
+ @agent.fetch noindex
1109
+ end
1110
+ end
1111
+
1112
+ def test_set_http
1113
+ @agent.set_http
1114
+
1115
+ assert_equal 'mechanize', @agent.http.name
1116
+ refute @agent.http.retry_change_requests
1117
+ end
1118
+
1119
+ def test_set_http_idle_timeout
1120
+ @agent.idle_timeout = 1
1121
+ @agent.set_http
1122
+
1123
+ assert_equal 'mechanize', @agent.http.name
1124
+ assert_equal 1, @agent.http.idle_timeout
1125
+ end
1126
+
1127
+ def test_set_http_ssl
1128
+ in_tmpdir do
1129
+ store = OpenSSL::X509::Store.new
1130
+ @agent.cert = ssl_certificate
1131
+ @agent.key = ssl_private_key
1132
+ @agent.cert_store = store
1133
+ @agent.ca_file = '.'
1134
+ @agent.verify_callback = proc { |ok, context| }
1135
+
1136
+ @agent.set_http
1137
+
1138
+ http = @agent.http
1139
+
1140
+ assert_equal ssl_certificate, http.certificate
1141
+ assert_equal ssl_private_key, http.private_key
1142
+ assert_equal store, http.cert_store
1143
+ assert_equal '.', http.ca_file
1144
+ assert_equal OpenSSL::SSL::VERIFY_PEER, http.verify_mode
1145
+ assert http.verify_callback
1146
+ end
1147
+ end
1148
+
1149
+ def test_set_http_ssl_verify_none
1150
+ in_tmpdir do
1151
+ @agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
1152
+
1153
+ @agent.set_http
1154
+
1155
+ http = @agent.http
1156
+
1157
+ assert_equal OpenSSL::SSL::VERIFY_NONE, http.verify_mode
1158
+ end
1159
+ end
1160
+
1161
+ def test_set_http_retry_change_request
1162
+ @agent.retry_change_requests = true
1163
+ @agent.set_http
1164
+
1165
+ assert_equal 'mechanize', @agent.http.name
1166
+ assert @agent.http.retry_change_requests
1167
+ end
1168
+
687
1169
  def test_set_proxy
688
- @agent.set_proxy('www.example.com', 9001, 'joe', 'lol')
1170
+ @agent.set_proxy 'www.example.com', 9001, 'joe', 'lol'
1171
+
1172
+ assert_equal @agent.proxy_uri.host, 'www.example.com'
1173
+ assert_equal @agent.proxy_uri.port, 9001
1174
+ assert_equal @agent.proxy_uri.user, 'joe'
1175
+ assert_equal @agent.proxy_uri.password, 'lol'
1176
+ end
1177
+
1178
+ def test_set_proxy_port_string
1179
+ @agent.set_proxy 'www.example.com', '9001', 'joe', 'lol'
1180
+
1181
+ assert_equal @agent.proxy_uri.host, 'www.example.com'
1182
+ assert_equal @agent.proxy_uri.port, 9001
1183
+ assert_equal @agent.proxy_uri.user, 'joe'
1184
+ assert_equal @agent.proxy_uri.password, 'lol'
1185
+ end
1186
+
1187
+ def test_set_proxy_service_name
1188
+ @agent.set_proxy 'www.example.com', 'http', 'joe', 'lol'
1189
+
1190
+ assert_equal @agent.proxy_uri.host, 'www.example.com'
1191
+ assert_equal @agent.proxy_uri.port, 80
1192
+ assert_equal @agent.proxy_uri.user, 'joe'
1193
+ assert_equal @agent.proxy_uri.password, 'lol'
1194
+ end
1195
+
1196
+ def test_set_proxy_service_name_bad
1197
+ e = assert_raises ArgumentError do
1198
+ @agent.set_proxy 'www.example.com', 'nonexistent service', 'joe', 'lol'
1199
+ end
689
1200
 
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')
1201
+ assert_equal 'invalid value for port: "nonexistent service"', e.message
694
1202
  end
695
1203
 
696
1204
  end