paperclip_with_versions 2.3.1.1

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.
Files changed (48) hide show
  1. data/LICENSE +26 -0
  2. data/README.rdoc +174 -0
  3. data/Rakefile +103 -0
  4. data/generators/paperclip/USAGE +5 -0
  5. data/generators/paperclip/paperclip_generator.rb +27 -0
  6. data/generators/paperclip/templates/paperclip_migration.rb.erb +19 -0
  7. data/init.rb +1 -0
  8. data/lib/paperclip.rb +356 -0
  9. data/lib/paperclip/attachment.rb +414 -0
  10. data/lib/paperclip/callback_compatability.rb +33 -0
  11. data/lib/paperclip/geometry.rb +115 -0
  12. data/lib/paperclip/interpolations.rb +108 -0
  13. data/lib/paperclip/iostream.rb +58 -0
  14. data/lib/paperclip/matchers.rb +4 -0
  15. data/lib/paperclip/matchers/have_attached_file_matcher.rb +49 -0
  16. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +66 -0
  17. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +48 -0
  18. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +83 -0
  19. data/lib/paperclip/processor.rb +49 -0
  20. data/lib/paperclip/storage.rb +243 -0
  21. data/lib/paperclip/thumbnail.rb +73 -0
  22. data/lib/paperclip/upfile.rb +49 -0
  23. data/shoulda_macros/paperclip.rb +117 -0
  24. data/tasks/paperclip_tasks.rake +79 -0
  25. data/test/attachment_test.rb +815 -0
  26. data/test/database.yml +4 -0
  27. data/test/fixtures/12k.png +0 -0
  28. data/test/fixtures/50x50.png +0 -0
  29. data/test/fixtures/5k.png +0 -0
  30. data/test/fixtures/bad.png +1 -0
  31. data/test/fixtures/s3.yml +8 -0
  32. data/test/fixtures/text.txt +0 -0
  33. data/test/fixtures/twopage.pdf +0 -0
  34. data/test/geometry_test.rb +177 -0
  35. data/test/helper.rb +108 -0
  36. data/test/integration_test.rb +483 -0
  37. data/test/interpolations_test.rb +124 -0
  38. data/test/iostream_test.rb +71 -0
  39. data/test/matchers/have_attached_file_matcher_test.rb +21 -0
  40. data/test/matchers/validate_attachment_content_type_matcher_test.rb +30 -0
  41. data/test/matchers/validate_attachment_presence_matcher_test.rb +21 -0
  42. data/test/matchers/validate_attachment_size_matcher_test.rb +50 -0
  43. data/test/paperclip_test.rb +327 -0
  44. data/test/processor_test.rb +10 -0
  45. data/test/storage_test.rb +303 -0
  46. data/test/thumbnail_test.rb +227 -0
  47. data/test/upfile_test.rb +28 -0
  48. metadata +161 -0
@@ -0,0 +1,10 @@
1
+ require 'test/helper'
2
+
3
+ class ProcessorTest < Test::Unit::TestCase
4
+ should "instantiate and call #make when sent #make to the class" do
5
+ processor = mock
6
+ processor.expects(:make).with()
7
+ Paperclip::Processor.expects(:new).with(:one, :two, :three).returns(processor)
8
+ Paperclip::Processor.make(:one, :two, :three)
9
+ end
10
+ end
@@ -0,0 +1,303 @@
1
+ require 'test/helper'
2
+ require 'aws/s3'
3
+
4
+ class StorageTest < Test::Unit::TestCase
5
+ def rails_env(env)
6
+ silence_warnings do
7
+ Object.const_set(:RAILS_ENV, env)
8
+ end
9
+ end
10
+
11
+ context "Parsing S3 credentials" do
12
+ setup do
13
+ AWS::S3::Base.stubs(:establish_connection!)
14
+ rebuild_model :storage => :s3,
15
+ :bucket => "testing",
16
+ :s3_credentials => {:not => :important}
17
+
18
+ @dummy = Dummy.new
19
+ @avatar = @dummy.avatar
20
+
21
+ @current_env = RAILS_ENV
22
+ end
23
+
24
+ teardown do
25
+ rails_env(@current_env)
26
+ end
27
+
28
+ should "get the correct credentials when RAILS_ENV is production" do
29
+ rails_env("production")
30
+ assert_equal({:key => "12345"},
31
+ @avatar.parse_credentials('production' => {:key => '12345'},
32
+ :development => {:key => "54321"}))
33
+ end
34
+
35
+ should "get the correct credentials when RAILS_ENV is development" do
36
+ rails_env("development")
37
+ assert_equal({:key => "54321"},
38
+ @avatar.parse_credentials('production' => {:key => '12345'},
39
+ :development => {:key => "54321"}))
40
+ end
41
+
42
+ should "return the argument if the key does not exist" do
43
+ rails_env("not really an env")
44
+ assert_equal({:test => "12345"}, @avatar.parse_credentials(:test => "12345"))
45
+ end
46
+ end
47
+
48
+ context "" do
49
+ setup do
50
+ AWS::S3::Base.stubs(:establish_connection!)
51
+ rebuild_model :storage => :s3,
52
+ :s3_credentials => {},
53
+ :bucket => "bucket",
54
+ :path => ":attachment/:basename.:extension",
55
+ :url => ":s3_path_url"
56
+ @dummy = Dummy.new
57
+ @dummy.avatar = StringIO.new(".")
58
+ end
59
+
60
+ should "return a url based on an S3 path" do
61
+ assert_match %r{^http://s3.amazonaws.com/bucket/avatars/stringio.txt}, @dummy.avatar.url
62
+ end
63
+ end
64
+ context "" do
65
+ setup do
66
+ AWS::S3::Base.stubs(:establish_connection!)
67
+ rebuild_model :storage => :s3,
68
+ :s3_credentials => {},
69
+ :bucket => "bucket",
70
+ :path => ":attachment/:basename.:extension",
71
+ :url => ":s3_domain_url"
72
+ @dummy = Dummy.new
73
+ @dummy.avatar = StringIO.new(".")
74
+ end
75
+
76
+ should "return a url based on an S3 subdomain" do
77
+ assert_match %r{^http://bucket.s3.amazonaws.com/avatars/stringio.txt}, @dummy.avatar.url
78
+ end
79
+ end
80
+ context "" do
81
+ setup do
82
+ AWS::S3::Base.stubs(:establish_connection!)
83
+ rebuild_model :storage => :s3,
84
+ :s3_credentials => {
85
+ :production => { :bucket => "prod_bucket" },
86
+ :development => { :bucket => "dev_bucket" }
87
+ },
88
+ :s3_host_alias => "something.something.com",
89
+ :path => ":attachment/:basename.:extension",
90
+ :url => ":s3_alias_url"
91
+ @dummy = Dummy.new
92
+ @dummy.avatar = StringIO.new(".")
93
+ end
94
+
95
+ should "return a url based on the host_alias" do
96
+ assert_match %r{^http://something.something.com/avatars/stringio.txt}, @dummy.avatar.url
97
+ end
98
+ end
99
+
100
+ context "Parsing S3 credentials with a bucket in them" do
101
+ setup do
102
+ AWS::S3::Base.stubs(:establish_connection!)
103
+ rebuild_model :storage => :s3,
104
+ :s3_credentials => {
105
+ :production => { :bucket => "prod_bucket" },
106
+ :development => { :bucket => "dev_bucket" }
107
+ }
108
+ @dummy = Dummy.new
109
+ @old_env = RAILS_ENV
110
+ end
111
+
112
+ teardown{ rails_env(@old_env) }
113
+
114
+ should "get the right bucket in production" do
115
+ rails_env("production")
116
+ assert_equal "prod_bucket", @dummy.avatar.bucket_name
117
+ end
118
+
119
+ should "get the right bucket in development" do
120
+ rails_env("development")
121
+ assert_equal "dev_bucket", @dummy.avatar.bucket_name
122
+ end
123
+ end
124
+
125
+ context "An attachment with S3 storage" do
126
+ setup do
127
+ rebuild_model :storage => :s3,
128
+ :bucket => "testing",
129
+ :path => ":attachment/:style/:basename.:extension",
130
+ :s3_credentials => {
131
+ 'access_key_id' => "12345",
132
+ 'secret_access_key' => "54321"
133
+ }
134
+ end
135
+
136
+ should "be extended by the S3 module" do
137
+ assert Dummy.new.avatar.is_a?(Paperclip::Storage::S3)
138
+ end
139
+
140
+ should "not be extended by the Filesystem module" do
141
+ assert ! Dummy.new.avatar.is_a?(Paperclip::Storage::Filesystem)
142
+ end
143
+
144
+ context "when assigned" do
145
+ setup do
146
+ @file = File.new(File.join(File.dirname(__FILE__), 'fixtures', '5k.png'), 'rb')
147
+ @dummy = Dummy.new
148
+ @dummy.avatar = @file
149
+ end
150
+
151
+ teardown { @file.close }
152
+
153
+ should "not get a bucket to get a URL" do
154
+ @dummy.avatar.expects(:s3).never
155
+ @dummy.avatar.expects(:s3_bucket).never
156
+ assert_match %r{^http://s3\.amazonaws\.com/testing/avatars/original/5k\.png}, @dummy.avatar.url
157
+ end
158
+
159
+ context "and saved" do
160
+ setup do
161
+ AWS::S3::S3Object.stubs(:store).with(@dummy.avatar.path, anything, 'testing', :content_type => 'image/png', :access => :public_read)
162
+ @dummy.save
163
+ end
164
+
165
+ should "succeed" do
166
+ assert true
167
+ end
168
+ end
169
+
170
+ context "and remove" do
171
+ setup do
172
+ AWS::S3::S3Object.stubs(:exists?).returns(true)
173
+ AWS::S3::S3Object.stubs(:delete)
174
+ @dummy.destroy_attached_files
175
+ end
176
+
177
+ should "succeed" do
178
+ assert true
179
+ end
180
+ end
181
+ end
182
+ end
183
+
184
+ context "An attachment with S3 storage and bucket defined as a Proc" do
185
+ setup do
186
+ AWS::S3::Base.stubs(:establish_connection!)
187
+ rebuild_model :storage => :s3,
188
+ :bucket => lambda { |attachment| "bucket_#{attachment.instance.other}" },
189
+ :s3_credentials => {:not => :important}
190
+ end
191
+
192
+ should "get the right bucket name" do
193
+ assert "bucket_a", Dummy.new(:other => 'a').avatar.bucket_name
194
+ assert "bucket_b", Dummy.new(:other => 'b').avatar.bucket_name
195
+ end
196
+ end
197
+
198
+ context "An attachment with S3 storage and specific s3 headers set" do
199
+ setup do
200
+ AWS::S3::Base.stubs(:establish_connection!)
201
+ rebuild_model :storage => :s3,
202
+ :bucket => "testing",
203
+ :path => ":attachment/:style/:basename.:extension",
204
+ :s3_credentials => {
205
+ 'access_key_id' => "12345",
206
+ 'secret_access_key' => "54321"
207
+ },
208
+ :s3_headers => {'Cache-Control' => 'max-age=31557600'}
209
+ end
210
+
211
+ context "when assigned" do
212
+ setup do
213
+ @file = File.new(File.join(File.dirname(__FILE__), 'fixtures', '5k.png'), 'rb')
214
+ @dummy = Dummy.new
215
+ @dummy.avatar = @file
216
+ end
217
+
218
+ teardown { @file.close }
219
+
220
+ context "and saved" do
221
+ setup do
222
+ AWS::S3::Base.stubs(:establish_connection!)
223
+ AWS::S3::S3Object.stubs(:store).with(@dummy.avatar.path,
224
+ anything,
225
+ 'testing',
226
+ :content_type => 'image/png',
227
+ :access => :public_read,
228
+ 'Cache-Control' => 'max-age=31557600')
229
+ @dummy.save
230
+ end
231
+
232
+ should "succeed" do
233
+ assert true
234
+ end
235
+ end
236
+ end
237
+ end
238
+
239
+ context "with S3 credentials in a YAML file" do
240
+ setup do
241
+ ENV['S3_KEY'] = 'env_key'
242
+ ENV['S3_BUCKET'] = 'env_bucket'
243
+ ENV['S3_SECRET'] = 'env_secret'
244
+
245
+ rails_env('test')
246
+
247
+ rebuild_model :storage => :s3,
248
+ :s3_credentials => File.new(File.join(File.dirname(__FILE__), "fixtures/s3.yml"))
249
+
250
+ Dummy.delete_all
251
+
252
+ @dummy = Dummy.new
253
+ end
254
+
255
+ should "run it the file through ERB" do
256
+ assert_equal 'env_bucket', @dummy.avatar.bucket_name
257
+ assert_equal 'env_key', AWS::S3::Base.connection.options[:access_key_id]
258
+ assert_equal 'env_secret', AWS::S3::Base.connection.options[:secret_access_key]
259
+ end
260
+ end
261
+
262
+ unless ENV["S3_TEST_BUCKET"].blank?
263
+ context "Using S3 for real, an attachment with S3 storage" do
264
+ setup do
265
+ rebuild_model :styles => { :thumb => "100x100", :square => "32x32#" },
266
+ :storage => :s3,
267
+ :bucket => ENV["S3_TEST_BUCKET"],
268
+ :path => ":class/:attachment/:id/:style.:extension",
269
+ :s3_credentials => File.new(File.join(File.dirname(__FILE__), "s3.yml"))
270
+
271
+ Dummy.delete_all
272
+ @dummy = Dummy.new
273
+ end
274
+
275
+ should "be extended by the S3 module" do
276
+ assert Dummy.new.avatar.is_a?(Paperclip::Storage::S3)
277
+ end
278
+
279
+ context "when assigned" do
280
+ setup do
281
+ @file = File.new(File.join(File.dirname(__FILE__), 'fixtures', '5k.png'), 'rb')
282
+ @dummy.avatar = @file
283
+ end
284
+
285
+ teardown { @file.close }
286
+
287
+ should "still return a Tempfile when sent #to_file" do
288
+ assert_equal Tempfile, @dummy.avatar.to_file.class
289
+ end
290
+
291
+ context "and saved" do
292
+ setup do
293
+ @dummy.save
294
+ end
295
+
296
+ should "be on S3" do
297
+ assert true
298
+ end
299
+ end
300
+ end
301
+ end
302
+ end
303
+ end
@@ -0,0 +1,227 @@
1
+ require 'test/helper'
2
+
3
+ class ThumbnailTest < Test::Unit::TestCase
4
+
5
+ context "A Paperclip Tempfile" do
6
+ setup do
7
+ @tempfile = Paperclip::Tempfile.new("file.jpg")
8
+ end
9
+
10
+ should "have its path contain a real extension" do
11
+ assert_equal ".jpg", File.extname(@tempfile.path)
12
+ end
13
+
14
+ should "be a real Tempfile" do
15
+ assert @tempfile.is_a?(::Tempfile)
16
+ end
17
+ end
18
+
19
+ context "Another Paperclip Tempfile" do
20
+ setup do
21
+ @tempfile = Paperclip::Tempfile.new("file")
22
+ end
23
+
24
+ should "not have an extension if not given one" do
25
+ assert_equal "", File.extname(@tempfile.path)
26
+ end
27
+
28
+ should "still be a real Tempfile" do
29
+ assert @tempfile.is_a?(::Tempfile)
30
+ end
31
+ end
32
+
33
+ context "An image" do
34
+ setup do
35
+ @file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png"), 'rb')
36
+ end
37
+
38
+ teardown { @file.close }
39
+
40
+ [["600x600>", "434x66"],
41
+ ["400x400>", "400x61"],
42
+ ["32x32<", "434x66"]
43
+ ].each do |args|
44
+ context "being thumbnailed with a geometry of #{args[0]}" do
45
+ setup do
46
+ @thumb = Paperclip::Thumbnail.new(@file, :geometry => args[0])
47
+ end
48
+
49
+ should "start with dimensions of 434x66" do
50
+ cmd = %Q[identify -format "%wx%h" "#{@file.path}"]
51
+ assert_equal "434x66", `#{cmd}`.chomp
52
+ end
53
+
54
+ should "report the correct target geometry" do
55
+ assert_equal args[0], @thumb.target_geometry.to_s
56
+ end
57
+
58
+ context "when made" do
59
+ setup do
60
+ @thumb_result = @thumb.make
61
+ end
62
+
63
+ should "be the size we expect it to be" do
64
+ cmd = %Q[identify -format "%wx%h" "#{@thumb_result.path}"]
65
+ assert_equal args[1], `#{cmd}`.chomp
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ context "being thumbnailed at 100x50 with cropping" do
72
+ setup do
73
+ @thumb = Paperclip::Thumbnail.new(@file, :geometry => "100x50#")
74
+ end
75
+
76
+ should "report its correct current and target geometries" do
77
+ assert_equal "100x50#", @thumb.target_geometry.to_s
78
+ assert_equal "434x66", @thumb.current_geometry.to_s
79
+ end
80
+
81
+ should "report its correct format" do
82
+ assert_nil @thumb.format
83
+ end
84
+
85
+ should "have whiny turned on by default" do
86
+ assert @thumb.whiny
87
+ end
88
+
89
+ should "have convert_options set to nil by default" do
90
+ assert_equal nil, @thumb.convert_options
91
+ end
92
+
93
+ should "send the right command to convert when sent #make" do
94
+ Paperclip.expects(:"`").with do |arg|
95
+ arg.match %r{convert\s+"#{File.expand_path(@thumb.file.path)}\[0\]"\s+-resize\s+\"x50\"\s+-crop\s+\"100x50\+114\+0\"\s+\+repage\s+".*?"}
96
+ end
97
+ @thumb.make
98
+ end
99
+
100
+ should "create the thumbnail when sent #make" do
101
+ dst = @thumb.make
102
+ assert_match /100x50/, `identify "#{dst.path}"`
103
+ end
104
+ end
105
+
106
+ context "being thumbnailed with source file options set" do
107
+ setup do
108
+ @thumb = Paperclip::Thumbnail.new(@file,
109
+ :geometry => "100x50#",
110
+ :source_file_options => "-strip")
111
+ end
112
+
113
+ should "have source_file_options value set" do
114
+ assert_equal "-strip", @thumb.source_file_options
115
+ end
116
+
117
+ should "send the right command to convert when sent #make" do
118
+ Paperclip.expects(:"`").with do |arg|
119
+ arg.match %r{convert\s+-strip\s+"#{File.expand_path(@thumb.file.path)}\[0\]"\s+-resize\s+"x50"\s+-crop\s+"100x50\+114\+0"\s+\+repage\s+".*?"}
120
+ end
121
+ @thumb.make
122
+ end
123
+
124
+ should "create the thumbnail when sent #make" do
125
+ dst = @thumb.make
126
+ assert_match /100x50/, `identify "#{dst.path}"`
127
+ end
128
+
129
+ context "redefined to have bad source_file_options setting" do
130
+ setup do
131
+ @thumb = Paperclip::Thumbnail.new(@file,
132
+ :geometry => "100x50#",
133
+ :source_file_options => "-this-aint-no-option")
134
+ end
135
+
136
+ should "error when trying to create the thumbnail" do
137
+ assert_raises(Paperclip::PaperclipError) do
138
+ @thumb.make
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ context "being thumbnailed with convert options set" do
145
+ setup do
146
+ @thumb = Paperclip::Thumbnail.new(@file,
147
+ :geometry => "100x50#",
148
+ :convert_options => "-strip -depth 8")
149
+ end
150
+
151
+ should "have convert_options value set" do
152
+ assert_equal "-strip -depth 8", @thumb.convert_options
153
+ end
154
+
155
+ should "send the right command to convert when sent #make" do
156
+ Paperclip.expects(:"`").with do |arg|
157
+ arg.match %r{convert\s+"#{File.expand_path(@thumb.file.path)}\[0\]"\s+-resize\s+"x50"\s+-crop\s+"100x50\+114\+0"\s+\+repage\s+-strip\s+-depth\s+8\s+".*?"}
158
+ end
159
+ @thumb.make
160
+ end
161
+
162
+ should "create the thumbnail when sent #make" do
163
+ dst = @thumb.make
164
+ assert_match /100x50/, `identify "#{dst.path}"`
165
+ end
166
+
167
+ context "redefined to have bad convert_options setting" do
168
+ setup do
169
+ @thumb = Paperclip::Thumbnail.new(@file,
170
+ :geometry => "100x50#",
171
+ :convert_options => "-this-aint-no-option")
172
+ end
173
+
174
+ should "error when trying to create the thumbnail" do
175
+ assert_raises(Paperclip::PaperclipError) do
176
+ @thumb.make
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+ context "being thumbnailed with a blank geometry string" do
183
+ setup do
184
+ @thumb = Paperclip::Thumbnail.new(@file,
185
+ :geometry => "",
186
+ :convert_options => "-gravity center -crop \"300x300+0-0\"")
187
+ end
188
+
189
+ should "not get resized by default" do
190
+ assert_no_match(/-resize/, @thumb.transformation_command)
191
+ end
192
+ end
193
+ end
194
+
195
+ context "A multipage PDF" do
196
+ setup do
197
+ @file = File.new(File.join(File.dirname(__FILE__), "fixtures", "twopage.pdf"), 'rb')
198
+ end
199
+
200
+ teardown { @file.close }
201
+
202
+ should "start with two pages with dimensions 612x792" do
203
+ cmd = %Q[identify -format "%wx%h" "#{@file.path}"]
204
+ assert_equal "612x792"*2, `#{cmd}`.chomp
205
+ end
206
+
207
+ context "being thumbnailed at 100x100 with cropping" do
208
+ setup do
209
+ @thumb = Paperclip::Thumbnail.new(@file, :geometry => "100x100#", :format => :png)
210
+ end
211
+
212
+ should "report its correct current and target geometries" do
213
+ assert_equal "100x100#", @thumb.target_geometry.to_s
214
+ assert_equal "612x792", @thumb.current_geometry.to_s
215
+ end
216
+
217
+ should "report its correct format" do
218
+ assert_equal :png, @thumb.format
219
+ end
220
+
221
+ should "create the thumbnail when sent #make" do
222
+ dst = @thumb.make
223
+ assert_match /100x100/, `identify "#{dst.path}"`
224
+ end
225
+ end
226
+ end
227
+ end