aliyun-sdk 0.1.1

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,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