rubyforge 0.0.0 → 1.0.4
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/History.txt +100 -0
- data/Manifest.txt +11 -0
- data/README.txt +58 -0
- data/Rakefile +34 -0
- data/bin/rubyforge +231 -438
- data/lib/rubyforge/client.rb +145 -0
- data/lib/rubyforge/cookie_manager.rb +60 -0
- data/lib/rubyforge.rb +493 -0
- data/test/test_rubyforge.rb +400 -0
- data/test/test_rubyforge_client.rb +122 -0
- data/test/test_rubyforge_cookie_manager.rb +97 -0
- metadata +80 -32
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
require 'test/unit' unless defined? $ZENTEST and $ZENTEST
|
|
2
|
+
|
|
3
|
+
$TESTING = true
|
|
4
|
+
require 'rubyforge'
|
|
5
|
+
require 'tmpdir'
|
|
6
|
+
|
|
7
|
+
class RubyForge
|
|
8
|
+
attr_writer :client
|
|
9
|
+
|
|
10
|
+
alias :old_save_autoconfig :save_autoconfig
|
|
11
|
+
def save_autoconfig
|
|
12
|
+
# raise "not during test"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class RubyForge::FakeClient
|
|
17
|
+
def form; end
|
|
18
|
+
def save_cookie_store(*args) end
|
|
19
|
+
|
|
20
|
+
def post_content(*args)
|
|
21
|
+
FakeRubyForge::HTML
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def get_content(*args)
|
|
25
|
+
URI::HTTP.data.join("\n")
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class FakeRubyForge < RubyForge
|
|
30
|
+
HTML = "blah blah <form action=\"/frs/admin/editrelease.php?group_id=440&release_id=6948&package_id=491\" method=\"post\"> blah blah"
|
|
31
|
+
|
|
32
|
+
attr_accessor :page, :form, :extheader, :requests, :scrape
|
|
33
|
+
def run(page, form, extheader={})
|
|
34
|
+
@page, @form, @extheader = page, form, extheader
|
|
35
|
+
@requests ||= []
|
|
36
|
+
@requests << { :url => page, :form => form, :headers => extheader }
|
|
37
|
+
HTML
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def scrape_project(proj)
|
|
41
|
+
@scrape ||= []
|
|
42
|
+
@scrape << proj
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# TODO: remove this and make rubyforge use Client exclusively
|
|
47
|
+
class URI::HTTP
|
|
48
|
+
def self.data
|
|
49
|
+
@data ||= []
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def read
|
|
53
|
+
self.class.data.shift or raise "no more data"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
class TestRubyForge < Test::Unit::TestCase
|
|
58
|
+
def setup
|
|
59
|
+
srand(0)
|
|
60
|
+
util_new FakeRubyForge
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def teardown
|
|
64
|
+
File.unlink @cookie_path if defined? @cookie_path
|
|
65
|
+
# if defined? @old_autoconfig then
|
|
66
|
+
# @rubyforge.autoconfig.replace @old_autoconfig
|
|
67
|
+
# @rubyforge.save_autoconfig
|
|
68
|
+
# end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def test_new_with_proxy_uses_a_proxy_class
|
|
72
|
+
client = RubyForge::Client.new('http://localhost:8808/')
|
|
73
|
+
assert client.agent_class.proxy_class?, 'agent class should be a proxy'
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_new_with_bad_proxy_uses_normal_http
|
|
77
|
+
client = RubyForge::Client.new('asdfkjhalksdfjh')
|
|
78
|
+
assert !client.agent_class.proxy_class?, 'agent class should not be a proxy'
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_initialize_bad
|
|
82
|
+
@cookie_path = File.join(Dir.tmpdir, "cookie.#{$$}.dat")
|
|
83
|
+
File.open(@cookie_path, 'w') {} # touch
|
|
84
|
+
|
|
85
|
+
user_data = {
|
|
86
|
+
"uri" => "http://rubyforge.org",
|
|
87
|
+
"is_private" => false,
|
|
88
|
+
"cookie_jar" => @cookie_path,
|
|
89
|
+
"username" => "username",
|
|
90
|
+
"password" => "password"
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
assert_raise RuntimeError do
|
|
94
|
+
rf = RubyForge.new user_data
|
|
95
|
+
rf.configure "username" => nil
|
|
96
|
+
end
|
|
97
|
+
assert_raise RuntimeError do
|
|
98
|
+
rf = RubyForge.new user_data
|
|
99
|
+
rf.configure "password" => nil
|
|
100
|
+
end
|
|
101
|
+
assert_raise RuntimeError do
|
|
102
|
+
rf = RubyForge.new user_data
|
|
103
|
+
rf.configure "cookie_jar" => nil
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def test_setup
|
|
108
|
+
# TODO raise NotImplementedError, 'Need to write test_setup'
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def test_login
|
|
112
|
+
u, p = 'fooby', 's3kr3t'
|
|
113
|
+
@rubyforge.userconfig['username'] = u
|
|
114
|
+
@rubyforge.userconfig['password'] = p
|
|
115
|
+
@rubyforge.login
|
|
116
|
+
|
|
117
|
+
util_run('https://rubyforge.org/account/login.php',
|
|
118
|
+
'form_pw' => p,
|
|
119
|
+
'form_loginname' => u,
|
|
120
|
+
'return_to' => '',
|
|
121
|
+
'login' => 'Login')
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def test_create_package
|
|
125
|
+
@rubyforge.create_package(42, 'woot_pkg')
|
|
126
|
+
|
|
127
|
+
util_run('/frs/admin/index.php',
|
|
128
|
+
"submit" => "Create This Package",
|
|
129
|
+
"group_id" => 42,
|
|
130
|
+
"is_public" => 1,
|
|
131
|
+
"package_name" => "woot_pkg",
|
|
132
|
+
"func" => "add_package")
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def test_delete_package
|
|
136
|
+
@rubyforge.delete_package(42, 666)
|
|
137
|
+
util_delete_package
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def test_delete_package_package_name
|
|
141
|
+
@rubyforge.delete_package(42, "woot_pkg")
|
|
142
|
+
util_delete_package
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def test_delete_package_undefined_package_name
|
|
146
|
+
assert_raise RuntimeError do
|
|
147
|
+
@rubyforge.delete_package(42, "blah")
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def test_delete_package_group_name
|
|
152
|
+
@rubyforge.delete_package("seattlerb", 666)
|
|
153
|
+
util_delete_package
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def test_delete_package_undefined_group_name
|
|
157
|
+
assert_raise RuntimeError do
|
|
158
|
+
@rubyforge.delete_package("blah", 666)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def test_add_file
|
|
163
|
+
@rubyforge.autoconfig["package_ids"]["ringy_dingy"] = 314
|
|
164
|
+
@rubyforge.autoconfig["release_ids"]["ringy_dingy"] ||= {}
|
|
165
|
+
@rubyforge.autoconfig["release_ids"]["ringy_dingy"]["1.2.3"] = 43
|
|
166
|
+
|
|
167
|
+
@rubyforge.add_file('seattlerb', 'ringy_dingy', '1.2.3', __FILE__)
|
|
168
|
+
|
|
169
|
+
util_run('/frs/admin/editrelease.php?group_id=42&release_id=43&package_id=314',
|
|
170
|
+
{ "step2" => 1,
|
|
171
|
+
"type_id" => 9999,
|
|
172
|
+
"processor_id" => 8000,
|
|
173
|
+
"submit" => "Add This File"},
|
|
174
|
+
{"content-type"=> "multipart/form-data; boundary=___00__03__03__39__09__19__21__36___"})
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def test_add_release
|
|
178
|
+
@rubyforge.add_release(42, 666, '1.2.3', __FILE__)
|
|
179
|
+
util_add_release
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def test_add_release_multiple
|
|
183
|
+
@rubyforge.add_release(42, 666, '1.2.3', __FILE__, __FILE__) # dunno if that'll work
|
|
184
|
+
add_release = ({ :url=>"/frs/admin/qrs.php",
|
|
185
|
+
:form=>{"processor_id"=>8000,
|
|
186
|
+
"submit"=>"Release File",
|
|
187
|
+
"preformatted"=>0,
|
|
188
|
+
"release_changes"=>nil,
|
|
189
|
+
"type_id"=>9999,
|
|
190
|
+
"group_id"=>42,
|
|
191
|
+
"release_name"=>"1.2.3",
|
|
192
|
+
"release_notes"=>nil,
|
|
193
|
+
"package_id"=>666,
|
|
194
|
+
"release_date"=>"today"},
|
|
195
|
+
:headers=> {"content-type" => "multipart/form-data; boundary=___00__03__03__39__09__19__21__36___"}})
|
|
196
|
+
add_file = ({ :url => '/frs/admin/editrelease.php?group_id=42&release_id=6948&package_id=666',
|
|
197
|
+
:form => { "step2" => 1,
|
|
198
|
+
"type_id" => 9999,
|
|
199
|
+
"processor_id" => 8000,
|
|
200
|
+
"submit" => "Add This File"},
|
|
201
|
+
:headers => {"content-type"=> "multipart/form-data; boundary=___23__06__24__24__12__01__38__39___"}})
|
|
202
|
+
expected = [add_release, add_file]
|
|
203
|
+
|
|
204
|
+
result = @rubyforge.requests
|
|
205
|
+
result.each do |r|
|
|
206
|
+
r[:form].delete "userfile"
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
assert_equal expected, result
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def test_post_news
|
|
213
|
+
@rubyforge.post_news("seattlerb", "my summary", "my news")
|
|
214
|
+
|
|
215
|
+
util_run("/news/submit.php",
|
|
216
|
+
"group_id" => 42,
|
|
217
|
+
"post_changes" => "y",
|
|
218
|
+
"details" => "my news",
|
|
219
|
+
"summary" => "my summary",
|
|
220
|
+
"submit" => "Submit")
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def test_add_release_package_name
|
|
224
|
+
@rubyforge.add_release(42, "woot_pkg", '1.2.3', __FILE__)
|
|
225
|
+
util_add_release
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def test_add_release_undefined_package_name
|
|
229
|
+
assert_raise RuntimeError do
|
|
230
|
+
@rubyforge.add_release(42, "blah", '1.2.3', __FILE__)
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def test_add_release_group_name
|
|
235
|
+
@rubyforge.add_release("seattlerb", 666, '1.2.3', __FILE__)
|
|
236
|
+
util_add_release
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def test_add_release_undefined_group_name
|
|
240
|
+
assert_raise RuntimeError do
|
|
241
|
+
@rubyforge.add_release("blah", 666, '1.2.3', __FILE__)
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def test_lookup_id
|
|
246
|
+
assert_equal 43, @rubyforge.lookup("package", 43)
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def test_lookup_string_number
|
|
250
|
+
assert_raise RuntimeError do
|
|
251
|
+
@rubyforge.lookup("package", "43")
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def test_lookup_name
|
|
256
|
+
@rubyforge.autoconfig["package_ids"]["ringy_dingy"] = 314
|
|
257
|
+
assert_equal 314, @rubyforge.lookup("package", "ringy_dingy")
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def test_lookup_undefined
|
|
261
|
+
assert_raise RuntimeError do
|
|
262
|
+
@rubyforge.lookup("package", "blah")
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def test_run
|
|
267
|
+
util_new FakeRubyForge
|
|
268
|
+
result = @rubyforge.add_release(42, 666, '1.2.3', __FILE__)
|
|
269
|
+
|
|
270
|
+
assert_equal 6948, result
|
|
271
|
+
extheader = {"content-type"=> "multipart/form-data; boundary=___00__03__03__39__09__19__21__36___"}
|
|
272
|
+
|
|
273
|
+
form = {
|
|
274
|
+
"processor_id" => 8000,
|
|
275
|
+
"submit" => "Release File",
|
|
276
|
+
"preformatted" => 0,
|
|
277
|
+
"release_changes" => nil,
|
|
278
|
+
"type_id" => 9999,
|
|
279
|
+
"group_id" => 42,
|
|
280
|
+
"release_name" => "1.2.3",
|
|
281
|
+
"release_notes" => nil,
|
|
282
|
+
"package_id" => 666,
|
|
283
|
+
"release_date" => "today"
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
client = @rubyforge.client
|
|
287
|
+
# assert client.form.delete("userfile")
|
|
288
|
+
|
|
289
|
+
# assert_equal 'http://rubyforge.org/frs/admin/qrs.php', client.url.to_s
|
|
290
|
+
# assert_equal form, client.form
|
|
291
|
+
# assert_equal extheader, client.headers
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def test_scrape_project
|
|
295
|
+
orig_stdout = $stdout
|
|
296
|
+
orig_stderr = $stderr
|
|
297
|
+
$stdout = StringIO.new
|
|
298
|
+
$stderr = StringIO.new
|
|
299
|
+
util_new RubyForge # TODO: switch to Fake
|
|
300
|
+
@rubyforge.autoconfig.each { |k,v| v.clear }
|
|
301
|
+
|
|
302
|
+
URI::HTTP.data << "<a href='/tracker/?group_id=1513'>Tracker</a>"
|
|
303
|
+
URI::HTTP.data << <<-EOF
|
|
304
|
+
<h3>ar_mailer
|
|
305
|
+
<a href="/frs/monitor.php?filemodule_id=4566&group_id=1513&start=1">
|
|
306
|
+
<a href="shownotes.php?release_id=13368">1.3.1</a>
|
|
307
|
+
<a href="shownotes.php?release_id=12185">1.2.0</a></strong>
|
|
308
|
+
EOF
|
|
309
|
+
|
|
310
|
+
# @rubyforge.scrape << < <-EOF
|
|
311
|
+
URI::HTTP.data << <<-EOF
|
|
312
|
+
<select name="processor_id">
|
|
313
|
+
<option value="100">Must Choose One</option>
|
|
314
|
+
<option value="1000">i386</option>
|
|
315
|
+
<option value="1001">i387</option>
|
|
316
|
+
</select>
|
|
317
|
+
EOF
|
|
318
|
+
|
|
319
|
+
@rubyforge.scrape_project('my_project')
|
|
320
|
+
|
|
321
|
+
expected = {
|
|
322
|
+
"group_ids" => { "my_project" => 1513 },
|
|
323
|
+
"package_ids" => { "ar_mailer" => 4566 },
|
|
324
|
+
"processor_ids" => { "i386" => 1000, "i387" => 1001 },
|
|
325
|
+
"release_ids" => {
|
|
326
|
+
"ar_mailer" => { "1.2.0" => 12185, "1.3.1" => 13368 }
|
|
327
|
+
},
|
|
328
|
+
"type_ids" => {},
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
assert_equal expected, @rubyforge.autoconfig
|
|
332
|
+
ensure
|
|
333
|
+
$stdout = orig_stdout
|
|
334
|
+
$stderr = orig_stderr
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def util_new(klass)
|
|
338
|
+
@cookie_path = File.join(Dir.tmpdir, "cookie.#{$$}.dat")
|
|
339
|
+
File.open(@cookie_path, 'w') {} # touch
|
|
340
|
+
|
|
341
|
+
user_data = {
|
|
342
|
+
"uri" => "http://rubyforge.org",
|
|
343
|
+
"is_private" => false,
|
|
344
|
+
"cookie_jar" => @cookie_path,
|
|
345
|
+
"username" => "username",
|
|
346
|
+
"password" => "password"
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
auto_data = {
|
|
350
|
+
"group_ids" => {},
|
|
351
|
+
"package_ids" => {},
|
|
352
|
+
"release_ids" => Hash.new { |h,k| h[k] = {} },
|
|
353
|
+
"type_ids" => {},
|
|
354
|
+
"processor_ids" => {"Any"=>8000},
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
@rubyforge = klass.new user_data, auto_data
|
|
358
|
+
|
|
359
|
+
@rubyforge.client = RubyForge::FakeClient.new
|
|
360
|
+
|
|
361
|
+
@rubyforge.userconfig["release_date"] = "today"
|
|
362
|
+
@rubyforge.autoconfig["type_ids"][".rb"] = 9999
|
|
363
|
+
@rubyforge.autoconfig["group_ids"]["seattlerb"] = 42
|
|
364
|
+
@rubyforge.autoconfig["package_ids"]["woot_pkg"] = 666
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
def util_run(page, form={}, extheader={})
|
|
368
|
+
form_result = @rubyforge.form
|
|
369
|
+
assert form_result.delete("userfile") unless extheader.empty?
|
|
370
|
+
|
|
371
|
+
assert_equal page, @rubyforge.page.to_s
|
|
372
|
+
assert_equal form, form_result
|
|
373
|
+
assert_equal extheader, @rubyforge.extheader
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
def util_add_release
|
|
377
|
+
util_run('/frs/admin/qrs.php',
|
|
378
|
+
{"processor_id" => 8000,
|
|
379
|
+
"submit" => "Release File",
|
|
380
|
+
"preformatted" => 0,
|
|
381
|
+
"release_changes" => nil,
|
|
382
|
+
"type_id" => 9999,
|
|
383
|
+
"group_id" => 42,
|
|
384
|
+
"release_name" => "1.2.3",
|
|
385
|
+
"release_notes" => nil,
|
|
386
|
+
"package_id" => 666,
|
|
387
|
+
"release_date" => "today"},
|
|
388
|
+
{"content-type"=> "multipart/form-data; boundary=___00__03__03__39__09__19__21__36___"})
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
def util_delete_package
|
|
392
|
+
util_run('/frs/admin/index.php',
|
|
393
|
+
"submit" => "Delete",
|
|
394
|
+
"really_sure" => "1",
|
|
395
|
+
"group_id" => 42,
|
|
396
|
+
"func" => "delete_package",
|
|
397
|
+
"package_id" => 666,
|
|
398
|
+
"sure" => "1")
|
|
399
|
+
end
|
|
400
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
require 'test/unit' unless defined? $ZENTEST and $ZENTEST
|
|
2
|
+
require 'rubyforge'
|
|
3
|
+
|
|
4
|
+
class RubyForge::FakeAgent
|
|
5
|
+
class << self
|
|
6
|
+
attr_accessor :t_data, :t_request
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def initialize(*args)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def request(request, data)
|
|
13
|
+
self.class.t_request = request
|
|
14
|
+
self.class.t_data = data
|
|
15
|
+
response = Net::HTTPOK.new('1.1', 200, '')
|
|
16
|
+
def response.read_body; ''; end
|
|
17
|
+
return response
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class Post
|
|
21
|
+
def initialize(*args)
|
|
22
|
+
@args = args
|
|
23
|
+
@stuff = {}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def [] key
|
|
27
|
+
@stuff[key.downcase]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def []= key, val
|
|
31
|
+
@stuff[key.downcase] = val
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def method_missing(*stuff)
|
|
35
|
+
# warn stuff.inspect
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class TestRubyForgeClient < Test::Unit::TestCase
|
|
41
|
+
def setup
|
|
42
|
+
@client = RubyForge::Client.new
|
|
43
|
+
@client.agent_class = RubyForge::FakeAgent
|
|
44
|
+
RubyForge::FakeAgent.t_data = :unassigned
|
|
45
|
+
RubyForge::FakeAgent.t_request = :unassigned
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def test_post_with_params
|
|
49
|
+
@client.post_content('http://example.com', { :f => 'adsf aoeu'})
|
|
50
|
+
assert_equal('f=adsf+aoeu', RubyForge::FakeAgent.t_data)
|
|
51
|
+
|
|
52
|
+
@client.post_content('http://example.com', { :a => 'b', :c => 'd' })
|
|
53
|
+
assert_equal('a=b&c=d', RubyForge::FakeAgent.t_data)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_multipart_post_one_param
|
|
57
|
+
random = Array::new(8){ "%2.2d" % rand(42) }.join('__')
|
|
58
|
+
boundary = "multipart/form-data; boundary=___#{ random }___"
|
|
59
|
+
|
|
60
|
+
expected = <<-END
|
|
61
|
+
--___#{random}___\r
|
|
62
|
+
Content-Disposition: form-data; name="a"\r\n\r
|
|
63
|
+
a b c\r
|
|
64
|
+
--___#{random}___--\r
|
|
65
|
+
END
|
|
66
|
+
|
|
67
|
+
@client.post_content( 'http://example.com',
|
|
68
|
+
{ :a => 'a b c' },
|
|
69
|
+
{ 'content-type' => boundary }
|
|
70
|
+
)
|
|
71
|
+
assert_equal(expected, RubyForge::FakeAgent.t_data)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def test_multipart_post_two_params
|
|
75
|
+
random = Array::new(8){ "%2.2d" % rand(42) }.join('__')
|
|
76
|
+
boundary = "multipart/form-data; boundary=___#{ random }___"
|
|
77
|
+
|
|
78
|
+
request = <<-END
|
|
79
|
+
--___#{random}___\r
|
|
80
|
+
Content-Disposition: form-data; name="a"\r\n\r
|
|
81
|
+
b\r
|
|
82
|
+
--___#{random}___\r
|
|
83
|
+
Content-Disposition: form-data; name="c"\r\n\r
|
|
84
|
+
d\r
|
|
85
|
+
--___#{random}___--\r
|
|
86
|
+
END
|
|
87
|
+
|
|
88
|
+
@client.post_content( 'http://example.com',
|
|
89
|
+
{ :a => 'b', :c => 'd' },
|
|
90
|
+
{ 'content-type' => boundary }
|
|
91
|
+
)
|
|
92
|
+
assert_equal(request, RubyForge::FakeAgent.t_data)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def test_multipart_io
|
|
96
|
+
random = Array::new(8){ "%2.2d" % rand(42) }.join('__')
|
|
97
|
+
boundary = "multipart/form-data; boundary=___#{ random }___"
|
|
98
|
+
|
|
99
|
+
file_contents = 'blah blah blah'
|
|
100
|
+
file = StringIO.new(file_contents)
|
|
101
|
+
class << file
|
|
102
|
+
def path
|
|
103
|
+
'/one/two/three.rb'
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
request = <<-END
|
|
108
|
+
--___#{random}___\r
|
|
109
|
+
Content-Disposition: form-data; name="userfile"; filename="three.rb"\r
|
|
110
|
+
Content-Transfer-Encoding: binary\r
|
|
111
|
+
Content-Type: text/plain\r\n\r
|
|
112
|
+
#{file_contents}\r
|
|
113
|
+
--___#{random}___--\r
|
|
114
|
+
END
|
|
115
|
+
|
|
116
|
+
@client.post_content( 'http://example.com',
|
|
117
|
+
{ :userfile => file },
|
|
118
|
+
{ 'content-type' => boundary }
|
|
119
|
+
)
|
|
120
|
+
assert_equal(request, RubyForge::FakeAgent.t_data)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
require 'test/unit' unless defined? $ZENTEST and $ZENTEST
|
|
2
|
+
require 'rubyforge'
|
|
3
|
+
require 'time'
|
|
4
|
+
require 'yaml'
|
|
5
|
+
require 'tempfile'
|
|
6
|
+
|
|
7
|
+
class TestRubyForgeCookieManager < Test::Unit::TestCase
|
|
8
|
+
def setup
|
|
9
|
+
cookie = cookie_string('session_ser', 'zzzzzzzzzzzzzzzzzz')
|
|
10
|
+
@url = URI.parse('http://rubyforge.org/account/login.php')
|
|
11
|
+
@cookie = WEBrick::Cookie.parse_set_cookie(cookie)
|
|
12
|
+
@manager = RubyForge::CookieManager.new
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_empty?
|
|
16
|
+
manager = RubyForge::CookieManager.new
|
|
17
|
+
assert(manager.empty?)
|
|
18
|
+
|
|
19
|
+
assert_equal(0, manager[URI.parse('http://rubyforge.org/')].length)
|
|
20
|
+
assert(manager.empty?)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_add
|
|
24
|
+
manager = RubyForge::CookieManager.new
|
|
25
|
+
assert(manager.empty?)
|
|
26
|
+
manager.add(@url, @cookie)
|
|
27
|
+
assert(!manager.empty?)
|
|
28
|
+
|
|
29
|
+
cookie = manager[@url][@cookie.name]
|
|
30
|
+
assert cookie
|
|
31
|
+
assert_equal(@cookie.object_id, cookie.object_id)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_add_expired_cookie
|
|
35
|
+
cookie = cookie_string('session_ser', 'zzzz',
|
|
36
|
+
:expires => (Time.now - 10).strftime('%A, %d-%b-%Y %H:%M:%S %Z'))
|
|
37
|
+
cookie = WEBrick::Cookie.parse_set_cookie(cookie)
|
|
38
|
+
|
|
39
|
+
manager = RubyForge::CookieManager.new
|
|
40
|
+
assert(manager.empty?)
|
|
41
|
+
manager.add(@url, cookie)
|
|
42
|
+
assert(manager.empty?)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_marshal
|
|
46
|
+
@manager.add(@url, @cookie)
|
|
47
|
+
assert(!@manager.empty?)
|
|
48
|
+
m = YAML.load(YAML.dump(@manager))
|
|
49
|
+
assert(!m.empty?)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def test_save!
|
|
53
|
+
tmp = Tempfile.new('cookie_jar')
|
|
54
|
+
@manager.cookies_file = tmp.path
|
|
55
|
+
@manager.add(@url, @cookie)
|
|
56
|
+
@manager.save!
|
|
57
|
+
|
|
58
|
+
@manager = RubyForge::CookieManager.load(tmp.path)
|
|
59
|
+
assert(! @manager.empty?)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def test_load_empty_file
|
|
63
|
+
tmp = Tempfile.new('cookie_jar')
|
|
64
|
+
manager = RubyForge::CookieManager.load(tmp.path)
|
|
65
|
+
assert(manager.empty?)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def test_load_legacy_file
|
|
69
|
+
tmp = Tempfile.new('cookie_jar')
|
|
70
|
+
tmp.write([
|
|
71
|
+
'https://rubyforge.org/account/login.php',
|
|
72
|
+
'session_ser',
|
|
73
|
+
'zzzzzz',
|
|
74
|
+
'123456',
|
|
75
|
+
'.rubyforge.org',
|
|
76
|
+
'/',
|
|
77
|
+
'13'
|
|
78
|
+
].join("\t"))
|
|
79
|
+
manager = RubyForge::CookieManager.load(tmp.path)
|
|
80
|
+
assert(manager.empty?)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def test_cookies_file=
|
|
84
|
+
tmp = Tempfile.new('cookie_jar')
|
|
85
|
+
@manager.cookies_file = tmp.path
|
|
86
|
+
assert(@manager.empty?)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def cookie_string(name, value, options = {})
|
|
90
|
+
options = {
|
|
91
|
+
:expires => (Time.now + 86400).strftime('%A, %d-%b-%Y %H:%M:%S %Z'),
|
|
92
|
+
:path => '/',
|
|
93
|
+
:domain => '.rubyforge.org',
|
|
94
|
+
}.merge(options)
|
|
95
|
+
"#{name}=#{value}; #{options.map { |o| o.join('=') }.join('; ')}"
|
|
96
|
+
end
|
|
97
|
+
end
|