ghazel-aws-s3 0.6.4 → 0.6.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,114 @@
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
+ def test_expires_in_is_coerced_to_being_an_integer_in_case_it_is_a_special_integer_proxy
36
+ # References bug: http://rubyforge.org/tracker/index.php?func=detail&aid=17458&group_id=2409&atid=9356
37
+ integer_proxy = Class.new do
38
+ attr_reader :integer
39
+ def initialize(integer)
40
+ @integer = integer
41
+ end
42
+
43
+ def to_int
44
+ integer
45
+ end
46
+ end
47
+
48
+ actual_integer = 25
49
+ query_string = Authentication::QueryString.new(request, key_id, secret, :expires_in => integer_proxy.new(actual_integer))
50
+ assert_equal actual_integer, query_string.send(:expires_in)
51
+ end
52
+
53
+ private
54
+ def request; AmazonDocExampleData::Example3.request end
55
+ def key_id ; AmazonDocExampleData::Example3.access_key_id end
56
+ def secret ; AmazonDocExampleData::Example3.secret_access_key end
57
+ def expires; AmazonDocExampleData::Example3.expires end
58
+ end
59
+
60
+ class CanonicalStringTest < Test::Unit::TestCase
61
+ def setup
62
+ @request = Net::HTTP::Post.new('/test')
63
+ @canonical_string = Authentication::CanonicalString.new(@request)
64
+ end
65
+
66
+ def test_path_does_not_include_query_string
67
+ request = Net::HTTP::Get.new('/test/query/string?foo=bar&baz=quux')
68
+ assert_equal '/test/query/string', Authentication::CanonicalString.new(request).send(:path)
69
+
70
+ # Make sure things still work when there is *no* query string
71
+ request = Net::HTTP::Get.new('/')
72
+ assert_equal '/', Authentication::CanonicalString.new(request).send(:path)
73
+ request = Net::HTTP::Get.new('/foo/bar')
74
+ assert_equal '/foo/bar', Authentication::CanonicalString.new(request).send(:path)
75
+ end
76
+
77
+ def test_path_includes_significant_query_strings
78
+ significant_query_strings = [
79
+ ['/test/query/string?acl', '/test/query/string?acl'],
80
+ ['/test/query/string?acl&foo=bar', '/test/query/string?acl'],
81
+ ['/test/query/string?foo=bar&acl', '/test/query/string?acl'],
82
+ ['/test/query/string?acl=foo', '/test/query/string?acl'],
83
+ ['/test/query/string?torrent=foo', '/test/query/string?torrent'],
84
+ ['/test/query/string?logging=foo', '/test/query/string?logging'],
85
+ ['/test/query/string?bar=baz&acl=foo', '/test/query/string?acl']
86
+ ]
87
+
88
+ significant_query_strings.each do |uncleaned_path, expected_cleaned_path|
89
+ assert_equal expected_cleaned_path, Authentication::CanonicalString.new(Net::HTTP::Get.new(uncleaned_path)).send(:path)
90
+ end
91
+ end
92
+
93
+ def test_default_headers_set
94
+ Authentication::CanonicalString.default_headers.each do |header|
95
+ assert @canonical_string.headers.include?(header)
96
+ end
97
+ end
98
+
99
+ def test_interesting_headers_are_copied_over
100
+ an_interesting_header = 'content-md5'
101
+ string_without_interesting_header = Authentication::CanonicalString.new(@request)
102
+ assert string_without_interesting_header.headers[an_interesting_header].empty?
103
+
104
+ # Add an interesting header
105
+ @request[an_interesting_header] = 'foo'
106
+ string_with_interesting_header = Authentication::CanonicalString.new(@request)
107
+ assert_equal 'foo', string_with_interesting_header.headers[an_interesting_header]
108
+ end
109
+
110
+ def test_canonical_string
111
+ request = AmazonDocExampleData::Example1.request
112
+ assert_equal AmazonDocExampleData::Example1.canonical_string, Authentication::CanonicalString.new(request)
113
+ end
114
+ end
@@ -0,0 +1,136 @@
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
+ mock_connection_for(Bucket, :returns => [
27
+ # First request is an internal error
28
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
29
+ # Second request is a success
30
+ {:body => Fixtures::Buckets.empty_bucket, :code => 200}
31
+ ])
32
+ bucket = nil # Block scope hack
33
+ assert_nothing_raised do
34
+ bucket = Bucket.find('marcel')
35
+ end
36
+ # Don't call objects 'cause we don't want to make another request
37
+ assert bucket.object_cache.empty?
38
+ end
39
+
40
+ def test_request_tries_up_to_three_times
41
+ mock_connection_for(Bucket, :returns => [
42
+ # First request is an internal error
43
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
44
+ # Second request is also an internal error
45
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
46
+ # Ditto third
47
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
48
+ # Fourth works
49
+ {:body => Fixtures::Buckets.empty_bucket, :code => 200}
50
+ ])
51
+ bucket = nil # Block scope hack
52
+ assert_nothing_raised do
53
+ bucket = Bucket.find('marcel')
54
+ end
55
+ # Don't call objects 'cause we don't want to make another request
56
+ assert bucket.object_cache.empty?
57
+ end
58
+
59
+ def test_request_tries_again_three_times_and_gives_up
60
+ mock_connection_for(Bucket, :returns => [
61
+ # First request is an internal error
62
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
63
+ # Second request is also an internal error
64
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
65
+ # Ditto third
66
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
67
+ # Ditto fourth
68
+ {:body => Fixtures::Errors.internal_error, :code => 500, :error => true},
69
+ ])
70
+ assert_raises(InternalError) do
71
+ Bucket.find('marcel')
72
+ end
73
+ end
74
+ end
75
+
76
+ class MultiConnectionsTest < Test::Unit::TestCase
77
+ class ClassToTestSettingCurrentBucket < Base
78
+ set_current_bucket_to 'foo'
79
+ end
80
+
81
+ def setup
82
+ Base.send(:connections).clear
83
+ end
84
+
85
+ def test_default_connection_options_are_used_for_subsequent_connections
86
+ assert !Base.connected?
87
+
88
+ assert_raises(MissingAccessKey) do
89
+ Base.establish_connection!
90
+ end
91
+
92
+ assert !Base.connected?
93
+
94
+ assert_raises(NoConnectionEstablished) do
95
+ Base.connection
96
+ end
97
+
98
+ assert_nothing_raised do
99
+ Base.establish_connection!(:access_key_id => '123', :secret_access_key => 'abc')
100
+ end
101
+
102
+ assert Base.connected?
103
+
104
+ assert_nothing_raised do
105
+ Base.connection
106
+ end
107
+
108
+ # All subclasses are currently using the default connection
109
+ assert_equal Base.connection, Bucket.connection
110
+
111
+ # No need to pass in the required options. The default connection will supply them
112
+ assert_nothing_raised do
113
+ Bucket.establish_connection!(:server => 'foo.s3.amazonaws.com')
114
+ end
115
+
116
+ assert Base.connection != Bucket.connection
117
+ assert_equal '123', Bucket.connection.access_key_id
118
+ assert_equal 'foo', Bucket.connection.subdomain
119
+ end
120
+
121
+ def test_current_bucket
122
+ Base.establish_connection!(:access_key_id => '123', :secret_access_key => 'abc')
123
+ assert_raises(CurrentBucketNotSpecified) do
124
+ Base.current_bucket
125
+ end
126
+
127
+ S3Object.establish_connection!(:server => 'foo-bucket.s3.amazonaws.com')
128
+ assert_nothing_raised do
129
+ assert_equal 'foo-bucket', S3Object.current_bucket
130
+ end
131
+ end
132
+
133
+ def test_setting_the_current_bucket
134
+ assert_equal 'foo', ClassToTestSettingCurrentBucket.current_bucket
135
+ end
136
+ end