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,1164 @@
1
+ # coding: utf-8
2
+
3
+ require 'mechanize/test_case'
4
+
5
+ class TestMechanize < Mechanize::TestCase
6
+
7
+ def setup
8
+ super
9
+
10
+ @uri = URI 'http://example/'
11
+ @req = Net::HTTP::Get.new '/'
12
+
13
+ @res = Net::HTTPOK.allocate
14
+ @res.instance_variable_set :@code, 200
15
+ @res.instance_variable_set :@header, {}
16
+
17
+ @headers = if RUBY_VERSION > '1.9' then
18
+ %w[accept user-agent]
19
+ else
20
+ %w[accept]
21
+ end
22
+ end
23
+
24
+ def test_back
25
+ 0.upto(5) do |i|
26
+ assert_equal(i, @mech.history.size)
27
+ @mech.get("http://localhost/")
28
+ end
29
+ @mech.get("http://localhost/form_test.html")
30
+
31
+ assert_equal("http://localhost/form_test.html",
32
+ @mech.history.last.uri.to_s)
33
+ assert_equal("http://localhost/",
34
+ @mech.history[-2].uri.to_s)
35
+
36
+ assert_equal(7, @mech.history.size)
37
+ @mech.back
38
+ assert_equal(6, @mech.history.size)
39
+ assert_equal("http://localhost/",
40
+ @mech.history.last.uri.to_s)
41
+ end
42
+
43
+ def test_basic_auth
44
+ @mech.basic_auth('user', 'pass')
45
+ page = @mech.get("http://localhost/basic_auth")
46
+ assert_equal('You are authenticated', page.body)
47
+ end
48
+
49
+ def test_cert_key_file
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
53
+
54
+ mech = Mechanize.new do |a|
55
+ a.cert = 'cert.pem'
56
+ a.key = 'key.pem'
57
+ end
58
+
59
+ # Certificate#== seems broken
60
+ assert_equal ssl_certificate.to_pem, mech.certificate.to_pem
61
+ end
62
+ end
63
+
64
+ def test_cert_key_object
65
+ mech = Mechanize.new do |a|
66
+ a.cert = ssl_certificate
67
+ a.key = ssl_private_key
68
+ end
69
+
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
80
+ end
81
+
82
+ def test_click
83
+ @mech.user_agent_alias = 'Mac Safari'
84
+ page = @mech.get("http://localhost/frame_test.html")
85
+ link = page.link_with(:text => "Form Test")
86
+
87
+ page = @mech.click(link)
88
+
89
+ assert_equal("http://localhost/form_test.html",
90
+ @mech.history.last.uri.to_s)
91
+ end
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
+
102
+ def test_click_frame_hpricot_style
103
+ page = @mech.get("http://localhost/frame_test.html")
104
+ link = (page/"//frame[@name='frame2']").first
105
+
106
+ page = @mech.click(link)
107
+
108
+ assert_equal("http://localhost/form_test.html",
109
+ @mech.history.last.uri.to_s)
110
+ end
111
+
112
+ def test_click_hpricot_style # HACK move to test_divide in Page
113
+ page = @mech.get("http://localhost/frame_test.html")
114
+ link = (page/"//a[@class='bar']").first
115
+
116
+ page = @mech.click(link)
117
+
118
+ assert_equal("http://localhost/form_test.html",
119
+ @mech.history.last.uri.to_s)
120
+ end
121
+
122
+ def test_click_link
123
+ link = node 'a', 'href' => '/index.html'
124
+ link = Mechanize::Page::Link.new link, @mech, fake_page
125
+
126
+ @mech.click link
127
+
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
198
+ end
199
+
200
+ def test_click_link_hpricot_style # HACK move to test_search in Page
201
+ page = @mech.get("http://localhost/tc_encoded_links.html")
202
+
203
+ page = @mech.click(page.search('a').first)
204
+
205
+ assert_equal("http://localhost/form_post?a=b&b=c", page.uri.to_s)
206
+ end
207
+
208
+ def test_click_link_query
209
+ page = @mech.get("http://localhost/tc_encoded_links.html")
210
+ link = page.links.first
211
+ assert_equal('/form_post?a=b&b=c', link.href)
212
+
213
+ page = @mech.click(link)
214
+
215
+ assert_equal("http://localhost/form_post?a=b&b=c", page.uri.to_s)
216
+ end
217
+
218
+ def test_click_link_space
219
+ page = @mech.get("http://localhost/tc_bad_links.html")
220
+
221
+ @mech.click page.links.first
222
+
223
+ assert_match(/alt_text.html$/, @mech.history.last.uri.to_s)
224
+ assert_equal(2, @mech.history.length)
225
+ end
226
+
227
+ def test_click_more
228
+ @mech.get 'http://localhost/test_click.html'
229
+ @mech.click 'A Button'
230
+ assert_equal 'http://localhost/frame_test.html?words=nil',
231
+ @mech.page.uri.to_s
232
+ @mech.back
233
+ @mech.click 'A Link'
234
+ assert_equal 'http://localhost/index.html',
235
+ @mech.page.uri.to_s
236
+ @mech.back
237
+ @mech.click @mech.page.link_with(:text => 'A Link')
238
+ assert_equal 'http://localhost/index.html',
239
+ @mech.page.uri.to_s
240
+ end
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
+
264
+ def test_delete
265
+ page = @mech.delete('http://localhost/verb', { 'q' => 'foo' })
266
+ assert_equal 1, @mech.history.length
267
+ assert_equal 'DELETE', page.header['X-Request-Method']
268
+ end
269
+
270
+ def test_delete_redirect
271
+ page = @mech.delete('http://localhost/redirect')
272
+
273
+ assert_equal(page.uri.to_s, 'http://localhost/verb')
274
+
275
+ assert_equal 'GET', page.header['X-Request-Method']
276
+ end
277
+
278
+ #def test_download
279
+ # Dir.mktmpdir do |dir|
280
+ # file = "#{dir}/download"
281
+ # open file, 'w' do |io|
282
+ # @mech.download 'http://example', io
283
+ # end
284
+
285
+ # assert_equal 1, File.stat(file).size
286
+ # end
287
+ #end
288
+
289
+ def test_get
290
+ uri = URI 'http://localhost'
291
+
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
296
+ end
297
+
298
+ def test_get_HTTP
299
+ page = @mech.get('HTTP://localhost/', { :q => 'hello' })
300
+ assert_equal('HTTP://localhost/?q=hello', page.uri.to_s)
301
+ end
302
+
303
+ def test_get_anchor
304
+ page = @mech.get('http://localhost/?foo=bar&#34;')
305
+ assert_equal('http://localhost/?foo=bar%22', page.uri.to_s)
306
+ end
307
+
308
+ def test_get_bad_url
309
+ assert_raises ArgumentError do
310
+ @mech.get '/foo.html'
311
+ end
312
+ end
313
+
314
+ def test_get_basic_auth_bad
315
+ @mech.basic_auth('aaron', 'aaron')
316
+
317
+ e = assert_raises Mechanize::UnauthorizedError do
318
+ @mech.get("http://localhost/basic_auth")
319
+ end
320
+
321
+ assert_equal("401", e.response_code)
322
+ end
323
+
324
+ def test_get_basic_auth_none
325
+ e = assert_raises Mechanize::UnauthorizedError do
326
+ @mech.get("http://localhost/basic_auth")
327
+ end
328
+
329
+ assert_equal("401", e.response_code)
330
+ end
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
+
345
+ def test_get_digest_auth
346
+ block_called = false
347
+
348
+ @mech.basic_auth('user', 'pass')
349
+
350
+ @mech.pre_connect_hooks << lambda { |_, request|
351
+ block_called = true
352
+ request.to_hash.each do |k,v|
353
+ assert_equal(1, v.length)
354
+ end
355
+ }
356
+
357
+ page = @mech.get("http://localhost/digest_auth")
358
+ assert_equal('You are authenticated', page.body)
359
+ assert block_called
360
+ end
361
+
362
+ def test_get_file
363
+ page = @mech.get("http://localhost/frame_test.html")
364
+ content_length = page.header['Content-Length']
365
+ page_as_string = @mech.get_file("http://localhost/frame_test.html")
366
+ assert_equal(content_length.to_i, page_as_string.length.to_i)
367
+ end
368
+
369
+ def test_get_follow_meta_refresh
370
+ @mech.follow_meta_refresh = true
371
+
372
+ page = @mech.get('http://localhost/tc_follow_meta.html')
373
+
374
+ assert_equal(2, @mech.history.length)
375
+
376
+ assert_equal('http://localhost/tc_follow_meta.html',
377
+ @mech.history.first.uri.to_s)
378
+ assert_equal('http://localhost/index.html', page.uri.to_s)
379
+ assert_equal('http://localhost/index.html', @mech.history.last.uri.to_s)
380
+ end
381
+
382
+ def test_get_follow_meta_refresh_anywhere
383
+ @mech.follow_meta_refresh = :anywhere
384
+ requests = []
385
+ @mech.pre_connect_hooks << lambda { |_, request|
386
+ requests << request
387
+ }
388
+
389
+ @mech.get('http://localhost/tc_meta_in_body.html')
390
+ assert_equal 2, requests.length
391
+ end
392
+
393
+ def test_get_follow_meta_refresh_disabled
394
+ page = @mech.get('http://localhost/tc_follow_meta.html')
395
+ assert_equal('http://localhost/tc_follow_meta.html', page.uri.to_s)
396
+ assert_equal(1, page.meta_refresh.length)
397
+ end
398
+
399
+ def test_get_follow_meta_refresh_empty_url
400
+ @mech.follow_meta_refresh = true
401
+ @mech.follow_meta_refresh_self = true
402
+
403
+ page = @mech.get('http://localhost/refresh_with_empty_url')
404
+
405
+ assert_equal(3, @mech.history.length)
406
+ assert_equal('http://localhost/refresh_with_empty_url',
407
+ @mech.history[0].uri.to_s)
408
+ assert_equal('http://localhost/refresh_with_empty_url',
409
+ @mech.history[1].uri.to_s)
410
+ assert_equal('http://localhost/index.html', page.uri.to_s)
411
+ assert_equal('http://localhost/index.html', @mech.history.last.uri.to_s)
412
+ end
413
+
414
+ def test_get_follow_meta_refresh_in_body
415
+ @mech.follow_meta_refresh = true
416
+ requests = []
417
+ @mech.pre_connect_hooks << lambda { |_, request|
418
+ requests << request
419
+ }
420
+
421
+ @mech.get('http://localhost/tc_meta_in_body.html')
422
+ assert_equal 1, requests.length
423
+ end
424
+
425
+ def test_get_follow_meta_refresh_no_url
426
+ @mech.follow_meta_refresh = true
427
+ @mech.follow_meta_refresh_self = true
428
+
429
+ page = @mech.get('http://localhost/refresh_without_url')
430
+
431
+ assert_equal(3, @mech.history.length)
432
+ assert_equal('http://localhost/refresh_without_url',
433
+ @mech.history[0].uri.to_s)
434
+ assert_equal('http://localhost/refresh_without_url',
435
+ @mech.history[1].uri.to_s)
436
+ assert_equal('http://localhost/index.html', page.uri.to_s)
437
+ assert_equal('http://localhost/index.html', @mech.history.last.uri.to_s)
438
+ end
439
+
440
+ def test_get_follow_meta_refresh_referer_not_sent
441
+ @mech.follow_meta_refresh = true
442
+
443
+ requests = []
444
+
445
+ @mech.pre_connect_hooks << lambda { |_, request|
446
+ requests << request
447
+ }
448
+
449
+ @mech.get('http://localhost/tc_follow_meta.html')
450
+
451
+ assert_equal 2, @mech.history.length
452
+ assert_nil requests.last['referer']
453
+ end
454
+
455
+ def test_get_referer_download
456
+ download = Mechanize::Download.new URI 'http://example/prev'
457
+
458
+ uri = URI 'http://example'
459
+
460
+ page = @mech.get uri, { :q => 'h' }, download, { 'X-H' => 'v' }
461
+
462
+ assert_equal URI('http://example/?q=h'), page.uri
463
+ assert_equal URI('http://example'), uri
464
+
465
+ assert_equal 'http://example/prev', requests.first['referer']
466
+ end
467
+
468
+ def test_get_robots
469
+ @mech.robots = true
470
+
471
+ assert_equal "Page Title", @mech.get("http://localhost/index.html").title
472
+
473
+ assert_raises Mechanize::RobotsDisallowedError do
474
+ @mech.get "http://localhost/norobots.html"
475
+ end
476
+ end
477
+
478
+ def test_follow_meta_refresh_self
479
+ refute @mech.agent.follow_meta_refresh_self
480
+
481
+ @mech.follow_meta_refresh_self = true
482
+
483
+ assert @mech.agent.follow_meta_refresh_self
484
+ end
485
+
486
+ def test_get_gzip
487
+ page = @mech.get("http://localhost/gzip?file=index.html")
488
+
489
+ assert_kind_of(Mechanize::Page, page)
490
+
491
+ assert_match('Hello World', page.body)
492
+ end
493
+
494
+ def test_content_encoding_hooks_header
495
+ h = {'X-ResponseContentEncoding' => 'agzip'}
496
+
497
+ # test of X-ResponseContentEncoding feature
498
+ assert_raises(Mechanize::Error, 'Unsupported Content-Encoding: agzip') do
499
+ @mech.get("http://localhost/gzip?file=index.html", nil, nil, h)
500
+ end
501
+
502
+ @mech.content_encoding_hooks << lambda{|agent, uri, response, response_body_io|
503
+ response['content-encoding'] = 'gzip' if response['content-encoding'] == 'agzip'}
504
+
505
+ page = @mech.get("http://localhost/gzip?file=index.html", nil, nil, h)
506
+
507
+ assert_match('Hello World', page.body)
508
+ end
509
+
510
+ def external_cmd(io); Zlib::GzipReader.new(io).read; end
511
+
512
+ def test_content_encoding_hooks_body_io
513
+ h = {'X-ResponseContentEncoding' => 'unsupported_content_encoding'}
514
+
515
+ @mech.content_encoding_hooks << lambda{|agent, uri, response, response_body_io|
516
+ if response['content-encoding'] == 'unsupported_content_encoding'
517
+ response['content-encoding'] = 'none'
518
+ response_body_io.string = external_cmd(response_body_io)
519
+ end}
520
+
521
+ page = @mech.get("http://localhost/gzip?file=index.html", nil, nil, h)
522
+
523
+ assert_match('Hello World', page.body)
524
+ end
525
+
526
+ def test_get_http_refresh
527
+ @mech.follow_meta_refresh = true
528
+
529
+ requests = []
530
+
531
+ @mech.pre_connect_hooks << lambda { |_, request|
532
+ requests << request
533
+ }
534
+
535
+ page = @mech.get('http://localhost/http_refresh?refresh_time=0')
536
+
537
+ assert_equal('http://localhost/index.html', page.uri.to_s)
538
+ assert_equal(2, @mech.history.length)
539
+ assert_nil requests.last['referer']
540
+ end
541
+
542
+ def test_get_http_refresh_delay
543
+ @mech.follow_meta_refresh = true
544
+ class << @mech.agent
545
+ attr_accessor :slept
546
+ def sleep *args
547
+ @slept = args
548
+ end
549
+ end
550
+
551
+ @mech.get('http://localhost/http_refresh?refresh_time=1')
552
+ assert_equal [1], @mech.agent.slept
553
+ end
554
+
555
+ def test_get_http_refresh_disabled
556
+ page = @mech.get('http://localhost/http_refresh?refresh_time=0')
557
+ assert_equal('http://localhost/http_refresh?refresh_time=0', page.uri.to_s)
558
+ end
559
+
560
+ def test_get_kcode
561
+ $KCODE = 'u'
562
+ page = @mech.get("http://localhost/?a=#{[0xd6].pack('U')}")
563
+
564
+ assert_equal('http://localhost/?a=%D6', page.uri.to_s)
565
+
566
+ $KCODE = 'NONE'
567
+ end unless RUBY_VERSION >= '1.9.0'
568
+
569
+ def test_get_query
570
+ page = @mech.get('http://localhost/', { :q => 'hello' })
571
+ assert_equal('http://localhost/?q=hello', page.uri.to_s)
572
+ end
573
+
574
+ def test_get_redirect
575
+ page = @mech.get('http://localhost/redirect')
576
+
577
+ assert_equal(page.uri.to_s, 'http://localhost/verb')
578
+
579
+ assert_equal 'GET', page.header['X-Request-Method']
580
+ end
581
+
582
+ def test_get_redirect_found
583
+ page = @mech.get('http://localhost/response_code?code=302&ct=test/xml')
584
+
585
+ assert_equal('http://localhost/index.html', page.uri.to_s)
586
+
587
+ assert_equal(2, @mech.history.length)
588
+ end
589
+
590
+ def test_get_redirect_infinite
591
+ assert_raises(Mechanize::RedirectLimitReachedError) {
592
+ @mech.get('http://localhost/infinite_refresh')
593
+ }
594
+ end
595
+
596
+ def test_get_referer
597
+ request = nil
598
+ @mech.pre_connect_hooks << lambda { |_, req|
599
+ request = req
600
+ }
601
+
602
+ @mech.get('http://localhost/', [], 'http://tenderlovemaking.com/')
603
+ assert_equal 'http://tenderlovemaking.com/', request['Referer']
604
+ end
605
+
606
+ def test_get_referer_file
607
+ uri = URI 'http://tenderlovemaking.com/crossdomain.xml'
608
+ file = Mechanize::File.new uri
609
+
610
+ @mech.get('http://localhost', [], file)
611
+
612
+ # HACK no assertion of behavior
613
+ end
614
+
615
+ def test_get_referer_none
616
+ requests = []
617
+ @mech.pre_connect_hooks << lambda { |_, request|
618
+ requests << request
619
+ }
620
+
621
+ @mech.get('http://localhost/')
622
+ @mech.get('http://localhost/')
623
+ assert_equal(2, requests.length)
624
+ requests.each do |request|
625
+ assert_nil request['referer']
626
+ end
627
+ end
628
+
629
+ def test_get_scheme_unsupported
630
+ assert_raises Mechanize::UnsupportedSchemeError do
631
+ @mech.get('ftp://server.com/foo.html')
632
+ end
633
+ end
634
+
635
+ def test_get_space
636
+ page = nil
637
+
638
+ page = @mech.get("http://localhost/tc_bad_links.html ")
639
+
640
+ assert_match(/tc_bad_links.html$/, @mech.history.last.uri.to_s)
641
+
642
+ assert_equal(1, @mech.history.length)
643
+ end
644
+
645
+ def test_get_tilde
646
+ page = @mech.get('http://localhost/?foo=~2')
647
+
648
+ assert_equal('http://localhost/?foo=~2', page.uri.to_s)
649
+ end
650
+
651
+ def test_get_weird
652
+ @mech.get('http://localhost/?action=bing&bang=boom=1|a=|b=|c=')
653
+ @mech.get('http://localhost/?a=b&#038;b=c&#038;c=d')
654
+ @mech.get("http://localhost/?a=#{[0xd6].pack('U')}")
655
+
656
+ # HACK no assertion of behavior
657
+ end
658
+
659
+ def test_get_yield
660
+ pages = nil
661
+
662
+ @mech.get("http://localhost/file_upload.html") { |page|
663
+ pages = page
664
+ }
665
+
666
+ assert pages
667
+ assert_equal('File Upload Form', pages.title)
668
+ end
669
+
670
+ def test_head
671
+ page = @mech.head('http://localhost/verb', { 'q' => 'foo' })
672
+ assert_equal 0, @mech.history.length
673
+ assert_equal 'HEAD', page.header['X-Request-Method']
674
+ end
675
+
676
+ def test_head_redirect
677
+ page = @mech.head('http://localhost/redirect')
678
+
679
+ assert_equal(page.uri.to_s, 'http://localhost/verb')
680
+
681
+ assert_equal 'HEAD', page.header['X-Request-Method']
682
+ end
683
+
684
+ def test_history
685
+ 2.times do |i|
686
+ assert_equal(i, @mech.history.size)
687
+
688
+ @mech.get("http://localhost/")
689
+ end
690
+
691
+ page = @mech.get("http://localhost/form_test.html")
692
+
693
+ assert_equal("http://localhost/form_test.html",
694
+ @mech.history.last.uri.to_s)
695
+ assert_equal("http://localhost/",
696
+ @mech.history[-2].uri.to_s)
697
+
698
+ assert @mech.visited?("http://localhost/")
699
+ assert @mech.visited?("/form_test.html"), 'relative'
700
+ assert !@mech.visited?("http://google.com/")
701
+ assert @mech.visited?(page.links.first)
702
+ end
703
+
704
+ def test_history_added_gets_called
705
+ added_page = nil
706
+
707
+ @mech.history_added = lambda { |page|
708
+ added_page = page
709
+ }
710
+
711
+ assert_equal @mech.get('http://localhost/tc_blank_form.html'), added_page
712
+ end
713
+
714
+ def test_history_order
715
+ @mech.max_history = 2
716
+ assert_equal(0, @mech.history.length)
717
+
718
+ @mech.get('http://localhost/form_test.html')
719
+ assert_equal(1, @mech.history.length)
720
+
721
+ @mech.get('http://localhost/empty_form.html')
722
+ assert_equal(2, @mech.history.length)
723
+
724
+ @mech.get('http://localhost/tc_checkboxes.html')
725
+ assert_equal(2, @mech.history.length)
726
+ assert_equal('http://localhost/empty_form.html', @mech.history[0].uri.to_s)
727
+ assert_equal('http://localhost/tc_checkboxes.html',
728
+ @mech.history[1].uri.to_s)
729
+ end
730
+
731
+ def test_html_parser_equals
732
+ @mech.html_parser = {}
733
+ assert_raises(NoMethodError) {
734
+ @mech.get('http://localhost/?foo=~2').links
735
+ }
736
+ end
737
+
738
+ def test_idle_timeout_equals
739
+ @mech.idle_timeout = 5
740
+
741
+ assert_equal 5, @mech.idle_timeout
742
+ end
743
+
744
+ def test_keep_alive_equals
745
+ assert @mech.keep_alive
746
+
747
+ @mech.keep_alive = false
748
+
749
+ refute @mech.keep_alive
750
+ end
751
+
752
+ def test_keep_alive_time
753
+ assert_equal 0, @mech.keep_alive_time
754
+
755
+ @mech.keep_alive_time = 1
756
+
757
+ assert_equal 1, @mech.keep_alive_time
758
+ end
759
+
760
+ def test_log
761
+ assert_nil @mech.log
762
+ end
763
+
764
+ def test_log_equals
765
+ @mech.log = Logger.new $stderr
766
+
767
+ refute_nil @mech.log
768
+ assert_nil Mechanize.log
769
+ end
770
+
771
+ def test_max_file_buffer_equals
772
+ @mech.max_file_buffer = 1024
773
+
774
+ assert_equal 1024, @mech.agent.max_file_buffer
775
+ end
776
+
777
+ def test_max_history_equals
778
+ @mech.max_history = 10
779
+ 0.upto(10) do |i|
780
+ assert_equal(i, @mech.history.size)
781
+ @mech.get("http://localhost/")
782
+ end
783
+
784
+ 0.upto(10) do |i|
785
+ assert_equal(10, @mech.history.size)
786
+ @mech.get("http://localhost/")
787
+ end
788
+ end
789
+
790
+ def test_open_timeout_equals
791
+ @mech.open_timeout = 5
792
+
793
+ assert_equal 5, @mech.open_timeout
794
+ end
795
+
796
+ def test_parse_download
797
+ @mech.pluggable_parser['application/octet-stream'] = Mechanize::Download
798
+
799
+ response = Net::HTTPOK.allocate
800
+ response.instance_variable_set(:@header,
801
+ 'content-type' =>
802
+ ['application/octet-stream'])
803
+
804
+ download = @mech.parse @uri, response, StringIO.new('raw')
805
+
806
+ assert_kind_of Mechanize::Download, download
807
+ assert_kind_of StringIO, download.content
808
+ end
809
+
810
+ def test_parse_html
811
+ response = Net::HTTPOK.allocate
812
+ response.instance_variable_set :@header, 'content-type' => ['text/html']
813
+
814
+ page = @mech.parse URI('http://example/'), response, ''
815
+
816
+ assert_kind_of Mechanize::Page, page
817
+ end
818
+
819
+ def test_post
820
+ @mech.post "http://example", 'gender' => 'female'
821
+
822
+ assert_equal "gender=female", requests.first.body
823
+ end
824
+
825
+ def test_post_basic_auth
826
+ requests = []
827
+
828
+ @mech.pre_connect_hooks << proc { |agent, request|
829
+ requests << request.class
830
+ }
831
+
832
+ @mech.basic_auth('user', 'pass')
833
+ page = @mech.post("http://localhost/basic_auth")
834
+ assert_equal('You are authenticated', page.body)
835
+ assert_equal(2, requests.length)
836
+ r1 = requests[0]
837
+ r2 = requests[1]
838
+ assert_equal(r1, r2)
839
+ end
840
+
841
+ def test_post_entity
842
+ @mech.post "http://localhost/form_post", 'json' => '["&quot;"]'
843
+
844
+ assert_equal "json=%5B%22%22%22%5D", requests.first.body
845
+ end
846
+
847
+ def test_post_multiple_values
848
+ @mech.post "http://localhost/form_post",
849
+ [%w[gender female], %w[gender male]]
850
+
851
+ assert_equal "gender=female&gender=male", requests.first.body
852
+ end
853
+
854
+ def test_post_multipart
855
+ page = @mech.post('http://localhost/file_upload', {
856
+ :name => 'Some file',
857
+ :userfile1 => File.open(__FILE__)
858
+ })
859
+
860
+ name = File.basename __FILE__
861
+ assert_match(
862
+ "Content-Disposition: form-data; name=\"userfile1\"; filename=\"#{name}\"",
863
+ page.body
864
+ )
865
+ assert page.body.length > File.read(__FILE__).length
866
+ end
867
+
868
+ def test_post_redirect
869
+ page = @mech.post('http://localhost/redirect')
870
+
871
+ assert_equal(page.uri.to_s, 'http://localhost/verb')
872
+
873
+ assert_equal 'GET', page.header['X-Request-Method']
874
+ end
875
+
876
+ def test_put
877
+ page = @mech.put('http://localhost/verb', 'foo')
878
+ assert_equal 1, @mech.history.length
879
+ assert_equal 'PUT', page.header['X-Request-Method']
880
+ end
881
+
882
+ def test_put_redirect
883
+ page = @mech.put('http://localhost/redirect', 'foo')
884
+
885
+ assert_equal(page.uri.to_s, 'http://localhost/verb')
886
+
887
+ assert_equal 'GET', page.header['X-Request-Method']
888
+ end
889
+
890
+ def test_read_timeout_equals
891
+ @mech.read_timeout = 5
892
+
893
+ assert_equal 5, @mech.read_timeout
894
+ end
895
+
896
+ def test_retry_change_requests_equals
897
+ refute @mech.retry_change_requests
898
+
899
+ @mech.retry_change_requests = true
900
+
901
+ assert @mech.retry_change_requests
902
+ end
903
+
904
+ def test_set_proxy
905
+ http = @mech.agent.http
906
+
907
+ @mech.set_proxy 'localhost', 8080, 'user', 'pass'
908
+
909
+ assert_equal 'localhost', @mech.proxy_addr
910
+ assert_equal 8080, @mech.proxy_port
911
+ assert_equal 'user', @mech.proxy_user
912
+ assert_equal 'pass', @mech.proxy_pass
913
+
914
+ refute_same http, @mech.agent.http
915
+ end
916
+
917
+ def test_submit_bad_form_method
918
+ page = @mech.get("http://localhost/bad_form_test.html")
919
+ assert_raises ArgumentError do
920
+ @mech.submit(page.forms.first)
921
+ end
922
+ end
923
+
924
+ def test_submit_check_one
925
+ page = @mech.get('http://localhost/tc_checkboxes.html')
926
+ form = page.forms.first
927
+ form.checkboxes_with(:name => 'green')[1].check
928
+
929
+ page = @mech.submit(form)
930
+
931
+ assert_equal(1, page.links.length)
932
+ assert_equal('green:on', page.links.first.text)
933
+ end
934
+
935
+ def test_submit_check_two
936
+ page = @mech.get('http://localhost/tc_checkboxes.html')
937
+ form = page.forms.first
938
+ form.checkboxes_with(:name => 'green')[0].check
939
+ form.checkboxes_with(:name => 'green')[1].check
940
+
941
+ page = @mech.submit(form)
942
+
943
+ assert_equal(2, page.links.length)
944
+ assert_equal('green:on', page.links[0].text)
945
+ assert_equal('green:on', page.links[1].text)
946
+ end
947
+
948
+ def test_submit_enctype
949
+ page = @mech.get("http://localhost/file_upload.html")
950
+ assert_equal('multipart/form-data', page.forms[0].enctype)
951
+
952
+ form = page.forms.first
953
+ form.file_uploads.first.file_name = __FILE__
954
+ form.file_uploads.first.mime_type = "text/plain"
955
+ form.file_uploads.first.file_data = "Hello World\n\n"
956
+
957
+ page = @mech.submit(form)
958
+
959
+ basename = File.basename __FILE__
960
+
961
+ assert_match(
962
+ "Content-Disposition: form-data; name=\"userfile1\"; filename=\"#{basename}\"",
963
+ page.body
964
+ )
965
+ assert_match(
966
+ "Content-Disposition: form-data; name=\"name\"",
967
+ page.body
968
+ )
969
+ assert_match('Content-Type: text/plain', page.body)
970
+ assert_match('Hello World', page.body)
971
+ assert_match('foo[aaron]', page.body)
972
+ end
973
+
974
+ def test_submit_file_data
975
+ page = @mech.get("http://localhost/file_upload.html")
976
+ assert_equal('multipart/form-data', page.forms[1].enctype)
977
+
978
+ form = page.forms[1]
979
+ form.file_uploads.first.file_name = __FILE__
980
+ form.file_uploads.first.file_data = File.read __FILE__
981
+
982
+ page = @mech.submit(form)
983
+
984
+ contents = File.read __FILE__
985
+ basename = File.basename __FILE__
986
+
987
+ assert_match(
988
+ "Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"#{basename}\"",
989
+ page.body
990
+ )
991
+
992
+ assert_match(contents, page.body)
993
+ end
994
+
995
+ def test_submit_file_name
996
+ page = @mech.get("http://localhost/file_upload.html")
997
+ assert_equal('multipart/form-data', page.forms[1].enctype)
998
+
999
+ form = page.forms[1]
1000
+ form.file_uploads.first.file_name = __FILE__
1001
+
1002
+ page = @mech.submit(form)
1003
+
1004
+ contents = File.read __FILE__
1005
+ basename = File.basename __FILE__
1006
+ assert_match(
1007
+ "Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"#{basename}\"",
1008
+ page.body
1009
+ )
1010
+ assert_match(contents, page.body)
1011
+ end
1012
+
1013
+ def test_submit_get
1014
+ form = node 'form', 'method' => 'GET', 'action' => '/?a=b'
1015
+ form = Mechanize::Form.new form, @mech, fake_page
1016
+
1017
+ @mech.submit form
1018
+
1019
+ assert_equal '/', requests.first.path
1020
+ end
1021
+
1022
+ def test_submit_headers
1023
+ page = @mech.get 'http://localhost:2000/form_no_action.html'
1024
+
1025
+ assert form = page.forms.first
1026
+ form.action = '/http_headers'
1027
+
1028
+ page = @mech.submit form, nil, 'foo' => 'bar'
1029
+
1030
+ headers = page.body.split("\n").map { |x| x.split('|', 2) }.flatten
1031
+ headers = Hash[*headers]
1032
+
1033
+ assert_equal 'bar', headers['foo']
1034
+ end
1035
+
1036
+ def test_submit_multipart
1037
+ page = @mech.get("http://localhost/file_upload.html")
1038
+
1039
+ assert_equal('multipart/form-data', page.forms[1].enctype)
1040
+
1041
+ form = page.forms[1]
1042
+ form.file_uploads.first.file_name = __FILE__
1043
+ form.file_uploads.first.mime_type = "text/plain"
1044
+ form.file_uploads.first.file_data = "Hello World\n\n"
1045
+
1046
+ page = @mech.submit(form)
1047
+
1048
+ basename = File.basename __FILE__
1049
+
1050
+ assert_match(
1051
+ "Content-Disposition: form-data; name=\"green[eggs]\"; filename=\"#{basename}\"",
1052
+ page.body
1053
+ )
1054
+ end
1055
+
1056
+ def test_submit_no_file
1057
+ page = @mech.get("http://localhost/file_upload.html")
1058
+ form = page.forms.first
1059
+ form.field_with(:name => 'name').value = 'Aaron'
1060
+ @page = @mech.submit(form)
1061
+ assert_match('Aaron', @page.body)
1062
+ assert_match(
1063
+ "Content-Disposition: form-data; name=\"userfile1\"; filename=\"\"",
1064
+ @page.body
1065
+ )
1066
+ end
1067
+
1068
+ def test_submit_post
1069
+ form = node 'form', 'method' => 'POST', 'action' => '/?a=b'
1070
+ form = Mechanize::Form.new form, @mech, fake_page
1071
+
1072
+ @mech.submit form
1073
+
1074
+ assert_equal '/?a=b', requests.first.path
1075
+ end
1076
+
1077
+ def test_submit_post_pound
1078
+ form = node 'form', 'method' => 'POST', 'action' => '/#1'
1079
+ form = Mechanize::Form.new form, @mech, fake_page
1080
+
1081
+ @mech.submit form
1082
+
1083
+ assert_equal '/', requests.first.path
1084
+ end
1085
+
1086
+ def test_submit_too_many_radiobuttons
1087
+ page = @mech.get("http://localhost/form_test.html")
1088
+ form = page.form_with(:name => 'post_form1')
1089
+ form.radiobuttons.each { |r| r.checked = true }
1090
+
1091
+ assert_raises Mechanize::Error do
1092
+ @mech.submit(form)
1093
+ end
1094
+ end
1095
+
1096
+ def test_transact
1097
+ @mech.get("http://localhost/frame_test.html")
1098
+ assert_equal(1, @mech.history.length)
1099
+ @mech.transact { |a|
1100
+ 5.times {
1101
+ @mech.get("http://localhost/frame_test.html")
1102
+ }
1103
+ assert_equal(6, @mech.history.length)
1104
+ }
1105
+ assert_equal(1, @mech.history.length)
1106
+ end
1107
+
1108
+ def test_user_agent_alias_equals_unknown
1109
+ assert_raises ArgumentError do
1110
+ @mech.user_agent_alias = "Aaron's Browser"
1111
+ end
1112
+ end
1113
+
1114
+ def test_verify_mode
1115
+ assert_equal OpenSSL::SSL::VERIFY_PEER, @mech.verify_mode
1116
+
1117
+ @mech.verify_mode = OpenSSL::SSL::VERIFY_NONE
1118
+
1119
+ assert_equal OpenSSL::SSL::VERIFY_NONE, @mech.verify_mode
1120
+ end
1121
+
1122
+ def test_visited_eh
1123
+ @mech.get("http://localhost/content_type_test?ct=application/pdf")
1124
+
1125
+ assert \
1126
+ @mech.visited?("http://localhost/content_type_test?ct=application/pdf")
1127
+ assert \
1128
+ !@mech.visited?("http://localhost/content_type_test")
1129
+ assert \
1130
+ !@mech.visited?("http://localhost/content_type_test?ct=text/html")
1131
+ end
1132
+
1133
+ def test_visited_eh_link
1134
+ @mech.get("http://example/index.html")
1135
+
1136
+ page = page URI 'http://example'
1137
+ link = node 'a', 'href' => '/index.html'
1138
+ link = Mechanize::Page::Link.new link, page, @mech
1139
+
1140
+ assert @mech.visited? link
1141
+ end
1142
+
1143
+ def test_visited_eh_redirect
1144
+ @mech.get("http://localhost/response_code?code=302")
1145
+
1146
+ assert_equal("http://localhost/index.html", @mech.current_page.uri.to_s)
1147
+
1148
+ assert @mech.visited?('http://localhost/response_code?code=302')
1149
+ end
1150
+
1151
+ def assert_header(page, header)
1152
+ headers = {}
1153
+
1154
+ page.body.split(/[\r\n]+/).each do |page_header|
1155
+ headers.[]=(*page_header.chomp.split(/\|/))
1156
+ end
1157
+
1158
+ header.each do |key, value|
1159
+ assert(headers.has_key?(key))
1160
+ assert_equal(value, headers[key])
1161
+ end
1162
+ end
1163
+ end
1164
+