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
Binary file
|
data/test/helper.rb
CHANGED
@@ -10,7 +10,8 @@ require 'active_record'
|
|
10
10
|
require 'active_record/version'
|
11
11
|
require 'active_support'
|
12
12
|
require 'mime/types'
|
13
|
-
require '
|
13
|
+
require 'pathname'
|
14
|
+
|
14
15
|
require 'pathname'
|
15
16
|
|
16
17
|
puts "Testing against version #{ActiveRecord::VERSION::STRING}"
|
@@ -53,6 +54,10 @@ ActiveRecord::Base.logger = ActiveSupport::BufferedLogger.new(File.dirname(__FIL
|
|
53
54
|
ActiveRecord::Base.establish_connection(config['test'])
|
54
55
|
Paperclip.options[:logger] = ActiveRecord::Base.logger
|
55
56
|
|
57
|
+
Dir[File.join(File.dirname(__FILE__), 'support','*')].each do |f|
|
58
|
+
require f
|
59
|
+
end
|
60
|
+
|
56
61
|
def reset_class class_name
|
57
62
|
ActiveRecord::Base.send(:include, Paperclip::Glue)
|
58
63
|
Object.send(:remove_const, class_name) rescue nil
|
@@ -152,3 +157,21 @@ def with_exitstatus_returning(code)
|
|
152
157
|
`ruby -e 'exit #{saved_exitstatus.to_i}'`
|
153
158
|
end
|
154
159
|
end
|
160
|
+
|
161
|
+
def fixture_file(filename)
|
162
|
+
File.join(File.dirname(__FILE__), 'fixtures', filename)
|
163
|
+
end
|
164
|
+
|
165
|
+
def assert_success_response(url)
|
166
|
+
Net::HTTP.get_response(URI.parse(url)) do |response|
|
167
|
+
assert_equal "200", response.code,
|
168
|
+
"Expected HTTP response code 200, got #{response.code}"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def assert_not_found_response(url)
|
173
|
+
Net::HTTP.get_response(URI.parse(url)) do |response|
|
174
|
+
assert_equal "404", response.code,
|
175
|
+
"Expected HTTP response code 404, got #{response.code}"
|
176
|
+
end
|
177
|
+
end
|
data/test/interpolations_test.rb
CHANGED
@@ -88,6 +88,13 @@ class InterpolationsTest < Test::Unit::TestCase
|
|
88
88
|
assert_equal 23, Paperclip::Interpolations.id(attachment, :style)
|
89
89
|
end
|
90
90
|
|
91
|
+
should "return nil for attachments to new records" do
|
92
|
+
attachment = mock
|
93
|
+
attachment.expects(:id).returns(nil)
|
94
|
+
attachment.expects(:instance).returns(attachment)
|
95
|
+
assert_nil Paperclip::Interpolations.id(attachment, :style)
|
96
|
+
end
|
97
|
+
|
91
98
|
should "return the partitioned id of the attachment when the id is an integer" do
|
92
99
|
attachment = mock
|
93
100
|
attachment.expects(:id).returns(23)
|
@@ -102,6 +109,13 @@ class InterpolationsTest < Test::Unit::TestCase
|
|
102
109
|
assert_equal "32f/nj2/3oi", Paperclip::Interpolations.id_partition(attachment, :style)
|
103
110
|
end
|
104
111
|
|
112
|
+
should "return nil for the partitioned id of an attachment to a new record (when the id is nil)" do
|
113
|
+
attachment = mock
|
114
|
+
attachment.expects(:id).returns(nil)
|
115
|
+
attachment.expects(:instance).returns(attachment)
|
116
|
+
assert_nil Paperclip::Interpolations.id_partition(attachment, :style)
|
117
|
+
end
|
118
|
+
|
105
119
|
should "return the name of the attachment" do
|
106
120
|
attachment = mock
|
107
121
|
attachment.expects(:name).returns("file")
|
@@ -181,14 +195,14 @@ class InterpolationsTest < Test::Unit::TestCase
|
|
181
195
|
should "return attachment's hash when passing both arguments" do
|
182
196
|
attachment = mock
|
183
197
|
fake_hash = "a_wicked_secure_hash"
|
184
|
-
attachment.expects(:
|
198
|
+
attachment.expects(:hash_key).returns(fake_hash)
|
185
199
|
assert_equal fake_hash, Paperclip::Interpolations.hash(attachment, :style)
|
186
200
|
end
|
187
201
|
|
188
202
|
should "return Object#hash when passing no argument" do
|
189
203
|
attachment = mock
|
190
204
|
fake_hash = "a_wicked_secure_hash"
|
191
|
-
attachment.expects(:
|
205
|
+
attachment.expects(:hash_key).never.returns(fake_hash)
|
192
206
|
assert_not_equal fake_hash, Paperclip::Interpolations.hash
|
193
207
|
end
|
194
208
|
|
@@ -68,6 +68,22 @@ class PaperclipMissingAttachmentStylesTest < Test::Unit::TestCase
|
|
68
68
|
Paperclip.save_current_attachments_styles!
|
69
69
|
assert_equal Hash.new, Paperclip.missing_attachments_styles
|
70
70
|
end
|
71
|
+
|
72
|
+
should "be able to calculate differences when a new attachment is added to a model" do
|
73
|
+
rebuild_model :styles => {:croppable => '600x600>', :big => '1000x1000>'}
|
74
|
+
Paperclip.save_current_attachments_styles!
|
75
|
+
|
76
|
+
class ::Dummy
|
77
|
+
has_attached_file :photo, :styles => {:small => 'x100', :large => '1000x1000>'}
|
78
|
+
end
|
79
|
+
|
80
|
+
expected_hash = {
|
81
|
+
:Dummy => {:photo => [:large, :small]}
|
82
|
+
}
|
83
|
+
assert_equal expected_hash, Paperclip.missing_attachments_styles
|
84
|
+
Paperclip.save_current_attachments_styles!
|
85
|
+
assert_equal Hash.new, Paperclip.missing_attachments_styles
|
86
|
+
end
|
71
87
|
|
72
88
|
# It's impossible to build styles hash without loading from database whole bunch of records
|
73
89
|
should "skip lambda-styles" do
|
data/test/paperclip_test.rb
CHANGED
@@ -86,6 +86,16 @@ class PaperclipTest < Test::Unit::TestCase
|
|
86
86
|
has_attached_file :blah
|
87
87
|
end
|
88
88
|
end
|
89
|
+
|
90
|
+
should "not generate warning if attachment is redifined with the same url string but has :class in it" do
|
91
|
+
Paperclip.expects(:log).never
|
92
|
+
Dummy.class_eval do
|
93
|
+
has_attached_file :blah, :url => "/system/:class/:attachment/:id/:style/:filename"
|
94
|
+
end
|
95
|
+
Dummy2.class_eval do
|
96
|
+
has_attached_file :blah, :url => "/system/:class/:attachment/:id/:style/:filename"
|
97
|
+
end
|
98
|
+
end
|
89
99
|
end
|
90
100
|
|
91
101
|
context "An ActiveRecord model with an 'avatar' attachment" do
|
@@ -170,38 +180,78 @@ class PaperclipTest < Test::Unit::TestCase
|
|
170
180
|
end
|
171
181
|
|
172
182
|
context "a validation with an if guard clause" do
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
183
|
+
context "as a lambda" do
|
184
|
+
setup do
|
185
|
+
Dummy.send(:"validates_attachment_presence", :avatar, :if => lambda{|i| i.foo })
|
186
|
+
@dummy = Dummy.new
|
187
|
+
@dummy.stubs(:avatar_file_name).returns(nil)
|
188
|
+
end
|
178
189
|
|
179
|
-
|
180
|
-
|
181
|
-
|
190
|
+
should "attempt validation if the guard returns true" do
|
191
|
+
@dummy.expects(:foo).returns(true)
|
192
|
+
assert ! @dummy.valid?
|
193
|
+
end
|
194
|
+
|
195
|
+
should "not attempt validation if the guard returns false" do
|
196
|
+
@dummy.expects(:foo).returns(false)
|
197
|
+
assert @dummy.valid?
|
198
|
+
end
|
182
199
|
end
|
183
200
|
|
184
|
-
|
185
|
-
|
186
|
-
|
201
|
+
context "as a method name" do
|
202
|
+
setup do
|
203
|
+
Dummy.send(:"validates_attachment_presence", :avatar, :if => :foo)
|
204
|
+
@dummy = Dummy.new
|
205
|
+
@dummy.stubs(:avatar_file_name).returns(nil)
|
206
|
+
end
|
207
|
+
|
208
|
+
should "attempt validation if the guard returns true" do
|
209
|
+
@dummy.expects(:foo).returns(true)
|
210
|
+
assert ! @dummy.valid?
|
211
|
+
end
|
212
|
+
|
213
|
+
should "not attempt validation if the guard returns false" do
|
214
|
+
@dummy.expects(:foo).returns(false)
|
215
|
+
assert @dummy.valid?
|
216
|
+
end
|
187
217
|
end
|
188
218
|
end
|
189
219
|
|
190
220
|
context "a validation with an unless guard clause" do
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
221
|
+
context "as a lambda" do
|
222
|
+
setup do
|
223
|
+
Dummy.send(:"validates_attachment_presence", :avatar, :unless => lambda{|i| i.foo })
|
224
|
+
@dummy = Dummy.new
|
225
|
+
@dummy.stubs(:avatar_file_name).returns(nil)
|
226
|
+
end
|
227
|
+
|
228
|
+
should "attempt validation if the guard returns true" do
|
229
|
+
@dummy.expects(:foo).returns(false)
|
230
|
+
assert ! @dummy.valid?
|
231
|
+
end
|
196
232
|
|
197
|
-
|
198
|
-
|
199
|
-
|
233
|
+
should "not attempt validation if the guard returns false" do
|
234
|
+
@dummy.expects(:foo).returns(true)
|
235
|
+
assert @dummy.valid?
|
236
|
+
end
|
200
237
|
end
|
201
238
|
|
202
|
-
|
203
|
-
|
204
|
-
|
239
|
+
context "as a method name" do
|
240
|
+
setup do
|
241
|
+
Dummy.send(:"validates_attachment_presence", :avatar, :unless => :foo)
|
242
|
+
@dummy = Dummy.new
|
243
|
+
@dummy.stubs(:avatar_file_name).returns(nil)
|
244
|
+
end
|
245
|
+
|
246
|
+
should "attempt validation if the guard returns true" do
|
247
|
+
@dummy.expects(:foo).returns(false)
|
248
|
+
assert ! @dummy.valid?
|
249
|
+
end
|
250
|
+
|
251
|
+
should "not attempt validation if the guard returns false" do
|
252
|
+
@dummy.expects(:foo).returns(true)
|
253
|
+
assert @dummy.valid?
|
254
|
+
end
|
205
255
|
end
|
206
256
|
end
|
207
257
|
|
data/test/schema_test.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require './test/helper'
|
2
|
+
require 'paperclip/schema'
|
3
|
+
|
4
|
+
class MockSchema
|
5
|
+
include Paperclip::Schema
|
6
|
+
|
7
|
+
def initialize(table_name = nil)
|
8
|
+
@table_name = table_name
|
9
|
+
@columns = {}
|
10
|
+
@deleted_columns = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def column(name, type)
|
14
|
+
@columns[name] = type
|
15
|
+
end
|
16
|
+
|
17
|
+
def remove_column(table_name, column_name)
|
18
|
+
return if @table_name && @table_name != table_name
|
19
|
+
@columns.delete(column_name)
|
20
|
+
@deleted_columns.push(column_name)
|
21
|
+
end
|
22
|
+
|
23
|
+
def has_column?(column_name)
|
24
|
+
@columns.key?(column_name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def deleted_column?(column_name)
|
28
|
+
@deleted_columns.include?(column_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def type_of(column_name)
|
32
|
+
@columns[column_name]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class SchemaTest < Test::Unit::TestCase
|
37
|
+
context "Migrating up" do
|
38
|
+
setup do
|
39
|
+
@schema = MockSchema.new
|
40
|
+
@schema.has_attached_file :avatar
|
41
|
+
end
|
42
|
+
|
43
|
+
should "create the file_name column" do
|
44
|
+
assert @schema.has_column?(:avatar_file_name)
|
45
|
+
end
|
46
|
+
|
47
|
+
should "create the content_type column" do
|
48
|
+
assert @schema.has_column?(:avatar_content_type)
|
49
|
+
end
|
50
|
+
|
51
|
+
should "create the file_size column" do
|
52
|
+
assert @schema.has_column?(:avatar_file_size)
|
53
|
+
end
|
54
|
+
|
55
|
+
should "create the updated_at column" do
|
56
|
+
assert @schema.has_column?(:avatar_updated_at)
|
57
|
+
end
|
58
|
+
|
59
|
+
should "make the file_name column a string" do
|
60
|
+
assert_equal :string, @schema.type_of(:avatar_file_name)
|
61
|
+
end
|
62
|
+
|
63
|
+
should "make the content_type column a string" do
|
64
|
+
assert_equal :string, @schema.type_of(:avatar_content_type)
|
65
|
+
end
|
66
|
+
|
67
|
+
should "make the file_size column an integer" do
|
68
|
+
assert_equal :integer, @schema.type_of(:avatar_file_size)
|
69
|
+
end
|
70
|
+
|
71
|
+
should "make the updated_at column a datetime" do
|
72
|
+
assert_equal :datetime, @schema.type_of(:avatar_updated_at)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "Migrating down" do
|
77
|
+
setup do
|
78
|
+
@schema = MockSchema.new(:users)
|
79
|
+
@schema.drop_attached_file :users, :avatar
|
80
|
+
end
|
81
|
+
|
82
|
+
should "remove the file_name column" do
|
83
|
+
assert @schema.deleted_column?(:avatar_file_name)
|
84
|
+
end
|
85
|
+
|
86
|
+
should "remove the content_type column" do
|
87
|
+
assert @schema.deleted_column?(:avatar_content_type)
|
88
|
+
end
|
89
|
+
|
90
|
+
should "remove the file_size column" do
|
91
|
+
assert @schema.deleted_column?(:avatar_file_size)
|
92
|
+
end
|
93
|
+
|
94
|
+
should "remove the updated_at column" do
|
95
|
+
assert @schema.deleted_column?(:avatar_updated_at)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -6,7 +6,7 @@ class FileSystemTest < Test::Unit::TestCase
|
|
6
6
|
rebuild_model :styles => { :thumbnail => "25x25#" }
|
7
7
|
@dummy = Dummy.create!
|
8
8
|
|
9
|
-
@dummy.avatar = File.open(
|
9
|
+
@dummy.avatar = File.open(fixture_file('5k.png'))
|
10
10
|
end
|
11
11
|
|
12
12
|
should "allow file assignment" do
|
@@ -36,7 +36,7 @@ class FileSystemTest < Test::Unit::TestCase
|
|
36
36
|
rebuild_model :styles => { :thumbnail => "25x25#" }
|
37
37
|
@dummy = Dummy.create!
|
38
38
|
|
39
|
-
@dummy.avatar = File.open(
|
39
|
+
@dummy.avatar = File.open(fixture_file('spaced file.png'))
|
40
40
|
@dummy.save
|
41
41
|
end
|
42
42
|
|
@@ -12,9 +12,9 @@ class FogTest < Test::Unit::TestCase
|
|
12
12
|
:storage => :fog,
|
13
13
|
:url => '/:attachment/:filename',
|
14
14
|
:fog_directory => "paperclip",
|
15
|
-
:fog_credentials =>
|
15
|
+
:fog_credentials => fixture_file('fog.yml')
|
16
16
|
@dummy = Dummy.new
|
17
|
-
@dummy.avatar = File.new(
|
17
|
+
@dummy.avatar = File.new(fixture_file('5k.png'), 'rb')
|
18
18
|
end
|
19
19
|
|
20
20
|
should "have the proper information loading credentials from a file" do
|
@@ -28,9 +28,9 @@ class FogTest < Test::Unit::TestCase
|
|
28
28
|
:storage => :fog,
|
29
29
|
:url => '/:attachment/:filename',
|
30
30
|
:fog_directory => "paperclip",
|
31
|
-
:fog_credentials => File.open(
|
31
|
+
:fog_credentials => File.open(fixture_file('fog.yml'))
|
32
32
|
@dummy = Dummy.new
|
33
|
-
@dummy.avatar = File.new(
|
33
|
+
@dummy.avatar = File.new(fixture_file('5k.png'), 'rb')
|
34
34
|
end
|
35
35
|
|
36
36
|
should "have the proper information loading credentials from a file" do
|
@@ -50,10 +50,10 @@ class FogTest < Test::Unit::TestCase
|
|
50
50
|
:aws_secret_access_key => 'AWS_SECRET'
|
51
51
|
}
|
52
52
|
@dummy = Dummy.new
|
53
|
-
@dummy.avatar = File.new(
|
53
|
+
@dummy.avatar = File.new(fixture_file('5k.png'), 'rb')
|
54
54
|
end
|
55
55
|
should "be able to interpolate the path without blowing up" do
|
56
|
-
assert_equal File.expand_path(File.join(File.dirname(__FILE__), "
|
56
|
+
assert_equal File.expand_path(File.join(File.dirname(__FILE__), "../../public/avatars/5k.png")),
|
57
57
|
@dummy.avatar.path
|
58
58
|
end
|
59
59
|
|
@@ -98,7 +98,7 @@ class FogTest < Test::Unit::TestCase
|
|
98
98
|
|
99
99
|
context "when assigned" do
|
100
100
|
setup do
|
101
|
-
@file = File.new(
|
101
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
102
102
|
@dummy = Dummy.new
|
103
103
|
@dummy.avatar = @file
|
104
104
|
end
|
@@ -181,11 +181,38 @@ class FogTest < Test::Unit::TestCase
|
|
181
181
|
end
|
182
182
|
|
183
183
|
should 'set the @fog_public instance variable to false' do
|
184
|
-
assert_equal false, @dummy.avatar.options
|
184
|
+
assert_equal false, @dummy.avatar.instance_variable_get('@options')[:fog_public]
|
185
185
|
assert_equal false, @dummy.avatar.fog_public
|
186
186
|
end
|
187
187
|
end
|
188
188
|
|
189
|
+
context "with a valid bucket name for a subdomain" do
|
190
|
+
should "provide an url in subdomain style" do
|
191
|
+
assert_match /^https:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png\?\d*$/, @dummy.avatar.url
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context "with an invalid bucket name for a subdomain" do
|
196
|
+
setup do
|
197
|
+
rebuild_model(@options.merge(:fog_directory => "this_is_invalid"))
|
198
|
+
@dummy = Dummy.new
|
199
|
+
@dummy.avatar = @file
|
200
|
+
@dummy.save
|
201
|
+
end
|
202
|
+
|
203
|
+
should "not match the bucket-subdomain restrictions" do
|
204
|
+
invalid_subdomains = %w(this_is_invalid in iamareallylongbucketnameiamareallylongbucketnameiamareallylongbu invalid- inval..id inval-.id inval.-id -invalid 192.168.10.2)
|
205
|
+
invalid_subdomains.each do |name|
|
206
|
+
assert_no_match Paperclip::Storage::Fog::AWS_BUCKET_SUBDOMAIN_RESTRICTON_REGEX, name
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
should "provide an url in folder style" do
|
211
|
+
assert_match /^https:\/\/s3.amazonaws.com\/this_is_invalid\/avatars\/5k.png\?\d*$/, @dummy.avatar.url
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|
189
216
|
end
|
190
217
|
|
191
218
|
end
|
@@ -1,15 +1,31 @@
|
|
1
1
|
require './test/helper'
|
2
|
-
require 'aws
|
2
|
+
require 'aws'
|
3
3
|
|
4
|
-
unless ENV["
|
4
|
+
unless ENV["S3_BUCKET"].blank?
|
5
5
|
class S3LiveTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Generating an expiring url on a nonexistant attachment" do
|
8
|
+
setup do
|
9
|
+
rebuild_model :styles => { :thumb => "100x100", :square => "32x32#" },
|
10
|
+
:storage => :s3,
|
11
|
+
:bucket => ENV["S3_BUCKET"],
|
12
|
+
:path => ":class/:attachment/:id/:style.:extension",
|
13
|
+
:s3_credentials => File.new(File.join(File.dirname(__FILE__), "..", "fixtures", "s3.yml"))
|
14
|
+
|
15
|
+
@dummy = Dummy.new
|
16
|
+
end
|
17
|
+
should "return nil" do
|
18
|
+
assert_nil @dummy.avatar.expiring_url
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
6
22
|
context "Using S3 for real, an attachment with S3 storage" do
|
7
23
|
setup do
|
8
24
|
rebuild_model :styles => { :thumb => "100x100", :square => "32x32#" },
|
9
25
|
:storage => :s3,
|
10
|
-
:bucket => ENV["
|
26
|
+
:bucket => ENV["S3_BUCKET"],
|
11
27
|
:path => ":class/:attachment/:id/:style.:extension",
|
12
|
-
:s3_credentials => File.new(File.join(File.dirname(__FILE__), "..", "s3.yml"))
|
28
|
+
:s3_credentials => File.new(File.join(File.dirname(__FILE__), "..", "fixtures", "s3.yml"))
|
13
29
|
|
14
30
|
Dummy.delete_all
|
15
31
|
@dummy = Dummy.new
|
@@ -21,7 +37,7 @@ unless ENV["S3_TEST_BUCKET"].blank?
|
|
21
37
|
|
22
38
|
context "when assigned" do
|
23
39
|
setup do
|
24
|
-
@file = File.new(
|
40
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
25
41
|
@dummy.avatar = @file
|
26
42
|
end
|
27
43
|
|
@@ -54,18 +70,16 @@ unless ENV["S3_TEST_BUCKET"].blank?
|
|
54
70
|
context "An attachment that uses S3 for storage and has spaces in file name" do
|
55
71
|
setup do
|
56
72
|
rebuild_model :styles => { :thumb => "100x100", :square => "32x32#" },
|
57
|
-
|
58
|
-
|
59
|
-
|
73
|
+
:storage => :s3,
|
74
|
+
:bucket => ENV["S3_BUCKET"],
|
75
|
+
:s3_credentials => File.new(File.join(File.dirname(__FILE__), "..", "fixtures", "s3.yml"))
|
60
76
|
|
61
77
|
Dummy.delete_all
|
62
78
|
@dummy = Dummy.new
|
63
|
-
@dummy.avatar = File.new(
|
79
|
+
@dummy.avatar = File.new(fixture_file('spaced file.png'), 'rb')
|
64
80
|
@dummy.save
|
65
81
|
end
|
66
82
|
|
67
|
-
teardown { @dummy.destroy }
|
68
|
-
|
69
83
|
should "return an unescaped version for path" do
|
70
84
|
assert_match /.+\/spaced file\.png/, @dummy.avatar.path
|
71
85
|
end
|
@@ -75,13 +89,49 @@ unless ENV["S3_TEST_BUCKET"].blank?
|
|
75
89
|
end
|
76
90
|
|
77
91
|
should "be accessible" do
|
78
|
-
|
92
|
+
assert_success_response @dummy.avatar.url
|
79
93
|
end
|
80
94
|
|
81
95
|
should "be destoryable" do
|
82
96
|
url = @dummy.avatar.url
|
83
97
|
@dummy.destroy
|
84
|
-
|
98
|
+
assert_not_found_response url
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "An attachment that uses S3 for storage and has a question mark in file name" do
|
103
|
+
setup do
|
104
|
+
rebuild_model :styles => { :thumb => "100x100", :square => "32x32#" },
|
105
|
+
:storage => :s3,
|
106
|
+
:bucket => ENV["S3_BUCKET"],
|
107
|
+
:s3_credentials => File.new(File.join(File.dirname(__FILE__), "..", "fixtures", "s3.yml"))
|
108
|
+
|
109
|
+
Dummy.delete_all
|
110
|
+
@dummy = Dummy.new
|
111
|
+
@dummy.avatar = File.new(File.join(File.dirname(__FILE__), '..', 'fixtures', 'question?mark.png'), 'rb')
|
112
|
+
@dummy.save
|
113
|
+
end
|
114
|
+
|
115
|
+
should "return an unescaped version for path" do
|
116
|
+
assert_match /.+\/question\?mark\.png/, @dummy.avatar.path
|
117
|
+
end
|
118
|
+
|
119
|
+
should "return an escaped version for url" do
|
120
|
+
assert_match /.+\/question%3Fmark\.png/, @dummy.avatar.url
|
121
|
+
end
|
122
|
+
|
123
|
+
should "be accessible" do
|
124
|
+
assert_success_response @dummy.avatar.url
|
125
|
+
end
|
126
|
+
|
127
|
+
should "be accessible with an expiring url" do
|
128
|
+
assert_success_response @dummy.avatar.expiring_url
|
129
|
+
end
|
130
|
+
|
131
|
+
should "be destroyable" do
|
132
|
+
url = @dummy.avatar.url
|
133
|
+
@dummy.destroy
|
134
|
+
assert_not_found_response url
|
85
135
|
end
|
86
136
|
end
|
87
137
|
end
|