mechanize 1.0.0 → 1.0.1.beta.20110107104205

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 (53) hide show
  1. data/CHANGELOG.rdoc +19 -0
  2. data/EXAMPLES.rdoc +13 -13
  3. data/Manifest.txt +0 -1
  4. data/Rakefile +4 -9
  5. data/lib/mechanize/chain/body_decoding_handler.rb +2 -0
  6. data/lib/mechanize/chain/connection_resolver.rb +6 -55
  7. data/lib/mechanize/chain/header_resolver.rb +3 -12
  8. data/lib/mechanize/chain/parameter_resolver.rb +2 -2
  9. data/lib/mechanize/chain/request_resolver.rb +1 -0
  10. data/lib/mechanize/chain/response_body_parser.rb +4 -6
  11. data/lib/mechanize/chain/response_header_handler.rb +1 -15
  12. data/lib/mechanize/chain/uri_resolver.rb +2 -2
  13. data/lib/mechanize/chain.rb +4 -1
  14. data/lib/mechanize/cookie.rb +1 -1
  15. data/lib/mechanize/file.rb +7 -0
  16. data/lib/mechanize/form/field.rb +6 -0
  17. data/lib/mechanize/form.rb +16 -4
  18. data/lib/mechanize/headers.rb +14 -0
  19. data/lib/mechanize/page/link.rb +7 -1
  20. data/lib/mechanize/page/meta.rb +3 -5
  21. data/lib/mechanize/page.rb +17 -4
  22. data/lib/mechanize/util.rb +8 -4
  23. data/lib/mechanize.rb +82 -56
  24. data/test/chain/test_header_resolver.rb +0 -2
  25. data/test/chain/test_parameter_resolver.rb +1 -1
  26. data/test/helper.rb +20 -13
  27. data/test/htdocs/form_multival.html +2 -2
  28. data/test/htdocs/form_test.html +2 -2
  29. data/test/htdocs/tc_links.html +1 -1
  30. data/test/htdocs/tc_referer.html +2 -0
  31. data/test/servlets.rb +41 -5
  32. data/test/test_authenticate.rb +3 -3
  33. data/test/test_cookies.rb +10 -4
  34. data/test/test_errors.rb +1 -1
  35. data/test/test_field_precedence.rb +4 -1
  36. data/test/test_follow_meta.rb +3 -3
  37. data/test/test_form_button.rb +8 -0
  38. data/test/test_forms.rb +63 -42
  39. data/test/test_gzipping.rb +1 -1
  40. data/test/test_headers.rb +33 -0
  41. data/test/test_history.rb +2 -2
  42. data/test/test_history_added.rb +1 -1
  43. data/test/test_links.rb +9 -0
  44. data/test/test_mech.rb +22 -7
  45. data/test/test_mech_proxy.rb +4 -4
  46. data/test/test_meta.rb +5 -3
  47. data/test/test_no_attributes.rb +1 -1
  48. data/test/test_referer.rb +21 -3
  49. data/test/test_relative_links.rb +4 -4
  50. data/test/test_response_code.rb +1 -1
  51. data/test/test_scheme.rb +7 -0
  52. metadata +61 -18
  53. data/test/test_keep_alive.rb +0 -31
data/lib/mechanize.rb CHANGED
@@ -1,5 +1,5 @@
1
- require 'net/http'
2
- require 'net/https'
1
+ require 'openssl'
2
+ require 'net/http/persistent'
3
3
  require 'uri'
4
4
  require 'webrick/httputils'
5
5
  require 'zlib'
@@ -8,7 +8,9 @@ require 'digest/md5'
8
8
  require 'fileutils'
9
9
  require 'nokogiri'
10
10
  require 'forwardable'
11
- require 'iconv'
11
+
12
+ require 'iconv' if RUBY_VERSION < '1.9.2'
13
+
12
14
  require 'nkf'
13
15
  require 'mutex_m'
14
16
 
@@ -48,7 +50,7 @@ require 'mechanize/monkey_patch'
48
50
  class Mechanize
49
51
  ##
50
52
  # The version of Mechanize you are using.
51
- VERSION = '1.0.0'
53
+ VERSION = '1.0.1.beta'
52
54
 
53
55
  ##
54
56
  # User Agent aliases
@@ -74,7 +76,14 @@ class Mechanize
74
76
  attr_accessor :key
75
77
  attr_accessor :cert
76
78
  attr_accessor :pass
79
+
80
+ # Controls how this agent deals with redirects. If it is set to
81
+ # true or :all, all 3xx redirects are automatically followed. This
82
+ # is the default behavior. If it is :permanent, only 301 (Moved
83
+ # Permanently) redirects are followed. If it is a false value, no
84
+ # redirects are followed.
77
85
  attr_accessor :redirect_ok
86
+
78
87
  attr_accessor :gzip_enabled
79
88
  attr_accessor :keep_alive_time
80
89
  attr_accessor :keep_alive
@@ -97,6 +106,8 @@ class Mechanize
97
106
  # The HTML parser to be used when parsing documents
98
107
  attr_accessor :html_parser
99
108
 
109
+ attr_reader :http # :nodoc:
110
+
100
111
  attr_reader :history
101
112
  attr_reader :pluggable_parser
102
113
 
@@ -131,7 +142,7 @@ class Mechanize
131
142
  @cert = nil # OpenSSL Certificate
132
143
  @key = nil # OpenSSL Private Key
133
144
  @pass = nil # OpenSSL Password
134
- @redirect_ok = true # Should we follow redirects?
145
+ @redirect_ok = true
135
146
  @gzip_enabled = true
136
147
 
137
148
  # attr_readers
@@ -145,19 +156,12 @@ class Mechanize
145
156
  @auth_hash = {} # Keep track of urls for sending auth
146
157
  @request_headers= {} # A hash of request headers to be used
147
158
 
148
- # Proxy settings
149
- @proxy_addr = nil
150
- @proxy_pass = nil
151
- @proxy_port = nil
152
- @proxy_user = nil
153
-
154
159
  @conditional_requests = true
155
160
 
156
161
  @follow_meta_refresh = false
157
162
  @redirection_limit = 20
158
163
 
159
164
  # Connection Cache & Keep alive
160
- @connection_cache = {}
161
165
  @keep_alive_time = 300
162
166
  @keep_alive = true
163
167
 
@@ -174,6 +178,7 @@ class Mechanize
174
178
  @pre_connect_hook = Chain::PreConnectHook.new
175
179
  @post_connect_hook = Chain::PostConnectHook.new
176
180
 
181
+ set_http
177
182
  @html_parser = self.class.html_parser
178
183
 
179
184
  yield self if block_given?
@@ -195,7 +200,14 @@ class Mechanize
195
200
  # Sets the proxy address, port, user, and password
196
201
  # +addr+ should be a host, with no "http://"
197
202
  def set_proxy(addr, port, user = nil, pass = nil)
198
- @proxy_addr, @proxy_port, @proxy_user, @proxy_pass = addr, port, user, pass
203
+ proxy = URI.parse "http://#{addr}"
204
+ proxy.port = port
205
+ proxy.user = user if user
206
+ proxy.password = pass if pass
207
+
208
+ set_http proxy
209
+
210
+ nil
199
211
  end
200
212
 
201
213
  # Set the user agent for the Mechanize object.
@@ -235,7 +247,7 @@ class Mechanize
235
247
  end
236
248
 
237
249
  unless referer
238
- if url.to_s =~ /^http/
250
+ if url.to_s =~ %r{\Ahttps?://}
239
251
  referer = Page.new(nil, {'content-type'=>'text/html'})
240
252
  else
241
253
  referer = current_page || Page.new(nil, {'content-type'=>'text/html'})
@@ -306,13 +318,28 @@ class Mechanize
306
318
  get(url).body
307
319
  end
308
320
 
309
- # Clicks the Mechanize::Link object passed in and returns the
310
- # page fetched.
321
+ # If the parameter is a string, finds the button or link with the
322
+ # value of the string and clicks it. Otherwise, clicks the
323
+ # Mechanize::Page::Link object passed in. Returns the page fetched.
311
324
  def click(link)
312
- referer = link.page rescue referer = nil
313
- href = link.respond_to?(:href) ? link.href :
314
- (link['href'] || link['src'])
315
- get(:url => href, :referer => (referer || current_page()))
325
+ case link
326
+ when String, Regexp
327
+ if real_link = page.link_with(:text => link)
328
+ click real_link
329
+ else
330
+ button = nil
331
+ form = page.forms.find do |f|
332
+ button = f.button_with(:value => link)
333
+ button.is_a? Form::Submit
334
+ end
335
+ submit form, button if form
336
+ end
337
+ else
338
+ referer = link.page rescue referer = nil
339
+ href = link.respond_to?(:href) ? link.href :
340
+ (link['href'] || link['src'])
341
+ get(:url => href, :referer => (referer || current_page()))
342
+ end
316
343
  end
317
344
 
318
345
  # Equivalent to the browser back button. Returns the most recent page
@@ -439,12 +466,26 @@ class Mechanize
439
466
 
440
467
  def resolve(url, referer = current_page())
441
468
  hash = { :uri => url, :referer => referer }
442
- chain = Chain.new([
469
+ Chain.new([
443
470
  Chain::URIResolver.new(@scheme_handlers)
444
471
  ]).handle(hash)
445
472
  hash[:uri].to_s
446
473
  end
447
474
 
475
+ def set_http proxy = nil
476
+ @http = Net::HTTP::Persistent.new 'mechanize', proxy
477
+
478
+ @http.keep_alive = @keep_alive_time
479
+
480
+ @http.ca_file = @ca_file
481
+ @http.verify_callback = @verify_callback
482
+
483
+ if @cert and @key then
484
+ @http.certificate = OpenSSL::X509::Certificate.new ::File.read(@cert)
485
+ @http.private_key = OpenSSL::PKey::RSA.new ::File.read(@key), @pass
486
+ end
487
+ end
488
+
448
489
  def post_form(url, form, headers = {})
449
490
  cur_page = form.page || current_page ||
450
491
  Page.new( nil, {'content-type'=>'text/html'})
@@ -485,19 +526,9 @@ class Mechanize
485
526
  Chain::URIResolver.new(@scheme_handlers),
486
527
  Chain::ParameterResolver.new,
487
528
  Chain::RequestResolver.new,
488
- Chain::ConnectionResolver.new(
489
- @connection_cache,
490
- @keep_alive,
491
- @proxy_addr,
492
- @proxy_port,
493
- @proxy_user,
494
- @proxy_pass
495
- ),
496
- Chain::SSLResolver.new(@ca_file, @verify_callback, @cert, @key, @pass),
529
+ Chain::ConnectionResolver.new,
497
530
  Chain::AuthHeaders.new(@auth_hash, @user, @password, @digest),
498
531
  Chain::HeaderResolver.new(
499
- @keep_alive,
500
- @keep_alive_time,
501
532
  @cookie_jar,
502
533
  @user_agent,
503
534
  @gzip_enabled,
@@ -505,7 +536,8 @@ class Mechanize
505
536
  ),
506
537
  Chain::CustomHeaders.new,
507
538
  @pre_connect_hook,
508
- ])
539
+ ], @http)
540
+
509
541
  before_connect.handle(options)
510
542
 
511
543
  uri = options[:uri]
@@ -520,11 +552,9 @@ class Mechanize
520
552
  request['If-Modified-Since'] = page.response['Last-Modified']
521
553
  end if(@conditional_requests)
522
554
 
523
- http_obj.mu_lock
524
555
  # Specify timeouts if given
525
556
  http_obj.open_timeout = @open_timeout if @open_timeout
526
557
  http_obj.read_timeout = @read_timeout if @read_timeout
527
- http_obj.start unless http_obj.started?
528
558
 
529
559
  # Log specified headers for the request
530
560
  log.info("#{ request.class }: #{ request.path }") if log
@@ -533,32 +563,20 @@ class Mechanize
533
563
  end if log
534
564
 
535
565
  # Send the request
536
- attempts = 0
537
- begin
538
- response = http_obj.request(request, *request_data) { |r|
539
- connection_chain = Chain.new([
540
- Chain::ResponseReader.new(r),
541
- Chain::BodyDecodingHandler.new,
542
- ])
543
- connection_chain.handle(options)
544
- }
545
- rescue EOFError, Errno::ECONNRESET, Errno::EPIPE => x
546
- log.error("Rescuing EOF error") if log
547
- http_obj.finish
548
- raise x if attempts >= 2
549
- request.body = nil
550
- http_obj.start
551
- attempts += 1
552
- retry
553
- end
566
+ response = http_obj.request(uri, request) { |r|
567
+ connection_chain = Chain.new([
568
+ Chain::ResponseReader.new(r),
569
+ Chain::BodyDecodingHandler.new,
570
+ ])
571
+ connection_chain.handle(options)
572
+ }
554
573
 
555
574
  after_connect = Chain.new([
556
575
  @post_connect_hook,
557
576
  Chain::ResponseBodyParser.new(@pluggable_parser, @watch_for_set),
558
- Chain::ResponseHeaderHandler.new(@cookie_jar, @connection_cache),
577
+ Chain::ResponseHeaderHandler.new(@cookie_jar),
559
578
  ])
560
579
  after_connect.handle(options)
561
- http_obj.mu_unlock
562
580
 
563
581
  res_klass = options[:res_klass]
564
582
  response_body = options[:response_body]
@@ -581,6 +599,7 @@ class Mechanize
581
599
  end
582
600
  sleep delay.to_f
583
601
  end
602
+
584
603
  if redirect_uri
585
604
  @history.push(page, page.uri)
586
605
  return fetch_page(
@@ -599,7 +618,14 @@ class Mechanize
599
618
  log.debug("Got cached page") if log
600
619
  return visited_page(uri) || page
601
620
  elsif res_klass <= Net::HTTPRedirection
602
- return page unless follow_redirect?
621
+ case redirect_ok
622
+ when true, :all
623
+ # shortcut
624
+ when false, nil
625
+ return page
626
+ when :permanent
627
+ return page if res_klass != Net::HTTPMovedPermanently
628
+ end
603
629
  log.info("follow redirect to: #{ response['Location'] }") if log
604
630
  from_uri = page.uri
605
631
  raise RedirectLimitReachedError.new(page, redirects) if redirects + 1 > redirection_limit
@@ -4,8 +4,6 @@ class TestHeaderResolver < Test::Unit::TestCase
4
4
  def setup
5
5
  @chain = Mechanize::Chain.new([
6
6
  Mechanize::Chain::HeaderResolver.new(
7
- true,
8
- 300,
9
7
  Mechanize::CookieJar.new,
10
8
  'foobar',
11
9
  true,
@@ -14,7 +14,7 @@ class TestParameterResolver < Test::Unit::TestCase
14
14
  v.handle(hash)
15
15
  }
16
16
  assert_equal('q=hello', hash[:uri].query)
17
- assert_equal([], hash[:params])
17
+ assert_nil(hash[:params])
18
18
  end
19
19
 
20
20
  def test_handle_post
data/test/helper.rb CHANGED
@@ -15,7 +15,7 @@ module MechTestHelper
15
15
  </body></html>
16
16
  END
17
17
  html_response = { 'content-type' => 'text/html' }
18
- page = Mechanize::Page.new( nil, html_response, html, 200, agent )
18
+ Mechanize::Page.new( nil, html_response, html, 200, agent )
19
19
  end
20
20
  end
21
21
 
@@ -42,10 +42,12 @@ class Net::HTTP
42
42
  '/many_cookies' => ManyCookiesTest,
43
43
  '/many_cookies_as_string' => ManyCookiesAsStringTest,
44
44
  '/send_cookies' => SendCookiesTest,
45
+ '/quoted_value_cookie' => QuotedValueCookieTest,
45
46
  '/if_modified_since' => ModifiedSinceServlet,
46
47
  '/http_headers' => HeaderServlet,
47
48
  '/infinite_redirect' => InfiniteRedirectTest,
48
49
  '/infinite_refresh' => InfiniteRefreshTest,
50
+ '/redirect_ok' => RedirectOkTest,
49
51
  '/redirect' => RedirectTest,
50
52
  '/refresh_without_url' => RefreshWithoutUrl,
51
53
  '/refresh_with_empty_url' => RefreshWithEmptyUrl,
@@ -59,32 +61,36 @@ class Net::HTTP
59
61
 
60
62
  def request(request, *data, &block)
61
63
  url = URI.parse(request.path)
62
- path = URI.unescape(url.path)
64
+ path = WEBrick::HTTPUtils.unescape(url.path)
63
65
 
64
66
  path = '/index.html' if path == '/'
65
67
 
66
68
  res = Response.new
67
69
  res.query_params = url.query
68
70
 
69
- request.query = WEBrick::HTTPUtils.parse_query(url.query)
71
+ request.query = if 'POST' != request.method && url.query then
72
+ WEBrick::HTTPUtils.parse_query url.query
73
+ elsif request['content-type'] =~ /www-form-urlencoded/ then
74
+ WEBrick::HTTPUtils.parse_query request.body
75
+ elsif request['content-type'] =~ /boundary=(.+)/ then
76
+ boundary = WEBrick::HTTPUtils.dequote $1
77
+ WEBrick::HTTPUtils.parse_form_data request.body, boundary
78
+ else
79
+ {}
80
+ end
81
+
70
82
  request.cookies = WEBrick::Cookie.parse(request['Cookie'])
83
+
71
84
  if SERVLETS[path]
72
- if request.method == "POST"
73
- if request['Content-Type'] =~ /^multipart\/form-data/
74
- request.body = data.first
75
- else
76
- request.query = WEBrick::HTTPUtils.parse_query(data.first)
77
- res.query_params = data.first
78
- end
79
- end
80
85
  SERVLETS[path].new({}).send("do_#{request.method}", request, res)
81
86
  else
82
- filename = "htdocs#{path.gsub(/[^\/\\.\w_\s]/, '_')}"
87
+ filename = "htdocs#{path.gsub(/[^\/\\.\w\s]/, '_')}"
83
88
  unless PAGE_CACHE[filename]
84
89
  File.open("#{BASE_DIR}/#{filename}", 'rb') { |file|
85
90
  PAGE_CACHE[filename] = file.read
86
91
  }
87
92
  end
93
+
88
94
  res.body = PAGE_CACHE[filename]
89
95
  end
90
96
 
@@ -109,7 +115,7 @@ class Response
109
115
 
110
116
  attr_reader :code
111
117
  attr_accessor :body, :query, :cookies
112
- attr_accessor :query_params
118
+ attr_accessor :query_params, :http_version
113
119
 
114
120
  def code=(c)
115
121
  @code = c.to_s
@@ -124,6 +130,7 @@ class Response
124
130
  @code = nil
125
131
  @query = nil
126
132
  @cookies = []
133
+ @http_version = '1.1'
127
134
  end
128
135
 
129
136
  def read_body
@@ -1,11 +1,11 @@
1
1
  <html>
2
2
  <head><title>Page Title</title></head>
3
3
  <body>
4
- <form name="post_form" method="post" action="/form_post">
4
+ <form name="post_form" id="user_post_form" method="post" action="/form_post">
5
5
  <table>
6
6
  <tr>
7
7
  <td>First Name</td>
8
- <td><input name="first" type="text" /></td>
8
+ <td><input name="first" type="text" id="name_first" /></td>
9
9
  </tr>
10
10
  <tr>
11
11
  <td>First Name Again</td>
@@ -2,11 +2,11 @@
2
2
  <head><title>Page Title</title></head>
3
3
  <body>
4
4
  <h1>Post Form 1</h1>
5
- <form name="post_form1" method="post" action="/form_post">
5
+ <form name="post_form1" method="post" action="/form_post" id="generic_form" >
6
6
  <table>
7
7
  <tr>
8
8
  <td>First Name</td>
9
- <td><input type="text" name="first_name" /></td>
9
+ <td><input type="text" name="first_name" id="name_first" /></td>
10
10
  </tr>
11
11
  <tr>
12
12
  <td>Gender</td>
@@ -3,7 +3,7 @@
3
3
  <a href="thing.html"><b>Bold Dude</b></a>
4
4
  <a href="thing.html">Dude</a>
5
5
  <a href="thing.html">Aaron <b>James</b> Patterson</a>
6
- <a href="thing.html"><b>Aaron</b> Patterson</a>
6
+ <a href="thing.html" id="bold_aaron_link"><b>Aaron</b> Patterson</a>
7
7
  <a href="thing.html">Ruby <b>Rocks!</b></a>
8
8
  <!-- Testing a bug with escaped stuff in links:
9
9
  http://rubyforge.org/pipermail/mechanize-users/2006-September/000002.html
@@ -1,6 +1,8 @@
1
1
  <html>
2
2
  <body>
3
3
  <a href="/referer">Referer Servlet</a>
4
+ <a href="http://localhost/referer">Referer Servlet forced to http</a>
5
+ <a href="https://localhost/referer">Referer Servlet forced to https</a>
4
6
  <br />
5
7
  <form method="post" action="/referer">
6
8
  <input type="text" name="first" /></br>
data/test/servlets.rb CHANGED
@@ -28,7 +28,7 @@ class BasicAuthServlet < WEBrick::HTTPServlet::AbstractServlet
28
28
  begin
29
29
  authenticator.authenticate(req,res)
30
30
  res.body = 'You are authenticated'
31
- rescue WEBrick::HTTPStatus::Unauthorized => ex
31
+ rescue WEBrick::HTTPStatus::Unauthorized
32
32
  res.status = 401
33
33
  end
34
34
  FileUtils.rm('dot.htpasswd')
@@ -54,7 +54,7 @@ class DigestAuthServlet < WEBrick::HTTPServlet::AbstractServlet
54
54
  begin
55
55
  @@authenticator.authenticate(req,res)
56
56
  res.body = 'You are authenticated'
57
- rescue WEBrick::HTTPStatus::Unauthorized => ex
57
+ rescue WEBrick::HTTPStatus::Unauthorized
58
58
  res.status = 401
59
59
  end
60
60
  FileUtils.rm('digest.htpasswd') if File.exists?('digest.htpasswd')
@@ -200,6 +200,29 @@ class InfiniteRedirectTest < WEBrick::HTTPServlet::AbstractServlet
200
200
  alias :do_POST :do_GET
201
201
  end
202
202
 
203
+ class RedirectOkTest < WEBrick::HTTPServlet::AbstractServlet
204
+ def do_GET(req, res)
205
+ res['Content-Type'] = "text/plain"
206
+ case q = req.query['q']
207
+ when '1'..'2'
208
+ res.status = '301'
209
+ q.succ!
210
+ when '3'..'4'
211
+ res.status = '302'
212
+ q.succ!
213
+ when '5'
214
+ res.status = '200'
215
+ res.body = 'Finally OK.'
216
+ return
217
+ else
218
+ res.status = '301'
219
+ q = '1'
220
+ end
221
+ res['Location'] = "/redirect_ok?q=#{q}"
222
+ end
223
+ alias :do_POST :do_GET
224
+ end
225
+
203
226
  class RedirectTest < WEBrick::HTTPServlet::AbstractServlet
204
227
  def do_GET(req, res)
205
228
  res['Content-Type'] = req.query['ct'] || "text/html"
@@ -242,7 +265,7 @@ class FormTest < WEBrick::HTTPServlet::AbstractServlet
242
265
  res.body = "<HTML><body>"
243
266
  req.query.each_key { |k|
244
267
  req.query[k].each_data { |data|
245
- res.body << "<a href=\"#\">#{URI.unescape(k)}:#{URI.unescape(data)}</a><br />"
268
+ res.body << "<a href=\"#\">#{WEBrick::HTTPUtils.unescape(k)}:#{WEBrick::HTTPUtils.unescape(data)}</a><br />"
246
269
  }
247
270
  }
248
271
  res.body << "<div id=\"query\">#{res.query}</div></body></HTML>"
@@ -251,12 +274,14 @@ class FormTest < WEBrick::HTTPServlet::AbstractServlet
251
274
 
252
275
  def do_POST(req, res)
253
276
  res.body = "<HTML><body>"
277
+
254
278
  req.query.each_key { |k|
255
279
  req.query[k].each_data { |data|
256
280
  res.body << "<a href=\"#\">#{k}:#{data}</a><br />"
257
281
  }
258
282
  }
259
- res.body << "<div id=\"query\">#{res.query_params}</div></body></HTML>"
283
+
284
+ res.body << "<div id=\"query\">#{req.body}</div></body></HTML>"
260
285
  res['Content-Type'] = "text/html"
261
286
  end
262
287
  end
@@ -357,9 +382,20 @@ class SendCookiesTest < WEBrick::HTTPServlet::AbstractServlet
357
382
  def do_GET(req, res)
358
383
  res['Content-Type'] = "text/html"
359
384
  res.body = "<html><body>"
360
- req.cookies.each { |c|
385
+ req.cookies.each { |c|
361
386
  res.body << "<a href=\"#\">#{c.name}:#{c.value}</a>"
362
387
  }
363
388
  res.body << "</body></html>"
364
389
  end
365
390
  end
391
+
392
+ class QuotedValueCookieTest < WEBrick::HTTPServlet::AbstractServlet
393
+ def do_GET(req, res)
394
+ cookie = WEBrick::Cookie.new("quoted", "\"value\"")
395
+ cookie.path = "/"
396
+ cookie.expires = Time.now + 86400
397
+ res.cookies << cookie
398
+ res['Content-Type'] = "text/html"
399
+ res.body = "<html><body>hello</body></html>"
400
+ end
401
+ end
@@ -27,7 +27,7 @@ class BasicAuthTest < Test::Unit::TestCase
27
27
  end
28
28
  }
29
29
  @agent.basic_auth('user', 'pass')
30
- page = @agent.get("http://localhost/digest_auth")
30
+ @agent.get("http://localhost/digest_auth")
31
31
  assert block_called
32
32
  end
33
33
 
@@ -54,7 +54,7 @@ class BasicAuthTest < Test::Unit::TestCase
54
54
  def test_auth_bad_user_pass
55
55
  @agent.basic_auth('aaron', 'aaron')
56
56
  begin
57
- page = @agent.get("http://localhost/basic_auth")
57
+ @agent.get("http://localhost/basic_auth")
58
58
  rescue Mechanize::ResponseCodeError => e
59
59
  assert_equal("401", e.response_code)
60
60
  end
@@ -62,7 +62,7 @@ class BasicAuthTest < Test::Unit::TestCase
62
62
 
63
63
  def test_auth_failure
64
64
  begin
65
- page = @agent.get("http://localhost/basic_auth")
65
+ @agent.get("http://localhost/basic_auth")
66
66
  rescue Mechanize::ResponseCodeError => e
67
67
  assert_equal("401", e.response_code)
68
68
  end
data/test/test_cookies.rb CHANGED
@@ -5,9 +5,15 @@ class CookiesMechTest < Test::Unit::TestCase
5
5
  @agent = Mechanize.new
6
6
  end
7
7
 
8
+ def test_quoted_value_cookie
9
+ @agent.get("http://localhost/quoted_value_cookie")
10
+ quoted_cookie = @agent.cookies.find { |k| k.name == 'quoted' }
11
+ assert_equal("\"value\"", quoted_cookie.value)
12
+ end
13
+
8
14
  def test_meta_tag_cookies
9
15
  cookies = @agent.cookies.length
10
- page = @agent.get("http://localhost/meta_cookie.html")
16
+ @agent.get("http://localhost/meta_cookie.html")
11
17
  assert_equal(cookies + 1, @agent.cookies.length)
12
18
  end
13
19
 
@@ -20,7 +26,7 @@ class CookiesMechTest < Test::Unit::TestCase
20
26
  end
21
27
 
22
28
  def test_no_space_cookies
23
- page = @agent.get("http://localhost/one_cookie_no_space")
29
+ @agent.get("http://localhost/one_cookie_no_space")
24
30
  assert_equal(1, @agent.cookies.length)
25
31
  foo_cookie = @agent.cookies.find { |k| k.name == 'foo' }
26
32
  assert_not_nil(foo_cookie, 'Foo cookie was nil')
@@ -30,7 +36,7 @@ class CookiesMechTest < Test::Unit::TestCase
30
36
  end
31
37
 
32
38
  def test_many_cookies_as_string
33
- page = @agent.get("http://localhost/many_cookies_as_string")
39
+ @agent.get("http://localhost/many_cookies_as_string")
34
40
  assert_equal(4, @agent.cookies.length)
35
41
 
36
42
  name_cookie = @agent.cookies.find { |k| k.name == "name" }
@@ -61,7 +67,7 @@ class CookiesMechTest < Test::Unit::TestCase
61
67
  end
62
68
 
63
69
  def test_many_cookies
64
- page = @agent.get("http://localhost/many_cookies")
70
+ @agent.get("http://localhost/many_cookies")
65
71
  assert_equal(4, @agent.cookies.length)
66
72
 
67
73
  name_cookie = @agent.cookies.find { |k| k.name == "name" }
data/test/test_errors.rb CHANGED
@@ -14,7 +14,7 @@ class MechErrorsTest < Test::Unit::TestCase
14
14
 
15
15
  def test_non_exist
16
16
  begin
17
- page = @agent.get("http://localhost/bad_form_test.html")
17
+ @agent.get("http://localhost/bad_form_test.html")
18
18
  rescue RuntimeError => ex
19
19
  assert_equal("404", ex.inspect)
20
20
  end
@@ -10,7 +10,10 @@ class TestFieldPrecedence < Test::Unit::TestCase
10
10
  form = @page.forms.first
11
11
  assert !form.checkboxes.empty?
12
12
  assert_equal "1", form.checkboxes.first.value
13
- assert_equal 'ticky=1&ticky=0', form.submit.parser.at('#query').text
13
+
14
+ submitted = form.submit
15
+
16
+ assert_equal 'ticky=1&ticky=0', submitted.parser.at('#query').text
14
17
  end
15
18
 
16
19
  def test_field_sort
@@ -12,7 +12,7 @@ class FollowMetaTest < Test::Unit::TestCase
12
12
  requests << params[:request]
13
13
  }
14
14
 
15
- page = @agent.get('http://localhost/tc_meta_in_body.html')
15
+ @agent.get('http://localhost/tc_meta_in_body.html')
16
16
  assert_equal 1, requests.length
17
17
  end
18
18
 
@@ -29,7 +29,7 @@ class FollowMetaTest < Test::Unit::TestCase
29
29
  requests << params[:request]
30
30
  }
31
31
 
32
- page = @agent.get('http://localhost/tc_follow_meta.html')
32
+ @agent.get('http://localhost/tc_follow_meta.html')
33
33
  assert_nil requests[1]['referer']
34
34
  end
35
35
 
@@ -112,7 +112,7 @@ class FollowMetaTest < Test::Unit::TestCase
112
112
  end
113
113
  end
114
114
 
115
- page = @agent.get('http://localhost/http_refresh?refresh_time=1')
115
+ @agent.get('http://localhost/http_refresh?refresh_time=1')
116
116
  assert_equal [1], @agent.slept
117
117
  end
118
118
 
@@ -21,6 +21,14 @@ class TestFormButtons < Test::Unit::TestCase
21
21
  assert_form_contains_button('<button type="button" value="submit"/>')
22
22
  end
23
23
 
24
+ def test_image_button_tag
25
+ assert_form_contains_button('<input type="image" name="submit" src="http://foo.com/image.jpg"/>')
26
+ end
27
+
28
+ def test_no_name_image_button_tag
29
+ assert_form_contains_button('<input type="image" src="http://foo.com/image.jpg"/>')
30
+ end
31
+
24
32
  def assert_form_contains_button(button)
25
33
  page = Mechanize::Page.new(nil, html_response, html(button), 200, @agent)
26
34
  assert_equal(1, page.forms.length)