aliyun-oss 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/COPYING +19 -0
  2. data/INSTALL +35 -0
  3. data/README +443 -0
  4. data/Rakefile +333 -0
  5. data/bin/oss +6 -0
  6. data/bin/setup.rb +11 -0
  7. data/lib/aliyun/oss.rb +55 -0
  8. data/lib/aliyun/oss/acl.rb +132 -0
  9. data/lib/aliyun/oss/authentication.rb +222 -0
  10. data/lib/aliyun/oss/base.rb +241 -0
  11. data/lib/aliyun/oss/bucket.rb +320 -0
  12. data/lib/aliyun/oss/connection.rb +279 -0
  13. data/lib/aliyun/oss/error.rb +70 -0
  14. data/lib/aliyun/oss/exceptions.rb +134 -0
  15. data/lib/aliyun/oss/extensions.rb +364 -0
  16. data/lib/aliyun/oss/logging.rb +304 -0
  17. data/lib/aliyun/oss/object.rb +612 -0
  18. data/lib/aliyun/oss/owner.rb +45 -0
  19. data/lib/aliyun/oss/parsing.rb +100 -0
  20. data/lib/aliyun/oss/response.rb +181 -0
  21. data/lib/aliyun/oss/service.rb +52 -0
  22. data/lib/aliyun/oss/version.rb +13 -0
  23. data/support/faster-xml-simple/lib/faster_xml_simple.rb +188 -0
  24. data/support/faster-xml-simple/test/regression_test.rb +48 -0
  25. data/support/faster-xml-simple/test/test_helper.rb +18 -0
  26. data/support/faster-xml-simple/test/xml_simple_comparison_test.rb +47 -0
  27. data/support/rdoc/code_info.rb +212 -0
  28. data/test/acl_test.rb +70 -0
  29. data/test/authentication_test.rb +114 -0
  30. data/test/base_test.rb +137 -0
  31. data/test/bucket_test.rb +75 -0
  32. data/test/connection_test.rb +218 -0
  33. data/test/error_test.rb +71 -0
  34. data/test/extensions_test.rb +346 -0
  35. data/test/fixtures.rb +90 -0
  36. data/test/fixtures/buckets.yml +133 -0
  37. data/test/fixtures/errors.yml +34 -0
  38. data/test/fixtures/headers.yml +3 -0
  39. data/test/fixtures/logging.yml +15 -0
  40. data/test/fixtures/loglines.yml +5 -0
  41. data/test/fixtures/logs.yml +7 -0
  42. data/test/fixtures/policies.yml +16 -0
  43. data/test/logging_test.rb +90 -0
  44. data/test/mocks/fake_response.rb +27 -0
  45. data/test/object_test.rb +221 -0
  46. data/test/parsing_test.rb +67 -0
  47. data/test/remote/acl_test.rb +28 -0
  48. data/test/remote/bucket_test.rb +147 -0
  49. data/test/remote/logging_test.rb +86 -0
  50. data/test/remote/object_test.rb +350 -0
  51. data/test/remote/test_file.data +0 -0
  52. data/test/remote/test_helper.rb +34 -0
  53. data/test/response_test.rb +69 -0
  54. data/test/service_test.rb +24 -0
  55. data/test/test_helper.rb +110 -0
  56. metadata +185 -0
@@ -0,0 +1,34 @@
1
+ not_implemented: >
2
+ <Error>
3
+ <Code>NotImplemented</Code>
4
+ <Message>A header you provided implies functionality that is not implemented</Message>
5
+ <RequestId>D1D13A09AC92427F</RequestId>
6
+ <Header>Host</Header>
7
+ <HostId>oNZgzTTmWiovwGGwHXAzz+1vRmAJVAplS9TF7B0cuOGfEwoi7DYSTa/1Qhv90CfW</HostId>
8
+ </Error>
9
+
10
+ access_denied: >
11
+ <Error>
12
+ <Code>AccessDenied</Code>
13
+ <Message>Access Denied</Message>
14
+ <RequestId>F99F6D58B96C98E0</RequestId>
15
+ <HostId>XwCF7k3llrcEwtoHR7MusZ6ilCdF5DKDmwYpglvjKNjvwo24INCeXlEpo1M03Wxm</HostId>
16
+ </Error>
17
+
18
+ internal_error: >
19
+ <Error>
20
+ <Code>InternalError</Code>
21
+ <Message>Internal Error</Message>
22
+ <RequestId>F99F6D223B96C98E0</RequestId>
23
+ <HostId>XwCF7k3llrcEwtoHR7MusZ6ilCdF5DKDmwYpglvjKNjvwo24INCeXlEpo1M03Wxm</HostId>
24
+ </Error>
25
+
26
+ error_with_no_message: >
27
+ <Error>
28
+ <Code>InvalidArgument</Code>
29
+ <Message></Message>
30
+ <ArgumentValue>READ</ArgumentValue>
31
+ <RequestId>74A377B1C0FA2BCF</RequestId>
32
+ <HostId>cP4rqsAEtHpN6Ckv08Hr3LXjLzx15/YgyoSqzs779vMR8MrAFSodxZp96wtuMQuI</HostId>
33
+ <ArgumentName>x-oss-acl</ArgumentName>
34
+ </Error>
@@ -0,0 +1,3 @@
1
+ headers_including_one_piece_of_metadata:
2
+ x-oss-meta-test: foo
3
+ content_type: text/plain
@@ -0,0 +1,15 @@
1
+ logging_enabled: >
2
+ <BucketLoggingStatus xmlns="http://oss.aliyuncs.com/doc/2006-03-01/">
3
+ <LoggingEnabled>
4
+ <TargetBucket>mylogs</TargetBucket>
5
+ <TargetPrefix>access_log-</TargetPrefix>
6
+ </LoggingEnabled>
7
+ </BucketLoggingStatus>
8
+
9
+ logging_disabled: >
10
+ <BucketLoggingStatus xmlns="http://oss.aliyuncs.com/doc/2006-03-01/">
11
+ <!--<LoggingEnabled>
12
+ <TargetBucket>myLogsBucket</TargetBucket>
13
+ <TargetPrefix>add/this/prefix/to/my/log/files/access_log-</TargetPrefix>
14
+ </LoggingEnabled>-->
15
+ </BucketLoggingStatus>
@@ -0,0 +1,5 @@
1
+ bucket_get:
2
+ "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [14/Nov/2006:06:36:48 +0000] 67.165.183.125 bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 8B5297D428A05432 REST.GET.BUCKET - \"GET /marcel HTTP/1.1\" 200 - 4534 - 398 395 \"-\" \"-\"\n"
3
+
4
+ browser_get:
5
+ "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [25/Nov/2006:06:26:23 +0000] 67.165.183.125 65a011a29cdf8ec533ec3d1ccaae921c 41521D07CA012312 REST.GET.OBJECT kiss.jpg \"GET /marcel/kiss.jpg HTTP/1.1\" 200 - 67748 67748 259 104 \"-\" \"Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0\"\n"
@@ -0,0 +1,7 @@
1
+ simple_log:
2
+ - "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [14/Nov/2006:06:36:48 +0000] 67.165.183.125 bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 8B5297D428A05432 REST.GET.BUCKET - \"GET /marcel HTTP/1.1\" 200 - 4534 - 398 395 \"-\" \"-\"\n"
3
+ - "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [14/Nov/2006:06:38:58 +0000] 67.165.183.125 bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 8F6F3C4027849420 REST.GET.BUCKET - \"GET /marcel HTTP/1.1\" 200 - 4534 - 458 456 \"-\" \"-\"\n"
4
+
5
+ requests_from_a_browser:
6
+ - "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [25/Nov/2006:06:26:23 +0000] 67.165.183.125 65a011a29cdf8ec533ec3d1ccaae921c 41521D07CA012312 REST.GET.OBJECT kiss.jpg \"GET /marcel/kiss.jpg HTTP/1.1\" 200 - 67748 67748 259 104 \"-\" \"Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0\"\n"
7
+ - "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [25/Nov/2006:06:26:27 +0000] 67.165.183.125 65a011a29cdf8ec533ec3d1ccaae921c 88629578AFDDD9B5 REST.GET.TORRENT kiss.jpg \"GET /marcel/kiss.jpg?torrent HTTP/1.1\" 200 - 215 - 379 - \"-\" \"Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0\"\n"
@@ -0,0 +1,16 @@
1
+ policy_with_one_grant: >
2
+ <AccessControlPolicy>
3
+ <Owner>
4
+ <ID>bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1</ID>
5
+ <DisplayName>mmolina@onramp.net</DisplayName>
6
+ </Owner>
7
+ <AccessControlList>
8
+ <Grant>
9
+ <Grantee xsi:type="CanonicalUser" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
10
+ <ID>bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1</ID>
11
+ <DisplayName>mmolina@onramp.net</DisplayName>
12
+ </Grantee>
13
+ <Permission>FULL_CONTROL</Permission>
14
+ </Grant>
15
+ </AccessControlList>
16
+ </AccessControlPolicy>
@@ -0,0 +1,90 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require File.dirname(__FILE__) + '/test_helper'
3
+
4
+ class LoggingStatusReadingTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @disabled = logging_status(:logging_disabled)
8
+ @enabled = logging_status(:logging_enabled)
9
+ @new_status = Logging::Status.new('target_bucket' => 'foo', 'target_prefix' => 'access-log-')
10
+ end
11
+
12
+ def test_logging_enabled?
13
+ assert !@disabled.logging_enabled?
14
+ assert !@new_status.logging_enabled?
15
+ assert @enabled.logging_enabled?
16
+ end
17
+
18
+ def test_passing_in_prefix_and_bucket
19
+ assert_equal 'foo', @new_status.target_bucket
20
+ assert_equal 'access-log-', @new_status.target_prefix
21
+ assert !@new_status.logging_enabled?
22
+ end
23
+
24
+ private
25
+ def logging_status(fixture)
26
+ Logging::Status.new(Parsing::XmlParser.new(Fixtures::Logging[fixture.to_s]))
27
+ end
28
+ end
29
+
30
+ class LoggingStatusWritingTest < LoggingStatusReadingTest
31
+ def setup
32
+ super
33
+ @disabled = Logging::Status.new(Parsing::XmlParser.new(@disabled.to_xml))
34
+ @enabled = Logging::Status.new(Parsing::XmlParser.new(@enabled.to_xml))
35
+ end
36
+ end
37
+
38
+ class LogTest < Test::Unit::TestCase
39
+ def test_value_converted_to_log_lines
40
+ log_object = OSSObject.new
41
+ log_object.value = Fixtures::Logs.simple_log.join
42
+ log = Logging::Log.new(log_object)
43
+ assert_nothing_raised do
44
+ log.lines
45
+ end
46
+
47
+ assert_equal 2, log.lines.size
48
+ assert_kind_of Logging::Log::Line, log.lines.first
49
+ assert_equal 'marcel', log.lines.first.bucket
50
+ end
51
+ end
52
+
53
+ class LogLineTest < Test::Unit::TestCase
54
+ def setup
55
+ @line = Logging::Log::Line.new(Fixtures::Loglines.bucket_get)
56
+ end
57
+
58
+ def test_field_accessors
59
+ expected_results = {
60
+ :owner => Owner.new('id' => 'bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1'),
61
+ :bucket => 'marcel',
62
+ :time => Time.parse('Nov 14 2006 06:36:48 +0000'),
63
+ :remote_ip => '67.165.183.125',
64
+ :request_id => '8B5297D428A05432',
65
+ :requestor => Owner.new('id' => 'bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1'),
66
+ :operation => 'REST.GET.BUCKET',
67
+ :key => nil,
68
+ :request_uri => 'GET /marcel HTTP/1.1',
69
+ :http_status => 200,
70
+ :error_code => nil,
71
+ :bytes_sent => 4534,
72
+ :object_size => nil,
73
+ :total_time => 398,
74
+ :turn_around_time => 395,
75
+ :referrer => nil,
76
+ :user_agent => nil
77
+ }
78
+
79
+ expected_results.each do |field, expected|
80
+ assert_equal expected, @line.send(field)
81
+ end
82
+
83
+ assert_equal expected_results, @line.attributes
84
+ end
85
+
86
+ def test_user_agent
87
+ line = Logging::Log::Line.new(Fixtures::Loglines.browser_get)
88
+ assert_equal 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0', line.user_agent
89
+ end
90
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Aliyun
3
+ module OSS
4
+ class FakeResponse
5
+ attr_reader :code, :body, :headers
6
+ def initialize(options = {})
7
+ @code = options.delete(:code) || 200
8
+ @body = options.delete(:body) || ''
9
+ @headers = {'content-type' => 'application/xml'}.merge(options.delete(:headers) || {})
10
+ end
11
+
12
+ # For ErrorResponse
13
+ def response
14
+ body
15
+ end
16
+
17
+ def [](header)
18
+ headers[header]
19
+ end
20
+
21
+ def each(&block)
22
+ headers.each(&block)
23
+ end
24
+ alias_method :each_header, :each
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,221 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require File.dirname(__FILE__) + '/test_helper'
3
+
4
+ class ObjectTest < Test::Unit::TestCase
5
+ def setup
6
+ bucket = Bucket.new(Parsing::XmlParser.new(Fixtures::Buckets.bucket_with_one_key))
7
+ @object = bucket.objects.first
8
+ end
9
+
10
+ def test_header_settings_reader_and_writer
11
+ headers = {'content-type' => 'text/plain'}
12
+ mock_connection_for(OSSObject, :returns => {:headers => headers})
13
+
14
+ assert_nothing_raised do
15
+ @object.content_type
16
+ end
17
+
18
+ assert_equal 'text/plain', @object.content_type
19
+
20
+ assert_nothing_raised do
21
+ @object.content_type = 'image/jpg'
22
+ end
23
+
24
+ assert_equal 'image/jpg', @object.content_type
25
+
26
+ assert_raises(NoMethodError) do
27
+ @object.non_existant_header_setting
28
+ end
29
+ end
30
+
31
+ def test_key_name_validation
32
+ assert_raises(InvalidKeyName) do
33
+ OSSObject.create(nil, '', 'marcel')
34
+ end
35
+
36
+ assert_raises(InvalidKeyName) do
37
+ huge_name = 'a' * 1500
38
+ OSSObject.create(huge_name, '', 'marcel')
39
+ end
40
+ end
41
+
42
+ def test_content_type_inference
43
+ [
44
+ ['foo.jpg', {}, 'image/jpeg'],
45
+ ['foo.txt', {}, 'text/plain'],
46
+ ['foo', {}, nil],
47
+ ['foo.asdf', {}, nil],
48
+ ['foo.jpg', {:content_type => nil}, nil],
49
+ ['foo', {:content_type => 'image/jpg'}, 'image/jpg'],
50
+ ['foo.jpg', {:content_type => 'image/png'}, 'image/png'],
51
+ ['foo.asdf', {:content_type => 'image/jpg'}, 'image/jpg']
52
+ ].each do |key, options, content_type|
53
+ OSSObject.send(:infer_content_type!, key, options)
54
+ assert_equal content_type, options[:content_type]
55
+ end
56
+ end
57
+
58
+ def test_object_has_owner
59
+ assert_kind_of Owner, @object.owner
60
+ end
61
+
62
+ def test_owner_attributes_are_accessible
63
+ owner = @object.owner
64
+ assert owner.id
65
+ assert owner.display_name
66
+ assert_equal 'bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1', owner.id
67
+ assert_equal 'mmolina@onramp.net', owner.display_name
68
+ end
69
+
70
+ def test_only_valid_attributes_accessible
71
+ assert_raises(NoMethodError) do
72
+ @object.owner.foo
73
+ end
74
+ end
75
+
76
+ def test_fetching_object_value_generates_value_object
77
+ mock_connection_for(OSSObject, :returns => {:body => 'hello!'})
78
+ value = OSSObject.value('foo', 'bar')
79
+ assert_kind_of OSSObject::Value, value
80
+ assert_equal 'hello!', value
81
+ end
82
+
83
+ def test_fetching_file_by_name_raises_when_heuristic_fails
84
+ mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.bucket_with_one_key})
85
+ assert_raises(NoSuchKey) do
86
+ OSSObject.find('not_tongue_overload.jpg', 'marcel_molina')
87
+ end
88
+
89
+ object = nil # Block scoping
90
+ assert_nothing_raised do
91
+ object = OSSObject.find('tongue_overload.jpg', 'marcel_molina')
92
+ end
93
+ assert_kind_of OSSObject, object
94
+ assert_equal 'tongue_overload.jpg', object.key
95
+ end
96
+
97
+ def test_about
98
+ headers = {'content-size' => '12345', 'date' => Time.now.httpdate, 'content-type' => 'application/xml'}
99
+ mock_connection_for(OSSObject, :returns => [
100
+ {:headers => headers},
101
+ {:code => 404}
102
+ ]
103
+ )
104
+ about = OSSObject.about('foo', 'bar')
105
+ assert_kind_of OSSObject::About, about
106
+ assert_equal headers, about
107
+
108
+ assert_raises(NoSuchKey) do
109
+ OSSObject.about('foo', 'bar')
110
+ end
111
+ end
112
+
113
+ def test_can_tell_that_an_ossobject_does_not_exist
114
+ mock_connection_for(OSSObject, :returns => {:code => 404})
115
+ assert_equal false, OSSObject.exists?('foo', 'bar')
116
+ end
117
+
118
+ def test_can_tell_that_an_ossobject_exists
119
+ mock_connection_for(OSSObject, :returns => {:code => 200})
120
+ assert_equal true, OSSObject.exists?('foo', 'bar')
121
+ end
122
+
123
+ def test_ossobject_equality
124
+ mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.bucket_with_more_than_one_key})
125
+ file1, file2 = Bucket.objects('does not matter')
126
+ assert file1 == file1
127
+ assert file2 == file2
128
+ assert !(file1 == file2) # /!\ Parens required /!\
129
+ end
130
+
131
+ def test_inspect
132
+ mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.bucket_with_one_key})
133
+ object = OSSObject.find('tongue_overload.jpg', 'bucket does not matter')
134
+ assert object.path
135
+ assert_nothing_raised { object.inspect }
136
+ assert object.inspect[object.path]
137
+ end
138
+
139
+ def test_etag
140
+ mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.bucket_with_one_key})
141
+ file = OSSObject.find('tongue_overload.jpg', 'bucket does not matter')
142
+ assert file.etag
143
+ assert_equal 'f21f7c4e8ea6e34b268887b07d6da745', file.etag
144
+ end
145
+
146
+ def test_fetching_information_about_an_object_that_does_not_exist_raises_no_such_key
147
+ mock_connection_for(OSSObject, :returns => {:body => '', :code => 404})
148
+ assert_raises(NoSuchKey) do
149
+ OSSObject.about('asdfasdfasdfas-this-does-not-exist', 'bucket does not matter')
150
+ end
151
+ end
152
+ def test_copy_options_are_used
153
+ options = {'x-oss-storage-class' => 'REDUCED_REDUNDANCY'}
154
+ resp = FakeResponse.new
155
+
156
+ connection = flexmock('Mock connection') do |mock|
157
+ mock.should_receive(:request).
158
+ # The storage-class key must be passed to connection.request(:put, ...)
159
+ with(:put, '/some-bucket/new', hsh(options), any, any).
160
+ and_return(resp)
161
+ end
162
+ flexmock(OSSObject).should_receive(:connection).and_return(connection)
163
+
164
+ result = OSSObject.copy('old', 'new', 'some-bucket', options)
165
+ assert_equal resp.code, result.code
166
+ end
167
+ end
168
+
169
+ class MetadataTest < Test::Unit::TestCase
170
+ def setup
171
+ @metadata = OSSObject::Metadata.new(Fixtures::Headers.headers_including_one_piece_of_metadata)
172
+ end
173
+
174
+ def test_only_metadata_is_extracted
175
+ assert @metadata.to_headers.size == 1
176
+ assert @metadata.to_headers['x-oss-meta-test']
177
+ assert_equal 'foo', @metadata.to_headers['x-oss-meta-test']
178
+ end
179
+
180
+ def test_setting_new_metadata_normalizes_name
181
+ @metadata[:bar] = 'baz'
182
+ assert @metadata.to_headers.include?('x-oss-meta-bar')
183
+ @metadata['baz'] = 'quux'
184
+ assert @metadata.to_headers.include?('x-oss-meta-baz')
185
+ @metadata['x-oss-meta-quux'] = 'whatever'
186
+ assert @metadata.to_headers.include?('x-oss-meta-quux')
187
+ end
188
+
189
+ def test_clobbering_existing_header
190
+ @metadata[:bar] = 'baz'
191
+ assert_equal 'baz', @metadata.to_headers['x-oss-meta-bar']
192
+ @metadata[:bar] = 'quux'
193
+ assert_equal 'quux', @metadata.to_headers['x-oss-meta-bar']
194
+ @metadata['bar'] = 'foo'
195
+ assert_equal 'foo', @metadata.to_headers['x-oss-meta-bar']
196
+ @metadata['x-oss-meta-bar'] = 'bar'
197
+ assert_equal 'bar', @metadata.to_headers['x-oss-meta-bar']
198
+ end
199
+
200
+ def test_invalid_metadata
201
+ @metadata[:invalid_header] = ' ' * (OSSObject::Metadata::SIZE_LIMIT + 1)
202
+ assert_raises InvalidMetadataValue do
203
+ @metadata.to_headers
204
+ end
205
+ end
206
+ end
207
+
208
+ class ValueTest < Test::Unit::TestCase
209
+ def setup
210
+ @response = FakeResponse.new(:body => 'hello there')
211
+ @value = OSSObject::Value.new(@response)
212
+ end
213
+
214
+ def test_value_is_set_to_response_body
215
+ assert_equal @response.body, @value
216
+ end
217
+
218
+ def test_response_is_accessible_from_value_object
219
+ assert_equal @response, @value.response
220
+ end
221
+ end
@@ -0,0 +1,67 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require File.dirname(__FILE__) + '/test_helper'
3
+
4
+ class TypecastingTest < Test::Unit::TestCase
5
+ # Make it easier to call methods in tests
6
+ Parsing::Typecasting.public_instance_methods.each do |method|
7
+ Parsing::Typecasting.send(:module_function, method)
8
+ end
9
+
10
+ def test_array_with_one_element_that_is_a_hash
11
+ value = [{'Available' => 'true'}]
12
+ assert_equal [{'available' => true}], Parsing::Typecasting.typecast(value)
13
+ end
14
+
15
+ def test_hash_with_one_key_whose_value_is_an_array
16
+ value = {
17
+ 'Bucket' =>
18
+ [
19
+ {'Available' => 'true'}
20
+ ]
21
+ }
22
+
23
+ expected = {
24
+ 'bucket' =>
25
+ [
26
+ {'available' => true}
27
+ ]
28
+ }
29
+ assert_equal expected, Parsing::Typecasting.typecast(value)
30
+ end
31
+
32
+ end
33
+
34
+ class XmlParserTest < Test::Unit::TestCase
35
+ def test_bucket_is_always_forced_to_be_an_array_unless_empty
36
+ one_bucket = Parsing::XmlParser.new(Fixtures::Buckets.bucket_list_with_one_bucket)
37
+ more_than_one = Parsing::XmlParser.new(Fixtures::Buckets.bucket_list_with_more_than_one_bucket)
38
+
39
+ [one_bucket, more_than_one].each do |bucket_list|
40
+ assert_kind_of Array, bucket_list['buckets']['bucket']
41
+ end
42
+
43
+ no_buckets = Parsing::XmlParser.new(Fixtures::Buckets.empty_bucket_list)
44
+ assert no_buckets.has_key?('buckets')
45
+ assert_nil no_buckets['buckets']
46
+ end
47
+
48
+ def test_bucket_contents_are_forced_to_be_an_array_unless_empty
49
+ one_key = Parsing::XmlParser.new(Fixtures::Buckets.bucket_with_one_key)
50
+ more_than_one = Parsing::XmlParser.new(Fixtures::Buckets.bucket_with_more_than_one_key)
51
+ [one_key, more_than_one].each do |bucket_with_contents|
52
+ assert_kind_of Array, bucket_with_contents['contents']
53
+ end
54
+
55
+ no_keys = Parsing::XmlParser.new(Fixtures::Buckets.empty_bucket)
56
+ assert !no_keys.has_key?('contents')
57
+ end
58
+
59
+ def test_policy_grants_are_always_an_array
60
+ policy = Parsing::XmlParser.new(Fixtures::Policies.policy_with_one_grant)
61
+ assert_kind_of Array, policy['access_control_list']['grant']
62
+ end
63
+
64
+ def test_empty_xml_response_is_not_parsed
65
+ assert_equal({}, Parsing::XmlParser.new(''))
66
+ end
67
+ end