aliyun-sdk 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,741 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'spec_helper'
4
+ require 'yaml'
5
+ require 'nokogiri'
6
+
7
+ module Aliyun
8
+ module OSS
9
+
10
+ describe "Object" do
11
+
12
+ before :all do
13
+ @endpoint = 'oss.aliyuncs.com'
14
+ @protocol = Protocol.new(
15
+ Config.new(:endpoint => @endpoint,
16
+ :access_key_id => 'xxx', :access_key_secret => 'yyy'))
17
+ @bucket = 'rubysdk-bucket'
18
+ end
19
+
20
+ def get_request_path(object = nil)
21
+ p = "#{@bucket}.#{@endpoint}/"
22
+ p += CGI.escape(object) if object
23
+ p
24
+ end
25
+
26
+ def get_resource_path(object)
27
+ "/#{@bucket}/#{object}"
28
+ end
29
+
30
+ def mock_copy_object(last_modified, etag)
31
+ builder = Nokogiri::XML::Builder.new do |xml|
32
+ xml.CopyObjectResult {
33
+ xml.LastModified last_modified.to_s
34
+ xml.ETag etag
35
+ }
36
+ end
37
+
38
+ builder.to_xml
39
+ end
40
+
41
+ def mock_acl(acl)
42
+ Nokogiri::XML::Builder.new do |xml|
43
+ xml.AccessControlPolicy {
44
+ xml.Owner {
45
+ xml.ID 'owner_id'
46
+ xml.DisplayName 'owner_name'
47
+ }
48
+
49
+ xml.AccessControlList {
50
+ xml.Grant acl
51
+ }
52
+ }
53
+ end.to_xml
54
+ end
55
+
56
+ def mock_delete(objects, opts = {})
57
+ Nokogiri::XML::Builder.new do |xml|
58
+ xml.Delete {
59
+ xml.Quiet opts[:quiet]? true : false
60
+ objects.each do |o|
61
+ xml.Object {
62
+ xml.Key o
63
+ }
64
+ end
65
+ }
66
+ end.to_xml
67
+ end
68
+
69
+ def mock_delete_result(deleted, opts = {})
70
+ Nokogiri::XML::Builder.new do |xml|
71
+ xml.DeleteResult {
72
+ xml.EncodingType opts[:encoding] if opts[:encoding]
73
+ deleted.each do |o|
74
+ xml.Deleted {
75
+ xml.Key o
76
+ }
77
+ end
78
+ }
79
+ end.to_xml
80
+ end
81
+
82
+ def mock_error(code, message)
83
+ builder = Nokogiri::XML::Builder.new do |xml|
84
+ xml.Error {
85
+ xml.Code code
86
+ xml.Message message
87
+ }
88
+ end
89
+
90
+ builder.to_xml
91
+ end
92
+
93
+ context "Put object" do
94
+
95
+ it "should PUT to create object" do
96
+ object_name = 'ruby'
97
+ url = get_request_path(object_name)
98
+ stub_request(:put, url)
99
+
100
+ content = "hello world"
101
+ @protocol.put_object(@bucket, object_name) do |c|
102
+ c << content
103
+ end
104
+
105
+ expect(WebMock).to have_requested(:put, url)
106
+ .with(:body => content, :query => {})
107
+ end
108
+
109
+ it "should raise Exception on error" do
110
+ object_name = 'ruby'
111
+ url = get_request_path(object_name)
112
+
113
+ code = 'NoSuchBucket'
114
+ message = 'The bucket does not exist.'
115
+ stub_request(:put, url).to_return(
116
+ :status => 404, :body => mock_error(code, message))
117
+
118
+ content = "hello world"
119
+ expect {
120
+ @protocol.put_object(@bucket, object_name) do |c|
121
+ c << content
122
+ end
123
+ }.to raise_error(Exception, message)
124
+
125
+ expect(WebMock).to have_requested(:put, url)
126
+ .with(:body => content, :query => {})
127
+ end
128
+
129
+ it "should use default content-type" do
130
+ object_name = 'ruby'
131
+ url = get_request_path(object_name)
132
+ stub_request(:put, url)
133
+
134
+ @protocol.put_object(@bucket, object_name) do |content|
135
+ content << 'hello world'
136
+ end
137
+
138
+ expect(WebMock).to have_requested(:put, url)
139
+ .with(:body => 'hello world',
140
+ :headers => {'Content-Type' => HTTP::DEFAULT_CONTENT_TYPE})
141
+ end
142
+
143
+ it "should use customized content-type" do
144
+ object_name = 'ruby'
145
+ url = get_request_path(object_name)
146
+ stub_request(:put, url)
147
+
148
+ @protocol.put_object(
149
+ @bucket, object_name, :content_type => 'application/ruby'
150
+ ) do |content|
151
+ content << 'hello world'
152
+ end
153
+
154
+ expect(WebMock).to have_requested(:put, url)
155
+ .with(:body => 'hello world',
156
+ :headers => {'Content-Type' => 'application/ruby'})
157
+ end
158
+
159
+ it "should support non-ascii object name" do
160
+ object_name = '中国のruby'
161
+ url = get_request_path(object_name)
162
+ stub_request(:put, url)
163
+
164
+ content = "hello world"
165
+ @protocol.put_object(@bucket, object_name) do |c|
166
+ c << content
167
+ end
168
+
169
+ expect(WebMock).to have_requested(:put, url)
170
+ .with(:body => content, :query => {})
171
+ end
172
+
173
+ it "should set user defined metas" do
174
+ object_name = 'ruby'
175
+ url = get_request_path(object_name)
176
+ stub_request(:put, url)
177
+
178
+ @protocol.put_object(
179
+ @bucket, object_name, :metas => {'year' => '2015', 'people' => 'mary'}
180
+ ) do |content|
181
+ content << 'hello world'
182
+ end
183
+
184
+ expect(WebMock).to have_requested(:put, url)
185
+ .with(:body => 'hello world',
186
+ :headers => {
187
+ 'x-oss-meta-year' => '2015',
188
+ 'x-oss-meta-people' => 'mary'})
189
+ end
190
+
191
+ end # put object
192
+
193
+ context "Append object" do
194
+
195
+ it "should POST to append object" do
196
+ object_name = 'ruby'
197
+ url = get_request_path(object_name)
198
+
199
+ query = {'append' => '', 'position' => 11}
200
+ return_headers = {'x-oss-next-append-position' => '101'}
201
+ stub_request(:post, url).with(:query => query)
202
+ .to_return(:headers => return_headers)
203
+
204
+ content = "hello world"
205
+ next_pos = @protocol.append_object(@bucket, object_name, 11) do |c|
206
+ c << content
207
+ end
208
+
209
+ expect(WebMock).to have_requested(:post, url)
210
+ .with(:body => content, :query => query)
211
+ expect(next_pos).to eq(101)
212
+ end
213
+
214
+ it "should raise Exception on error" do
215
+ object_name = 'ruby'
216
+ url = get_request_path(object_name)
217
+
218
+ query = {'append' => '', 'position' => 11}
219
+ code = 'ObjectNotAppendable'
220
+ message = 'Normal object cannot be appended.'
221
+ stub_request(:post, url).with(:query => query).
222
+ to_return(:status => 409, :body => mock_error(code, message))
223
+
224
+ content = "hello world"
225
+ expect {
226
+ @protocol.append_object(@bucket, object_name, 11) do |c|
227
+ c << content
228
+ end
229
+ }.to raise_error(Exception, message)
230
+
231
+ expect(WebMock).to have_requested(:post, url)
232
+ .with(:body => content, :query => query)
233
+ end
234
+
235
+ it "should use default content-type" do
236
+ object_name = 'ruby'
237
+ url = get_request_path(object_name)
238
+ query = {'append' => '', 'position' => 0}
239
+
240
+ stub_request(:post, url).with(:query => query)
241
+
242
+ @protocol.append_object(@bucket, object_name, 0) do |content|
243
+ content << 'hello world'
244
+ end
245
+
246
+ expect(WebMock).to have_requested(:post, url)
247
+ .with(:body => 'hello world',
248
+ :query => query,
249
+ :headers => {'Content-Type' => HTTP::DEFAULT_CONTENT_TYPE})
250
+ end
251
+
252
+ it "should use customized content-type" do
253
+ object_name = 'ruby'
254
+ url = get_request_path(object_name)
255
+ query = {'append' => '', 'position' => 0}
256
+
257
+ stub_request(:post, url).with(:query => query)
258
+
259
+ @protocol.append_object(
260
+ @bucket, object_name, 0, :content_type => 'application/ruby'
261
+ ) do |content|
262
+ content << 'hello world'
263
+ end
264
+
265
+ expect(WebMock).to have_requested(:post, url)
266
+ .with(:body => 'hello world',
267
+ :query => query,
268
+ :headers => {'Content-Type' => 'application/ruby'})
269
+ end
270
+
271
+ it "should set user defined metas" do
272
+ object_name = 'ruby'
273
+ url = get_request_path(object_name)
274
+ query = {'append' => '', 'position' => 0}
275
+
276
+ stub_request(:post, url).with(:query => query)
277
+
278
+ @protocol.append_object(
279
+ @bucket, object_name, 0, :metas => {'year' => '2015', 'people' => 'mary'}
280
+ ) do |content|
281
+ content << 'hello world'
282
+ end
283
+
284
+ expect(WebMock).to have_requested(:post, url)
285
+ .with(:query => query,
286
+ :body => 'hello world',
287
+ :headers => {
288
+ 'x-oss-meta-year' => '2015',
289
+ 'x-oss-meta-people' => 'mary'})
290
+ end
291
+ end # append object
292
+
293
+ context "Copy object" do
294
+
295
+ it "should copy object" do
296
+ src_object = 'ruby'
297
+ dst_object = 'rails'
298
+ url = get_request_path(dst_object)
299
+
300
+ last_modified = Time.parse(Time.now.rfc822)
301
+ etag = '0000'
302
+ stub_request(:put, url).to_return(
303
+ :body => mock_copy_object(last_modified, etag))
304
+
305
+ result = @protocol.copy_object(@bucket, src_object, dst_object)
306
+
307
+ expect(WebMock).to have_requested(:put, url)
308
+ .with(:body => nil, :headers => {
309
+ 'x-oss-copy-source' => get_resource_path(src_object)})
310
+
311
+ expect(result[:last_modified]).to eq(last_modified)
312
+ expect(result[:etag]).to eq(etag)
313
+ end
314
+
315
+ it "should set acl and conditions when copy object" do
316
+ src_object = 'ruby'
317
+ dst_object = 'rails'
318
+ url = get_request_path(dst_object)
319
+
320
+ modified_since = Time.now
321
+ unmodified_since = Time.now
322
+ last_modified = Time.parse(Time.now.rfc822)
323
+ etag = '0000'
324
+
325
+ headers = {
326
+ 'x-oss-copy-source' => get_resource_path(src_object),
327
+ 'x-oss-object-acl' => ACL::PRIVATE,
328
+ 'x-oss-metadata-directive' => MetaDirective::REPLACE,
329
+ 'x-oss-copy-source-if-modified-since' => modified_since.httpdate,
330
+ 'x-oss-copy-source-if-unmodified-since' => unmodified_since.httpdate,
331
+ 'x-oss-copy-source-if-match' => 'me',
332
+ 'x-oss-copy-source-if-none-match' => 'ume'
333
+ }
334
+ stub_request(:put, url).to_return(
335
+ :body => mock_copy_object(last_modified, etag))
336
+
337
+ result = @protocol.copy_object(
338
+ @bucket, src_object, dst_object,
339
+ {:acl => ACL::PRIVATE,
340
+ :meta_directive => MetaDirective::REPLACE,
341
+ :condition => {
342
+ :if_modified_since => modified_since,
343
+ :if_unmodified_since => unmodified_since,
344
+ :if_match_etag => 'me',
345
+ :if_unmatch_etag => 'ume'
346
+ }
347
+ })
348
+
349
+ expect(WebMock).to have_requested(:put, url)
350
+ .with(:body => nil, :headers => headers)
351
+
352
+ expect(result[:last_modified]).to eq(last_modified)
353
+ expect(result[:etag]).to eq(etag)
354
+ end
355
+
356
+ it "should set user defined metas" do
357
+ src_object = 'ruby'
358
+ dst_object = 'rails'
359
+ url = get_request_path(dst_object)
360
+
361
+ stub_request(:put, url)
362
+
363
+ @protocol.copy_object(@bucket, src_object, dst_object,
364
+ :metas => {
365
+ 'year' => '2015',
366
+ 'people' => 'mary'
367
+ })
368
+
369
+ expect(WebMock).to have_requested(:put, url)
370
+ .with(:body => nil,
371
+ :headers => {
372
+ 'x-oss-meta-year' => '2015',
373
+ 'x-oss-meta-people' => 'mary'})
374
+ end
375
+
376
+ it "should raise Exception on error" do
377
+ src_object = 'ruby'
378
+ dst_object = 'rails'
379
+ url = get_request_path(dst_object)
380
+
381
+ code = 'EntityTooLarge'
382
+ message = 'The object to copy is too large.'
383
+ stub_request(:put, url).to_return(
384
+ :status => 400,
385
+ :headers => {'x-oss-request-id' => '0000-1111'},
386
+ :body => mock_error(code, message))
387
+
388
+ begin
389
+ @protocol.copy_object(@bucket, src_object, dst_object)
390
+ expect(false).to be true
391
+ rescue ServerError => e
392
+ expect(e.http_code).to eq(400)
393
+ expect(e.error_code).to eq(code)
394
+ expect(e.message).to eq(message)
395
+ expect(e.request_id).to eq('0000-1111')
396
+ end
397
+
398
+ expect(WebMock).to have_requested(:put, url)
399
+ .with(:body => nil, :headers => {
400
+ 'x-oss-copy-source' => get_resource_path(src_object)})
401
+ end
402
+ end # copy object
403
+
404
+ context "Get object" do
405
+
406
+ it "should GET to get object" do
407
+ object_name = 'ruby'
408
+ url = get_request_path(object_name)
409
+
410
+ return_content = "hello world"
411
+ stub_request(:get, url).to_return(:body => return_content)
412
+
413
+ content = ""
414
+ @protocol.get_object(@bucket, object_name) {|c| content << c}
415
+
416
+ expect(WebMock).to have_requested(:get, url)
417
+ .with(:body => nil, :query => {})
418
+
419
+ expect(content).to eq(return_content)
420
+ end
421
+
422
+ it "should return object meta" do
423
+ object_name = 'ruby'
424
+ url = get_request_path(object_name)
425
+
426
+ last_modified = Time.now.rfc822
427
+ return_headers = {
428
+ 'x-oss-object-type' => 'Normal',
429
+ 'ETag' => 'xxxyyyzzz',
430
+ 'Content-Length' => 1024,
431
+ 'Last-Modified' => last_modified,
432
+ 'x-oss-meta-year' => '2015',
433
+ 'x-oss-meta-people' => 'mary'
434
+ }
435
+ return_content = "hello world"
436
+ stub_request(:get, url)
437
+ .to_return(:headers => return_headers, :body => return_content)
438
+
439
+ content = ""
440
+ obj = @protocol.get_object(@bucket, object_name) {|c| content << c}
441
+
442
+ expect(WebMock).to have_requested(:get, url)
443
+ .with(:body => nil, :query => {})
444
+
445
+ expect(content).to eq(return_content)
446
+ expect(obj.key).to eq(object_name)
447
+ expect(obj.type).to eq('Normal')
448
+ expect(obj.etag).to eq('xxxyyyzzz')
449
+ expect(obj.size).to eq(1024)
450
+ expect(obj.last_modified.rfc822).to eq(last_modified)
451
+ expect(obj.metas).to eq({'year' => '2015', 'people' => 'mary'})
452
+ end
453
+
454
+ it "should raise Exception on error" do
455
+ object_name = 'ruby'
456
+ url = get_request_path(object_name)
457
+
458
+ code = 'NoSuchKey'
459
+ message = 'The object does not exist'
460
+ stub_request(:get, url).to_return(
461
+ :status => 404, :body => mock_error(code, message))
462
+
463
+ expect {
464
+ @protocol.get_object(@bucket, object_name) {|c| true}
465
+ }.to raise_error(Exception, message)
466
+
467
+ expect(WebMock).to have_requested(:get, url)
468
+ .with(:body => nil, :query => {})
469
+ end
470
+
471
+ it "should get object range" do
472
+ object_name = 'ruby'
473
+ url = get_request_path(object_name)
474
+
475
+ stub_request(:get, url)
476
+
477
+ @protocol.get_object(@bucket, object_name, {:range => [0, 10]}) {}
478
+
479
+ expect(WebMock).to have_requested(:get, url)
480
+ .with(:body => nil, :query => {},
481
+ :headers => {
482
+ 'Range' => 'bytes=0-9'
483
+ })
484
+ end
485
+
486
+ it "should match modify time and etag" do
487
+ object_name = 'ruby'
488
+ url = get_request_path(object_name)
489
+
490
+ stub_request(:get, url)
491
+
492
+ modified_since = Time.now
493
+ unmodified_since = Time.now
494
+ etag = 'xxxyyyzzz'
495
+ not_etag = 'aaabbbccc'
496
+ @protocol.get_object(
497
+ @bucket, object_name,
498
+ {:condition => {
499
+ :if_modified_since => modified_since,
500
+ :if_unmodified_since => unmodified_since,
501
+ :if_match_etag => etag,
502
+ :if_unmatch_etag => not_etag}}) {}
503
+
504
+ expect(WebMock).to have_requested(:get, url)
505
+ .with(:body => nil, :query => {},
506
+ :headers => {
507
+ 'If-Modified-Since' => modified_since.httpdate,
508
+ 'If-Unmodified-since' => unmodified_since.httpdate,
509
+ 'If-Match' => etag,
510
+ 'If-None-Match' => not_etag})
511
+ end
512
+
513
+ it "should rewrite response headers" do
514
+ object_name = 'ruby'
515
+ url = get_request_path(object_name)
516
+
517
+ expires = Time.now
518
+ rewrites = {
519
+ :content_type => 'ct',
520
+ :content_language => 'cl',
521
+ :expires => expires,
522
+ :cache_control => 'cc',
523
+ :content_disposition => 'cd',
524
+ :content_encoding => 'ce'
525
+ }
526
+ query = Hash[rewrites.map {|k, v| ["response-#{k.to_s.sub('_', '-')}", v]}]
527
+ query['response-expires'] = rewrites[:expires].httpdate
528
+
529
+ stub_request(:get, url).with(:query => query)
530
+
531
+ @protocol.get_object(@bucket, object_name, :rewrite => rewrites) {}
532
+
533
+ expect(WebMock).to have_requested(:get, url)
534
+ .with(:body => nil, :query => query)
535
+ end
536
+ end # Get object
537
+
538
+ context "Get object meta" do
539
+
540
+ it "should get object meta" do
541
+ object_name = 'ruby'
542
+ url = get_request_path(object_name)
543
+
544
+ last_modified = Time.now.rfc822
545
+ return_headers = {
546
+ 'x-oss-object-type' => 'Normal',
547
+ 'ETag' => 'xxxyyyzzz',
548
+ 'Content-Length' => 1024,
549
+ 'Last-Modified' => last_modified,
550
+ 'x-oss-meta-year' => '2015',
551
+ 'x-oss-meta-people' => 'mary'
552
+ }
553
+ stub_request(:head, url).to_return(:headers => return_headers)
554
+
555
+ obj = @protocol.get_object_meta(@bucket, object_name)
556
+
557
+ expect(WebMock).to have_requested(:head, url)
558
+ .with(:body => nil, :query => {})
559
+
560
+ expect(obj.key).to eq(object_name)
561
+ expect(obj.type).to eq('Normal')
562
+ expect(obj.etag).to eq('xxxyyyzzz')
563
+ expect(obj.size).to eq(1024)
564
+ expect(obj.last_modified.rfc822).to eq(last_modified)
565
+ expect(obj.metas).to eq({'year' => '2015', 'people' => 'mary'})
566
+ end
567
+
568
+ it "should set conditions" do
569
+ object_name = 'ruby'
570
+ url = get_request_path(object_name)
571
+
572
+ stub_request(:head, url)
573
+
574
+ modified_since = Time.now
575
+ unmodified_since = Time.now
576
+ etag = 'xxxyyyzzz'
577
+ not_etag = 'aaabbbccc'
578
+
579
+ @protocol.get_object_meta(
580
+ @bucket, object_name,
581
+ :condition => {
582
+ :if_modified_since => modified_since,
583
+ :if_unmodified_since => unmodified_since,
584
+ :if_match_etag => etag,
585
+ :if_unmatch_etag => not_etag})
586
+
587
+ expect(WebMock).to have_requested(:head, url)
588
+ .with(:body => nil, :query => {},
589
+ :headers => {
590
+ 'If-Modified-Since' => modified_since.httpdate,
591
+ 'If-Unmodified-since' => unmodified_since.httpdate,
592
+ 'If-Match' => etag,
593
+ 'If-None-Match' => not_etag})
594
+ end
595
+ end # Get object meta
596
+
597
+ context "Delete object" do
598
+
599
+ it "should DELETE to delete object" do
600
+ object_name = 'ruby'
601
+ url = get_request_path(object_name)
602
+
603
+ stub_request(:delete, url)
604
+
605
+ @protocol.delete_object(@bucket, object_name)
606
+
607
+ expect(WebMock).to have_requested(:delete, url)
608
+ .with(:body => nil, :query => {})
609
+ end
610
+
611
+ it "should raise Exception on error" do
612
+ object_name = 'ruby'
613
+ url = get_request_path(object_name)
614
+
615
+ code = 'NoSuchBucket'
616
+ message = 'The bucket does not exist.'
617
+ stub_request(:delete, url).to_return(
618
+ :status => 404, :body => mock_error(code, message))
619
+
620
+ expect {
621
+ @protocol.delete_object(@bucket, object_name)
622
+ }.to raise_error(Exception, message)
623
+
624
+ expect(WebMock).to have_requested(:delete, url)
625
+ .with(:body => nil, :query => {})
626
+ end
627
+
628
+ it "should batch delete objects" do
629
+ url = get_request_path
630
+ query = {'delete' => '', 'encoding-type' => KeyEncoding::URL}
631
+
632
+ object_names = (1..5).map do |i|
633
+ "object-#{i}"
634
+ end
635
+
636
+ stub_request(:post, url)
637
+ .with(:query => query)
638
+ .to_return(:body => mock_delete_result(object_names))
639
+
640
+ opts = {:quiet => false, :encoding => KeyEncoding::URL}
641
+ deleted = @protocol.batch_delete_objects(@bucket, object_names, opts)
642
+
643
+ expect(WebMock).to have_requested(:post, url)
644
+ .with(:query => query, :body => mock_delete(object_names, opts))
645
+ expect(deleted).to match_array(object_names)
646
+ end
647
+
648
+ it "should decode object key in batch delete response" do
649
+ url = get_request_path
650
+ query = {'delete' => '', 'encoding-type' => KeyEncoding::URL}
651
+
652
+ object_names = (1..5).map do |i|
653
+ "对象-#{i}"
654
+ end
655
+ es_objects = (1..5).map do |i|
656
+ CGI.escape "对象-#{i}"
657
+ end
658
+ opts = {:quiet => false, :encoding => KeyEncoding::URL}
659
+
660
+ stub_request(:post, url)
661
+ .with(:query => query)
662
+ .to_return(:body => mock_delete_result(es_objects, opts))
663
+
664
+ deleted = @protocol.batch_delete_objects(@bucket, object_names, opts)
665
+
666
+ expect(WebMock).to have_requested(:post, url)
667
+ .with(:query => query, :body => mock_delete(object_names, opts))
668
+ expect(deleted).to match_array(object_names)
669
+ end
670
+ end # delete object
671
+
672
+ context "acl" do
673
+ it "should update acl" do
674
+ object_name = 'ruby'
675
+ url = get_request_path(object_name)
676
+
677
+ query = {'acl' => ''}
678
+ stub_request(:put, url).with(:query => query)
679
+
680
+ @protocol.put_object_acl(@bucket, object_name, ACL::PUBLIC_READ)
681
+
682
+ expect(WebMock).to have_requested(:put, url)
683
+ .with(:query => query,
684
+ :headers => {'x-oss-object-acl' => ACL::PUBLIC_READ},
685
+ :body => nil)
686
+ end
687
+
688
+ it "should get acl" do
689
+ object_name = 'ruby'
690
+ url = get_request_path(object_name)
691
+
692
+ query = {'acl' => ''}
693
+ return_acl = ACL::PUBLIC_READ
694
+
695
+ stub_request(:get, url)
696
+ .with(:query => query)
697
+ .to_return(:body => mock_acl(return_acl))
698
+
699
+ acl = @protocol.get_object_acl(@bucket, object_name)
700
+
701
+ expect(WebMock).to have_requested(:get, url)
702
+ .with(:body => nil, :query => query)
703
+ expect(acl).to eq(return_acl)
704
+ end
705
+ end # acl
706
+
707
+ context "cors" do
708
+ it "should get object cors" do
709
+ object_name = 'ruby'
710
+ url = get_request_path(object_name)
711
+
712
+ return_rule = CORSRule.new(
713
+ :allowed_origins => 'origin',
714
+ :allowed_methods => 'PUT',
715
+ :allowed_headers => 'Authorization',
716
+ :expose_headers => 'x-oss-test',
717
+ :max_age_seconds => 10
718
+ )
719
+ stub_request(:options, url).to_return(
720
+ :headers => {
721
+ 'Access-Control-Allow-Origin' => return_rule.allowed_origins,
722
+ 'Access-Control-Allow-Methods' => return_rule.allowed_methods,
723
+ 'Access-Control-Allow-Headers' => return_rule.allowed_headers,
724
+ 'Access-Control-Expose-Headers' => return_rule.expose_headers,
725
+ 'Access-Control-Max-Age' => return_rule.max_age_seconds
726
+ }
727
+ )
728
+
729
+ rule = @protocol.get_object_cors(
730
+ @bucket, object_name, 'origin', 'PUT', ['Authorization'])
731
+
732
+ expect(WebMock).to have_requested(:options, url)
733
+ .with(:body => nil, :query => {})
734
+ expect(rule.to_s).to eq(return_rule.to_s)
735
+ end
736
+ end # cors
737
+
738
+ end # Object
739
+
740
+ end # OSS
741
+ end # Aliyun