paperclip 2.4.5 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of paperclip might be problematic. Click here for more details.
- data/.gitignore +22 -0
- data/.travis.yml +13 -0
- data/Appraisals +14 -0
- data/CONTRIBUTING.md +38 -0
- data/Gemfile +5 -0
- data/NEWS +23 -0
- data/README.md +72 -42
- data/Rakefile +1 -46
- data/cucumber/paperclip_steps.rb +6 -0
- data/features/basic_integration.feature +46 -0
- data/features/rake_tasks.feature +63 -0
- data/features/step_definitions/attachment_steps.rb +65 -0
- data/features/step_definitions/html_steps.rb +15 -0
- data/features/step_definitions/rails_steps.rb +182 -0
- data/features/step_definitions/s3_steps.rb +14 -0
- data/features/step_definitions/web_steps.rb +209 -0
- data/features/support/env.rb +8 -0
- data/features/support/fakeweb.rb +3 -0
- data/features/support/fixtures/.boot_config.rb.swo +0 -0
- data/features/support/fixtures/boot_config.txt +15 -0
- data/features/support/fixtures/gemfile.txt +5 -0
- data/features/support/fixtures/preinitializer.txt +20 -0
- data/features/support/paths.rb +28 -0
- data/features/support/rails.rb +46 -0
- data/features/support/selectors.rb +19 -0
- data/gemfiles/rails2.gemfile +9 -0
- data/gemfiles/rails3.gemfile +9 -0
- data/gemfiles/rails3_1.gemfile +9 -0
- data/lib/paperclip.rb +26 -19
- data/lib/paperclip/attachment.rb +123 -109
- data/lib/paperclip/interpolations.rb +7 -4
- data/lib/paperclip/matchers.rb +33 -2
- data/lib/paperclip/missing_attachment_styles.rb +1 -1
- data/lib/paperclip/railtie.rb +5 -0
- data/lib/paperclip/schema.rb +39 -0
- data/lib/paperclip/storage/fog.rb +21 -10
- data/lib/paperclip/storage/s3.rb +107 -40
- data/lib/paperclip/style.rb +13 -5
- data/lib/paperclip/url_generator.rb +64 -0
- data/lib/paperclip/version.rb +1 -1
- data/lib/tasks/paperclip.rake +1 -1
- data/paperclip.gemspec +41 -0
- data/test/.gitignore +1 -0
- data/test/attachment_test.rb +155 -168
- data/test/fixtures/question?mark.png +0 -0
- data/test/helper.rb +24 -1
- data/test/interpolations_test.rb +16 -2
- data/test/paperclip_missing_attachment_styles_test.rb +16 -0
- data/test/paperclip_test.rb +72 -22
- data/test/schema_test.rb +98 -0
- data/test/storage/filesystem_test.rb +2 -2
- data/test/{fog_test.rb → storage/fog_test.rb} +35 -8
- data/test/storage/s3_live_test.rb +63 -13
- data/test/storage/s3_test.rb +394 -91
- data/test/style_test.rb +50 -21
- data/test/support/mock_attachment.rb +22 -0
- data/test/support/mock_interpolator.rb +24 -0
- data/test/support/mock_model.rb +2 -0
- data/test/support/mock_url_generator_builder.rb +27 -0
- data/test/url_generator_test.rb +187 -0
- metadata +307 -125
- data/lib/paperclip/options.rb +0 -78
- data/test/options_test.rb +0 -75
data/test/storage/s3_test.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require './test/helper'
|
2
|
-
require 'aws
|
2
|
+
require 'aws'
|
3
3
|
|
4
4
|
class S3Test < Test::Unit::TestCase
|
5
5
|
def rails_env(env)
|
@@ -8,10 +8,17 @@ class S3Test < Test::Unit::TestCase
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
def setup
|
12
|
+
AWS.config(:access_key_id => "TESTKEY", :secret_access_key => "TESTSECRET", :stub_requests => true)
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
AWS.config(:access_key_id => nil, :secret_access_key => nil, :stub_requests => nil)
|
17
|
+
end
|
18
|
+
|
11
19
|
context "Parsing S3 credentials" do
|
12
20
|
setup do
|
13
21
|
@proxy_settings = {:host => "127.0.0.1", :port => 8888, :user => "foo", :password => "bar"}
|
14
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
15
22
|
rebuild_model :storage => :s3,
|
16
23
|
:bucket => "testing",
|
17
24
|
:http_proxy => @proxy_settings,
|
@@ -51,9 +58,54 @@ class S3Test < Test::Unit::TestCase
|
|
51
58
|
|
52
59
|
end
|
53
60
|
|
61
|
+
context ":bucket option via :s3_credentials" do
|
62
|
+
|
63
|
+
setup do
|
64
|
+
rebuild_model :storage => :s3, :s3_credentials => {:bucket => 'testing'}
|
65
|
+
@dummy = Dummy.new
|
66
|
+
end
|
67
|
+
|
68
|
+
should "populate #bucket_name" do
|
69
|
+
assert_equal @dummy.avatar.bucket_name, 'testing'
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
context ":bucket option" do
|
75
|
+
|
76
|
+
setup do
|
77
|
+
rebuild_model :storage => :s3, :bucket => "testing", :s3_credentials => {}
|
78
|
+
@dummy = Dummy.new
|
79
|
+
end
|
80
|
+
|
81
|
+
should "populate #bucket_name" do
|
82
|
+
assert_equal @dummy.avatar.bucket_name, 'testing'
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
context "missing :bucket option" do
|
88
|
+
|
89
|
+
setup do
|
90
|
+
rebuild_model :storage => :s3,
|
91
|
+
#:bucket => "testing", # intentionally left out
|
92
|
+
:http_proxy => @proxy_settings,
|
93
|
+
:s3_credentials => {:not => :important}
|
94
|
+
|
95
|
+
@dummy = Dummy.new
|
96
|
+
@dummy.avatar = StringIO.new(".")
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
should "raise an argument error" do
|
101
|
+
exception = assert_raise(ArgumentError) { @dummy.save }
|
102
|
+
assert_match /missing required :bucket option/, exception.message
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
54
107
|
context "" do
|
55
108
|
setup do
|
56
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
57
109
|
rebuild_model :storage => :s3,
|
58
110
|
:s3_credentials => {},
|
59
111
|
:bucket => "bucket",
|
@@ -66,11 +118,46 @@ class S3Test < Test::Unit::TestCase
|
|
66
118
|
should "return a url based on an S3 path" do
|
67
119
|
assert_match %r{^http://s3.amazonaws.com/bucket/avatars/stringio.txt}, @dummy.avatar.url
|
68
120
|
end
|
121
|
+
|
122
|
+
should "use the correct bucket" do
|
123
|
+
assert_equal "bucket", @dummy.avatar.s3_bucket.name
|
124
|
+
end
|
125
|
+
|
126
|
+
should "use the correct key" do
|
127
|
+
assert_equal "avatars/stringio.txt", @dummy.avatar.s3_object.key
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
context "An attachment that uses S3 for storage and has the style in the path" do
|
133
|
+
setup do
|
134
|
+
rebuild_model :storage => :s3,
|
135
|
+
:bucket => "testing",
|
136
|
+
:path => ":attachment/:style/:basename.:extension",
|
137
|
+
:styles => {
|
138
|
+
:thumb => "80x80>"
|
139
|
+
},
|
140
|
+
:s3_credentials => {
|
141
|
+
'access_key_id' => "12345",
|
142
|
+
'secret_access_key' => "54321"
|
143
|
+
}
|
144
|
+
|
145
|
+
@dummy = Dummy.new
|
146
|
+
@dummy.avatar = StringIO.new(".")
|
147
|
+
@avatar = @dummy.avatar
|
148
|
+
end
|
149
|
+
|
150
|
+
should "use an S3 object based on the correct path for the default style" do
|
151
|
+
assert_equal("avatars/original/stringio.txt", @dummy.avatar.s3_object.key)
|
152
|
+
end
|
153
|
+
|
154
|
+
should "use an S3 object based on the correct path for the custom style" do
|
155
|
+
assert_equal("avatars/thumb/stringio.txt", @dummy.avatar.s3_object(:thumb).key)
|
156
|
+
end
|
69
157
|
end
|
70
158
|
|
71
159
|
context "s3_host_name" do
|
72
160
|
setup do
|
73
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
74
161
|
rebuild_model :storage => :s3,
|
75
162
|
:s3_credentials => {},
|
76
163
|
:bucket => "bucket",
|
@@ -83,11 +170,14 @@ class S3Test < Test::Unit::TestCase
|
|
83
170
|
should "return a url based on an :s3_host_name path" do
|
84
171
|
assert_match %r{^http://s3-ap-northeast-1.amazonaws.com/bucket/avatars/stringio.txt}, @dummy.avatar.url
|
85
172
|
end
|
173
|
+
|
174
|
+
should "use the S3 bucket with the correct host name" do
|
175
|
+
assert_equal "s3-ap-northeast-1.amazonaws.com", @dummy.avatar.s3_bucket.config.s3_endpoint
|
176
|
+
end
|
86
177
|
end
|
87
178
|
|
88
179
|
context "An attachment that uses S3 for storage and has styles that return different file types" do
|
89
180
|
setup do
|
90
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
91
181
|
rebuild_model :styles => { :large => ['500x500#', :jpg] },
|
92
182
|
:storage => :s3,
|
93
183
|
:bucket => "bucket",
|
@@ -98,21 +188,28 @@ class S3Test < Test::Unit::TestCase
|
|
98
188
|
}
|
99
189
|
|
100
190
|
@dummy = Dummy.new
|
101
|
-
@dummy.avatar = File.new(
|
191
|
+
@dummy.avatar = File.new(fixture_file('5k.png'), 'rb')
|
102
192
|
end
|
103
193
|
|
104
194
|
should "return a url containing the correct original file mime type" do
|
105
195
|
assert_match /.+\/5k.png/, @dummy.avatar.url
|
106
196
|
end
|
107
197
|
|
198
|
+
should 'use the correct key for the original file mime type' do
|
199
|
+
assert_match /.+\/5k.png/, @dummy.avatar.s3_object.key
|
200
|
+
end
|
201
|
+
|
108
202
|
should "return a url containing the correct processed file mime type" do
|
109
203
|
assert_match /.+\/5k.jpg/, @dummy.avatar.url(:large)
|
110
204
|
end
|
205
|
+
|
206
|
+
should "use the correct key for the processed file mime type" do
|
207
|
+
assert_match /.+\/5k.jpg/, @dummy.avatar.s3_object(:large).key
|
208
|
+
end
|
111
209
|
end
|
112
210
|
|
113
211
|
context "An attachment that uses S3 for storage and has spaces in file name" do
|
114
212
|
setup do
|
115
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
116
213
|
rebuild_model :styles => { :large => ['500x500#', :jpg] },
|
117
214
|
:storage => :s3,
|
118
215
|
:bucket => "bucket",
|
@@ -122,7 +219,7 @@ class S3Test < Test::Unit::TestCase
|
|
122
219
|
}
|
123
220
|
|
124
221
|
@dummy = Dummy.new
|
125
|
-
@dummy.avatar = File.new(
|
222
|
+
@dummy.avatar = File.new(fixture_file('spaced file.png'), 'rb')
|
126
223
|
end
|
127
224
|
|
128
225
|
should "return an unescaped version for path" do
|
@@ -136,7 +233,6 @@ class S3Test < Test::Unit::TestCase
|
|
136
233
|
|
137
234
|
context "" do
|
138
235
|
setup do
|
139
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
140
236
|
rebuild_model :storage => :s3,
|
141
237
|
:s3_credentials => {},
|
142
238
|
:bucket => "bucket",
|
@@ -153,7 +249,6 @@ class S3Test < Test::Unit::TestCase
|
|
153
249
|
|
154
250
|
context "" do
|
155
251
|
setup do
|
156
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
157
252
|
rebuild_model :storage => :s3,
|
158
253
|
:s3_credentials => {
|
159
254
|
:production => { :bucket => "prod_bucket" },
|
@@ -173,7 +268,6 @@ class S3Test < Test::Unit::TestCase
|
|
173
268
|
|
174
269
|
context "generating a url with a proc as the host alias" do
|
175
270
|
setup do
|
176
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
177
271
|
rebuild_model :storage => :s3,
|
178
272
|
:s3_credentials => { :bucket => "prod_bucket" },
|
179
273
|
:s3_host_alias => Proc.new{|atch| "cdn#{atch.instance.counter % 4}.example.com"},
|
@@ -203,7 +297,6 @@ class S3Test < Test::Unit::TestCase
|
|
203
297
|
|
204
298
|
context "" do
|
205
299
|
setup do
|
206
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
207
300
|
rebuild_model :storage => :s3,
|
208
301
|
:s3_credentials => {},
|
209
302
|
:bucket => "bucket",
|
@@ -220,7 +313,6 @@ class S3Test < Test::Unit::TestCase
|
|
220
313
|
|
221
314
|
context "Generating a secure url with an expiration" do
|
222
315
|
setup do
|
223
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
224
316
|
rebuild_model :storage => :s3,
|
225
317
|
:s3_credentials => {
|
226
318
|
:production => { :bucket => "prod_bucket" },
|
@@ -236,7 +328,9 @@ class S3Test < Test::Unit::TestCase
|
|
236
328
|
@dummy = Dummy.new
|
237
329
|
@dummy.avatar = StringIO.new(".")
|
238
330
|
|
239
|
-
|
331
|
+
object = stub
|
332
|
+
@dummy.avatar.stubs(:s3_object).returns(object)
|
333
|
+
object.expects(:url_for).with(:read, :expires => 3600, :secure => true)
|
240
334
|
|
241
335
|
@dummy.avatar.expiring_url
|
242
336
|
end
|
@@ -246,9 +340,8 @@ class S3Test < Test::Unit::TestCase
|
|
246
340
|
end
|
247
341
|
end
|
248
342
|
|
249
|
-
context "Generating a url with an expiration" do
|
343
|
+
context "Generating a url with an expiration for each style" do
|
250
344
|
setup do
|
251
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
252
345
|
rebuild_model :storage => :s3,
|
253
346
|
:s3_credentials => {
|
254
347
|
:production => { :bucket => "prod_bucket" },
|
@@ -263,22 +356,25 @@ class S3Test < Test::Unit::TestCase
|
|
263
356
|
|
264
357
|
@dummy = Dummy.new
|
265
358
|
@dummy.avatar = StringIO.new(".")
|
359
|
+
end
|
266
360
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
361
|
+
should "should generate a url for the thumb" do
|
362
|
+
object = stub
|
363
|
+
@dummy.avatar.stubs(:s3_object).with(:thumb).returns(object)
|
364
|
+
object.expects(:url_for).with(:read, :expires => 1800, :secure => true)
|
271
365
|
@dummy.avatar.expiring_url(1800, :thumb)
|
272
366
|
end
|
273
367
|
|
274
|
-
should "should
|
275
|
-
|
368
|
+
should "should generate a url for the default style" do
|
369
|
+
object = stub
|
370
|
+
@dummy.avatar.stubs(:s3_object).with(:original).returns(object)
|
371
|
+
object.expects(:url_for).with(:read, :expires => 1800, :secure => true)
|
372
|
+
@dummy.avatar.expiring_url(1800)
|
276
373
|
end
|
277
374
|
end
|
278
375
|
|
279
376
|
context "Parsing S3 credentials with a bucket in them" do
|
280
377
|
setup do
|
281
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
282
378
|
rebuild_model :storage => :s3,
|
283
379
|
:s3_credentials => {
|
284
380
|
:production => { :bucket => "prod_bucket" },
|
@@ -290,18 +386,20 @@ class S3Test < Test::Unit::TestCase
|
|
290
386
|
should "get the right bucket in production" do
|
291
387
|
rails_env("production")
|
292
388
|
assert_equal "prod_bucket", @dummy.avatar.bucket_name
|
389
|
+
assert_equal "prod_bucket", @dummy.avatar.s3_bucket.name
|
293
390
|
end
|
294
391
|
|
295
392
|
should "get the right bucket in development" do
|
296
393
|
rails_env("development")
|
297
394
|
assert_equal "dev_bucket", @dummy.avatar.bucket_name
|
395
|
+
assert_equal "dev_bucket", @dummy.avatar.s3_bucket.name
|
298
396
|
end
|
299
397
|
end
|
300
398
|
|
301
399
|
context "Parsing S3 credentials with a s3_host_name in them" do
|
302
400
|
setup do
|
303
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
304
401
|
rebuild_model :storage => :s3,
|
402
|
+
:bucket => 'testing',
|
305
403
|
:s3_credentials => {
|
306
404
|
:production => { :s3_host_name => "s3-world-end.amazonaws.com" },
|
307
405
|
:development => { :s3_host_name => "s3-ap-northeast-1.amazonaws.com" }
|
@@ -312,16 +410,19 @@ class S3Test < Test::Unit::TestCase
|
|
312
410
|
should "get the right s3_host_name in production" do
|
313
411
|
rails_env("production")
|
314
412
|
assert_match %r{^s3-world-end.amazonaws.com}, @dummy.avatar.s3_host_name
|
413
|
+
assert_match %r{^s3-world-end.amazonaws.com}, @dummy.avatar.s3_bucket.config.s3_endpoint
|
315
414
|
end
|
316
415
|
|
317
416
|
should "get the right s3_host_name in development" do
|
318
417
|
rails_env("development")
|
319
418
|
assert_match %r{^s3-ap-northeast-1.amazonaws.com}, @dummy.avatar.s3_host_name
|
419
|
+
assert_match %r{^s3-ap-northeast-1.amazonaws.com}, @dummy.avatar.s3_bucket.config.s3_endpoint
|
320
420
|
end
|
321
421
|
|
322
422
|
should "get the right s3_host_name if the key does not exist" do
|
323
423
|
rails_env("test")
|
324
424
|
assert_match %r{^s3.amazonaws.com}, @dummy.avatar.s3_host_name
|
425
|
+
assert_match %r{^s3.amazonaws.com}, @dummy.avatar.s3_bucket.config.s3_endpoint
|
325
426
|
end
|
326
427
|
end
|
327
428
|
|
@@ -346,7 +447,7 @@ class S3Test < Test::Unit::TestCase
|
|
346
447
|
|
347
448
|
context "when assigned" do
|
348
449
|
setup do
|
349
|
-
@file = File.new(
|
450
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
350
451
|
@dummy = Dummy.new
|
351
452
|
@dummy.avatar = @file
|
352
453
|
end
|
@@ -361,7 +462,11 @@ class S3Test < Test::Unit::TestCase
|
|
361
462
|
|
362
463
|
context "and saved" do
|
363
464
|
setup do
|
364
|
-
|
465
|
+
object = stub
|
466
|
+
@dummy.avatar.stubs(:s3_object).returns(object)
|
467
|
+
object.expects(:write).with(anything,
|
468
|
+
:content_type => "image/png",
|
469
|
+
:acl => :public_read)
|
365
470
|
@dummy.save
|
366
471
|
end
|
367
472
|
|
@@ -371,7 +476,6 @@ class S3Test < Test::Unit::TestCase
|
|
371
476
|
end
|
372
477
|
|
373
478
|
should "delete tempfiles" do
|
374
|
-
AWS::S3::S3Object.stubs(:store).with(@dummy.avatar.path, anything, 'testing', :content_type => 'image/png', :access => :public_read)
|
375
479
|
File.stubs(:exist?).returns(true)
|
376
480
|
Paperclip::Tempfile.any_instance.expects(:close).at_least_once()
|
377
481
|
Paperclip::Tempfile.any_instance.expects(:unlink).at_least_once()
|
@@ -381,11 +485,12 @@ class S3Test < Test::Unit::TestCase
|
|
381
485
|
|
382
486
|
context "and saved without a bucket" do
|
383
487
|
setup do
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
488
|
+
AWS::S3::BucketCollection.any_instance.expects(:create).with("testing")
|
489
|
+
AWS::S3::S3Object.any_instance.stubs(:write).
|
490
|
+
raises(AWS::S3::Errors::NoSuchBucket.new(stub,
|
491
|
+
stub(:status => 404,
|
492
|
+
:body => "<foo/>"))).
|
493
|
+
then.returns(nil)
|
389
494
|
@dummy.save
|
390
495
|
end
|
391
496
|
|
@@ -396,8 +501,8 @@ class S3Test < Test::Unit::TestCase
|
|
396
501
|
|
397
502
|
context "and remove" do
|
398
503
|
setup do
|
399
|
-
AWS::S3::S3Object.stubs(:exists?).returns(true)
|
400
|
-
AWS::S3::S3Object.stubs(:delete)
|
504
|
+
AWS::S3::S3Object.any_instance.stubs(:exists?).returns(true)
|
505
|
+
AWS::S3::S3Object.any_instance.stubs(:delete)
|
401
506
|
@dummy.destroy_attached_files
|
402
507
|
end
|
403
508
|
|
@@ -410,7 +515,6 @@ class S3Test < Test::Unit::TestCase
|
|
410
515
|
|
411
516
|
context "An attachment with S3 storage and bucket defined as a Proc" do
|
412
517
|
setup do
|
413
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
414
518
|
rebuild_model :storage => :s3,
|
415
519
|
:bucket => lambda { |attachment| "bucket_#{attachment.instance.other}" },
|
416
520
|
:s3_credentials => {:not => :important}
|
@@ -418,13 +522,14 @@ class S3Test < Test::Unit::TestCase
|
|
418
522
|
|
419
523
|
should "get the right bucket name" do
|
420
524
|
assert "bucket_a", Dummy.new(:other => 'a').avatar.bucket_name
|
525
|
+
assert "bucket_a", Dummy.new(:other => 'a').avatar.s3_bucket.name
|
421
526
|
assert "bucket_b", Dummy.new(:other => 'b').avatar.bucket_name
|
527
|
+
assert "bucket_b", Dummy.new(:other => 'b').avatar.s3_bucket.name
|
422
528
|
end
|
423
529
|
end
|
424
530
|
|
425
531
|
context "An attachment with S3 storage and specific s3 headers set" do
|
426
532
|
setup do
|
427
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
428
533
|
rebuild_model :storage => :s3,
|
429
534
|
:bucket => "testing",
|
430
535
|
:path => ":attachment/:style/:basename.:extension",
|
@@ -435,6 +540,45 @@ class S3Test < Test::Unit::TestCase
|
|
435
540
|
:s3_headers => {'Cache-Control' => 'max-age=31557600'}
|
436
541
|
end
|
437
542
|
|
543
|
+
context "when assigned" do
|
544
|
+
setup do
|
545
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
546
|
+
@dummy = Dummy.new
|
547
|
+
@dummy.avatar = @file
|
548
|
+
end
|
549
|
+
|
550
|
+
teardown { @file.close }
|
551
|
+
|
552
|
+
context "and saved" do
|
553
|
+
setup do
|
554
|
+
object = stub
|
555
|
+
@dummy.avatar.stubs(:s3_object).returns(object)
|
556
|
+
object.expects(:write).with(anything,
|
557
|
+
:content_type => "image/png",
|
558
|
+
:acl => :public_read,
|
559
|
+
:cache_control => 'max-age=31557600')
|
560
|
+
@dummy.save
|
561
|
+
end
|
562
|
+
|
563
|
+
should "succeed" do
|
564
|
+
assert true
|
565
|
+
end
|
566
|
+
end
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
570
|
+
context "An attachment with S3 storage and metadata set using header names" do
|
571
|
+
setup do
|
572
|
+
rebuild_model :storage => :s3,
|
573
|
+
:bucket => "testing",
|
574
|
+
:path => ":attachment/:style/:basename.:extension",
|
575
|
+
:s3_credentials => {
|
576
|
+
'access_key_id' => "12345",
|
577
|
+
'secret_access_key' => "54321"
|
578
|
+
},
|
579
|
+
:s3_headers => {'x-amz-meta-color' => 'red'}
|
580
|
+
end
|
581
|
+
|
438
582
|
context "when assigned" do
|
439
583
|
setup do
|
440
584
|
@file = File.new(File.join(File.dirname(__FILE__), '..', 'fixtures', '5k.png'), 'rb')
|
@@ -446,13 +590,129 @@ class S3Test < Test::Unit::TestCase
|
|
446
590
|
|
447
591
|
context "and saved" do
|
448
592
|
setup do
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
593
|
+
object = stub
|
594
|
+
@dummy.avatar.stubs(:s3_object).returns(object)
|
595
|
+
object.expects(:write).with(anything,
|
596
|
+
:content_type => "image/png",
|
597
|
+
:acl => :public_read,
|
598
|
+
:metadata => { "color" => "red" })
|
599
|
+
@dummy.save
|
600
|
+
end
|
601
|
+
|
602
|
+
should "succeed" do
|
603
|
+
assert true
|
604
|
+
end
|
605
|
+
end
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
609
|
+
context "An attachment with S3 storage and metadata set using the :s3_metadata option" do
|
610
|
+
setup do
|
611
|
+
rebuild_model :storage => :s3,
|
612
|
+
:bucket => "testing",
|
613
|
+
:path => ":attachment/:style/:basename.:extension",
|
614
|
+
:s3_credentials => {
|
615
|
+
'access_key_id' => "12345",
|
616
|
+
'secret_access_key' => "54321"
|
617
|
+
},
|
618
|
+
:s3_metadata => { "color" => "red" }
|
619
|
+
end
|
620
|
+
|
621
|
+
context "when assigned" do
|
622
|
+
setup do
|
623
|
+
@file = File.new(File.join(File.dirname(__FILE__), '..', 'fixtures', '5k.png'), 'rb')
|
624
|
+
@dummy = Dummy.new
|
625
|
+
@dummy.avatar = @file
|
626
|
+
end
|
627
|
+
|
628
|
+
teardown { @file.close }
|
629
|
+
|
630
|
+
context "and saved" do
|
631
|
+
setup do
|
632
|
+
object = stub
|
633
|
+
@dummy.avatar.stubs(:s3_object).returns(object)
|
634
|
+
object.expects(:write).with(anything,
|
635
|
+
:content_type => "image/png",
|
636
|
+
:acl => :public_read,
|
637
|
+
:metadata => { "color" => "red" })
|
638
|
+
@dummy.save
|
639
|
+
end
|
640
|
+
|
641
|
+
should "succeed" do
|
642
|
+
assert true
|
643
|
+
end
|
644
|
+
end
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
648
|
+
context "An attachment with S3 storage and storage class set using the header name" do
|
649
|
+
setup do
|
650
|
+
rebuild_model :storage => :s3,
|
651
|
+
:bucket => "testing",
|
652
|
+
:path => ":attachment/:style/:basename.:extension",
|
653
|
+
:s3_credentials => {
|
654
|
+
'access_key_id' => "12345",
|
655
|
+
'secret_access_key' => "54321"
|
656
|
+
},
|
657
|
+
:s3_headers => { "x-amz-storage-class" => "reduced_redundancy" }
|
658
|
+
end
|
659
|
+
|
660
|
+
context "when assigned" do
|
661
|
+
setup do
|
662
|
+
@file = File.new(File.join(File.dirname(__FILE__), '..', 'fixtures', '5k.png'), 'rb')
|
663
|
+
@dummy = Dummy.new
|
664
|
+
@dummy.avatar = @file
|
665
|
+
end
|
666
|
+
|
667
|
+
teardown { @file.close }
|
668
|
+
|
669
|
+
context "and saved" do
|
670
|
+
setup do
|
671
|
+
object = stub
|
672
|
+
@dummy.avatar.stubs(:s3_object).returns(object)
|
673
|
+
object.expects(:write).with(anything,
|
674
|
+
:content_type => "image/png",
|
675
|
+
:acl => :public_read,
|
676
|
+
:storage_class => "reduced_redundancy")
|
677
|
+
@dummy.save
|
678
|
+
end
|
679
|
+
|
680
|
+
should "succeed" do
|
681
|
+
assert true
|
682
|
+
end
|
683
|
+
end
|
684
|
+
end
|
685
|
+
end
|
686
|
+
|
687
|
+
context "An attachment with S3 storage and storage class set using the :storage_class option" do
|
688
|
+
setup do
|
689
|
+
rebuild_model :storage => :s3,
|
690
|
+
:bucket => "testing",
|
691
|
+
:path => ":attachment/:style/:basename.:extension",
|
692
|
+
:s3_credentials => {
|
693
|
+
'access_key_id' => "12345",
|
694
|
+
'secret_access_key' => "54321"
|
695
|
+
},
|
696
|
+
:s3_storage_class => :reduced_redundancy
|
697
|
+
end
|
698
|
+
|
699
|
+
context "when assigned" do
|
700
|
+
setup do
|
701
|
+
@file = File.new(File.join(File.dirname(__FILE__), '..', 'fixtures', '5k.png'), 'rb')
|
702
|
+
@dummy = Dummy.new
|
703
|
+
@dummy.avatar = @file
|
704
|
+
end
|
705
|
+
|
706
|
+
teardown { @file.close }
|
707
|
+
|
708
|
+
context "and saved" do
|
709
|
+
setup do
|
710
|
+
object = stub
|
711
|
+
@dummy.avatar.stubs(:s3_object).returns(object)
|
712
|
+
object.expects(:write).with(anything,
|
713
|
+
:content_type => "image/png",
|
714
|
+
:acl => :public_read,
|
715
|
+
:storage_class => :reduced_redundancy)
|
456
716
|
@dummy.save
|
457
717
|
end
|
458
718
|
|
@@ -464,25 +724,25 @@ class S3Test < Test::Unit::TestCase
|
|
464
724
|
end
|
465
725
|
|
466
726
|
context "with S3 credentials supplied as Pathname" do
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
727
|
+
setup do
|
728
|
+
ENV['S3_KEY'] = 'pathname_key'
|
729
|
+
ENV['S3_BUCKET'] = 'pathname_bucket'
|
730
|
+
ENV['S3_SECRET'] = 'pathname_secret'
|
471
731
|
|
472
|
-
|
732
|
+
rails_env('test')
|
473
733
|
|
474
|
-
|
475
|
-
|
734
|
+
rebuild_model :storage => :s3,
|
735
|
+
:s3_credentials => Pathname.new(fixture_file('s3.yml'))
|
476
736
|
|
477
|
-
|
478
|
-
|
479
|
-
|
737
|
+
Dummy.delete_all
|
738
|
+
@dummy = Dummy.new
|
739
|
+
end
|
480
740
|
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
741
|
+
should "parse the credentials" do
|
742
|
+
assert_equal 'pathname_bucket', @dummy.avatar.bucket_name
|
743
|
+
assert_equal 'pathname_key', @dummy.avatar.s3_bucket.config.access_key_id
|
744
|
+
assert_equal 'pathname_secret', @dummy.avatar.s3_bucket.config.secret_access_key
|
745
|
+
end
|
486
746
|
end
|
487
747
|
|
488
748
|
context "with S3 credentials in a YAML file" do
|
@@ -494,7 +754,7 @@ class S3Test < Test::Unit::TestCase
|
|
494
754
|
rails_env('test')
|
495
755
|
|
496
756
|
rebuild_model :storage => :s3,
|
497
|
-
:s3_credentials => File.new(
|
757
|
+
:s3_credentials => File.new(fixture_file('s3.yml'))
|
498
758
|
|
499
759
|
Dummy.delete_all
|
500
760
|
|
@@ -503,8 +763,8 @@ class S3Test < Test::Unit::TestCase
|
|
503
763
|
|
504
764
|
should "run the file through ERB" do
|
505
765
|
assert_equal 'env_bucket', @dummy.avatar.bucket_name
|
506
|
-
assert_equal 'env_key',
|
507
|
-
assert_equal 'env_secret',
|
766
|
+
assert_equal 'env_key', @dummy.avatar.s3_bucket.config.access_key_id
|
767
|
+
assert_equal 'env_secret', @dummy.avatar.s3_bucket.config.secret_access_key
|
508
768
|
end
|
509
769
|
end
|
510
770
|
|
@@ -522,7 +782,7 @@ class S3Test < Test::Unit::TestCase
|
|
522
782
|
|
523
783
|
context "when assigned" do
|
524
784
|
setup do
|
525
|
-
@file = File.new(
|
785
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
526
786
|
@dummy = Dummy.new
|
527
787
|
@dummy.avatar = @file
|
528
788
|
end
|
@@ -531,12 +791,11 @@ class S3Test < Test::Unit::TestCase
|
|
531
791
|
|
532
792
|
context "and saved" do
|
533
793
|
setup do
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
:access => :public_read)
|
794
|
+
object = stub
|
795
|
+
@dummy.avatar.stubs(:s3_object).returns(object)
|
796
|
+
object.expects(:write).with(anything,
|
797
|
+
:content_type => "image/png",
|
798
|
+
:acl => :public_read)
|
540
799
|
@dummy.save
|
541
800
|
end
|
542
801
|
|
@@ -561,7 +820,7 @@ class S3Test < Test::Unit::TestCase
|
|
561
820
|
|
562
821
|
context "when assigned" do
|
563
822
|
setup do
|
564
|
-
@file = File.new(
|
823
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
565
824
|
@dummy = Dummy.new
|
566
825
|
@dummy.avatar = @file
|
567
826
|
end
|
@@ -570,12 +829,11 @@ class S3Test < Test::Unit::TestCase
|
|
570
829
|
|
571
830
|
context "and saved" do
|
572
831
|
setup do
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
:access => :private)
|
832
|
+
object = stub
|
833
|
+
@dummy.avatar.stubs(:s3_object).returns(object)
|
834
|
+
object.expects(:write).with(anything,
|
835
|
+
:content_type => "image/png",
|
836
|
+
:acl => :private)
|
579
837
|
@dummy.save
|
580
838
|
end
|
581
839
|
|
@@ -606,7 +864,7 @@ class S3Test < Test::Unit::TestCase
|
|
606
864
|
|
607
865
|
context "when assigned" do
|
608
866
|
setup do
|
609
|
-
@file = File.new(
|
867
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
610
868
|
@dummy = Dummy.new
|
611
869
|
@dummy.avatar = @file
|
612
870
|
end
|
@@ -615,13 +873,12 @@ class S3Test < Test::Unit::TestCase
|
|
615
873
|
|
616
874
|
context "and saved" do
|
617
875
|
setup do
|
618
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
619
876
|
[:thumb, :original].each do |style|
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
877
|
+
object = stub
|
878
|
+
@dummy.avatar.stubs(:s3_object).with(style).returns(object)
|
879
|
+
object.expects(:write).with(anything,
|
880
|
+
:content_type => "image/png",
|
881
|
+
:acl => style == :thumb ? :public_read : :private)
|
625
882
|
end
|
626
883
|
@dummy.save
|
627
884
|
end
|
@@ -654,7 +911,7 @@ class S3Test < Test::Unit::TestCase
|
|
654
911
|
|
655
912
|
context "when assigned" do
|
656
913
|
setup do
|
657
|
-
@file = File.new(
|
914
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
658
915
|
@dummy = Dummy.new
|
659
916
|
@dummy.stubs(:private_attachment? => true)
|
660
917
|
@dummy.avatar = @file
|
@@ -664,15 +921,12 @@ class S3Test < Test::Unit::TestCase
|
|
664
921
|
|
665
922
|
context "and saved" do
|
666
923
|
setup do
|
667
|
-
AWS::S3::Base.stubs(:establish_connection!)
|
668
924
|
[:thumb, :original].each do |style|
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
:access => style == :thumb ? :public_read : :private
|
675
|
-
)
|
925
|
+
object = stub
|
926
|
+
@dummy.avatar.stubs(:s3_object).with(style).returns(object)
|
927
|
+
object.expects(:write).with(anything,
|
928
|
+
:content_type => "image/png",
|
929
|
+
:acl => style == :thumb ? :public_read : :private)
|
676
930
|
end
|
677
931
|
@dummy.save
|
678
932
|
end
|
@@ -686,4 +940,53 @@ class S3Test < Test::Unit::TestCase
|
|
686
940
|
|
687
941
|
end
|
688
942
|
end
|
943
|
+
|
944
|
+
context "An attachment with S3 storage and metadata set using a proc as headers" do
|
945
|
+
setup do
|
946
|
+
rebuild_model(
|
947
|
+
:storage => :s3,
|
948
|
+
:bucket => "testing",
|
949
|
+
:path => ":attachment/:style/:basename.:extension",
|
950
|
+
:styles => {
|
951
|
+
:thumb => "80x80>"
|
952
|
+
},
|
953
|
+
:s3_credentials => {
|
954
|
+
'access_key_id' => "12345",
|
955
|
+
'secret_access_key' => "54321"
|
956
|
+
},
|
957
|
+
:s3_headers => lambda {|attachment|
|
958
|
+
{'Content-Disposition' => "attachment; filename=\"#{attachment.name}\""}
|
959
|
+
}
|
960
|
+
)
|
961
|
+
end
|
962
|
+
|
963
|
+
context "when assigned" do
|
964
|
+
setup do
|
965
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
966
|
+
@dummy = Dummy.new
|
967
|
+
@dummy.stubs(:name => 'Custom Avatar Name.png')
|
968
|
+
@dummy.avatar = @file
|
969
|
+
end
|
970
|
+
|
971
|
+
teardown { @file.close }
|
972
|
+
|
973
|
+
context "and saved" do
|
974
|
+
setup do
|
975
|
+
[:thumb, :original].each do |style|
|
976
|
+
object = stub
|
977
|
+
@dummy.avatar.stubs(:s3_object).with(style).returns(object)
|
978
|
+
object.expects(:write).with(anything,
|
979
|
+
:content_type => "image/png",
|
980
|
+
:acl => :public_read,
|
981
|
+
:content_disposition => 'attachment; filename="Custom Avatar Name.png"')
|
982
|
+
end
|
983
|
+
@dummy.save
|
984
|
+
end
|
985
|
+
|
986
|
+
should "succeed" do
|
987
|
+
assert true
|
988
|
+
end
|
989
|
+
end
|
990
|
+
end
|
991
|
+
end
|
689
992
|
end
|