isaacfeliu-aws-s3 0.4.0

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/test/acl_test.rb ADDED
@@ -0,0 +1,254 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class PolicyReadingTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @policy = prepare_policy
7
+ end
8
+
9
+ def test_policy_owner
10
+ assert_kind_of Owner, @policy.owner
11
+ assert_equal 'bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1', @policy.owner.id
12
+ assert_equal 'mmolina@onramp.net', @policy.owner.display_name
13
+ end
14
+
15
+ def test_grants
16
+ assert @policy.grants
17
+ assert !@policy.grants.empty?
18
+ grant = @policy.grants.first
19
+ assert_kind_of ACL::Grant, grant
20
+ assert_equal 'FULL_CONTROL', grant.permission
21
+ end
22
+
23
+ def test_grants_have_grantee
24
+ grant = @policy.grants.first
25
+ assert grantee = grant.grantee
26
+ assert_kind_of ACL::Grantee, grantee
27
+ assert_equal 'bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1', grantee.id
28
+ assert_equal 'mmolina@onramp.net', grantee.display_name
29
+ assert_equal 'CanonicalUser', grantee.type
30
+ end
31
+
32
+ def test_grantee_always_responds_to_email_address
33
+ assert_nothing_raised do
34
+ @policy.grants.first.grantee.email_address
35
+ end
36
+ end
37
+
38
+ private
39
+ def prepare_policy
40
+ ACL::Policy.new(parsed_policy)
41
+ end
42
+
43
+ def parsed_policy
44
+ Parsing::XmlParser.new Fixtures::Policies.policy_with_one_grant
45
+ end
46
+ end
47
+
48
+ class PolicyWritingTest < PolicyReadingTest
49
+
50
+ def setup
51
+ policy = prepare_policy
52
+ # Dump the policy to xml and retranslate it back from the xml then run all the tests in the xml reading
53
+ # test. This round tripping indirectly asserts that the original xml document is the same as the to_xml
54
+ # dump.
55
+ @policy = ACL::Policy.new(Parsing::XmlParser.new(policy.to_xml))
56
+ end
57
+
58
+ end
59
+
60
+ class PolicyTest < Test::Unit::TestCase
61
+ def test_building_policy_by_hand
62
+ policy = grant = grantee = nil
63
+ assert_nothing_raised do
64
+ policy = ACL::Policy.new
65
+ grant = ACL::Grant.new
66
+ grantee = ACL::Grantee.new
67
+ grantee.email_address = 'marcel@vernix.org'
68
+ grant.permission = 'READ_ACP'
69
+ grant.grantee = grantee
70
+ policy.grants << grant
71
+ policy.owner = Owner.new('id' => '123456789', 'display_name' => 'noradio')
72
+ end
73
+
74
+ assert_nothing_raised do
75
+ policy.to_xml
76
+ end
77
+
78
+ assert !policy.grants.empty?
79
+ assert_equal 1, policy.grants.size
80
+ assert_equal 'READ_ACP', policy.grants.first.permission
81
+ end
82
+
83
+ def test_include?
84
+ policy = ACL::Policy.new(Parsing::XmlParser.new(Fixtures::Policies.policy_with_one_grant))
85
+ assert !policy.grants.include?(:public_read)
86
+ policy.grants << ACL::Grant.grant(:public_read)
87
+ assert policy.grants.include?(:public_read)
88
+
89
+ assert policy.grants.include?(ACL::Grant.grant(:public_read))
90
+ [false, 1, '1'].each do |non_grant|
91
+ assert !policy.grants.include?(non_grant)
92
+ end
93
+ end
94
+
95
+ def test_delete
96
+ policy = ACL::Policy.new(Parsing::XmlParser.new(Fixtures::Policies.policy_with_one_grant))
97
+ policy.grants << ACL::Grant.grant(:public_read)
98
+ assert policy.grants.include?(:public_read)
99
+ assert policy.grants.delete(:public_read)
100
+ assert !policy.grants.include?(:public_read)
101
+ [false, 1, '1'].each do |non_grant|
102
+ assert_nil policy.grants.delete(non_grant)
103
+ end
104
+ end
105
+
106
+ def test_grant_list_comparison
107
+ policy = ACL::Policy.new
108
+ policy2 = ACL::Policy.new
109
+
110
+ grant_names = [:public_read, :public_read_acp, :authenticated_write]
111
+ grant_names.each {|grant_name| policy.grants << ACL::Grant.grant(grant_name)}
112
+ grant_names.reverse_each {|grant_name| policy2.grants << ACL::Grant.grant(grant_name)}
113
+
114
+ assert_equal policy.grants, policy2.grants
115
+ end
116
+ end
117
+
118
+ class GrantTest < Test::Unit::TestCase
119
+ def test_permission_must_be_valid
120
+ grant = ACL::Grant.new
121
+ assert_nothing_raised do
122
+ grant.permission = 'READ_ACP'
123
+ end
124
+
125
+ assert_raises(InvalidAccessControlLevel) do
126
+ grant.permission = 'not a valid permission'
127
+ end
128
+ end
129
+
130
+ def test_stock_grants
131
+ assert_raises(ArgumentError) do
132
+ ACL::Grant.grant :this_is_not_a_stock_grant
133
+ end
134
+
135
+ grant = nil
136
+ assert_nothing_raised do
137
+ grant = ACL::Grant.grant(:public_read)
138
+ end
139
+
140
+ assert grant
141
+ assert_kind_of ACL::Grant, grant
142
+ assert_equal 'READ', grant.permission
143
+ assert grant.grantee
144
+ assert_kind_of ACL::Grantee, grant.grantee
145
+ assert_equal 'AllUsers', grant.grantee.group
146
+ end
147
+ end
148
+
149
+ class GranteeTest < Test::Unit::TestCase
150
+ def test_type_inference
151
+ grantee = ACL::Grantee.new
152
+
153
+ assert_nothing_raised do
154
+ grantee.type
155
+ end
156
+
157
+ assert_nil grantee.type
158
+ grantee.group = 'AllUsers'
159
+ assert_equal 'AllUsers', grantee.group
160
+ assert_equal 'Group', grantee.type
161
+ grantee.email_address = 'marcel@vernix.org'
162
+ assert_equal 'AmazonCustomerByEmail', grantee.type
163
+ grantee.display_name = 'noradio'
164
+ assert_equal 'AmazonCustomerByEmail', grantee.type
165
+ grantee.id = '123456789'
166
+ assert_equal 'CanonicalUser', grantee.type
167
+ end
168
+
169
+ def test_type_is_extracted_if_present
170
+ grantee = ACL::Grantee.new('xsi:type' => 'CanonicalUser')
171
+ assert_equal 'CanonicalUser', grantee.type
172
+ end
173
+
174
+ def test_type_representation
175
+ grantee = ACL::Grantee.new('uri' => 'http://acs.amazonaws.com/groups/global/AllUsers')
176
+
177
+ assert_equal 'AllUsers Group', grantee.type_representation
178
+ grantee.group = 'AuthenticatedUsers'
179
+ assert_equal 'AuthenticatedUsers Group', grantee.type_representation
180
+ grantee.email_address = 'marcel@vernix.org'
181
+ assert_equal 'marcel@vernix.org', grantee.type_representation
182
+ grantee.display_name = 'noradio'
183
+ grantee.id = '123456789'
184
+ assert_equal 'noradio', grantee.type_representation
185
+ end
186
+ end
187
+
188
+ class ACLOptionProcessorTest < Test::Unit::TestCase
189
+ def test_empty_options
190
+ options = {}
191
+ assert_nothing_raised do
192
+ process! options
193
+ end
194
+ assert_equal({}, options)
195
+ end
196
+
197
+ def test_invalid_access_level
198
+ options = {:access => :foo}
199
+ assert_raises(InvalidAccessControlLevel) do
200
+ process! options
201
+ end
202
+ end
203
+
204
+ def test_valid_access_level_is_normalized
205
+ valid_access_levels = [
206
+ {:access => :private},
207
+ {'access' => 'private'},
208
+ {:access => 'private'},
209
+ {'access' => :private},
210
+ {'x-amz-acl' => 'private'},
211
+ {:x_amz_acl => :private},
212
+ {:x_amz_acl => 'private'},
213
+ {'x_amz_acl' => :private}
214
+ ]
215
+
216
+ valid_access_levels.each do |options|
217
+ assert_nothing_raised do
218
+ process! options
219
+ end
220
+ assert_equal 'private', acl(options)
221
+ end
222
+
223
+ valid_hyphenated_access_levels = [
224
+ {:access => :public_read},
225
+ {'access' => 'public_read'},
226
+ {'access' => 'public-read'},
227
+ {:access => 'public_read'},
228
+ {:access => 'public-read'},
229
+ {'access' => :public_read},
230
+
231
+ {'x-amz-acl' => 'public_read'},
232
+ {:x_amz_acl => :public_read},
233
+ {:x_amz_acl => 'public_read'},
234
+ {:x_amz_acl => 'public-read'},
235
+ {'x_amz_acl' => :public_read}
236
+ ]
237
+
238
+ valid_hyphenated_access_levels.each do |options|
239
+ assert_nothing_raised do
240
+ process! options
241
+ end
242
+ assert_equal 'public-read', acl(options)
243
+ end
244
+ end
245
+
246
+ private
247
+ def process!(options)
248
+ ACL::OptionProcessor.process!(options)
249
+ end
250
+
251
+ def acl(options)
252
+ options['x-amz-acl']
253
+ end
254
+ end
@@ -0,0 +1,96 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class HeaderAuthenticationTest < Test::Unit::TestCase
4
+ def test_encoded_canonical
5
+ signature = Authentication::Signature.new(request, key_id, secret)
6
+ assert_equal AmazonDocExampleData::Example1.canonical_string, signature.send(:canonical_string)
7
+ assert_equal AmazonDocExampleData::Example1.signature, signature.send(:encoded_canonical)
8
+ end
9
+
10
+ def test_authorization_header
11
+ header = Authentication::Header.new(request, key_id, secret)
12
+ assert_equal AmazonDocExampleData::Example1.canonical_string, header.send(:canonical_string)
13
+ assert_equal AmazonDocExampleData::Example1.authorization_header, header
14
+ end
15
+
16
+ private
17
+ def request; AmazonDocExampleData::Example1.request end
18
+ def key_id ; AmazonDocExampleData::Example1.access_key_id end
19
+ def secret ; AmazonDocExampleData::Example1.secret_access_key end
20
+ end
21
+
22
+ class QueryStringAuthenticationTest < Test::Unit::TestCase
23
+ def test_query_string
24
+ query_string = Authentication::QueryString.new(request, key_id, secret, :expires_in => 60)
25
+ assert_equal AmazonDocExampleData::Example3.canonical_string, query_string.send(:canonical_string)
26
+ assert_equal AmazonDocExampleData::Example3.query_string, query_string
27
+ end
28
+
29
+ def test_query_string_with_explicit_expiry
30
+ query_string = Authentication::QueryString.new(request, key_id, secret, :expires => expires)
31
+ assert_equal expires, query_string.send(:canonical_string).instance_variable_get(:@options)[:expires]
32
+ assert_equal AmazonDocExampleData::Example3.query_string, query_string
33
+ end
34
+
35
+ private
36
+ def request; AmazonDocExampleData::Example3.request end
37
+ def key_id ; AmazonDocExampleData::Example3.access_key_id end
38
+ def secret ; AmazonDocExampleData::Example3.secret_access_key end
39
+ def expires; AmazonDocExampleData::Example3.expires end
40
+ end
41
+
42
+ class CanonicalStringTest < Test::Unit::TestCase
43
+ def setup
44
+ @request = Net::HTTP::Post.new('/test')
45
+ @canonical_string = Authentication::CanonicalString.new(@request)
46
+ end
47
+
48
+ def test_path_does_not_include_query_string
49
+ request = Net::HTTP::Get.new('/test/query/string?foo=bar&baz=quux')
50
+ assert_equal '/test/query/string', Authentication::CanonicalString.new(request).send(:path)
51
+
52
+ # Make sure things still work when there is *no* query string
53
+ request = Net::HTTP::Get.new('/')
54
+ assert_equal '/', Authentication::CanonicalString.new(request).send(:path)
55
+ request = Net::HTTP::Get.new('/foo/bar')
56
+ assert_equal '/foo/bar', Authentication::CanonicalString.new(request).send(:path)
57
+ end
58
+
59
+ def test_path_includes_significant_query_strings
60
+ significant_query_strings = [
61
+ ['/test/query/string?acl', '/test/query/string?acl'],
62
+ ['/test/query/string?acl&foo=bar', '/test/query/string?acl'],
63
+ ['/test/query/string?foo=bar&acl', '/test/query/string?acl'],
64
+ ['/test/query/string?acl=foo', '/test/query/string?acl'],
65
+ ['/test/query/string?torrent=foo', '/test/query/string?torrent'],
66
+ ['/test/query/string?logging=foo', '/test/query/string?logging'],
67
+ ['/test/query/string?bar=baz&acl=foo', '/test/query/string?acl']
68
+ ]
69
+
70
+ significant_query_strings.each do |uncleaned_path, expected_cleaned_path|
71
+ assert_equal expected_cleaned_path, Authentication::CanonicalString.new(Net::HTTP::Get.new(uncleaned_path)).send(:path)
72
+ end
73
+ end
74
+
75
+ def test_default_headers_set
76
+ Authentication::CanonicalString.default_headers.each do |header|
77
+ assert @canonical_string.headers.include?(header)
78
+ end
79
+ end
80
+
81
+ def test_interesting_headers_are_copied_over
82
+ an_interesting_header = 'content-md5'
83
+ string_without_interesting_header = Authentication::CanonicalString.new(@request)
84
+ assert string_without_interesting_header.headers[an_interesting_header].empty?
85
+
86
+ # Add an interesting header
87
+ @request[an_interesting_header] = 'foo'
88
+ string_with_interesting_header = Authentication::CanonicalString.new(@request)
89
+ assert_equal 'foo', string_with_interesting_header.headers[an_interesting_header]
90
+ end
91
+
92
+ def test_canonical_string
93
+ request = AmazonDocExampleData::Example1.request
94
+ assert_equal AmazonDocExampleData::Example1.canonical_string, Authentication::CanonicalString.new(request)
95
+ end
96
+ end
data/test/base_test.rb ADDED
@@ -0,0 +1,143 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class BaseTest < Test::Unit::TestCase
4
+ def test_connection_established
5
+ assert_raises(NoConnectionEstablished) do
6
+ Base.connection
7
+ end
8
+
9
+ Base.establish_connection!(:access_key_id => '123', :secret_access_key => 'abc')
10
+ assert_kind_of Connection, Base.connection
11
+
12
+ instance = Base.new
13
+ assert_equal instance.send(:connection), Base.connection
14
+ assert_equal instance.send(:http), Base.connection.http
15
+ end
16
+
17
+ def test_respond_with
18
+ assert_equal Base::Response, Base.send(:response_class)
19
+ Base.send(:respond_with, Bucket::Response) do
20
+ assert_equal Bucket::Response, Base.send(:response_class)
21
+ end
22
+ assert_equal Base::Response, Base.send(:response_class)
23
+ end
24
+
25
+ def test_request_tries_again_when_encountering_an_internal_error
26
+ Bucket.in_test_mode do
27
+ Bucket.request_returns [
28
+ # First request is an internal error
29
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
30
+ # Second request is a success
31
+ {:body => Fixtures::Buckets.empty_bucket, :code => 200}
32
+ ]
33
+ bucket = nil # Block scope hack
34
+ assert_nothing_raised do
35
+ bucket = Bucket.find('marcel')
36
+ end
37
+ # Don't call objects 'cause we don't want to make another request
38
+ assert bucket.object_cache.empty?
39
+ end
40
+ end
41
+
42
+ def test_request_tries_up_to_three_times
43
+ Bucket.in_test_mode do
44
+ Bucket.request_returns [
45
+ # First request is an internal error
46
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
47
+ # Second request is also an internal error
48
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
49
+ # Ditto third
50
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
51
+ # Fourth works
52
+ {:body => Fixtures::Buckets.empty_bucket, :code => 200}
53
+ ]
54
+ bucket = nil # Block scope hack
55
+ assert_nothing_raised do
56
+ bucket = Bucket.find('marcel')
57
+ end
58
+ # Don't call objects 'cause we don't want to make another request
59
+ assert bucket.object_cache.empty?
60
+ end
61
+ end
62
+
63
+ def test_request_tries_again_three_times_and_gives_up
64
+ Bucket.in_test_mode do
65
+ Bucket.request_returns [
66
+ # First request is an internal error
67
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
68
+ # Second request is also an internal error
69
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
70
+ # Ditto third
71
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
72
+ # Ditto fourth
73
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
74
+ ]
75
+ assert_raises(InternalError) do
76
+ Bucket.find('marcel')
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ class MultiConnectionsTest < Test::Unit::TestCase
83
+ class ClassToTestSettingCurrentBucket < Base
84
+ set_current_bucket_to 'foo'
85
+ end
86
+
87
+ def setup
88
+ Base.send(:connections).clear
89
+ end
90
+ alias_method :teardown, :setup
91
+
92
+ def test_default_connection_options_are_used_for_subsequent_connections
93
+ assert !Base.connected?
94
+
95
+ assert_raises(MissingAccessKey) do
96
+ Base.establish_connection!
97
+ end
98
+
99
+ assert !Base.connected?
100
+
101
+ assert_raises(NoConnectionEstablished) do
102
+ Base.connection
103
+ end
104
+
105
+ assert_nothing_raised do
106
+ Base.establish_connection!(:access_key_id => '123', :secret_access_key => 'abc')
107
+ end
108
+
109
+ assert Base.connected?
110
+
111
+ assert_nothing_raised do
112
+ Base.connection
113
+ end
114
+
115
+ # All subclasses are currently using the default connection
116
+ assert Base.connection == Bucket.connection
117
+
118
+ # No need to pass in the required options. The default connection will supply them
119
+ assert_nothing_raised do
120
+ Bucket.establish_connection!(:server => 'foo.s3.amazonaws.com')
121
+ end
122
+
123
+ assert Base.connection != Bucket.connection
124
+ assert_equal '123', Bucket.connection.access_key_id
125
+ assert_equal 'foo', Bucket.connection.subdomain
126
+ end
127
+
128
+ def test_current_bucket
129
+ Base.establish_connection!(:access_key_id => '123', :secret_access_key => 'abc')
130
+ assert_raises(CurrentBucketNotSpecified) do
131
+ Base.current_bucket
132
+ end
133
+
134
+ S3Object.establish_connection!(:server => 'foo-bucket.s3.amazonaws.com')
135
+ assert_nothing_raised do
136
+ assert_equal 'foo-bucket', S3Object.current_bucket
137
+ end
138
+ end
139
+
140
+ def test_setting_the_current_bucket
141
+ assert_equal 'foo', ClassToTestSettingCurrentBucket.current_bucket
142
+ end
143
+ end