tenderlove-mechanize 0.9.3.20090617085936
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +496 -0
- data/EXAMPLES.rdoc +171 -0
- data/FAQ.rdoc +11 -0
- data/GUIDE.rdoc +122 -0
- data/LICENSE.rdoc +340 -0
- data/Manifest.txt +169 -0
- data/README.rdoc +60 -0
- data/Rakefile +43 -0
- data/examples/flickr_upload.rb +23 -0
- data/examples/mech-dump.rb +7 -0
- data/examples/proxy_req.rb +9 -0
- data/examples/rubyforge.rb +21 -0
- data/examples/spider.rb +11 -0
- data/lib/mechanize.rb +7 -0
- data/lib/www/mechanize/chain/auth_headers.rb +80 -0
- data/lib/www/mechanize/chain/body_decoding_handler.rb +48 -0
- data/lib/www/mechanize/chain/connection_resolver.rb +78 -0
- data/lib/www/mechanize/chain/custom_headers.rb +23 -0
- data/lib/www/mechanize/chain/handler.rb +9 -0
- data/lib/www/mechanize/chain/header_resolver.rb +53 -0
- data/lib/www/mechanize/chain/parameter_resolver.rb +24 -0
- data/lib/www/mechanize/chain/post_connect_hook.rb +0 -0
- data/lib/www/mechanize/chain/pre_connect_hook.rb +22 -0
- data/lib/www/mechanize/chain/request_resolver.rb +32 -0
- data/lib/www/mechanize/chain/response_body_parser.rb +40 -0
- data/lib/www/mechanize/chain/response_header_handler.rb +50 -0
- data/lib/www/mechanize/chain/response_reader.rb +41 -0
- data/lib/www/mechanize/chain/ssl_resolver.rb +42 -0
- data/lib/www/mechanize/chain/uri_resolver.rb +77 -0
- data/lib/www/mechanize/chain.rb +34 -0
- data/lib/www/mechanize/content_type_error.rb +16 -0
- data/lib/www/mechanize/cookie.rb +72 -0
- data/lib/www/mechanize/cookie_jar.rb +191 -0
- data/lib/www/mechanize/file.rb +73 -0
- data/lib/www/mechanize/file_response.rb +62 -0
- data/lib/www/mechanize/file_saver.rb +39 -0
- data/lib/www/mechanize/form/button.rb +8 -0
- data/lib/www/mechanize/form/check_box.rb +13 -0
- data/lib/www/mechanize/form/field.rb +28 -0
- data/lib/www/mechanize/form/file_upload.rb +24 -0
- data/lib/www/mechanize/form/image_button.rb +23 -0
- data/lib/www/mechanize/form/multi_select_list.rb +69 -0
- data/lib/www/mechanize/form/option.rb +51 -0
- data/lib/www/mechanize/form/radio_button.rb +38 -0
- data/lib/www/mechanize/form/select_list.rb +45 -0
- data/lib/www/mechanize/form.rb +360 -0
- data/lib/www/mechanize/headers.rb +12 -0
- data/lib/www/mechanize/history.rb +67 -0
- data/lib/www/mechanize/inspect.rb +90 -0
- data/lib/www/mechanize/monkey_patch.rb +37 -0
- data/lib/www/mechanize/page/base.rb +10 -0
- data/lib/www/mechanize/page/frame.rb +22 -0
- data/lib/www/mechanize/page/link.rb +50 -0
- data/lib/www/mechanize/page/meta.rb +51 -0
- data/lib/www/mechanize/page.rb +176 -0
- data/lib/www/mechanize/pluggable_parsers.rb +103 -0
- data/lib/www/mechanize/redirect_limit_reached_error.rb +18 -0
- data/lib/www/mechanize/redirect_not_get_or_head_error.rb +20 -0
- data/lib/www/mechanize/response_code_error.rb +25 -0
- data/lib/www/mechanize/unsupported_scheme_error.rb +10 -0
- data/lib/www/mechanize/util.rb +76 -0
- data/lib/www/mechanize.rb +619 -0
- data/mechanize.gemspec +41 -0
- data/test/chain/test_argument_validator.rb +14 -0
- data/test/chain/test_auth_headers.rb +25 -0
- data/test/chain/test_custom_headers.rb +18 -0
- data/test/chain/test_header_resolver.rb +28 -0
- data/test/chain/test_parameter_resolver.rb +35 -0
- data/test/chain/test_request_resolver.rb +29 -0
- data/test/chain/test_response_reader.rb +24 -0
- data/test/data/htpasswd +1 -0
- data/test/data/server.crt +16 -0
- data/test/data/server.csr +12 -0
- data/test/data/server.key +15 -0
- data/test/data/server.pem +15 -0
- data/test/helper.rb +129 -0
- data/test/htdocs/alt_text.html +10 -0
- data/test/htdocs/bad_form_test.html +9 -0
- data/test/htdocs/button.jpg +0 -0
- data/test/htdocs/empty_form.html +6 -0
- data/test/htdocs/file_upload.html +26 -0
- data/test/htdocs/find_link.html +41 -0
- data/test/htdocs/form_multi_select.html +16 -0
- data/test/htdocs/form_multival.html +37 -0
- data/test/htdocs/form_no_action.html +18 -0
- data/test/htdocs/form_no_input_name.html +16 -0
- data/test/htdocs/form_select.html +16 -0
- data/test/htdocs/form_select_all.html +16 -0
- data/test/htdocs/form_select_none.html +17 -0
- data/test/htdocs/form_select_noopts.html +10 -0
- data/test/htdocs/form_set_fields.html +14 -0
- data/test/htdocs/form_test.html +188 -0
- data/test/htdocs/frame_test.html +30 -0
- data/test/htdocs/google.html +13 -0
- data/test/htdocs/iframe_test.html +16 -0
- data/test/htdocs/index.html +6 -0
- data/test/htdocs/link with space.html +5 -0
- data/test/htdocs/meta_cookie.html +11 -0
- data/test/htdocs/no_title_test.html +6 -0
- data/test/htdocs/relative/tc_relative_links.html +21 -0
- data/test/htdocs/tc_bad_links.html +5 -0
- data/test/htdocs/tc_base_link.html +8 -0
- data/test/htdocs/tc_blank_form.html +11 -0
- data/test/htdocs/tc_checkboxes.html +19 -0
- data/test/htdocs/tc_encoded_links.html +5 -0
- data/test/htdocs/tc_follow_meta.html +8 -0
- data/test/htdocs/tc_form_action.html +48 -0
- data/test/htdocs/tc_links.html +18 -0
- data/test/htdocs/tc_no_attributes.html +16 -0
- data/test/htdocs/tc_pretty_print.html +17 -0
- data/test/htdocs/tc_radiobuttons.html +17 -0
- data/test/htdocs/tc_referer.html +10 -0
- data/test/htdocs/tc_relative_links.html +19 -0
- data/test/htdocs/tc_textarea.html +23 -0
- data/test/htdocs/unusual______.html +5 -0
- data/test/servlets.rb +365 -0
- data/test/ssl_server.rb +48 -0
- data/test/test_authenticate.rb +71 -0
- data/test/test_bad_links.rb +25 -0
- data/test/test_blank_form.rb +16 -0
- data/test/test_checkboxes.rb +61 -0
- data/test/test_content_type.rb +13 -0
- data/test/test_cookie_class.rb +338 -0
- data/test/test_cookie_jar.rb +362 -0
- data/test/test_cookies.rb +123 -0
- data/test/test_encoded_links.rb +20 -0
- data/test/test_errors.rb +49 -0
- data/test/test_follow_meta.rb +108 -0
- data/test/test_form_action.rb +44 -0
- data/test/test_form_as_hash.rb +61 -0
- data/test/test_form_button.rb +38 -0
- data/test/test_form_no_inputname.rb +15 -0
- data/test/test_forms.rb +564 -0
- data/test/test_frames.rb +25 -0
- data/test/test_get_headers.rb +52 -0
- data/test/test_gzipping.rb +22 -0
- data/test/test_hash_api.rb +45 -0
- data/test/test_history.rb +142 -0
- data/test/test_history_added.rb +16 -0
- data/test/test_html_unscape_forms.rb +39 -0
- data/test/test_if_modified_since.rb +20 -0
- data/test/test_keep_alive.rb +31 -0
- data/test/test_links.rb +120 -0
- data/test/test_mech.rb +268 -0
- data/test/test_mechanize_file.rb +47 -0
- data/test/test_meta.rb +65 -0
- data/test/test_multi_select.rb +106 -0
- data/test/test_no_attributes.rb +13 -0
- data/test/test_option.rb +18 -0
- data/test/test_page.rb +119 -0
- data/test/test_pluggable_parser.rb +145 -0
- data/test/test_post_form.rb +34 -0
- data/test/test_pretty_print.rb +22 -0
- data/test/test_radiobutton.rb +75 -0
- data/test/test_redirect_limit_reached.rb +41 -0
- data/test/test_redirect_verb_handling.rb +45 -0
- data/test/test_referer.rb +39 -0
- data/test/test_relative_links.rb +40 -0
- data/test/test_request.rb +13 -0
- data/test/test_response_code.rb +52 -0
- data/test/test_save_file.rb +48 -0
- data/test/test_scheme.rb +48 -0
- data/test/test_select.rb +106 -0
- data/test/test_select_all.rb +15 -0
- data/test/test_select_none.rb +15 -0
- data/test/test_select_noopts.rb +16 -0
- data/test/test_set_fields.rb +44 -0
- data/test/test_ssl_server.rb +20 -0
- data/test/test_subclass.rb +14 -0
- data/test/test_textarea.rb +45 -0
- data/test/test_upload.rb +109 -0
- data/test/test_verbs.rb +25 -0
- metadata +314 -0
@@ -0,0 +1,338 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "helper"))
|
2
|
+
|
3
|
+
module Enumerable
|
4
|
+
def combine
|
5
|
+
masks = inject([[], 1]){|(ar, m), e| [ar << m, m << 1 ] }[0]
|
6
|
+
all = masks.inject(0){ |al, m| al|m }
|
7
|
+
|
8
|
+
result = []
|
9
|
+
for i in 1..all do
|
10
|
+
tmp = []
|
11
|
+
each_with_index do |e, idx|
|
12
|
+
tmp << e unless (masks[idx] & i) == 0
|
13
|
+
end
|
14
|
+
result << tmp
|
15
|
+
end
|
16
|
+
result
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class CookieClassTest < Test::Unit::TestCase
|
21
|
+
def silently
|
22
|
+
warn_level = $VERBOSE
|
23
|
+
$VERBOSE = false
|
24
|
+
res = yield
|
25
|
+
$VERBOSE = warn_level
|
26
|
+
res
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_parse_dates
|
30
|
+
url = URI.parse('http://localhost/')
|
31
|
+
|
32
|
+
yesterday = Time.now - 86400
|
33
|
+
|
34
|
+
dates = [ "14 Apr 89 03:20:12",
|
35
|
+
"14 Apr 89 03:20 GMT",
|
36
|
+
"Fri, 17 Mar 89 4:01:33",
|
37
|
+
"Fri, 17 Mar 89 4:01 GMT",
|
38
|
+
"Mon Jan 16 16:12 PDT 1989",
|
39
|
+
"Mon Jan 16 16:12 +0130 1989",
|
40
|
+
"6 May 1992 16:41-JST (Wednesday)",
|
41
|
+
#"22-AUG-1993 10:59:12.82",
|
42
|
+
"22-AUG-1993 10:59pm",
|
43
|
+
"22-AUG-1993 12:59am",
|
44
|
+
"22-AUG-1993 12:59 PM",
|
45
|
+
#"Friday, August 04, 1995 3:54 PM",
|
46
|
+
#"06/21/95 04:24:34 PM",
|
47
|
+
#"20/06/95 21:07",
|
48
|
+
"95-06-08 19:32:48 EDT",
|
49
|
+
]
|
50
|
+
|
51
|
+
dates.each do |date|
|
52
|
+
cookie = "PREF=1; expires=#{date}"
|
53
|
+
silently do
|
54
|
+
WWW::Mechanize::Cookie.parse(url, cookie) { |c|
|
55
|
+
assert c.expires, "Tried parsing: #{date}"
|
56
|
+
assert_equal(true, c.expires < yesterday)
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_parse_weird_cookie
|
63
|
+
cookie = 'n/a, ASPSESSIONIDCSRRQDQR=FBLDGHPBNDJCPCGNCPAENELB; path=/'
|
64
|
+
url = URI.parse('http://www.searchinnovation.com/')
|
65
|
+
WWW::Mechanize::Cookie.parse(url, cookie) { |c|
|
66
|
+
assert_equal('ASPSESSIONIDCSRRQDQR', c.name)
|
67
|
+
assert_equal('FBLDGHPBNDJCPCGNCPAENELB', c.value)
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_double_semicolon
|
72
|
+
double_semi = 'WSIDC=WEST;; domain=.williams-sonoma.com; path=/'
|
73
|
+
url = URI.parse('http://williams-sonoma.com/')
|
74
|
+
WWW::Mechanize::Cookie.parse(url, double_semi) { |cookie|
|
75
|
+
assert_equal('WSIDC', cookie.name)
|
76
|
+
assert_equal('WEST', cookie.value)
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_parse_bad_version
|
81
|
+
bad_cookie = 'PRETANET=TGIAqbFXtt; Name=/PRETANET; Path=/; Version=1.2; Content-type=text/html; Domain=192.168.6.196; expires=Friday, 13-November-2026 23:01:46 GMT;'
|
82
|
+
url = URI.parse('http://localhost/')
|
83
|
+
WWW::Mechanize::Cookie.parse(url, bad_cookie) { |cookie|
|
84
|
+
assert_nil(cookie.version)
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_parse_bad_max_age
|
89
|
+
bad_cookie = 'PRETANET=TGIAqbFXtt; Name=/PRETANET; Path=/; Max-Age=1.2; Content-type=text/html; Domain=192.168.6.196; expires=Friday, 13-November-2026 23:01:46 GMT;'
|
90
|
+
url = URI.parse('http://localhost/')
|
91
|
+
WWW::Mechanize::Cookie.parse(url, bad_cookie) { |cookie|
|
92
|
+
assert_nil(cookie.max_age)
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_parse_date_fail
|
97
|
+
url = URI.parse('http://localhost/')
|
98
|
+
|
99
|
+
dates = [
|
100
|
+
"20/06/95 21:07",
|
101
|
+
]
|
102
|
+
|
103
|
+
silently do
|
104
|
+
dates.each do |date|
|
105
|
+
cookie = "PREF=1; expires=#{date}"
|
106
|
+
WWW::Mechanize::Cookie.parse(url, cookie) { |c|
|
107
|
+
assert_equal(true, c.expires.nil?)
|
108
|
+
}
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_parse_valid_cookie
|
114
|
+
url = URI.parse('http://rubyforge.org/')
|
115
|
+
cookie_params = {}
|
116
|
+
cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
|
117
|
+
cookie_params['path'] = 'path=/'
|
118
|
+
cookie_params['domain'] = 'domain=.rubyforge.org'
|
119
|
+
cookie_params['httponly'] = 'HttpOnly'
|
120
|
+
cookie_value = '12345%7D=ASDFWEE345%3DASda'
|
121
|
+
|
122
|
+
expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
|
123
|
+
|
124
|
+
cookie_params.keys.combine.each do |c|
|
125
|
+
cookie_text = "#{cookie_value}; "
|
126
|
+
c.each_with_index do |key, idx|
|
127
|
+
if idx == (c.length - 1)
|
128
|
+
cookie_text << "#{cookie_params[key]}"
|
129
|
+
else
|
130
|
+
cookie_text << "#{cookie_params[key]}; "
|
131
|
+
end
|
132
|
+
end
|
133
|
+
cookie = nil
|
134
|
+
WWW::Mechanize::Cookie.parse(url, cookie_text) { |p_cookie| cookie = p_cookie }
|
135
|
+
assert_not_nil(cookie)
|
136
|
+
assert_equal('12345%7D=ASDFWEE345%3DASda', cookie.to_s)
|
137
|
+
assert_equal('/', cookie.path)
|
138
|
+
assert_equal('rubyforge.org', cookie.domain)
|
139
|
+
|
140
|
+
# if expires was set, make sure we parsed it
|
141
|
+
if c.find { |k| k == 'expires' }
|
142
|
+
assert_equal(expires, cookie.expires)
|
143
|
+
else
|
144
|
+
assert_nil(cookie.expires)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_parse_valid_cookie_empty_value
|
150
|
+
url = URI.parse('http://rubyforge.org/')
|
151
|
+
cookie_params = {}
|
152
|
+
cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
|
153
|
+
cookie_params['path'] = 'path=/'
|
154
|
+
cookie_params['domain'] = 'domain=.rubyforge.org'
|
155
|
+
cookie_params['httponly'] = 'HttpOnly'
|
156
|
+
cookie_value = '12345%7D='
|
157
|
+
|
158
|
+
expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
|
159
|
+
|
160
|
+
cookie_params.keys.combine.each do |c|
|
161
|
+
cookie_text = "#{cookie_value}; "
|
162
|
+
c.each_with_index do |key, idx|
|
163
|
+
if idx == (c.length - 1)
|
164
|
+
cookie_text << "#{cookie_params[key]}"
|
165
|
+
else
|
166
|
+
cookie_text << "#{cookie_params[key]}; "
|
167
|
+
end
|
168
|
+
end
|
169
|
+
cookie = nil
|
170
|
+
WWW::Mechanize::Cookie.parse(url, cookie_text) { |p_cookie| cookie = p_cookie }
|
171
|
+
assert_not_nil(cookie)
|
172
|
+
assert_equal('12345%7D=', cookie.to_s)
|
173
|
+
assert_equal('', cookie.value)
|
174
|
+
assert_equal('/', cookie.path)
|
175
|
+
assert_equal('rubyforge.org', cookie.domain)
|
176
|
+
|
177
|
+
# if expires was set, make sure we parsed it
|
178
|
+
if c.find { |k| k == 'expires' }
|
179
|
+
assert_equal(expires, cookie.expires)
|
180
|
+
else
|
181
|
+
assert_nil(cookie.expires)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# If no path was given, use the one from the URL
|
187
|
+
def test_cookie_using_url_path
|
188
|
+
url = URI.parse('http://rubyforge.org/login.php')
|
189
|
+
cookie_params = {}
|
190
|
+
cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
|
191
|
+
cookie_params['path'] = 'path=/'
|
192
|
+
cookie_params['domain'] = 'domain=.rubyforge.org'
|
193
|
+
cookie_params['httponly'] = 'HttpOnly'
|
194
|
+
cookie_value = '12345%7D=ASDFWEE345%3DASda'
|
195
|
+
|
196
|
+
expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
|
197
|
+
|
198
|
+
cookie_params.keys.combine.each do |c|
|
199
|
+
next if c.find { |k| k == 'path' }
|
200
|
+
cookie_text = "#{cookie_value}; "
|
201
|
+
c.each_with_index do |key, idx|
|
202
|
+
if idx == (c.length - 1)
|
203
|
+
cookie_text << "#{cookie_params[key]}"
|
204
|
+
else
|
205
|
+
cookie_text << "#{cookie_params[key]}; "
|
206
|
+
end
|
207
|
+
end
|
208
|
+
cookie = nil
|
209
|
+
WWW::Mechanize::Cookie.parse(url, cookie_text) { |p_cookie| cookie = p_cookie }
|
210
|
+
assert_not_nil(cookie)
|
211
|
+
assert_equal('12345%7D=ASDFWEE345%3DASda', cookie.to_s)
|
212
|
+
assert_equal('rubyforge.org', cookie.domain)
|
213
|
+
assert_equal('/', cookie.path)
|
214
|
+
|
215
|
+
# if expires was set, make sure we parsed it
|
216
|
+
if c.find { |k| k == 'expires' }
|
217
|
+
assert_equal(expires, cookie.expires)
|
218
|
+
else
|
219
|
+
assert_nil(cookie.expires)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# Test using secure cookies
|
225
|
+
def test_cookie_with_secure
|
226
|
+
url = URI.parse('http://rubyforge.org/')
|
227
|
+
cookie_params = {}
|
228
|
+
cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
|
229
|
+
cookie_params['path'] = 'path=/'
|
230
|
+
cookie_params['domain'] = 'domain=.rubyforge.org'
|
231
|
+
cookie_params['secure'] = 'secure'
|
232
|
+
cookie_value = '12345%7D=ASDFWEE345%3DASda'
|
233
|
+
|
234
|
+
expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
|
235
|
+
|
236
|
+
cookie_params.keys.combine.each do |c|
|
237
|
+
next unless c.find { |k| k == 'secure' }
|
238
|
+
cookie_text = "#{cookie_value}; "
|
239
|
+
c.each_with_index do |key, idx|
|
240
|
+
if idx == (c.length - 1)
|
241
|
+
cookie_text << "#{cookie_params[key]}"
|
242
|
+
else
|
243
|
+
cookie_text << "#{cookie_params[key]}; "
|
244
|
+
end
|
245
|
+
end
|
246
|
+
cookie = nil
|
247
|
+
WWW::Mechanize::Cookie.parse(url, cookie_text) { |p_cookie| cookie = p_cookie }
|
248
|
+
assert_not_nil(cookie)
|
249
|
+
assert_equal('12345%7D=ASDFWEE345%3DASda', cookie.to_s)
|
250
|
+
assert_equal('rubyforge.org', cookie.domain)
|
251
|
+
assert_equal('/', cookie.path)
|
252
|
+
assert_equal(true, cookie.secure)
|
253
|
+
|
254
|
+
# if expires was set, make sure we parsed it
|
255
|
+
if c.find { |k| k == 'expires' }
|
256
|
+
assert_equal(expires, cookie.expires)
|
257
|
+
else
|
258
|
+
assert_nil(cookie.expires)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
# If no domain was given, we must use the one from the URL
|
264
|
+
def test_cookie_with_url_domain
|
265
|
+
url = URI.parse('http://login.rubyforge.org/')
|
266
|
+
cookie_params = {}
|
267
|
+
cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
|
268
|
+
cookie_params['path'] = 'path=/'
|
269
|
+
cookie_params['domain'] = 'domain=.rubyforge.org'
|
270
|
+
cookie_params['httponly'] = 'HttpOnly'
|
271
|
+
cookie_value = '12345%7D=ASDFWEE345%3DASda'
|
272
|
+
|
273
|
+
expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
|
274
|
+
|
275
|
+
cookie_params.keys.combine.each do |c|
|
276
|
+
next if c.find { |k| k == 'domain' }
|
277
|
+
cookie_text = "#{cookie_value}; "
|
278
|
+
c.each_with_index do |key, idx|
|
279
|
+
if idx == (c.length - 1)
|
280
|
+
cookie_text << "#{cookie_params[key]}"
|
281
|
+
else
|
282
|
+
cookie_text << "#{cookie_params[key]}; "
|
283
|
+
end
|
284
|
+
end
|
285
|
+
cookie = nil
|
286
|
+
WWW::Mechanize::Cookie.parse(url, cookie_text) { |p_cookie| cookie = p_cookie }
|
287
|
+
assert_not_nil(cookie)
|
288
|
+
assert_equal('12345%7D=ASDFWEE345%3DASda', cookie.to_s)
|
289
|
+
assert_equal('/', cookie.path)
|
290
|
+
|
291
|
+
assert_equal('login.rubyforge.org', cookie.domain)
|
292
|
+
|
293
|
+
# if expires was set, make sure we parsed it
|
294
|
+
if c.find { |k| k == 'expires' }
|
295
|
+
assert_equal(expires, cookie.expires)
|
296
|
+
else
|
297
|
+
assert_nil(cookie.expires)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
def test_parse_cookie_no_spaces
|
303
|
+
url = URI.parse('http://rubyforge.org/')
|
304
|
+
cookie_params = {}
|
305
|
+
cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
|
306
|
+
cookie_params['path'] = 'path=/'
|
307
|
+
cookie_params['domain'] = 'domain=.rubyforge.org'
|
308
|
+
cookie_params['httponly'] = 'HttpOnly'
|
309
|
+
cookie_value = '12345%7D=ASDFWEE345%3DASda'
|
310
|
+
|
311
|
+
expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
|
312
|
+
|
313
|
+
cookie_params.keys.combine.each do |c|
|
314
|
+
cookie_text = "#{cookie_value};"
|
315
|
+
c.each_with_index do |key, idx|
|
316
|
+
if idx == (c.length - 1)
|
317
|
+
cookie_text << "#{cookie_params[key]}"
|
318
|
+
else
|
319
|
+
cookie_text << "#{cookie_params[key]};"
|
320
|
+
end
|
321
|
+
end
|
322
|
+
cookie = nil
|
323
|
+
WWW::Mechanize::Cookie.parse(url, cookie_text) { |p_cookie| cookie = p_cookie }
|
324
|
+
assert_not_nil(cookie)
|
325
|
+
assert_equal('12345%7D=ASDFWEE345%3DASda', cookie.to_s)
|
326
|
+
assert_equal('/', cookie.path)
|
327
|
+
assert_equal('rubyforge.org', cookie.domain)
|
328
|
+
|
329
|
+
# if expires was set, make sure we parsed it
|
330
|
+
if c.find { |k| k == 'expires' }
|
331
|
+
assert_equal(expires, cookie.expires)
|
332
|
+
else
|
333
|
+
assert_nil(cookie.expires)
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
@@ -0,0 +1,362 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "helper"))
|
2
|
+
|
3
|
+
class CookieJarTest < Test::Unit::TestCase
|
4
|
+
def cookie_from_hash(hash)
|
5
|
+
c = WWW::Mechanize::Cookie.new(hash[:name], hash[:value])
|
6
|
+
hash.each { |k,v|
|
7
|
+
next if k == :name || k == :value
|
8
|
+
c.send("#{k}=", v)
|
9
|
+
}
|
10
|
+
c
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_two_cookies_same_domain_and_name_different_paths
|
14
|
+
values = { :name => 'Foo',
|
15
|
+
:value => 'Bar',
|
16
|
+
:path => '/',
|
17
|
+
:expires => Time.now + (10 * 86400),
|
18
|
+
:domain => 'rubyforge.org'
|
19
|
+
}
|
20
|
+
|
21
|
+
url = URI.parse('http://rubyforge.org/')
|
22
|
+
|
23
|
+
jar = WWW::Mechanize::CookieJar.new
|
24
|
+
cookie = cookie_from_hash(values)
|
25
|
+
jar.add(url, cookie)
|
26
|
+
jar.add(url, cookie_from_hash(values.merge(:path => '/onetwo')))
|
27
|
+
|
28
|
+
assert_equal(1, jar.cookies(url).length)
|
29
|
+
assert_equal 2, jar.cookies(URI.parse('http://rubyforge.org/onetwo')).length
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_domain_case
|
33
|
+
values = { :name => 'Foo',
|
34
|
+
:value => 'Bar',
|
35
|
+
:path => '/',
|
36
|
+
:expires => Time.now + (10 * 86400),
|
37
|
+
:domain => 'rubyforge.org'
|
38
|
+
}
|
39
|
+
url = URI.parse('http://rubyforge.org/')
|
40
|
+
|
41
|
+
jar = WWW::Mechanize::CookieJar.new
|
42
|
+
assert_equal(0, jar.cookies(url).length)
|
43
|
+
|
44
|
+
# Add one cookie with an expiration date in the future
|
45
|
+
cookie = cookie_from_hash(values)
|
46
|
+
jar.add(url, cookie)
|
47
|
+
assert_equal(1, jar.cookies(url).length)
|
48
|
+
|
49
|
+
jar.add(url, cookie_from_hash( values.merge( :domain => 'RuByForge.Org',
|
50
|
+
:name => 'aaron'
|
51
|
+
) ) )
|
52
|
+
|
53
|
+
assert_equal(2, jar.cookies(url).length)
|
54
|
+
|
55
|
+
url2 = URI.parse('http://RuByFoRgE.oRg/')
|
56
|
+
assert_equal(2, jar.cookies(url2).length)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_empty_value
|
60
|
+
values = { :name => 'Foo',
|
61
|
+
:value => '',
|
62
|
+
:path => '/',
|
63
|
+
:expires => Time.now + (10 * 86400),
|
64
|
+
:domain => 'rubyforge.org'
|
65
|
+
}
|
66
|
+
url = URI.parse('http://rubyforge.org/')
|
67
|
+
|
68
|
+
jar = WWW::Mechanize::CookieJar.new
|
69
|
+
assert_equal(0, jar.cookies(url).length)
|
70
|
+
|
71
|
+
# Add one cookie with an expiration date in the future
|
72
|
+
cookie = cookie_from_hash(values)
|
73
|
+
jar.add(url, cookie)
|
74
|
+
assert_equal(1, jar.cookies(url).length)
|
75
|
+
|
76
|
+
jar.add(url, cookie_from_hash( values.merge( :domain => 'RuByForge.Org',
|
77
|
+
:name => 'aaron'
|
78
|
+
) ) )
|
79
|
+
|
80
|
+
assert_equal(2, jar.cookies(url).length)
|
81
|
+
|
82
|
+
url2 = URI.parse('http://RuByFoRgE.oRg/')
|
83
|
+
assert_equal(2, jar.cookies(url2).length)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_add_future_cookies
|
87
|
+
values = { :name => 'Foo',
|
88
|
+
:value => 'Bar',
|
89
|
+
:path => '/',
|
90
|
+
:expires => Time.now + (10 * 86400),
|
91
|
+
:domain => 'rubyforge.org'
|
92
|
+
}
|
93
|
+
url = URI.parse('http://rubyforge.org/')
|
94
|
+
|
95
|
+
jar = WWW::Mechanize::CookieJar.new
|
96
|
+
assert_equal(0, jar.cookies(url).length)
|
97
|
+
|
98
|
+
# Add one cookie with an expiration date in the future
|
99
|
+
cookie = cookie_from_hash(values)
|
100
|
+
jar.add(url, cookie)
|
101
|
+
assert_equal(1, jar.cookies(url).length)
|
102
|
+
|
103
|
+
# Add the same cookie, and we should still only have one
|
104
|
+
jar.add(url, cookie_from_hash(values))
|
105
|
+
assert_equal(1, jar.cookies(url).length)
|
106
|
+
|
107
|
+
# Make sure we can get the cookie from different paths
|
108
|
+
assert_equal(1, jar.cookies(URI.parse('http://rubyforge.org/login')).length)
|
109
|
+
|
110
|
+
# Make sure we can't get the cookie from different domains
|
111
|
+
assert_equal(0, jar.cookies(URI.parse('http://google.com/')).length)
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_add_multiple_cookies
|
115
|
+
values = { :name => 'Foo',
|
116
|
+
:value => 'Bar',
|
117
|
+
:path => '/',
|
118
|
+
:expires => Time.now + (10 * 86400),
|
119
|
+
:domain => 'rubyforge.org'
|
120
|
+
}
|
121
|
+
url = URI.parse('http://rubyforge.org/')
|
122
|
+
|
123
|
+
jar = WWW::Mechanize::CookieJar.new
|
124
|
+
assert_equal(0, jar.cookies(url).length)
|
125
|
+
|
126
|
+
# Add one cookie with an expiration date in the future
|
127
|
+
cookie = cookie_from_hash(values)
|
128
|
+
jar.add(url, cookie)
|
129
|
+
assert_equal(1, jar.cookies(url).length)
|
130
|
+
|
131
|
+
# Add the same cookie, and we should still only have one
|
132
|
+
jar.add(url, cookie_from_hash(values.merge( :name => 'Baz' )))
|
133
|
+
assert_equal(2, jar.cookies(url).length)
|
134
|
+
|
135
|
+
# Make sure we can get the cookie from different paths
|
136
|
+
assert_equal(2, jar.cookies(URI.parse('http://rubyforge.org/login')).length)
|
137
|
+
|
138
|
+
# Make sure we can't get the cookie from different domains
|
139
|
+
assert_equal(0, jar.cookies(URI.parse('http://google.com/')).length)
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_clear_cookies
|
143
|
+
values = { :name => 'Foo',
|
144
|
+
:value => 'Bar',
|
145
|
+
:path => '/',
|
146
|
+
:expires => Time.now + (10 * 86400),
|
147
|
+
:domain => 'rubyforge.org'
|
148
|
+
}
|
149
|
+
url = URI.parse('http://rubyforge.org/')
|
150
|
+
|
151
|
+
jar = WWW::Mechanize::CookieJar.new
|
152
|
+
assert_equal(0, jar.cookies(url).length)
|
153
|
+
|
154
|
+
# Add one cookie with an expiration date in the future
|
155
|
+
cookie = cookie_from_hash(values)
|
156
|
+
jar.add(url, cookie)
|
157
|
+
jar.add(url, cookie_from_hash(values.merge( :name => 'Baz' )))
|
158
|
+
assert_equal(2, jar.cookies(url).length)
|
159
|
+
|
160
|
+
jar.clear!
|
161
|
+
|
162
|
+
assert_equal(0, jar.cookies(url).length)
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_save_cookies
|
166
|
+
values = { :name => 'Foo',
|
167
|
+
:value => 'Bar',
|
168
|
+
:path => '/',
|
169
|
+
:expires => Time.now + (10 * 86400),
|
170
|
+
:domain => 'rubyforge.org'
|
171
|
+
}
|
172
|
+
url = URI.parse('http://rubyforge.org/')
|
173
|
+
|
174
|
+
jar = WWW::Mechanize::CookieJar.new
|
175
|
+
assert_equal(0, jar.cookies(url).length)
|
176
|
+
|
177
|
+
# Add one cookie with an expiration date in the future
|
178
|
+
cookie = cookie_from_hash(values)
|
179
|
+
jar.add(url, cookie)
|
180
|
+
jar.add(url, cookie_from_hash(values.merge( :name => 'Baz' )))
|
181
|
+
assert_equal(2, jar.cookies(url).length)
|
182
|
+
|
183
|
+
jar.save_as("cookies.yml")
|
184
|
+
jar.clear!
|
185
|
+
assert_equal(0, jar.cookies(url).length)
|
186
|
+
|
187
|
+
jar.load("cookies.yml")
|
188
|
+
assert_equal(2, jar.cookies(url).length)
|
189
|
+
FileUtils.rm("cookies.yml")
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_expire_cookies
|
193
|
+
values = { :name => 'Foo',
|
194
|
+
:value => 'Bar',
|
195
|
+
:path => '/',
|
196
|
+
:expires => Time.now + (10 * 86400),
|
197
|
+
:domain => 'rubyforge.org'
|
198
|
+
}
|
199
|
+
url = URI.parse('http://rubyforge.org/')
|
200
|
+
|
201
|
+
jar = WWW::Mechanize::CookieJar.new
|
202
|
+
assert_equal(0, jar.cookies(url).length)
|
203
|
+
|
204
|
+
# Add one cookie with an expiration date in the future
|
205
|
+
cookie = cookie_from_hash(values)
|
206
|
+
jar.add(url, cookie)
|
207
|
+
assert_equal(1, jar.cookies(url).length)
|
208
|
+
|
209
|
+
# Add a second cookie
|
210
|
+
jar.add(url, cookie_from_hash(values.merge( :name => 'Baz' )))
|
211
|
+
assert_equal(2, jar.cookies(url).length)
|
212
|
+
|
213
|
+
# Make sure we can get the cookie from different paths
|
214
|
+
assert_equal(2, jar.cookies(URI.parse('http://rubyforge.org/login')).length)
|
215
|
+
|
216
|
+
# Expire the first cookie
|
217
|
+
jar.add(url, cookie_from_hash(values.merge( :expires => Time.now - (10 * 86400))))
|
218
|
+
assert_equal(1, jar.cookies(url).length)
|
219
|
+
|
220
|
+
# Expire the second cookie
|
221
|
+
jar.add(url, cookie_from_hash(values.merge( :name => 'Baz',
|
222
|
+
:expires => Time.now - (10 * 86400))))
|
223
|
+
assert_equal(0, jar.cookies(url).length)
|
224
|
+
end
|
225
|
+
|
226
|
+
def test_session_cookies
|
227
|
+
values = { :name => 'Foo',
|
228
|
+
:value => 'Bar',
|
229
|
+
:path => '/',
|
230
|
+
:expires => nil,
|
231
|
+
:domain => 'rubyforge.org'
|
232
|
+
}
|
233
|
+
url = URI.parse('http://rubyforge.org/')
|
234
|
+
|
235
|
+
jar = WWW::Mechanize::CookieJar.new
|
236
|
+
assert_equal(0, jar.cookies(url).length)
|
237
|
+
|
238
|
+
# Add one cookie with an expiration date in the future
|
239
|
+
cookie = cookie_from_hash(values)
|
240
|
+
jar.add(url, cookie)
|
241
|
+
assert_equal(1, jar.cookies(url).length)
|
242
|
+
|
243
|
+
# Add a second cookie
|
244
|
+
jar.add(url, cookie_from_hash(values.merge( :name => 'Baz' )))
|
245
|
+
assert_equal(2, jar.cookies(url).length)
|
246
|
+
|
247
|
+
# Make sure we can get the cookie from different paths
|
248
|
+
assert_equal(2, jar.cookies(URI.parse('http://rubyforge.org/login')).length)
|
249
|
+
|
250
|
+
# Expire the first cookie
|
251
|
+
jar.add(url, cookie_from_hash(values.merge( :expires => Time.now - (10 * 86400))))
|
252
|
+
assert_equal(1, jar.cookies(url).length)
|
253
|
+
|
254
|
+
# Expire the second cookie
|
255
|
+
jar.add(url, cookie_from_hash(values.merge( :name => 'Baz',
|
256
|
+
:expires => Time.now - (10 * 86400))))
|
257
|
+
assert_equal(0, jar.cookies(url).length)
|
258
|
+
|
259
|
+
# When given a URI with a blank path, CookieJar#cookies should return
|
260
|
+
# cookies with the path '/':
|
261
|
+
url = URI.parse('http://rubyforge.org')
|
262
|
+
assert_equal '', url.path
|
263
|
+
assert_equal(0, jar.cookies(url).length)
|
264
|
+
# Now add a cookie with the path set to '/':
|
265
|
+
jar.add(url, cookie_from_hash(values.merge( :name => 'has_root_path',
|
266
|
+
:path => '/')))
|
267
|
+
assert_equal(1, jar.cookies(url).length)
|
268
|
+
end
|
269
|
+
|
270
|
+
def test_paths
|
271
|
+
values = { :name => 'Foo',
|
272
|
+
:value => 'Bar',
|
273
|
+
:path => '/login',
|
274
|
+
:expires => nil,
|
275
|
+
:domain => 'rubyforge.org'
|
276
|
+
}
|
277
|
+
url = URI.parse('http://rubyforge.org/login')
|
278
|
+
|
279
|
+
jar = WWW::Mechanize::CookieJar.new
|
280
|
+
assert_equal(0, jar.cookies(url).length)
|
281
|
+
|
282
|
+
# Add one cookie with an expiration date in the future
|
283
|
+
cookie = cookie_from_hash(values)
|
284
|
+
jar.add(url, cookie)
|
285
|
+
assert_equal(1, jar.cookies(url).length)
|
286
|
+
|
287
|
+
# Add a second cookie
|
288
|
+
jar.add(url, cookie_from_hash(values.merge( :name => 'Baz' )))
|
289
|
+
assert_equal(2, jar.cookies(url).length)
|
290
|
+
|
291
|
+
# Make sure we don't get the cookie in a different path
|
292
|
+
assert_equal(0, jar.cookies(URI.parse('http://rubyforge.org/hello')).length)
|
293
|
+
assert_equal(0, jar.cookies(URI.parse('http://rubyforge.org/')).length)
|
294
|
+
|
295
|
+
# Expire the first cookie
|
296
|
+
jar.add(url, cookie_from_hash(values.merge( :expires => Time.now - (10 * 86400))))
|
297
|
+
assert_equal(1, jar.cookies(url).length)
|
298
|
+
|
299
|
+
# Expire the second cookie
|
300
|
+
jar.add(url, cookie_from_hash(values.merge( :name => 'Baz',
|
301
|
+
:expires => Time.now - (10 * 86400))))
|
302
|
+
assert_equal(0, jar.cookies(url).length)
|
303
|
+
end
|
304
|
+
|
305
|
+
|
306
|
+
def test_save_and_read_cookiestxt
|
307
|
+
values = { :name => 'Foo',
|
308
|
+
:value => 'Bar',
|
309
|
+
:path => '/',
|
310
|
+
:expires => Time.now + (10 * 86400),
|
311
|
+
:domain => 'rubyforge.org'
|
312
|
+
}
|
313
|
+
url = URI.parse('http://rubyforge.org/')
|
314
|
+
|
315
|
+
jar = WWW::Mechanize::CookieJar.new
|
316
|
+
assert_equal(0, jar.cookies(url).length)
|
317
|
+
|
318
|
+
# Add one cookie with an expiration date in the future
|
319
|
+
cookie = cookie_from_hash(values)
|
320
|
+
jar.add(url, cookie)
|
321
|
+
jar.add(url, cookie_from_hash(values.merge( :name => 'Baz' )))
|
322
|
+
assert_equal(2, jar.cookies(url).length)
|
323
|
+
|
324
|
+
jar.save_as("cookies.txt", :cookiestxt)
|
325
|
+
jar.clear!
|
326
|
+
assert_equal(0, jar.cookies(url).length)
|
327
|
+
|
328
|
+
jar.load("cookies.txt", :cookiestxt)
|
329
|
+
assert_equal(2, jar.cookies(url).length)
|
330
|
+
|
331
|
+
FileUtils.rm("cookies.txt")
|
332
|
+
end
|
333
|
+
|
334
|
+
def test_ssl_cookies
|
335
|
+
# thanks to michal "ocher" ochman for reporting the bug responsible for this test.
|
336
|
+
values = { :name => 'Foo',
|
337
|
+
:value => 'Bar',
|
338
|
+
:path => '/login',
|
339
|
+
:expires => nil,
|
340
|
+
:domain => 'rubyforge.org'
|
341
|
+
}
|
342
|
+
values_ssl = { :name => 'Foo',
|
343
|
+
:value => 'Bar',
|
344
|
+
:path => '/login',
|
345
|
+
:expires => nil,
|
346
|
+
:domain => 'rubyforge.org:443'
|
347
|
+
}
|
348
|
+
url = URI.parse('https://rubyforge.org/login')
|
349
|
+
|
350
|
+
jar = WWW::Mechanize::CookieJar.new
|
351
|
+
assert_equal(0, jar.cookies(url).length)
|
352
|
+
|
353
|
+
cookie = cookie_from_hash(values)
|
354
|
+
jar.add(url, cookie)
|
355
|
+
assert_equal(1, jar.cookies(url).length, "did not handle SSL cookie")
|
356
|
+
|
357
|
+
cookie = cookie_from_hash(values_ssl)
|
358
|
+
jar.add(url, cookie)
|
359
|
+
assert_equal(2, jar.cookies(url).length, "did not handle SSL cookie with :443")
|
360
|
+
end
|
361
|
+
|
362
|
+
end
|