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.
Files changed (173) hide show
  1. data/CHANGELOG.rdoc +496 -0
  2. data/EXAMPLES.rdoc +171 -0
  3. data/FAQ.rdoc +11 -0
  4. data/GUIDE.rdoc +122 -0
  5. data/LICENSE.rdoc +340 -0
  6. data/Manifest.txt +169 -0
  7. data/README.rdoc +60 -0
  8. data/Rakefile +43 -0
  9. data/examples/flickr_upload.rb +23 -0
  10. data/examples/mech-dump.rb +7 -0
  11. data/examples/proxy_req.rb +9 -0
  12. data/examples/rubyforge.rb +21 -0
  13. data/examples/spider.rb +11 -0
  14. data/lib/mechanize.rb +7 -0
  15. data/lib/www/mechanize/chain/auth_headers.rb +80 -0
  16. data/lib/www/mechanize/chain/body_decoding_handler.rb +48 -0
  17. data/lib/www/mechanize/chain/connection_resolver.rb +78 -0
  18. data/lib/www/mechanize/chain/custom_headers.rb +23 -0
  19. data/lib/www/mechanize/chain/handler.rb +9 -0
  20. data/lib/www/mechanize/chain/header_resolver.rb +53 -0
  21. data/lib/www/mechanize/chain/parameter_resolver.rb +24 -0
  22. data/lib/www/mechanize/chain/post_connect_hook.rb +0 -0
  23. data/lib/www/mechanize/chain/pre_connect_hook.rb +22 -0
  24. data/lib/www/mechanize/chain/request_resolver.rb +32 -0
  25. data/lib/www/mechanize/chain/response_body_parser.rb +40 -0
  26. data/lib/www/mechanize/chain/response_header_handler.rb +50 -0
  27. data/lib/www/mechanize/chain/response_reader.rb +41 -0
  28. data/lib/www/mechanize/chain/ssl_resolver.rb +42 -0
  29. data/lib/www/mechanize/chain/uri_resolver.rb +77 -0
  30. data/lib/www/mechanize/chain.rb +34 -0
  31. data/lib/www/mechanize/content_type_error.rb +16 -0
  32. data/lib/www/mechanize/cookie.rb +72 -0
  33. data/lib/www/mechanize/cookie_jar.rb +191 -0
  34. data/lib/www/mechanize/file.rb +73 -0
  35. data/lib/www/mechanize/file_response.rb +62 -0
  36. data/lib/www/mechanize/file_saver.rb +39 -0
  37. data/lib/www/mechanize/form/button.rb +8 -0
  38. data/lib/www/mechanize/form/check_box.rb +13 -0
  39. data/lib/www/mechanize/form/field.rb +28 -0
  40. data/lib/www/mechanize/form/file_upload.rb +24 -0
  41. data/lib/www/mechanize/form/image_button.rb +23 -0
  42. data/lib/www/mechanize/form/multi_select_list.rb +69 -0
  43. data/lib/www/mechanize/form/option.rb +51 -0
  44. data/lib/www/mechanize/form/radio_button.rb +38 -0
  45. data/lib/www/mechanize/form/select_list.rb +45 -0
  46. data/lib/www/mechanize/form.rb +360 -0
  47. data/lib/www/mechanize/headers.rb +12 -0
  48. data/lib/www/mechanize/history.rb +67 -0
  49. data/lib/www/mechanize/inspect.rb +90 -0
  50. data/lib/www/mechanize/monkey_patch.rb +37 -0
  51. data/lib/www/mechanize/page/base.rb +10 -0
  52. data/lib/www/mechanize/page/frame.rb +22 -0
  53. data/lib/www/mechanize/page/link.rb +50 -0
  54. data/lib/www/mechanize/page/meta.rb +51 -0
  55. data/lib/www/mechanize/page.rb +176 -0
  56. data/lib/www/mechanize/pluggable_parsers.rb +103 -0
  57. data/lib/www/mechanize/redirect_limit_reached_error.rb +18 -0
  58. data/lib/www/mechanize/redirect_not_get_or_head_error.rb +20 -0
  59. data/lib/www/mechanize/response_code_error.rb +25 -0
  60. data/lib/www/mechanize/unsupported_scheme_error.rb +10 -0
  61. data/lib/www/mechanize/util.rb +76 -0
  62. data/lib/www/mechanize.rb +619 -0
  63. data/mechanize.gemspec +41 -0
  64. data/test/chain/test_argument_validator.rb +14 -0
  65. data/test/chain/test_auth_headers.rb +25 -0
  66. data/test/chain/test_custom_headers.rb +18 -0
  67. data/test/chain/test_header_resolver.rb +28 -0
  68. data/test/chain/test_parameter_resolver.rb +35 -0
  69. data/test/chain/test_request_resolver.rb +29 -0
  70. data/test/chain/test_response_reader.rb +24 -0
  71. data/test/data/htpasswd +1 -0
  72. data/test/data/server.crt +16 -0
  73. data/test/data/server.csr +12 -0
  74. data/test/data/server.key +15 -0
  75. data/test/data/server.pem +15 -0
  76. data/test/helper.rb +129 -0
  77. data/test/htdocs/alt_text.html +10 -0
  78. data/test/htdocs/bad_form_test.html +9 -0
  79. data/test/htdocs/button.jpg +0 -0
  80. data/test/htdocs/empty_form.html +6 -0
  81. data/test/htdocs/file_upload.html +26 -0
  82. data/test/htdocs/find_link.html +41 -0
  83. data/test/htdocs/form_multi_select.html +16 -0
  84. data/test/htdocs/form_multival.html +37 -0
  85. data/test/htdocs/form_no_action.html +18 -0
  86. data/test/htdocs/form_no_input_name.html +16 -0
  87. data/test/htdocs/form_select.html +16 -0
  88. data/test/htdocs/form_select_all.html +16 -0
  89. data/test/htdocs/form_select_none.html +17 -0
  90. data/test/htdocs/form_select_noopts.html +10 -0
  91. data/test/htdocs/form_set_fields.html +14 -0
  92. data/test/htdocs/form_test.html +188 -0
  93. data/test/htdocs/frame_test.html +30 -0
  94. data/test/htdocs/google.html +13 -0
  95. data/test/htdocs/iframe_test.html +16 -0
  96. data/test/htdocs/index.html +6 -0
  97. data/test/htdocs/link with space.html +5 -0
  98. data/test/htdocs/meta_cookie.html +11 -0
  99. data/test/htdocs/no_title_test.html +6 -0
  100. data/test/htdocs/relative/tc_relative_links.html +21 -0
  101. data/test/htdocs/tc_bad_links.html +5 -0
  102. data/test/htdocs/tc_base_link.html +8 -0
  103. data/test/htdocs/tc_blank_form.html +11 -0
  104. data/test/htdocs/tc_checkboxes.html +19 -0
  105. data/test/htdocs/tc_encoded_links.html +5 -0
  106. data/test/htdocs/tc_follow_meta.html +8 -0
  107. data/test/htdocs/tc_form_action.html +48 -0
  108. data/test/htdocs/tc_links.html +18 -0
  109. data/test/htdocs/tc_no_attributes.html +16 -0
  110. data/test/htdocs/tc_pretty_print.html +17 -0
  111. data/test/htdocs/tc_radiobuttons.html +17 -0
  112. data/test/htdocs/tc_referer.html +10 -0
  113. data/test/htdocs/tc_relative_links.html +19 -0
  114. data/test/htdocs/tc_textarea.html +23 -0
  115. data/test/htdocs/unusual______.html +5 -0
  116. data/test/servlets.rb +365 -0
  117. data/test/ssl_server.rb +48 -0
  118. data/test/test_authenticate.rb +71 -0
  119. data/test/test_bad_links.rb +25 -0
  120. data/test/test_blank_form.rb +16 -0
  121. data/test/test_checkboxes.rb +61 -0
  122. data/test/test_content_type.rb +13 -0
  123. data/test/test_cookie_class.rb +338 -0
  124. data/test/test_cookie_jar.rb +362 -0
  125. data/test/test_cookies.rb +123 -0
  126. data/test/test_encoded_links.rb +20 -0
  127. data/test/test_errors.rb +49 -0
  128. data/test/test_follow_meta.rb +108 -0
  129. data/test/test_form_action.rb +44 -0
  130. data/test/test_form_as_hash.rb +61 -0
  131. data/test/test_form_button.rb +38 -0
  132. data/test/test_form_no_inputname.rb +15 -0
  133. data/test/test_forms.rb +564 -0
  134. data/test/test_frames.rb +25 -0
  135. data/test/test_get_headers.rb +52 -0
  136. data/test/test_gzipping.rb +22 -0
  137. data/test/test_hash_api.rb +45 -0
  138. data/test/test_history.rb +142 -0
  139. data/test/test_history_added.rb +16 -0
  140. data/test/test_html_unscape_forms.rb +39 -0
  141. data/test/test_if_modified_since.rb +20 -0
  142. data/test/test_keep_alive.rb +31 -0
  143. data/test/test_links.rb +120 -0
  144. data/test/test_mech.rb +268 -0
  145. data/test/test_mechanize_file.rb +47 -0
  146. data/test/test_meta.rb +65 -0
  147. data/test/test_multi_select.rb +106 -0
  148. data/test/test_no_attributes.rb +13 -0
  149. data/test/test_option.rb +18 -0
  150. data/test/test_page.rb +119 -0
  151. data/test/test_pluggable_parser.rb +145 -0
  152. data/test/test_post_form.rb +34 -0
  153. data/test/test_pretty_print.rb +22 -0
  154. data/test/test_radiobutton.rb +75 -0
  155. data/test/test_redirect_limit_reached.rb +41 -0
  156. data/test/test_redirect_verb_handling.rb +45 -0
  157. data/test/test_referer.rb +39 -0
  158. data/test/test_relative_links.rb +40 -0
  159. data/test/test_request.rb +13 -0
  160. data/test/test_response_code.rb +52 -0
  161. data/test/test_save_file.rb +48 -0
  162. data/test/test_scheme.rb +48 -0
  163. data/test/test_select.rb +106 -0
  164. data/test/test_select_all.rb +15 -0
  165. data/test/test_select_none.rb +15 -0
  166. data/test/test_select_noopts.rb +16 -0
  167. data/test/test_set_fields.rb +44 -0
  168. data/test/test_ssl_server.rb +20 -0
  169. data/test/test_subclass.rb +14 -0
  170. data/test/test_textarea.rb +45 -0
  171. data/test/test_upload.rb +109 -0
  172. data/test/test_verbs.rb +25 -0
  173. 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