diamond-mechanize 2.2 → 2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. data/Rakefile +49 -0
  2. data/lib/mechanize.rb +1079 -0
  3. data/lib/mechanize/content_type_error.rb +13 -0
  4. data/lib/mechanize/cookie.rb +232 -0
  5. data/lib/mechanize/cookie_jar.rb +194 -0
  6. data/lib/mechanize/download.rb +59 -0
  7. data/lib/mechanize/element_matcher.rb +36 -0
  8. data/lib/mechanize/file.rb +65 -0
  9. data/lib/mechanize/file_connection.rb +17 -0
  10. data/lib/mechanize/file_request.rb +26 -0
  11. data/lib/mechanize/file_response.rb +74 -0
  12. data/lib/mechanize/file_saver.rb +39 -0
  13. data/lib/mechanize/form.rb +543 -0
  14. data/lib/mechanize/form/button.rb +6 -0
  15. data/lib/mechanize/form/check_box.rb +12 -0
  16. data/lib/mechanize/form/field.rb +54 -0
  17. data/lib/mechanize/form/file_upload.rb +21 -0
  18. data/lib/mechanize/form/hidden.rb +3 -0
  19. data/lib/mechanize/form/image_button.rb +19 -0
  20. data/lib/mechanize/form/keygen.rb +34 -0
  21. data/lib/mechanize/form/multi_select_list.rb +94 -0
  22. data/lib/mechanize/form/option.rb +50 -0
  23. data/lib/mechanize/form/radio_button.rb +55 -0
  24. data/lib/mechanize/form/reset.rb +3 -0
  25. data/lib/mechanize/form/select_list.rb +44 -0
  26. data/lib/mechanize/form/submit.rb +3 -0
  27. data/lib/mechanize/form/text.rb +3 -0
  28. data/lib/mechanize/form/textarea.rb +3 -0
  29. data/lib/mechanize/headers.rb +23 -0
  30. data/lib/mechanize/history.rb +82 -0
  31. data/lib/mechanize/http.rb +8 -0
  32. data/lib/mechanize/http/agent.rb +1004 -0
  33. data/lib/mechanize/http/auth_challenge.rb +59 -0
  34. data/lib/mechanize/http/auth_realm.rb +31 -0
  35. data/lib/mechanize/http/content_disposition_parser.rb +188 -0
  36. data/lib/mechanize/http/www_authenticate_parser.rb +155 -0
  37. data/lib/mechanize/monkey_patch.rb +16 -0
  38. data/lib/mechanize/page.rb +440 -0
  39. data/lib/mechanize/page/base.rb +7 -0
  40. data/lib/mechanize/page/frame.rb +27 -0
  41. data/lib/mechanize/page/image.rb +30 -0
  42. data/lib/mechanize/page/label.rb +20 -0
  43. data/lib/mechanize/page/link.rb +98 -0
  44. data/lib/mechanize/page/meta_refresh.rb +68 -0
  45. data/lib/mechanize/parser.rb +173 -0
  46. data/lib/mechanize/pluggable_parsers.rb +144 -0
  47. data/lib/mechanize/redirect_limit_reached_error.rb +19 -0
  48. data/lib/mechanize/redirect_not_get_or_head_error.rb +21 -0
  49. data/lib/mechanize/response_code_error.rb +21 -0
  50. data/lib/mechanize/response_read_error.rb +27 -0
  51. data/lib/mechanize/robots_disallowed_error.rb +28 -0
  52. data/lib/mechanize/test_case.rb +663 -0
  53. data/lib/mechanize/unauthorized_error.rb +3 -0
  54. data/lib/mechanize/unsupported_scheme_error.rb +6 -0
  55. data/lib/mechanize/util.rb +101 -0
  56. data/test/data/htpasswd +1 -0
  57. data/test/data/server.crt +16 -0
  58. data/test/data/server.csr +12 -0
  59. data/test/data/server.key +15 -0
  60. data/test/data/server.pem +15 -0
  61. data/test/htdocs/alt_text.html +10 -0
  62. data/test/htdocs/bad_form_test.html +9 -0
  63. data/test/htdocs/button.jpg +0 -0
  64. data/test/htdocs/canonical_uri.html +9 -0
  65. data/test/htdocs/dir with spaces/foo.html +1 -0
  66. data/test/htdocs/empty_form.html +6 -0
  67. data/test/htdocs/file_upload.html +26 -0
  68. data/test/htdocs/find_link.html +41 -0
  69. data/test/htdocs/form_multi_select.html +16 -0
  70. data/test/htdocs/form_multival.html +37 -0
  71. data/test/htdocs/form_no_action.html +18 -0
  72. data/test/htdocs/form_no_input_name.html +16 -0
  73. data/test/htdocs/form_order_test.html +11 -0
  74. data/test/htdocs/form_select.html +16 -0
  75. data/test/htdocs/form_set_fields.html +14 -0
  76. data/test/htdocs/form_test.html +188 -0
  77. data/test/htdocs/frame_referer_test.html +10 -0
  78. data/test/htdocs/frame_test.html +30 -0
  79. data/test/htdocs/google.html +13 -0
  80. data/test/htdocs/index.html +6 -0
  81. data/test/htdocs/link with space.html +5 -0
  82. data/test/htdocs/meta_cookie.html +11 -0
  83. data/test/htdocs/no_title_test.html +6 -0
  84. data/test/htdocs/noindex.html +9 -0
  85. data/test/htdocs/rails_3_encoding_hack_form_test.html +27 -0
  86. data/test/htdocs/relative/tc_relative_links.html +21 -0
  87. data/test/htdocs/robots.html +8 -0
  88. data/test/htdocs/robots.txt +2 -0
  89. data/test/htdocs/tc_bad_charset.html +9 -0
  90. data/test/htdocs/tc_bad_links.html +5 -0
  91. data/test/htdocs/tc_base_link.html +8 -0
  92. data/test/htdocs/tc_blank_form.html +11 -0
  93. data/test/htdocs/tc_charset.html +6 -0
  94. data/test/htdocs/tc_checkboxes.html +19 -0
  95. data/test/htdocs/tc_encoded_links.html +5 -0
  96. data/test/htdocs/tc_field_precedence.html +11 -0
  97. data/test/htdocs/tc_follow_meta.html +8 -0
  98. data/test/htdocs/tc_form_action.html +48 -0
  99. data/test/htdocs/tc_links.html +19 -0
  100. data/test/htdocs/tc_meta_in_body.html +9 -0
  101. data/test/htdocs/tc_pretty_print.html +17 -0
  102. data/test/htdocs/tc_referer.html +16 -0
  103. data/test/htdocs/tc_relative_links.html +19 -0
  104. data/test/htdocs/tc_textarea.html +23 -0
  105. data/test/htdocs/test_click.html +11 -0
  106. data/test/htdocs/unusual______.html +5 -0
  107. data/test/test_mechanize.rb +1164 -0
  108. data/test/test_mechanize_cookie.rb +451 -0
  109. data/test/test_mechanize_cookie_jar.rb +483 -0
  110. data/test/test_mechanize_download.rb +43 -0
  111. data/test/test_mechanize_file.rb +61 -0
  112. data/test/test_mechanize_file_connection.rb +21 -0
  113. data/test/test_mechanize_file_request.rb +19 -0
  114. data/test/test_mechanize_file_saver.rb +21 -0
  115. data/test/test_mechanize_form.rb +875 -0
  116. data/test/test_mechanize_form_check_box.rb +38 -0
  117. data/test/test_mechanize_form_encoding.rb +114 -0
  118. data/test/test_mechanize_form_field.rb +63 -0
  119. data/test/test_mechanize_form_file_upload.rb +20 -0
  120. data/test/test_mechanize_form_image_button.rb +12 -0
  121. data/test/test_mechanize_form_keygen.rb +32 -0
  122. data/test/test_mechanize_form_multi_select_list.rb +84 -0
  123. data/test/test_mechanize_form_option.rb +55 -0
  124. data/test/test_mechanize_form_radio_button.rb +78 -0
  125. data/test/test_mechanize_form_select_list.rb +76 -0
  126. data/test/test_mechanize_form_textarea.rb +52 -0
  127. data/test/test_mechanize_headers.rb +35 -0
  128. data/test/test_mechanize_history.rb +103 -0
  129. data/test/test_mechanize_http_agent.rb +1225 -0
  130. data/test/test_mechanize_http_auth_challenge.rb +39 -0
  131. data/test/test_mechanize_http_auth_realm.rb +49 -0
  132. data/test/test_mechanize_http_content_disposition_parser.rb +118 -0
  133. data/test/test_mechanize_http_www_authenticate_parser.rb +146 -0
  134. data/test/test_mechanize_link.rb +80 -0
  135. data/test/test_mechanize_page.rb +118 -0
  136. data/test/test_mechanize_page_encoding.rb +182 -0
  137. data/test/test_mechanize_page_frame.rb +16 -0
  138. data/test/test_mechanize_page_link.rb +390 -0
  139. data/test/test_mechanize_page_meta_refresh.rb +127 -0
  140. data/test/test_mechanize_parser.rb +289 -0
  141. data/test/test_mechanize_pluggable_parser.rb +52 -0
  142. data/test/test_mechanize_redirect_limit_reached_error.rb +24 -0
  143. data/test/test_mechanize_redirect_not_get_or_head_error.rb +14 -0
  144. data/test/test_mechanize_subclass.rb +22 -0
  145. data/test/test_mechanize_util.rb +103 -0
  146. data/test/test_multi_select.rb +119 -0
  147. metadata +148 -71
@@ -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
+
@@ -0,0 +1,52 @@
1
+ require 'mechanize/test_case'
2
+
3
+ class TestMechanizeFormTextarea < Mechanize::TestCase
4
+ def setup
5
+ super
6
+
7
+ @page = @mech.get("http://localhost/tc_textarea.html")
8
+ end
9
+
10
+ def test_empty_text_area
11
+ form = @page.forms_with(:name => 'form1').first
12
+ assert_equal('', form.field_with(:name => 'text1').value)
13
+ form.text1 = 'Hello World'
14
+ assert_equal('Hello World', form.field_with(:name => 'text1').value)
15
+ page = @mech.submit(form)
16
+ assert_equal(1, page.links.length)
17
+ assert_equal('text1:Hello World', page.links[0].text)
18
+ end
19
+
20
+ def test_non_empty_textfield
21
+ form = @page.forms_with(:name => 'form2').first
22
+ assert_equal('sample text', form.field_with(:name => 'text1').value)
23
+ page = @mech.submit(form)
24
+ assert_equal(1, page.links.length)
25
+ assert_equal('text1:sample text', page.links[0].text)
26
+ end
27
+
28
+ def test_multi_textfield
29
+ form = @page.form_with(:name => 'form3')
30
+
31
+ assert_equal(2, form.fields_with(:name => 'text1').length)
32
+ assert_equal('', form.fields_with(:name => 'text1')[0].value)
33
+ assert_equal('sample text', form.fields_with(:name => 'text1')[1].value)
34
+
35
+ form.text1 = 'Hello World'
36
+
37
+ assert_equal('Hello World', form.fields_with(:name => 'text1')[0].value)
38
+ assert_equal('sample text', form.fields_with(:name => 'text1')[1].value)
39
+
40
+ page = @mech.submit(form)
41
+
42
+ assert_equal(2, page.links.length)
43
+
44
+ link = page.links_with(:text => 'text1:sample text')
45
+
46
+ assert_equal(1, link.length)
47
+
48
+ link = page.links_with(:text => 'text1:Hello World')
49
+
50
+ assert_equal(1, link.length)
51
+ end
52
+ end
@@ -0,0 +1,35 @@
1
+ require 'mechanize/test_case'
2
+
3
+ class TestMechanizeHeaders < Mechanize::TestCase
4
+ def setup
5
+ super
6
+
7
+ @headers = Mechanize::Headers.new
8
+ @headers['content-type'] = 'text/html'
9
+ @headers['Content-encoding'] = 'gzip'
10
+ @headers['SERVER'] = 'Apache/2.2'
11
+ end
12
+
13
+ def test_aref
14
+ assert_equal('Apache/2.2', @headers['server'])
15
+ assert_equal('text/html', @headers['Content-Type'])
16
+ end
17
+
18
+ def test_key?
19
+ assert_equal(true, @headers.key?('content-Encoding'))
20
+ end
21
+
22
+ def test_canonical_each
23
+ all_keys = ['Content-Type', 'Content-Encoding', 'Server']
24
+ keys = all_keys.dup
25
+ @headers.canonical_each { |key, value|
26
+ case keys.delete(key)
27
+ when *all_keys
28
+ # ok
29
+ else
30
+ flunk "unexpected key: #{key}"
31
+ end
32
+ }
33
+ assert_equal([], keys)
34
+ end
35
+ end
@@ -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
+
@@ -0,0 +1,1225 @@
1
+ # coding: utf-8
2
+
3
+ require 'mechanize/test_case'
4
+
5
+ class TestMechanizeHttpAgent < Mechanize::TestCase
6
+
7
+ def setup
8
+ super
9
+
10
+ @agent = @mech.agent
11
+
12
+ @uri = URI.parse 'http://example/'
13
+
14
+ @req = Net::HTTP::Get.new '/'
15
+ @res = Net::HTTPOK.allocate
16
+ @res.instance_variable_set :@code, 200
17
+ @res.instance_variable_set :@header, {}
18
+
19
+ @headers = if RUBY_VERSION > '1.9' then
20
+ %w[accept user-agent]
21
+ else
22
+ %w[accept]
23
+ end
24
+ end
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
+
34
+ def test_connection_for_file
35
+ uri = URI.parse 'file:///nonexistent'
36
+ conn = @agent.connection_for uri
37
+
38
+ assert_equal Mechanize::FileConnection.new, conn
39
+ end
40
+
41
+ def test_connection_for_http
42
+ conn = @agent.connection_for @uri
43
+
44
+ assert_equal @agent.http, conn
45
+ end
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
+
61
+ def test_enable_gzip
62
+ @agent.enable_gzip @req
63
+
64
+ assert_equal 'gzip,deflate,identity', @req['accept-encoding']
65
+ end
66
+
67
+ def test_enable_gzip_no
68
+ @agent.gzip_enabled = false
69
+
70
+ @agent.enable_gzip @req
71
+
72
+ assert_equal 'identity', @req['accept-encoding']
73
+ end
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
+
91
+ def test_fetch_file_plus
92
+ Tempfile.open '++plus++' do |io|
93
+ content = 'plusses +++'
94
+ io.write content
95
+ io.rewind
96
+
97
+ uri = URI.parse "file://#{Mechanize::Util.uri_escape io.path}"
98
+
99
+ page = @agent.fetch uri
100
+
101
+ assert_equal content, page.body
102
+ assert_kind_of Mechanize::File, page
103
+ end
104
+ end
105
+
106
+ def test_fetch_file_space
107
+ foo = File.expand_path("../htdocs/dir with spaces/foo.html", __FILE__)
108
+
109
+ uri = URI.parse "file://#{Mechanize::Util.uri_escape foo}"
110
+
111
+ page = @agent.fetch uri
112
+
113
+ assert_equal File.read(foo), page.body
114
+ assert_kind_of Mechanize::Page, page
115
+ end
116
+
117
+ def test_fetch_file_nonexistent
118
+ uri = URI.parse 'file:///nonexistent'
119
+
120
+ e = assert_raises Mechanize::ResponseCodeError do
121
+ @agent.fetch uri
122
+ end
123
+
124
+ assert_equal '404 => Net::HTTPNotFound', e.message
125
+ end
126
+
127
+ def test_fetch_post_connect_hook
128
+ response = nil
129
+ @agent.post_connect_hooks << lambda { |_, _, res, _| response = res }
130
+
131
+ @agent.fetch 'http://localhost/'
132
+
133
+ assert response
134
+ end
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
+
144
+ def test_get_robots
145
+ robotstxt = @agent.get_robots 'http://localhost/robots.txt'
146
+ refute_equal '', robotstxt
147
+
148
+ robotstxt = @agent.get_robots 'http://localhost/response_code?code=404'
149
+ assert_equal '', robotstxt
150
+ end
151
+
152
+ def test_http_request_file
153
+ uri = URI.parse 'file:///nonexistent'
154
+ request = @agent.http_request uri, :get
155
+
156
+ assert_kind_of Mechanize::FileRequest, request
157
+ assert_equal '/nonexistent', request.path
158
+ end
159
+
160
+ def test_http_request_get
161
+ request = @agent.http_request @uri, :get
162
+
163
+ assert_kind_of Net::HTTP::Get, request
164
+ assert_equal '/', request.path
165
+ end
166
+
167
+ def test_http_request_post
168
+ request = @agent.http_request @uri, :post
169
+
170
+ assert_kind_of Net::HTTP::Post, request
171
+ assert_equal '/', request.path
172
+ end
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
+
181
+ def test_post_connect
182
+ @agent.post_connect_hooks << proc { |agent, uri, response, body|
183
+ assert_equal @agent, agent
184
+ assert_equal @res, response
185
+ assert_equal 'body', body
186
+ throw :called
187
+ }
188
+
189
+ io = StringIO.new 'body'
190
+
191
+ assert_throws :called do
192
+ @agent.post_connect @uri, @res, io
193
+ end
194
+
195
+ assert_equal 0, io.pos
196
+ end
197
+
198
+ def test_pre_connect
199
+ @agent.pre_connect_hooks << proc { |agent, request|
200
+ assert_equal @agent, agent
201
+ assert_equal @req, request
202
+ throw :called
203
+ }
204
+
205
+ assert_throws :called do
206
+ @agent.pre_connect @req
207
+ end
208
+ end
209
+
210
+ def test_request_cookies
211
+ uri = URI.parse 'http://host.example.com'
212
+ Mechanize::Cookie.parse uri, 'hello=world domain=.example.com' do |cookie|
213
+ @agent.cookie_jar.add uri, cookie
214
+ end
215
+
216
+ @agent.request_cookies @req, uri
217
+
218
+ assert_equal 'hello=world domain=.example.com', @req['Cookie']
219
+ end
220
+
221
+ def test_request_cookies_none
222
+ @agent.request_cookies @req, @uri
223
+
224
+ assert_nil @req['Cookie']
225
+ end
226
+
227
+ def test_request_cookies_many
228
+ uri = URI.parse 'http://host.example.com'
229
+ cookie_str = 'a=b domain=.example.com, c=d domain=.example.com'
230
+ Mechanize::Cookie.parse uri, cookie_str do |cookie|
231
+ @agent.cookie_jar.add uri, cookie
232
+ end
233
+
234
+ @agent.request_cookies @req, uri
235
+
236
+ expected = cookie_str.sub ', ', '; '
237
+
238
+ assert_equal expected, @req['Cookie']
239
+ end
240
+
241
+ def test_request_cookies_wrong_domain
242
+ uri = URI.parse 'http://host.example.com'
243
+ Mechanize::Cookie.parse uri, 'hello=world domain=.example.com' do |cookie|
244
+ @agent.cookie_jar.add uri, cookie
245
+ end
246
+
247
+ @agent.request_cookies @req, @uri
248
+
249
+ assert_nil @req['Cookie']
250
+ end
251
+
252
+ def test_request_host
253
+ @agent.request_host @req, @uri
254
+
255
+ assert_equal 'example', @req['host']
256
+ end
257
+
258
+ def test_request_host_nonstandard
259
+ @uri.port = 81
260
+
261
+ @agent.request_host @req, @uri
262
+
263
+ assert_equal 'example:81', @req['host']
264
+ end
265
+
266
+ def test_request_language_charset
267
+ @agent.request_language_charset @req
268
+
269
+ assert_equal 'en-us,en;q=0.5', @req['accept-language']
270
+ assert_equal 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', @req['accept-charset']
271
+ end
272
+
273
+ def test_request_add_headers
274
+ @agent.request_add_headers @req, 'Content-Length' => 300
275
+
276
+ assert_equal '300', @req['content-length']
277
+ end
278
+
279
+ def test_request_add_headers_etag
280
+ @agent.request_add_headers @req, :etag => '300'
281
+
282
+ assert_equal '300', @req['etag']
283
+ end
284
+
285
+ def test_request_add_headers_if_modified_since
286
+ @agent.request_add_headers @req, :if_modified_since => 'some_date'
287
+
288
+ assert_equal 'some_date', @req['if-modified-since']
289
+ end
290
+
291
+ def test_request_add_headers_none
292
+ @agent.request_add_headers @req
293
+
294
+ assert_equal @headers, @req.to_hash.keys.sort
295
+ end
296
+
297
+ def test_request_add_headers_request_headers
298
+ @agent.request_headers['X-Foo'] = 'bar'
299
+
300
+ @agent.request_add_headers @req
301
+
302
+ assert_equal @headers + %w[x-foo], @req.to_hash.keys.sort
303
+ end
304
+
305
+ def test_request_add_headers_symbol
306
+ e = assert_raises ArgumentError do
307
+ @agent.request_add_headers @req, :content_length => 300
308
+ end
309
+
310
+ assert_equal 'unknown header symbol content_length', e.message
311
+ end
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
+
356
+ def test_request_referer
357
+ referer = URI.parse 'http://old.example'
358
+
359
+ @agent.request_referer @req, @uri, referer
360
+
361
+ assert_equal 'http://old.example', @req['referer']
362
+ end
363
+
364
+ def test_request_referer_https
365
+ uri = URI.parse 'https://example'
366
+ referer = URI.parse 'https://old.example'
367
+
368
+ @agent.request_referer @req, uri, referer
369
+
370
+ assert_equal 'https://old.example', @req['referer']
371
+ end
372
+
373
+ def test_request_referer_https_downgrade
374
+ referer = URI.parse 'https://old.example'
375
+
376
+ @agent.request_referer @req, @uri, referer
377
+
378
+ assert_nil @req['referer']
379
+ end
380
+
381
+ def test_request_referer_https_downgrade_case
382
+ uri = URI.parse 'http://example'
383
+ referer = URI.parse 'httpS://old.example'
384
+
385
+ @agent.request_referer @req, uri, referer
386
+
387
+ assert_nil @req['referer']
388
+ end
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
+
399
+ def test_request_referer_none
400
+ @agent.request_referer @req, @uri, nil
401
+
402
+ assert_nil @req['referer']
403
+ end
404
+
405
+ def test_request_user_agent
406
+ @agent.request_user_agent @req
407
+
408
+ assert_match %r%^Mechanize/#{Mechanize::VERSION}%, @req['user-agent']
409
+
410
+ ruby_version = if RUBY_PATCHLEVEL >= 0 then
411
+ "#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
412
+ else
413
+ "#{RUBY_VERSION}dev#{RUBY_REVISION}"
414
+ end
415
+
416
+ assert_match %r%Ruby/#{ruby_version}%, @req['user-agent']
417
+ end
418
+
419
+ def test_resolve_bad_uri
420
+ e = assert_raises ArgumentError do
421
+ @agent.resolve 'google'
422
+ end
423
+
424
+ assert_equal 'absolute URL needed (not google)', e.message
425
+ end
426
+
427
+ def test_resolve_utf8
428
+ uri = 'http://example?q=ü'
429
+
430
+ resolved = @agent.resolve uri
431
+
432
+ assert_equal '/?q=%C3%BC', resolved.request_uri
433
+ end
434
+
435
+ def test_resolve_parameters_body
436
+ input_params = { :q => 'hello' }
437
+
438
+ uri, params = @agent.resolve_parameters @uri, :post, input_params
439
+
440
+ assert_equal 'http://example/', uri.to_s
441
+ assert_equal input_params, params
442
+ end
443
+
444
+ def test_resolve_parameters_query
445
+ uri, params = @agent.resolve_parameters @uri, :get, :q => 'hello'
446
+
447
+ assert_equal 'http://example/?q=hello', uri.to_s
448
+ assert_nil params
449
+ end
450
+
451
+ def test_resolve_parameters_query_append
452
+ input_params = { :q => 'hello' }
453
+ @uri.query = 'a=b'
454
+
455
+ uri, params = @agent.resolve_parameters @uri, :get, input_params
456
+
457
+ assert_equal 'http://example/?a=b&q=hello', uri.to_s
458
+ assert_nil params
459
+ end
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
+
543
+ def test_response_content_encoding_7_bit
544
+ def @res.content_length() 4 end
545
+ @res.instance_variable_set :@header, 'content-encoding' => %w[7bit]
546
+
547
+ body = @agent.response_content_encoding @res, StringIO.new('part')
548
+
549
+ assert_equal 'part', body.read
550
+ end
551
+
552
+ def test_response_content_encoding_deflate
553
+ def @res.content_length() 12 end
554
+ @res.instance_variable_set :@header, 'content-encoding' => %w[deflate]
555
+ body_io = StringIO.new "x\x9C+H,*\x01\x00\x04?\x01\xB8"
556
+
557
+ body = @agent.response_content_encoding @res, body_io
558
+
559
+ assert_equal 'part', body.read
560
+ end
561
+
562
+ def test_response_content_encoding_deflate_chunked
563
+ def @res.content_length() nil end
564
+ @res.instance_variable_set :@header, 'content-encoding' => %w[deflate]
565
+ body_io = StringIO.new "x\x9C+H,*\x01\x00\x04?\x01\xB8"
566
+
567
+ body = @agent.response_content_encoding @res, body_io
568
+
569
+ assert_equal 'part', body.read
570
+ end
571
+
572
+ # IIS/6.0 ASP.NET/2.0.50727 does not wrap deflate with zlib, WTF?
573
+ def test_response_content_encoding_deflate_no_zlib
574
+ def @res.content_length() 6 end
575
+ @res.instance_variable_set :@header, 'content-encoding' => %w[deflate]
576
+
577
+ body = @agent.response_content_encoding @res, StringIO.new("+H,*\001\000")
578
+
579
+ assert_equal 'part', body.read
580
+ end
581
+
582
+ def test_response_content_encoding_gzip
583
+ def @res.content_length() 24 end
584
+ @res.instance_variable_set :@header, 'content-encoding' => %w[gzip]
585
+ body_io = StringIO.new \
586
+ "\037\213\b\0002\002\225M\000\003+H,*\001\000\306p\017I\004\000\000\000"
587
+
588
+ body = @agent.response_content_encoding @res, body_io
589
+
590
+ assert_equal 'part', body.read
591
+ end
592
+
593
+ def test_response_content_encoding_gzip_chunked
594
+ def @res.content_length() nil end
595
+ @res.instance_variable_set :@header, 'content-encoding' => %w[gzip]
596
+ body_io = StringIO.new \
597
+ "\037\213\b\0002\002\225M\000\003+H,*\001\000\306p\017I\004\000\000\000"
598
+
599
+ body = @agent.response_content_encoding @res, body_io
600
+
601
+ assert_equal 'part', body.read
602
+ end
603
+
604
+ def test_response_content_encoding_gzip_encoding_bad
605
+ def @res.content_length() 24 end
606
+ @res.instance_variable_set(:@header,
607
+ 'content-encoding' => %w[gzip],
608
+ 'content-type' => 'text/html; charset=UTF-8')
609
+
610
+ # "test\xB2"
611
+ body_io = StringIO.new \
612
+ "\037\213\b\000*+\314N\000\003+I-.\331\004\000x\016\003\376\005\000\000\000"
613
+
614
+ body = @agent.response_content_encoding @res, body_io
615
+
616
+ expected = "test\xB2"
617
+ expected.force_encoding Encoding::BINARY if have_encoding?
618
+
619
+ content = body.read
620
+ assert_equal expected, content
621
+ assert_equal Encoding::BINARY, content.encoding if have_encoding?
622
+ end
623
+
624
+ def test_response_content_encoding_none
625
+ def @res.content_length() 4 end
626
+ @res.instance_variable_set :@header, 'content-encoding' => %w[none]
627
+
628
+ body = @agent.response_content_encoding @res, StringIO.new('part')
629
+
630
+ assert_equal 'part', body.read
631
+ end
632
+
633
+ def test_response_content_encoding_x_gzip
634
+ def @res.content_length() 24 end
635
+ @res.instance_variable_set :@header, 'content-encoding' => %w[x-gzip]
636
+ body_io = StringIO.new \
637
+ "\037\213\b\0002\002\225M\000\003+H,*\001\000\306p\017I\004\000\000\000"
638
+
639
+ body = @agent.response_content_encoding @res, body_io
640
+
641
+ assert_equal 'part', body.read
642
+ end
643
+
644
+ def test_response_content_encoding_unknown
645
+ def @res.content_length() 4 end
646
+ @res.instance_variable_set :@header, 'content-encoding' => %w[unknown]
647
+ body = StringIO.new 'part'
648
+
649
+ e = assert_raises Mechanize::Error do
650
+ @agent.response_content_encoding @res, body
651
+ end
652
+
653
+ assert_equal 'Unsupported Content-Encoding: unknown', e.message
654
+ end
655
+
656
+ def test_get_meta_refresh_header_follow_self
657
+ @agent.follow_meta_refresh = true
658
+ @agent.follow_meta_refresh_self = true
659
+
660
+ page = Mechanize::Page.new(@uri, {'content-type' => 'text/html'}, '',
661
+ 200, @mech)
662
+ @res.instance_variable_set :@header, 'refresh' => ['0']
663
+
664
+ refresh = @agent.get_meta_refresh @res, @uri, page
665
+
666
+ assert_equal [0.0, URI('http://example/')], refresh
667
+ end
668
+
669
+ def test_get_meta_refresh_header_no_follow
670
+ page = Mechanize::Page.new(@uri, {'content-type' => 'text/html'}, '',
671
+ 200, @mech)
672
+ @res.instance_variable_set :@header, 'refresh' => ['0']
673
+
674
+ refresh = @agent.get_meta_refresh @res, @uri, page
675
+
676
+ assert_nil refresh
677
+ end
678
+
679
+ def test_get_meta_refresh_header_no_follow_self
680
+ @agent.follow_meta_refresh = true
681
+
682
+ page = Mechanize::Page.new(@uri, {'content-type' => 'text/html'}, '',
683
+ 200, @mech)
684
+ @res.instance_variable_set :@header, 'refresh' => ['0']
685
+
686
+ refresh = @agent.get_meta_refresh @res, @uri, page
687
+
688
+ assert_nil refresh
689
+ end
690
+
691
+ def test_get_meta_refresh_meta_follow_self
692
+ @agent.follow_meta_refresh = true
693
+ @agent.follow_meta_refresh_self = true
694
+
695
+ body = <<-BODY
696
+ <title></title>
697
+ <meta http-equiv="refresh" content="0">
698
+ BODY
699
+
700
+ page = Mechanize::Page.new(@uri, {'content-type' => 'text/html'}, body,
701
+ 200, @mech)
702
+
703
+ refresh = @agent.get_meta_refresh @res, @uri, page
704
+
705
+ assert_equal [0, 'http://example/'], refresh
706
+ end
707
+
708
+ def test_get_meta_refresh_meta_no_follow
709
+ body = <<-BODY
710
+ <title></title>
711
+ <meta http-equiv="refresh" content="0">
712
+ BODY
713
+
714
+ page = Mechanize::Page.new(@uri, {'content-type' => 'text/html'}, body,
715
+ 200, @mech)
716
+
717
+ refresh = @agent.get_meta_refresh @res, @uri, page
718
+
719
+ assert_nil refresh
720
+ end
721
+
722
+ def test_get_meta_refresh_meta_no_follow_self
723
+ @agent.follow_meta_refresh = true
724
+
725
+ body = <<-BODY
726
+ <title></title>
727
+ <meta http-equiv="refresh" content="0">
728
+ BODY
729
+
730
+ page = Mechanize::Page.new(@uri, {'content-type' => 'text/html'}, body,
731
+ 200, @mech)
732
+
733
+ refresh = @agent.get_meta_refresh @res, @uri, page
734
+
735
+ assert_nil refresh
736
+ end
737
+
738
+ def test_hook_content_encoding_response
739
+ @mech.content_encoding_hooks << lambda{|agent, uri, response, response_body_io|
740
+ response['content-encoding'] = 'gzip' if response['content-encoding'] == 'agzip'}
741
+
742
+ @res.instance_variable_set :@header, 'content-encoding' => %w[agzip]
743
+ body_io = StringIO.new 'part'
744
+ @agent.hook_content_encoding @res, @uri, body_io
745
+
746
+ assert_equal 'gzip', @res['content-encoding']
747
+ end
748
+
749
+ def test_response_cookies
750
+ uri = URI.parse 'http://host.example.com'
751
+ cookie_str = 'a=b domain=.example.com'
752
+ @res.instance_variable_set(:@header,
753
+ 'set-cookie' => [cookie_str],
754
+ 'content-type' => %w[text/html])
755
+ page = Mechanize::Page.new uri, @res, '', 200, @mech
756
+
757
+ @agent.response_cookies @res, uri, page
758
+
759
+ assert_equal ['a=b domain=.example.com'],
760
+ @agent.cookie_jar.cookies(uri).map { |c| c.to_s }
761
+ end
762
+
763
+ def test_response_cookies_many
764
+ uri = URI.parse 'http://host.example.com'
765
+ cookie1 = 'a=b domain=.example.com'
766
+ cookie2 = 'c=d domain=.example.com'
767
+ @res.instance_variable_set(:@header,
768
+ 'set-cookie' => [cookie1, cookie2],
769
+ 'content-type' => %w[text/html])
770
+ page = Mechanize::Page.new uri, @res, '', 200, @mech
771
+
772
+ @agent.response_cookies @res, uri, page
773
+
774
+ assert_equal ['a=b domain=.example.com', 'c=d domain=.example.com'],
775
+ @agent.cookie_jar.cookies(uri).map { |c| c.to_s }
776
+ end
777
+
778
+ def test_response_cookies_meta
779
+ uri = URI.parse 'http://host.example.com'
780
+ cookie_str = 'a=b domain=.example.com'
781
+
782
+ body = <<-BODY
783
+ <head>
784
+ <meta http-equiv="Set-Cookie" content="#{cookie_str}">
785
+ </head>"
786
+ BODY
787
+
788
+ @res.instance_variable_set(:@header,
789
+ 'content-type' => %w[text/html])
790
+ page = Mechanize::Page.new uri, @res, body, 200, @mech
791
+
792
+ @agent.response_cookies @res, uri, page
793
+
794
+ assert_equal ['a=b domain=.example.com'],
795
+ @agent.cookie_jar.cookies(uri).map { |c| c.to_s }
796
+ end
797
+
798
+ def test_response_follow_meta_refresh
799
+ uri = URI.parse 'http://example/#id+1'
800
+
801
+ body = <<-BODY
802
+ <title></title>
803
+ <meta http-equiv="refresh" content="0">
804
+ BODY
805
+
806
+ page = Mechanize::Page.new(uri, {'content-type' => 'text/html'}, body,
807
+ 200, @mech)
808
+
809
+ @agent.follow_meta_refresh = true
810
+ @agent.follow_meta_refresh_self = true
811
+
812
+ page = @agent.response_follow_meta_refresh @res, uri, page, 0
813
+
814
+ assert_equal uri, page.uri
815
+ end
816
+
817
+ def test_response_follow_meta_refresh_limit
818
+ uri = URI.parse 'http://example/#id+1'
819
+
820
+ body = <<-BODY
821
+ <title></title>
822
+ <meta http-equiv="refresh" content="0">
823
+ BODY
824
+
825
+ page = Mechanize::Page.new(uri, {'content-type' => 'text/html'}, body,
826
+ 200, @mech)
827
+
828
+ @agent.follow_meta_refresh = true
829
+ @agent.follow_meta_refresh_self = true
830
+
831
+ assert_raises Mechanize::RedirectLimitReachedError do
832
+ @agent.response_follow_meta_refresh(@res, uri, page,
833
+ @agent.redirection_limit)
834
+ end
835
+ end
836
+
837
+ def test_response_read
838
+ def @res.read_body() yield 'part' end
839
+ def @res.content_length() 4 end
840
+
841
+ io = @agent.response_read @res, @req
842
+
843
+ body = io.read
844
+
845
+ assert_equal 'part', body
846
+ assert_equal Encoding::BINARY, body.encoding if body.respond_to? :encoding
847
+ end
848
+
849
+ def test_response_read_large
850
+ def @res.read_body() yield 'a' * 10241 end
851
+ def @res.content_length() 10241 end
852
+
853
+ io = @agent.response_read @res, @req
854
+
855
+ assert_kind_of Tempfile, io
856
+ assert_equal 10241, io.stat.size
857
+ end
858
+
859
+ def test_response_read_large_chunked
860
+ def @res.read_body
861
+ 11.times do yield 'a' * 1024 end
862
+ end
863
+ def @res.content_length() end
864
+
865
+ io = @agent.response_read @res, @req
866
+
867
+ assert_kind_of Tempfile, io
868
+ assert_equal 11264, io.stat.size
869
+ end
870
+
871
+ def test_response_read_content_length_head
872
+ req = Net::HTTP::Head.new '/'
873
+
874
+ def @res.content_length() end
875
+ def @res.read_body() end
876
+
877
+ io = @agent.response_read @res, req
878
+
879
+ assert_equal '', io.read
880
+ end
881
+
882
+ def test_response_read_content_length_mismatch
883
+ def @res.content_length() 5 end
884
+ def @res.read_body() yield 'part' end
885
+
886
+ e = assert_raises EOFError do
887
+ @agent.response_read @res, @req
888
+ end
889
+
890
+ assert_equal 'Content-Length (5) does not match response body length (4)',
891
+ e.message
892
+ end
893
+
894
+ def test_response_read_content_length_redirect
895
+ res = Net::HTTPFound.allocate
896
+ def res.content_length() 5 end
897
+ def res.code() 302 end
898
+ def res.read_body() yield 'part' end
899
+ res.instance_variable_set :@header, {}
900
+
901
+ io = @agent.response_read res, @req
902
+
903
+ assert_equal 'part', io.read
904
+ end
905
+
906
+ def test_response_read_error
907
+ def @res.read_body()
908
+ yield 'part'
909
+ raise Net::HTTP::Persistent::Error
910
+ end
911
+
912
+ e = assert_raises Mechanize::ResponseReadError do
913
+ @agent.response_read @res, @req
914
+ end
915
+
916
+ assert_equal @res, e.response
917
+ assert_equal 'part', e.body_io.read
918
+ assert_kind_of Net::HTTP::Persistent::Error, e.error
919
+ end
920
+
921
+ def test_response_read_file
922
+ Tempfile.open 'pi.txt' do |tempfile|
923
+ tempfile.write "π\n"
924
+ tempfile.flush
925
+ tempfile.rewind
926
+
927
+ uri = URI.parse "file://#{tempfile.path}"
928
+ req = Mechanize::FileRequest.new uri
929
+ res = Mechanize::FileResponse.new tempfile.path
930
+
931
+ io = @agent.response_read res, req
932
+
933
+ expected = "π\n"
934
+ expected.force_encoding Encoding::BINARY if expected.respond_to? :encoding
935
+
936
+ body = io.read
937
+ assert_equal expected, body
938
+ assert_equal Encoding::BINARY, body.encoding if body.respond_to? :encoding
939
+ end
940
+ end
941
+
942
+ def test_response_read_no_body
943
+ req = Net::HTTP::Options.new '/'
944
+
945
+ def @res.content_length() end
946
+ def @res.read_body() end
947
+
948
+ io = @agent.response_read @res, req
949
+
950
+ assert_equal '', io.read
951
+ end
952
+
953
+ def test_response_read_unknown_code
954
+ res = Net::HTTPUnknownResponse.allocate
955
+ res.instance_variable_set :@code, 9999
956
+ res.instance_variable_set :@header, {}
957
+ def res.read_body() yield 'part' end
958
+
959
+ e = assert_raises Mechanize::ResponseCodeError do
960
+ @agent.response_read res, @req
961
+ end
962
+
963
+ assert_equal res, e.page
964
+ end
965
+
966
+ def test_response_redirect
967
+ @agent.redirect_ok = true
968
+ referer = page 'http://example/referer'
969
+
970
+ page = fake_page
971
+ page = @agent.response_redirect({ 'Location' => '/index.html' }, :get,
972
+ page, 0, referer)
973
+
974
+ assert_equal URI('http://fake.example/index.html'), page.uri
975
+
976
+ assert_equal 'http://example/referer', requests.first['Referer']
977
+ end
978
+
979
+ def test_response_redirect_limit
980
+ @agent.redirect_ok = true
981
+ referer = page 'http://example/referer'
982
+
983
+ assert_raises Mechanize::RedirectLimitReachedError do
984
+ @agent.response_redirect({ 'Location' => '/index.html' }, :get,
985
+ fake_page, @agent.redirection_limit, referer)
986
+ end
987
+ end
988
+
989
+ def test_response_redirect_not_ok
990
+ @agent.redirect_ok = false
991
+
992
+ page = fake_page
993
+ page = @agent.response_redirect({ 'Location' => '/other' }, :get, page, 0,
994
+ page)
995
+
996
+ assert_equal URI('http://fake.example'), page.uri
997
+ end
998
+
999
+ def test_response_redirect_permanent
1000
+ @agent.redirect_ok = :permanent
1001
+
1002
+ response = Net::HTTPMovedPermanently.allocate
1003
+ response.instance_variable_set :@header, { 'location' => %w[/index.html] }
1004
+
1005
+ page = fake_page
1006
+ page = @agent.response_redirect response, :get, page, 0, page
1007
+
1008
+ assert_equal URI('http://fake.example/index.html'), page.uri
1009
+ end
1010
+
1011
+ def test_response_redirect_permanent_temporary
1012
+ @agent.redirect_ok = :permanent
1013
+
1014
+ response = Net::HTTPMovedTemporarily.allocate
1015
+ response.instance_variable_set :@header, { 'location' => %w[/index.html] }
1016
+
1017
+ page = fake_page
1018
+ page = @agent.response_redirect response, :get, page, 0, page
1019
+
1020
+ assert_equal URI('http://fake.example/'), page.uri
1021
+ end
1022
+
1023
+ def test_response_parse
1024
+ body = '<title>hi</title>'
1025
+ @res.instance_variable_set :@header, 'content-type' => %w[text/html]
1026
+
1027
+ page = @agent.response_parse @res, body, @uri
1028
+
1029
+ assert_instance_of Mechanize::Page, page
1030
+ assert_equal @mech, page.mech
1031
+ end
1032
+
1033
+ def test_response_parse_content_type_case
1034
+ body = '<title>hi</title>'
1035
+ @res.instance_variable_set(:@header, 'content-type' => %w[text/HTML])
1036
+
1037
+ page = @agent.response_parse @res, body, @uri
1038
+
1039
+ assert_instance_of Mechanize::Page, page
1040
+
1041
+ assert_equal 'text/HTML', page.content_type
1042
+ end
1043
+
1044
+ def test_response_parse_content_type_encoding
1045
+ body = '<title>hi</title>'
1046
+ @res.instance_variable_set(:@header,
1047
+ 'content-type' =>
1048
+ %w[text/html;charset=ISO-8859-1])
1049
+
1050
+ page = @agent.response_parse @res, body, @uri
1051
+
1052
+ assert_instance_of Mechanize::Page, page
1053
+ assert_equal @mech, page.mech
1054
+
1055
+ assert_equal 'ISO-8859-1', page.encoding
1056
+ assert_equal 'ISO-8859-1', page.parser.encoding
1057
+ end
1058
+
1059
+ def test_response_parse_content_type_encoding_garbage
1060
+ body = '<title>hi</title>'
1061
+ @res.instance_variable_set(:@header,
1062
+ 'content-type' =>
1063
+ %w[text/html; charset=garbage_charset])
1064
+
1065
+ page = @agent.response_parse @res, body, @uri
1066
+
1067
+ assert_instance_of Mechanize::Page, page
1068
+ assert_equal @mech, page.mech
1069
+ end
1070
+
1071
+ def test_response_parse_content_type_encoding_broken_iso_8859_1
1072
+ body = '<title>hi</title>'
1073
+ @res.instance_variable_set(:@header,
1074
+ 'content-type' =>
1075
+ %w[text/html; charset=ISO_8859-1])
1076
+
1077
+ page = @agent.response_parse @res, body, @uri
1078
+
1079
+ assert_instance_of Mechanize::Page, page
1080
+ assert_equal 'ISO_8859-1', page.encoding
1081
+ end
1082
+
1083
+ def test_response_parse_content_type_encoding_broken_utf_8
1084
+ body = '<title>hi</title>'
1085
+ @res.instance_variable_set(:@header,
1086
+ 'content-type' =>
1087
+ %w[text/html; charset=UTF8])
1088
+
1089
+ page = @agent.response_parse @res, body, @uri
1090
+
1091
+ assert_instance_of Mechanize::Page, page
1092
+ assert_equal 'UTF8', page.encoding
1093
+ assert_equal 'UTF8', page.parser.encoding
1094
+ end
1095
+
1096
+ def test_response_parse_content_type_encoding_semicolon
1097
+ body = '<title>hi</title>'
1098
+ @res.instance_variable_set(:@header,
1099
+ 'content-type' =>
1100
+ %w[text/html;charset=UTF-8;])
1101
+
1102
+ page = @agent.response_parse @res, body, @uri
1103
+
1104
+ assert_instance_of Mechanize::Page, page
1105
+
1106
+ assert_equal 'UTF-8', page.encoding
1107
+ end
1108
+
1109
+ def test_robots_allowed_eh
1110
+ allowed = URI 'http://localhost/index.html'
1111
+ disallowed = URI 'http://localhost/norobots.html'
1112
+
1113
+ assert @agent.robots_allowed? allowed
1114
+ refute @agent.robots_allowed? disallowed
1115
+
1116
+ refute @agent.robots_disallowed? allowed
1117
+ assert @agent.robots_disallowed? disallowed
1118
+ end
1119
+
1120
+ def test_robots_allowed_eh_noindex
1121
+ @agent.robots = true
1122
+
1123
+ noindex = URI 'http://localhost/noindex.html'
1124
+
1125
+ assert @agent.robots_allowed? noindex
1126
+
1127
+ assert_raises Mechanize::RobotsDisallowedError do
1128
+ @agent.fetch noindex
1129
+ end
1130
+ end
1131
+
1132
+ def test_set_http
1133
+ @agent.set_http
1134
+
1135
+ assert_equal 'mechanize', @agent.http.name
1136
+ refute @agent.http.retry_change_requests
1137
+ end
1138
+
1139
+ def test_set_http_idle_timeout
1140
+ @agent.idle_timeout = 1
1141
+ @agent.set_http
1142
+
1143
+ assert_equal 'mechanize', @agent.http.name
1144
+ assert_equal 1, @agent.http.idle_timeout
1145
+ end
1146
+
1147
+ def test_set_http_ssl
1148
+ in_tmpdir do
1149
+ store = OpenSSL::X509::Store.new
1150
+ @agent.cert = ssl_certificate
1151
+ @agent.key = ssl_private_key
1152
+ @agent.cert_store = store
1153
+ @agent.ca_file = '.'
1154
+ @agent.verify_callback = proc { |ok, context| }
1155
+
1156
+ @agent.set_http
1157
+
1158
+ http = @agent.http
1159
+
1160
+ assert_equal ssl_certificate, http.certificate
1161
+ assert_equal ssl_private_key, http.private_key
1162
+ assert_equal store, http.cert_store
1163
+ assert_equal '.', http.ca_file
1164
+ assert_equal OpenSSL::SSL::VERIFY_PEER, http.verify_mode
1165
+ assert http.verify_callback
1166
+ end
1167
+ end
1168
+
1169
+ def test_set_http_ssl_verify_none
1170
+ in_tmpdir do
1171
+ @agent.verify_mode = OpenSSL::SSL::VERIFY_NONE
1172
+
1173
+ @agent.set_http
1174
+
1175
+ http = @agent.http
1176
+
1177
+ assert_equal OpenSSL::SSL::VERIFY_NONE, http.verify_mode
1178
+ end
1179
+ end
1180
+
1181
+ def test_set_http_retry_change_request
1182
+ @agent.retry_change_requests = true
1183
+ @agent.set_http
1184
+
1185
+ assert_equal 'mechanize', @agent.http.name
1186
+ assert @agent.http.retry_change_requests
1187
+ end
1188
+
1189
+ def test_set_proxy
1190
+ @agent.set_proxy 'www.example.com', 9001, 'joe', 'lol'
1191
+
1192
+ assert_equal @agent.proxy_uri.host, 'www.example.com'
1193
+ assert_equal @agent.proxy_uri.port, 9001
1194
+ assert_equal @agent.proxy_uri.user, 'joe'
1195
+ assert_equal @agent.proxy_uri.password, 'lol'
1196
+ end
1197
+
1198
+ def test_set_proxy_port_string
1199
+ @agent.set_proxy 'www.example.com', '9001', 'joe', 'lol'
1200
+
1201
+ assert_equal @agent.proxy_uri.host, 'www.example.com'
1202
+ assert_equal @agent.proxy_uri.port, 9001
1203
+ assert_equal @agent.proxy_uri.user, 'joe'
1204
+ assert_equal @agent.proxy_uri.password, 'lol'
1205
+ end
1206
+
1207
+ def test_set_proxy_service_name
1208
+ @agent.set_proxy 'www.example.com', 'http', 'joe', 'lol'
1209
+
1210
+ assert_equal @agent.proxy_uri.host, 'www.example.com'
1211
+ assert_equal @agent.proxy_uri.port, 80
1212
+ assert_equal @agent.proxy_uri.user, 'joe'
1213
+ assert_equal @agent.proxy_uri.password, 'lol'
1214
+ end
1215
+
1216
+ def test_set_proxy_service_name_bad
1217
+ e = assert_raises ArgumentError do
1218
+ @agent.set_proxy 'www.example.com', 'nonexistent service', 'joe', 'lol'
1219
+ end
1220
+
1221
+ assert_equal 'invalid value for port: "nonexistent service"', e.message
1222
+ end
1223
+
1224
+ end
1225
+