s3restful 0.2.7

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.
@@ -0,0 +1,531 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ class ItemTest < Test::Unit::TestCase
4
+ context "An S3restful::S3::Item instance" do
5
+
6
+ setup do
7
+ S3restful::Log.level = Logger::ERROR
8
+ @item = S3restful::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :server => '127.0.0.1')
9
+
10
+ @time = "Thu, 25 Feb 2010 10:00:00 GMT"
11
+ Time.stubs(:now).returns(Time.parse(@time))
12
+ #stub(:utc_httpdate => @time, :to_i => 99, :usec => 88))
13
+ end
14
+
15
+ context "validation" do
16
+ should "require a bucket and a key" do
17
+ assert_raise(ArgumentError) do
18
+ item = S3restful::S3::Item.new()
19
+ end
20
+
21
+ assert_raise(ArgumentError) do
22
+ item = S3restful::S3::Item.new('the-key')
23
+ end
24
+
25
+ assert_nothing_raised(ArgumentError) do
26
+ item = S3restful::S3::Item.new('the-bucket', 'the-key')
27
+ end
28
+
29
+ end
30
+
31
+ should "not allow unknown options" do
32
+ assert_raise(ArgumentError) do
33
+ item = S3restful::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :lala => 'lulul')
34
+ end
35
+ end
36
+
37
+ should "check valid protocol" do
38
+ assert_raise(ArgumentError) do
39
+ item = S3restful::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :protocol => 'lulul')
40
+ end
41
+
42
+ assert_nothing_raised do
43
+ item = S3restful::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :protocol => 'http')
44
+ end
45
+
46
+ assert_nothing_raised do
47
+ item = S3restful::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :protocol => 'https')
48
+ end
49
+ end
50
+ end
51
+
52
+ context "when building the item url" do
53
+ should "build the full path out of the server, bucket, and key" do
54
+ @item = S3restful::S3::Item.new('the-bucketissoooooooooooooooooooooooooooooooooooooolonggggggggggggggggggggggggggggggggggg', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :server => '127.0.0.1')
55
+ assert_equal "https://127.0.0.1:443/the-bucketissoooooooooooooooooooooooooooooooooooooolonggggggggggggggggggggggggggggggggggg/the-key", @item.url
56
+ end
57
+
58
+ should "use the DNS bucket name where possible" do
59
+ @item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret')
60
+ assert_equal "https://bucket.s3.amazonaws.com:443/the-key", @item.url
61
+ end
62
+ end
63
+
64
+ context "when getting an item" do
65
+
66
+ should "call the on success callback" do
67
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {}, fake_response("data-here"))
68
+
69
+ called = false
70
+ data = nil
71
+ on_success = Proc.new {|http| called = true, data = http.response}
72
+ @item = S3restful::S3::Item.new('bucket', 'the-key')
73
+ run_in_em_loop do
74
+ @item.get(:on_success => on_success)
75
+
76
+ EM.add_timer(1) {
77
+ assert called
78
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {})
79
+ assert_equal "data-here\n", data
80
+ EM.stop_event_loop
81
+ }
82
+
83
+ end
84
+ end
85
+
86
+ should "support direct blocks" do
87
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {}, fake_response("data-here"))
88
+
89
+ called = false
90
+ data = nil
91
+ @item = S3restful::S3::Item.new('bucket', 'the-key')
92
+ run_in_em_loop do
93
+ @item.get do |http|
94
+ called = true
95
+ data = http.response
96
+ end
97
+
98
+ EM.add_timer(1) {
99
+ assert called
100
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {})
101
+ assert_equal "data-here\n", data
102
+ EM.stop_event_loop
103
+ }
104
+
105
+ end
106
+ end
107
+
108
+ should "support stream blocks" do
109
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {}, fake_response(""))
110
+
111
+ called = false
112
+ data = ""
113
+ @item = S3restful::S3::Item.new('bucket', 'the-key')
114
+ run_in_em_loop do
115
+ response = @item.get
116
+ response.stream do |chunk|
117
+ called = true
118
+ data << chunk
119
+ end
120
+ response.on_body_data "data-here"
121
+
122
+ EM.add_timer(1) {
123
+ assert called
124
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {})
125
+ assert_equal "data-here", data
126
+ EM.stop_event_loop
127
+ }
128
+
129
+ end
130
+ end
131
+
132
+ should "sign requests if AWS credentials are passend" do
133
+ time = "Thu, 25 Feb 2010 12:06:33 GMT"
134
+ Time.stubs(:now).returns(Time.parse(time))
135
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {"Authorization"=>"AWS abc:3OEcVbE//maUUmqh3A5ETEcr9TE=", 'date' => time}, fake_response("data-here"))
136
+
137
+ @item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
138
+ run_in_em_loop do
139
+ @item.get
140
+
141
+ EM.add_timer(1) {
142
+ EM.stop_event_loop
143
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {"Authorization"=>"AWS abc:3OEcVbE//maUUmqh3A5ETEcr9TE=", 'date' => time})
144
+ }
145
+
146
+ end
147
+ end
148
+
149
+ should "retry on error" do
150
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {}, error_response(400))
151
+
152
+ @item = S3restful::S3::Item.new('bucket', 'the-key')
153
+ run_in_em_loop do
154
+ @item.get(:on_error => Proc.new{} ) #ignore error
155
+
156
+ EM.add_timer(1) {
157
+ EM.stop_event_loop
158
+ assert_equal 5, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {})
159
+ }
160
+
161
+ end
162
+ end
163
+
164
+ should "handle re-direct" do
165
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {}, redirect_response('https://bucket.s3-external-3.amazonaws.com/the-key'))
166
+ EventMachine::MockHttpRequest.register('https://bucket.s3-external-3.amazonaws.com:443/the-key', :get, {}, fake_response('hy there'))
167
+
168
+ @item = S3restful::S3::Item.new('bucket', 'the-key')
169
+ run_in_em_loop do
170
+ @item.get
171
+
172
+ EM.add_timer(1) {
173
+ EM.stop_event_loop
174
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {})
175
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3-external-3.amazonaws.com:443/the-key', :get, {})
176
+ }
177
+
178
+ end
179
+ end
180
+ end
181
+
182
+ context "when deleting an item" do
183
+ should "send a DELETE to the items location" do
184
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
185
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
186
+ 'date' => @time,
187
+ 'url' => "/bucket/the-key"}, fake_response("data-here"))
188
+
189
+ @item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
190
+ run_in_em_loop do
191
+ @item.delete
192
+
193
+ EM.add_timer(1) {
194
+ EM.stop_event_loop
195
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
196
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
197
+ 'date' => @time,
198
+ 'url' => "/bucket/the-key"})
199
+ }
200
+
201
+ end
202
+ end
203
+
204
+ should "support direct blocks" do
205
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
206
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
207
+ 'date' => @time,
208
+ 'url' => "/bucket/the-key"}, fake_response("data-here"))
209
+
210
+ called = false
211
+ data = nil
212
+ @item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
213
+ run_in_em_loop do
214
+ @item.delete do |http|
215
+ called = true
216
+ data = http.response
217
+ end
218
+
219
+ EM.add_timer(1) {
220
+ assert called
221
+ assert_equal "data-here\n", data
222
+ EM.stop_event_loop
223
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
224
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
225
+ 'date' => @time,
226
+ 'url' => "/bucket/the-key"})
227
+ }
228
+
229
+ end
230
+ end
231
+
232
+ should "handle re-direct" do
233
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
234
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
235
+ 'date' => @time,
236
+ 'url' => "/bucket/the-key"}, redirect_response('https://bucket.s3-external-3.amazonaws.com/the-key'))
237
+ EventMachine::MockHttpRequest.register('https://bucket.s3-external-3.amazonaws.com:443/the-key', :delete, {
238
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
239
+ 'date' => @time,
240
+ 'url' => "/bucket/the-key"}, fake_response("success!"))
241
+
242
+ @item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
243
+ run_in_em_loop do
244
+ @item.delete
245
+
246
+ EM.add_timer(1) {
247
+ EM.stop_event_loop
248
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
249
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
250
+ 'date' => @time,
251
+ 'url' => "/bucket/the-key"})
252
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3-external-3.amazonaws.com:443/the-key', :delete, {
253
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
254
+ 'date' => @time,
255
+ 'url' => "/bucket/the-key"})
256
+ }
257
+
258
+ end
259
+ end
260
+
261
+ should "handle retry" do
262
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
263
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
264
+ 'date' => @time,
265
+ 'url' => "/bucket/the-key"}, error_response(400))
266
+
267
+ @item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
268
+ run_in_em_loop do
269
+ @item.delete(:on_error => Proc.new{} ) #ignore error
270
+
271
+ EM.add_timer(1) {
272
+ EM.stop_event_loop
273
+ assert_equal 5, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
274
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
275
+ 'date' => @time,
276
+ 'url' => "/bucket/the-key"})
277
+ }
278
+
279
+ end
280
+ end
281
+ end
282
+
283
+ context "when loading the headers" do
284
+ should "request via HEAD" do
285
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :head, {}, fake_response('hy there'))
286
+
287
+ @item = S3restful::S3::Item.new('bucket', 'the-key')
288
+ run_in_em_loop do
289
+ @item.head
290
+
291
+ EM.add_timer(1) {
292
+ EM.stop_event_loop
293
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :head, {})
294
+ }
295
+
296
+ end
297
+ end
298
+ end
299
+
300
+ context "when saving an item" do
301
+
302
+ should "post to the desired location" do
303
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
304
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
305
+ 'date' => @time,
306
+ 'url' => "/bucket/the-key"}, fake_response("data-here"))
307
+
308
+ @item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
309
+ run_in_em_loop do
310
+ @item.put('content')
311
+
312
+ EM.add_timer(1) {
313
+ EM.stop_event_loop
314
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
315
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
316
+ 'date' => @time,
317
+ 'url' => "/bucket/the-key"})
318
+ }
319
+
320
+ end
321
+ end
322
+
323
+ should "support direct blocks" do
324
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
325
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
326
+ 'date' => @time,
327
+ 'url' => "/bucket/the-key"}, fake_response("data-here"))
328
+
329
+ called = false
330
+ data = nil
331
+ @item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
332
+ run_in_em_loop do
333
+ @item.put('upload me') do |http|
334
+ called = true
335
+ data = http.response
336
+ end
337
+
338
+ EM.add_timer(1) {
339
+ assert called
340
+ assert_equal "data-here\n", data
341
+ EM.stop_event_loop
342
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
343
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
344
+ 'date' => @time,
345
+ 'url' => "/bucket/the-key"})
346
+ }
347
+
348
+ end
349
+ end
350
+
351
+ should "set the desired permissions" do
352
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
353
+ "Authorization"=>"AWS abc:cqkfX+nC7WIkYD+yWaUFuoRuePA=",
354
+ 'date' => @time,
355
+ 'url' => "/bucket/the-key",
356
+ "x-amz-acl" => 'public-read'}, fake_response("data-here"))
357
+
358
+ @item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123' , :permissions => 'public-read')
359
+ run_in_em_loop do
360
+ @item.put('content')
361
+
362
+ EM.add_timer(1) {
363
+ EM.stop_event_loop
364
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
365
+ "Authorization"=>"AWS abc:cqkfX+nC7WIkYD+yWaUFuoRuePA=",
366
+ 'date' => @time,
367
+ 'url' => "/bucket/the-key",
368
+ 'x-amz-acl' => 'public-read'})
369
+ }
370
+
371
+ end
372
+ end
373
+
374
+ should "allow to set custom headers" do
375
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
376
+ "Authorization"=>"AWS abc:wrPkGKrlwH2AtNzBVS80vU73TDc=",
377
+ 'date' => @time,
378
+ 'url' => "/bucket/the-key",
379
+ "x-amz-acl" => 'public-read',
380
+ 'Cache-Control' => "max-age=252460800",
381
+ 'Expires' => 'Fri, 16 Nov 2018 22:09:29 GMT',
382
+ 'x-amz-meta-abc' => 'ABC'}, fake_response("data-here"))
383
+
384
+ @item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc',
385
+ :aws_secret_access_key => '123' ,
386
+ :permissions => 'public-read')
387
+ run_in_em_loop do
388
+ @item.put('content', :headers => {
389
+ 'Expires' => 'Fri, 16 Nov 2018 22:09:29 GMT',
390
+ 'Cache-Control' => "max-age=252460800",
391
+ 'x-amz-meta-abc' => 'ABC'})
392
+
393
+ EM.add_timer(1) {
394
+ EM.stop_event_loop
395
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
396
+ "Authorization"=>"AWS abc:wrPkGKrlwH2AtNzBVS80vU73TDc=",
397
+ 'date' => @time,
398
+ 'url' => "/bucket/the-key",
399
+ 'x-amz-acl' => 'public-read',
400
+ 'Cache-Control' => "max-age=252460800",
401
+ 'Expires' => 'Fri, 16 Nov 2018 22:09:29 GMT',
402
+ 'x-amz-meta-abc' => 'ABC'})
403
+ }
404
+
405
+ end
406
+ end
407
+
408
+ should "validate the headers" do
409
+
410
+ @item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc',
411
+ :aws_secret_access_key => '123' ,
412
+ :permissions => 'public-read')
413
+
414
+ assert_raise(ArgumentError) do
415
+ @item.put('content', :headers => {
416
+ 'expires' => 'Fri, 16 Nov 2018 22:09:29 GMT',
417
+ 'cache_control' => "max-age=252460800"})
418
+ end
419
+ end
420
+
421
+ should "re-post to a new location" do
422
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
423
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
424
+ 'date' => @time,
425
+ 'url' => "/bucket/the-key"}, redirect_response('https://bucket.s3-external-3.amazonaws.com/the-key'))
426
+ EventMachine::MockHttpRequest.register('https://bucket.s3-external-3.amazonaws.com:443/the-key', :put, {
427
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
428
+ 'date' => @time,
429
+ 'url' => "/bucket/the-key"}, fake_response('Thanks!'))
430
+
431
+ @item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
432
+ run_in_em_loop do
433
+ @item.put('content')
434
+
435
+ EM.add_timer(1) {
436
+ EM.stop_event_loop
437
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
438
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
439
+ 'date' => @time,
440
+ 'url' => "/bucket/the-key"})
441
+
442
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3-external-3.amazonaws.com:443/the-key', :put, {
443
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
444
+ 'date' => @time,
445
+ 'url' => "/bucket/the-key"})
446
+ }
447
+
448
+ end
449
+ end
450
+
451
+ should "retry on error" do
452
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
453
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
454
+ 'date' => @time,
455
+ 'url' => "/bucket/the-key"}, error_response(400))
456
+
457
+ @item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
458
+ run_in_em_loop do
459
+ @item.put('content', :on_error => Proc.new{} )
460
+
461
+ EM.add_timer(1) {
462
+ EM.stop_event_loop
463
+ assert_equal 5, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
464
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
465
+ 'date' => @time,
466
+ 'url' => "/bucket/the-key"})
467
+ }
468
+
469
+ end
470
+ end
471
+
472
+ should "call error handler after retry reached" do
473
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
474
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
475
+ 'date' => @time,
476
+ 'url' => "/bucket/the-key"}, error_response(400))
477
+
478
+ called = false
479
+ on_error = Proc.new {|http| called = true}
480
+
481
+ @item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
482
+ run_in_em_loop do
483
+ @item.put('content', :on_error => on_error, :retry_count => 1)
484
+
485
+ EM.add_timer(1) {
486
+ EM.stop_event_loop
487
+ assert called
488
+ assert_equal 2, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
489
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
490
+ 'date' => @time,
491
+ 'url' => "/bucket/the-key"})
492
+ }
493
+
494
+ end
495
+ end
496
+
497
+ end
498
+
499
+ context "SSL options" do
500
+ setup do
501
+ S3restful::S3.ssl_options[:verify_peer] = true
502
+ S3restful::S3.ssl_options[:cert_chain_file] = '/etc/foo.ca'
503
+ end
504
+
505
+ should "re-use the global options" do
506
+ item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
507
+ assert item.options[:ssl][:verify_peer]
508
+ assert_equal '/etc/foo.ca', item.options[:ssl][:cert_chain_file]
509
+ end
510
+
511
+ should "allow to override global options" do
512
+ item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123', :ssl => {:cert_chain_file => nil, :verify_peer => false})
513
+ assert !item.options[:ssl][:verify_peer]
514
+ assert_nil item.options[:ssl][:cert_chain_file]
515
+ end
516
+
517
+ should "pass the options to the Request" do
518
+ item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
519
+ S3restful::S3::Request.expects(:new).with(:get, anything, {:ssl => {:cert_chain_file => '/etc/foo.ca', :verify_peer => true}, :headers => {'Authorization' => 'AWS abc:LGLdCdGTuLAHs+InbMWEnQR6djc=', 'date' => 'Thu, 25 Feb 2010 10:00:00 GMT'}}).returns(stub(:execute => nil))
520
+ item.get
521
+ end
522
+
523
+ should "allow to override the options per request" do
524
+ item = S3restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
525
+ S3restful::S3::Request.expects(:new).with(:get, anything, {:ssl => {:foo => :bar}, :headers => {'Authorization' => 'AWS abc:LGLdCdGTuLAHs+InbMWEnQR6djc=', 'date' => 'Thu, 25 Feb 2010 10:00:00 GMT'}}).returns(stub(:execute => nil))
526
+ item.get(:ssl => {:foo => :bar})
527
+ end
528
+ end
529
+
530
+ end
531
+ end
@@ -0,0 +1,109 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ class ItemTest < Test::Unit::TestCase
4
+ context "An S3restful::S3::Request instance" do
5
+
6
+ setup do
7
+ S3restful::Log.level = Logger::ERROR
8
+ @response_stub = stub()
9
+ @response_stub.stubs(:errback)
10
+ @response_stub.stubs(:callback)
11
+ end
12
+
13
+ context "validation" do
14
+ should "check HTTP method" do
15
+ assert_raise(ArgumentError) do
16
+ S3restful::S3::Request.new(:foo, 'https://www.example.com')
17
+ end
18
+
19
+ assert_nothing_raised do
20
+ S3restful::S3::Request.new(:get, 'https://www.example.com')
21
+ end
22
+ end
23
+
24
+ should "check the options" do
25
+ assert_raise(ArgumentError) do
26
+ S3restful::S3::Request.new(:get, 'https://www.example.com', {:foo => :bar})
27
+ end
28
+
29
+ assert_nothing_raised do
30
+ S3restful::S3::Request.new(:get, 'https://www.example.com', {:timeout => 4})
31
+ end
32
+ end
33
+ end
34
+
35
+ context "when executing" do
36
+ should "have no response before executing" do
37
+ assert_nil S3restful::S3::Request.new(:get, 'https://www.example.com').response
38
+ end
39
+
40
+ should "call em-http-request" do
41
+ request = mock(:get => @response_stub)
42
+ EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
43
+ S3restful::S3::Request.new(:get, 'https://www.example.com').execute
44
+ end
45
+
46
+ should "return the response" do
47
+ request = mock(:get => @response_stub)
48
+ EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
49
+ resp = S3restful::S3::Request.new(:get, 'https://www.example.com').execute
50
+ assert_equal resp, @response_stub
51
+ end
52
+
53
+ should "pass the given headers and options" do
54
+ request = mock('em-http-request')
55
+ request.expects(:get).with(:timeout => 10, :head => {'a' => 'b'}, :body => nil, :ssl => {:verify_peer => false, :cert_chain_file => nil}).returns(@response_stub)
56
+ EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
57
+ S3restful::S3::Request.new(:get, 'https://www.example.com', :headers => {'a' => 'b'}).execute
58
+ end
59
+
60
+ should "post any given data" do
61
+ request = mock('em-http-request')
62
+ request.expects(:put).with(:timeout => 10, :body => 'the-data', :head => {}, :ssl => {:verify_peer => false, :cert_chain_file => nil}).returns(@response_stub)
63
+ EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
64
+ S3restful::S3::Request.new(:put, 'https://www.example.com', :data => 'the-data').execute
65
+ end
66
+
67
+ should "pass SSL options to em-http-request" do
68
+ request = mock('em-http-request')
69
+ request.expects(:put).with(:timeout => 10, :body => 'the-data', :head => {}, :ssl => {:verfiy_peer => true, :cert_chain_file => '/tmp/server.crt'}).returns(@response_stub)
70
+ EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
71
+ S3restful::S3::Request.new(:put, 'https://www.example.com', :data => 'the-data', :ssl => {:verfiy_peer => true, :cert_chain_file => '/tmp/server.crt'}).execute
72
+ end
73
+
74
+ context "when handling errors" do
75
+ should "call the user error handler" do
76
+ EventMachine::MockHttpRequest.register('http://www.example.com:80/', :get, {}, error_response(400))
77
+
78
+ called = false
79
+ on_error = Proc.new {|http| called = true}
80
+
81
+ run_in_em_loop do
82
+ S3restful::S3::Request.new(:get, 'http://www.example.com/', :on_error => on_error).execute
83
+
84
+ EM.add_timer(1) {
85
+ EM.stop_event_loop
86
+ assert called
87
+ assert_equal 5, EventMachine::MockHttpRequest.count('http://www.example.com:80/', :get, {})
88
+ }
89
+
90
+ end
91
+ end
92
+
93
+ should "use a default error handler if there is no user handler" do
94
+ EventMachine::MockHttpRequest.register('http://www.example.com:80/', :get, {}, error_response(400))
95
+
96
+ assert_raise(S3restful::Error) do
97
+ run_in_em_loop do
98
+ S3restful::S3::Request.new(:get, 'http://www.example.com/').execute
99
+ end
100
+ end
101
+ EM.stop_event_loop if EM.reactor_running?
102
+ end
103
+
104
+ end
105
+
106
+ end
107
+
108
+ end
109
+ end
data/test/s3_test.rb ADDED
@@ -0,0 +1,32 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class S3Test < Test::Unit::TestCase
4
+ context "The S3restful::S3 module" do
5
+
6
+ should "allow to set global SSL options" do
7
+ assert S3restful::S3.respond_to?(:ssl_options)
8
+ assert S3restful::S3.respond_to?(:ssl_options=)
9
+ end
10
+
11
+ should "set and get verify_peer" do
12
+ S3restful::S3.ssl_options[:verify_peer] = true
13
+ assert S3restful::S3.ssl_options[:verify_peer]
14
+ S3restful::S3.ssl_options[:verify_peer] = false
15
+ assert !S3restful::S3.ssl_options[:verify_peer]
16
+ end
17
+
18
+ should "set and get cert_chain_file" do
19
+ S3restful::S3.ssl_options[:cert_chain_file] = '/etc/cacert'
20
+ assert_equal '/etc/cacert', S3restful::S3.ssl_options[:cert_chain_file]
21
+ S3restful::S3.ssl_options[:cert_chain_file] = nil
22
+ assert_nil S3restful::S3.ssl_options[:cert_chain_file]
23
+ end
24
+
25
+ should "default to no certificate file and no verification" do
26
+ S3restful::S3.instance_variable_set("@_ssl_options", nil)
27
+ assert !S3restful::S3.ssl_options[:verify_peer]
28
+ assert_nil S3restful::S3.ssl_options[:cert_chain_file]
29
+ end
30
+
31
+ end
32
+ end