paperclip 2.3.0 → 2.3.1
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/lib/paperclip.rb +5 -3
- data/lib/paperclip/interpolations.rb +4 -1
- data/lib/paperclip/storage.rb +32 -25
- data/lib/paperclip/thumbnail.rb +16 -13
- data/test/attachment_test.rb +13 -1
- data/test/helper.rb +10 -1
- data/test/integration_test.rb +13 -11
- data/test/interpolations_test.rb +5 -1
- data/test/paperclip_test.rb +68 -32
- data/test/storage_test.rb +33 -35
- data/test/thumbnail_test.rb +50 -0
- metadata +2 -2
data/lib/paperclip.rb
CHANGED
@@ -44,7 +44,7 @@ end
|
|
44
44
|
# documentation for Paperclip::ClassMethods for more useful information.
|
45
45
|
module Paperclip
|
46
46
|
|
47
|
-
VERSION = "2.3.
|
47
|
+
VERSION = "2.3.1"
|
48
48
|
|
49
49
|
class << self
|
50
50
|
# Provides configurability to Paperclip. There are a number of options available, such as:
|
@@ -93,7 +93,7 @@ module Paperclip
|
|
93
93
|
# Paperclip.options[:log_command] is set to true (defaults to false). This
|
94
94
|
# will only log if logging in general is set to true as well.
|
95
95
|
def run cmd, params = "", expected_outcodes = 0
|
96
|
-
command = %Q
|
96
|
+
command = %Q[#{path_for_command(cmd)} #{params}].gsub(/\s+/, " ")
|
97
97
|
command = "#{command} 2>#{bit_bucket}" if Paperclip.options[:swallow_stderr]
|
98
98
|
Paperclip.log(command) if Paperclip.options[:log_command]
|
99
99
|
output = `#{command}`
|
@@ -257,7 +257,9 @@ module Paperclip
|
|
257
257
|
range = (min..max)
|
258
258
|
message = options[:message] || "file size must be between :min and :max bytes."
|
259
259
|
|
260
|
-
attachment_definitions[name][:validations] << [:size, {:
|
260
|
+
attachment_definitions[name][:validations] << [:size, {:min => min,
|
261
|
+
:max => max,
|
262
|
+
:range => range,
|
261
263
|
:message => message,
|
262
264
|
:if => options[:if],
|
263
265
|
:unless => options[:unless]}]
|
@@ -63,7 +63,10 @@ module Paperclip
|
|
63
63
|
|
64
64
|
# Returns the underscored, pluralized version of the class name.
|
65
65
|
# e.g. "users" for the User class.
|
66
|
-
|
66
|
+
# NOTE: The arguments need to be optional, because some tools fetch
|
67
|
+
# all class names. Calling #class will return the expected class.
|
68
|
+
def class attachment = nil, style = nil
|
69
|
+
return super() if attachment.nil? && style.nil?
|
67
70
|
attachment.instance.class.to_s.underscore.pluralize
|
68
71
|
end
|
69
72
|
|
data/lib/paperclip/storage.rb
CHANGED
@@ -33,7 +33,6 @@ module Paperclip
|
|
33
33
|
def to_file style = default_style
|
34
34
|
@queued_for_write[style] || (File.new(path(style), 'rb') if exists?(style))
|
35
35
|
end
|
36
|
-
alias_method :to_io, :to_file
|
37
36
|
|
38
37
|
def flush_writes #:nodoc:
|
39
38
|
@queued_for_write.each do |style, file|
|
@@ -128,17 +127,27 @@ module Paperclip
|
|
128
127
|
# separate parts of your file name.
|
129
128
|
module S3
|
130
129
|
def self.extended base
|
131
|
-
|
130
|
+
begin
|
131
|
+
require 'aws/s3'
|
132
|
+
rescue LoadError => e
|
133
|
+
e.message << " (You may need to install the aws-s3 gem)"
|
134
|
+
raise e
|
135
|
+
end
|
136
|
+
|
132
137
|
base.instance_eval do
|
133
138
|
@s3_credentials = parse_credentials(@options[:s3_credentials])
|
134
139
|
@bucket = @options[:bucket] || @s3_credentials[:bucket]
|
135
140
|
@bucket = @bucket.call(self) if @bucket.is_a?(Proc)
|
136
141
|
@s3_options = @options[:s3_options] || {}
|
137
|
-
@s3_permissions = @options[:s3_permissions] ||
|
138
|
-
@s3_protocol = @options[:s3_protocol] || (@s3_permissions ==
|
142
|
+
@s3_permissions = @options[:s3_permissions] || :public_read
|
143
|
+
@s3_protocol = @options[:s3_protocol] || (@s3_permissions == :public_read ? 'http' : 'https')
|
139
144
|
@s3_headers = @options[:s3_headers] || {}
|
140
145
|
@s3_host_alias = @options[:s3_host_alias]
|
141
146
|
@url = ":s3_path_url" unless @url.to_s.match(/^:s3.*url$/)
|
147
|
+
AWS::S3::Base.establish_connection!( @s3_options.merge(
|
148
|
+
:access_key_id => @s3_credentials[:access_key_id],
|
149
|
+
:secret_access_key => @s3_credentials[:secret_access_key]
|
150
|
+
))
|
142
151
|
end
|
143
152
|
Paperclip.interpolates(:s3_alias_url) do |attachment, style|
|
144
153
|
"#{attachment.s3_protocol}://#{attachment.s3_host_alias}/#{attachment.path(style).gsub(%r{^/}, "")}"
|
@@ -151,16 +160,6 @@ module Paperclip
|
|
151
160
|
end
|
152
161
|
end
|
153
162
|
|
154
|
-
def s3
|
155
|
-
@s3 ||= RightAws::S3.new(@s3_credentials[:access_key_id],
|
156
|
-
@s3_credentials[:secret_access_key],
|
157
|
-
@s3_options)
|
158
|
-
end
|
159
|
-
|
160
|
-
def s3_bucket
|
161
|
-
@s3_bucket ||= s3.bucket(@bucket, true, @s3_permissions)
|
162
|
-
end
|
163
|
-
|
164
163
|
def bucket_name
|
165
164
|
@bucket
|
166
165
|
end
|
@@ -175,7 +174,11 @@ module Paperclip
|
|
175
174
|
end
|
176
175
|
|
177
176
|
def exists?(style = default_style)
|
178
|
-
|
177
|
+
if original_filename
|
178
|
+
AWS::S3::S3Object.exists?(path(style), bucket_name)
|
179
|
+
else
|
180
|
+
false
|
181
|
+
end
|
179
182
|
end
|
180
183
|
|
181
184
|
def s3_protocol
|
@@ -185,18 +188,24 @@ module Paperclip
|
|
185
188
|
# Returns representation of the data of the file assigned to the given
|
186
189
|
# style, in the format most representative of the current storage.
|
187
190
|
def to_file style = default_style
|
188
|
-
@queued_for_write[style]
|
191
|
+
return @queued_for_write[style] if @queued_for_write[style]
|
192
|
+
file = Tempfile.new(path(style))
|
193
|
+
file.write(AWS::S3::S3Object.value(path(style), bucket_name))
|
194
|
+
file.rewind
|
195
|
+
return file
|
189
196
|
end
|
190
|
-
alias_method :to_io, :to_file
|
191
197
|
|
192
198
|
def flush_writes #:nodoc:
|
193
199
|
@queued_for_write.each do |style, file|
|
194
200
|
begin
|
195
201
|
log("saving #{path(style)}")
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
202
|
+
AWS::S3::S3Object.store(path(style),
|
203
|
+
file,
|
204
|
+
bucket_name,
|
205
|
+
{:content_type => instance_read(:content_type),
|
206
|
+
:access => @s3_permissions,
|
207
|
+
}.merge(@s3_headers))
|
208
|
+
rescue AWS::S3::ResponseError => e
|
200
209
|
raise
|
201
210
|
end
|
202
211
|
end
|
@@ -207,10 +216,8 @@ module Paperclip
|
|
207
216
|
@queued_for_delete.each do |path|
|
208
217
|
begin
|
209
218
|
log("deleting #{path}")
|
210
|
-
|
211
|
-
|
212
|
-
end
|
213
|
-
rescue RightAws::AwsError
|
219
|
+
AWS::S3::S3Object.delete(path, bucket_name)
|
220
|
+
rescue AWS::S3::ResponseError
|
214
221
|
# Ignore this.
|
215
222
|
end
|
216
223
|
end
|
data/lib/paperclip/thumbnail.rb
CHANGED
@@ -2,7 +2,7 @@ module Paperclip
|
|
2
2
|
# Handles thumbnailing images that are uploaded.
|
3
3
|
class Thumbnail < Processor
|
4
4
|
|
5
|
-
attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options
|
5
|
+
attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options, :source_file_options
|
6
6
|
|
7
7
|
# Creates a Thumbnail object set to work on the +file+ given. It
|
8
8
|
# will attempt to transform the image into one defined by +target_geometry+
|
@@ -12,17 +12,18 @@ module Paperclip
|
|
12
12
|
# set, the options will be appended to the convert command upon image conversion
|
13
13
|
def initialize file, options = {}, attachment = nil
|
14
14
|
super
|
15
|
-
geometry
|
16
|
-
@file
|
17
|
-
@crop
|
18
|
-
@target_geometry
|
19
|
-
@current_geometry
|
20
|
-
@
|
21
|
-
@
|
22
|
-
@
|
15
|
+
geometry = options[:geometry]
|
16
|
+
@file = file
|
17
|
+
@crop = geometry[-1,1] == '#'
|
18
|
+
@target_geometry = Geometry.parse geometry
|
19
|
+
@current_geometry = Geometry.from_file @file
|
20
|
+
@source_file_options = options[:source_file_options]
|
21
|
+
@convert_options = options[:convert_options]
|
22
|
+
@whiny = options[:whiny].nil? ? true : options[:whiny]
|
23
|
+
@format = options[:format]
|
23
24
|
|
24
|
-
@current_format
|
25
|
-
@basename
|
25
|
+
@current_format = File.extname(@file.path)
|
26
|
+
@basename = File.basename(@file.path, @current_format)
|
26
27
|
end
|
27
28
|
|
28
29
|
# Returns true if the +target_geometry+ is meant to crop.
|
@@ -32,7 +33,7 @@ module Paperclip
|
|
32
33
|
|
33
34
|
# Returns true if the image is meant to make use of additional convert options.
|
34
35
|
def convert_options?
|
35
|
-
|
36
|
+
!@convert_options.nil? && !@convert_options.empty?
|
36
37
|
end
|
37
38
|
|
38
39
|
# Performs the conversion of the +file+ into a thumbnail. Returns the Tempfile
|
@@ -43,6 +44,7 @@ module Paperclip
|
|
43
44
|
dst.binmode
|
44
45
|
|
45
46
|
command = <<-end_command
|
47
|
+
#{ source_file_options }
|
46
48
|
"#{ File.expand_path(src.path) }[0]"
|
47
49
|
#{ transformation_command }
|
48
50
|
"#{ File.expand_path(dst.path) }"
|
@@ -61,7 +63,8 @@ module Paperclip
|
|
61
63
|
# into the thumbnail.
|
62
64
|
def transformation_command
|
63
65
|
scale, crop = @current_geometry.transformation_to(@target_geometry, crop?)
|
64
|
-
trans = "
|
66
|
+
trans = ""
|
67
|
+
trans << " -resize \"#{scale}\"" unless scale.nil? || scale.empty?
|
65
68
|
trans << " -crop \"#{crop}\" +repage" if crop
|
66
69
|
trans << " #{convert_options}" if convert_options?
|
67
70
|
trans
|
data/test/attachment_test.rb
CHANGED
@@ -14,6 +14,18 @@ class AttachmentTest < Test::Unit::TestCase
|
|
14
14
|
assert_equal "#{RAILS_ROOT}/public/fake_models/1234/fake", @attachment.path
|
15
15
|
end
|
16
16
|
|
17
|
+
should "call a proc sent to check_guard" do
|
18
|
+
@dummy = Dummy.new
|
19
|
+
@dummy.expects(:one).returns(:one)
|
20
|
+
assert_equal :one, @dummy.avatar.send(:check_guard, lambda{|x| x.one })
|
21
|
+
end
|
22
|
+
|
23
|
+
should "call a method name sent to check_guard" do
|
24
|
+
@dummy = Dummy.new
|
25
|
+
@dummy.expects(:one).returns(:one)
|
26
|
+
assert_equal :one, @dummy.avatar.send(:check_guard, :one)
|
27
|
+
end
|
28
|
+
|
17
29
|
context "Attachment default_options" do
|
18
30
|
setup do
|
19
31
|
rebuild_model
|
@@ -592,7 +604,7 @@ class AttachmentTest < Test::Unit::TestCase
|
|
592
604
|
|
593
605
|
should "commit the files to disk" do
|
594
606
|
[:large, :medium, :small].each do |style|
|
595
|
-
io = @attachment.
|
607
|
+
io = @attachment.to_file(style)
|
596
608
|
assert File.exists?(io)
|
597
609
|
assert ! io.is_a?(::Tempfile)
|
598
610
|
io.close
|
data/test/helper.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'test/unit'
|
3
3
|
require 'shoulda'
|
4
|
-
require 'mocha'
|
5
4
|
require 'tempfile'
|
6
5
|
|
6
|
+
gem 'jferris-mocha', '0.9.5.0.1241126838'
|
7
|
+
require 'mocha'
|
8
|
+
|
7
9
|
gem 'sqlite3-ruby'
|
8
10
|
|
9
11
|
require 'active_record'
|
@@ -97,3 +99,10 @@ end
|
|
97
99
|
def attachment options
|
98
100
|
Paperclip::Attachment.new(:avatar, FakeModel.new, options)
|
99
101
|
end
|
102
|
+
|
103
|
+
def silence_warnings
|
104
|
+
old_verbose, $VERBOSE = $VERBOSE, nil
|
105
|
+
yield
|
106
|
+
ensure
|
107
|
+
$VERBOSE = old_verbose
|
108
|
+
end
|
data/test/integration_test.rb
CHANGED
@@ -379,6 +379,11 @@ class IntegrationTest < Test::Unit::TestCase
|
|
379
379
|
@files_on_s3 = s3_files_for @dummy.avatar
|
380
380
|
end
|
381
381
|
|
382
|
+
should "have the same contents as the original" do
|
383
|
+
@file.rewind
|
384
|
+
assert_equal @file.read, @files_on_s3[:original].read
|
385
|
+
end
|
386
|
+
|
382
387
|
should "write and delete its files" do
|
383
388
|
[["434x66", :original],
|
384
389
|
["300x46", :large],
|
@@ -403,10 +408,8 @@ class IntegrationTest < Test::Unit::TestCase
|
|
403
408
|
assert @dummy.valid?
|
404
409
|
assert @dummy.save
|
405
410
|
|
406
|
-
|
407
|
-
|
408
|
-
saved_keys.each do |key|
|
409
|
-
assert key.exists?
|
411
|
+
[:thumb, :medium, :large, :original].each do |style|
|
412
|
+
assert @dummy.avatar.exists?(style)
|
410
413
|
end
|
411
414
|
|
412
415
|
@dummy.avatar.clear
|
@@ -414,8 +417,8 @@ class IntegrationTest < Test::Unit::TestCase
|
|
414
417
|
assert @dummy.valid?
|
415
418
|
assert @dummy.save
|
416
419
|
|
417
|
-
|
418
|
-
assert !
|
420
|
+
[:thumb, :medium, :large, :original].each do |style|
|
421
|
+
assert ! @dummy.avatar.exists?(style)
|
419
422
|
end
|
420
423
|
|
421
424
|
@d2 = Dummy.find(@dummy.id)
|
@@ -427,7 +430,7 @@ class IntegrationTest < Test::Unit::TestCase
|
|
427
430
|
|
428
431
|
assert_equal @dummy.avatar_file_name, @d2.avatar_file_name
|
429
432
|
[:thumb, :medium, :large, :original].each do |style|
|
430
|
-
assert_equal @dummy.avatar.to_file(style).
|
433
|
+
assert_equal @dummy.avatar.to_file(style).read, @d2.avatar.to_file(style).read
|
431
434
|
end
|
432
435
|
|
433
436
|
saved_keys = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.to_file(s) }
|
@@ -435,8 +438,8 @@ class IntegrationTest < Test::Unit::TestCase
|
|
435
438
|
@d2.avatar.clear
|
436
439
|
assert @d2.save
|
437
440
|
|
438
|
-
|
439
|
-
assert !
|
441
|
+
[:thumb, :medium, :large, :original].each do |style|
|
442
|
+
assert ! @dummy.avatar.exists?(style)
|
440
443
|
end
|
441
444
|
end
|
442
445
|
|
@@ -444,7 +447,7 @@ class IntegrationTest < Test::Unit::TestCase
|
|
444
447
|
expected = @dummy.avatar.to_file
|
445
448
|
@dummy.avatar = "not a file"
|
446
449
|
assert @dummy.valid?
|
447
|
-
assert_equal expected.
|
450
|
+
assert_equal expected.read, @dummy.avatar.to_file.read
|
448
451
|
|
449
452
|
@dummy.avatar = @bad_file
|
450
453
|
assert ! @dummy.valid?
|
@@ -472,7 +475,6 @@ class IntegrationTest < Test::Unit::TestCase
|
|
472
475
|
|
473
476
|
should "have the right content type" do
|
474
477
|
headers = s3_headers_for(@dummy.avatar, :original)
|
475
|
-
p headers
|
476
478
|
assert_equal 'image/png', headers['content-type']
|
477
479
|
end
|
478
480
|
end
|
data/test/interpolations_test.rb
CHANGED
@@ -7,7 +7,7 @@ class InterpolationsTest < Test::Unit::TestCase
|
|
7
7
|
assert ! methods.include?(:[]=)
|
8
8
|
assert ! methods.include?(:all)
|
9
9
|
methods.each do |m|
|
10
|
-
assert Paperclip::Interpolations.respond_to?
|
10
|
+
assert Paperclip::Interpolations.respond_to?(m)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -19,6 +19,10 @@ class InterpolationsTest < Test::Unit::TestCase
|
|
19
19
|
assert_equal RAILS_ENV, Paperclip::Interpolations.rails_env(:attachment, :style)
|
20
20
|
end
|
21
21
|
|
22
|
+
should "return the class of the Interpolations module when called with no params" do
|
23
|
+
assert_equal Module, Paperclip::Interpolations.class
|
24
|
+
end
|
25
|
+
|
22
26
|
should "return the class of the instance" do
|
23
27
|
attachment = mock
|
24
28
|
attachment.expects(:instance).returns(attachment)
|
data/test/paperclip_test.rb
CHANGED
@@ -1,14 +1,18 @@
|
|
1
1
|
require 'test/helper'
|
2
2
|
|
3
3
|
class PaperclipTest < Test::Unit::TestCase
|
4
|
-
[:image_magick_path, :
|
5
|
-
context "Calling Paperclip.run with
|
4
|
+
[:image_magick_path, :command_path].each do |path|
|
5
|
+
context "Calling Paperclip.run with #{path} specified" do
|
6
6
|
setup do
|
7
7
|
Paperclip.options[:image_magick_path] = nil
|
8
|
-
Paperclip.options[:
|
8
|
+
Paperclip.options[:command_path] = nil
|
9
9
|
Paperclip.options[path] = "/usr/bin"
|
10
10
|
end
|
11
11
|
|
12
|
+
should "return the expected path for path_for_command" do
|
13
|
+
assert_equal "/usr/bin/convert", Paperclip.path_for_command("convert")
|
14
|
+
end
|
15
|
+
|
12
16
|
should "execute the right command" do
|
13
17
|
Paperclip.expects(:path_for_command).with("convert").returns("/usr/bin/convert")
|
14
18
|
Paperclip.expects(:bit_bucket).returns("/dev/null")
|
@@ -21,7 +25,11 @@ class PaperclipTest < Test::Unit::TestCase
|
|
21
25
|
context "Calling Paperclip.run with no path specified" do
|
22
26
|
setup do
|
23
27
|
Paperclip.options[:image_magick_path] = nil
|
24
|
-
Paperclip.options[:
|
28
|
+
Paperclip.options[:command_path] = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
should "return the expected path fro path_for_command" do
|
32
|
+
assert_equal "convert", Paperclip.path_for_command("convert")
|
25
33
|
end
|
26
34
|
|
27
35
|
should "execute the right command" do
|
@@ -30,38 +38,38 @@ class PaperclipTest < Test::Unit::TestCase
|
|
30
38
|
Paperclip.expects(:"`").with("convert one.jpg two.jpg 2>/dev/null")
|
31
39
|
Paperclip.run("convert", "one.jpg two.jpg")
|
32
40
|
end
|
41
|
+
end
|
33
42
|
|
34
|
-
|
43
|
+
context "Calling Paperclip.run and logging" do
|
44
|
+
setup do
|
45
|
+
Paperclip.options[:image_magick_path] = nil
|
46
|
+
Paperclip.options[:command_path] = nil
|
47
|
+
Paperclip.stubs(:bit_bucket).returns("/dev/null")
|
48
|
+
Paperclip.stubs(:log)
|
49
|
+
Paperclip.stubs(:"`").with("this is the command 2>/dev/null")
|
50
|
+
end
|
51
|
+
|
52
|
+
should "log the command when :log_command is true" do
|
35
53
|
Paperclip.options[:log_command] = true
|
36
|
-
Paperclip.expects(:bit_bucket).returns("/dev/null")
|
37
|
-
Paperclip.expects(:log).with("this is the command 2>/dev/null")
|
38
|
-
Paperclip.expects(:"`").with("this is the command 2>/dev/null")
|
39
54
|
Paperclip.run("this","is the command")
|
55
|
+
assert_received(Paperclip, :log) do |p|
|
56
|
+
p.with("this is the command 2>/dev/null")
|
57
|
+
end
|
58
|
+
assert_received(Paperclip, :`) do |p|
|
59
|
+
p.with("this is the command 2>/dev/null")
|
60
|
+
end
|
40
61
|
end
|
41
|
-
end
|
42
|
-
|
43
|
-
should "raise when sent #processor and the name of a class that exists but isn't a subclass of Processor" do
|
44
|
-
assert_raises(Paperclip::PaperclipError){ Paperclip.processor(:attachment) }
|
45
|
-
end
|
46
|
-
|
47
|
-
should "raise when sent #processor and the name of a class that doesn't exist" do
|
48
|
-
assert_raises(NameError){ Paperclip.processor(:boogey_man) }
|
49
|
-
end
|
50
|
-
|
51
|
-
should "return a class when sent #processor and the name of a class under Paperclip" do
|
52
|
-
assert_equal ::Paperclip::Thumbnail, Paperclip.processor(:thumbnail)
|
53
|
-
end
|
54
62
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
63
|
+
should "not log the command when :log_command is false" do
|
64
|
+
Paperclip.options[:log_command] = false
|
65
|
+
Paperclip.run("this","is the command")
|
66
|
+
assert_received(Paperclip, :log) do |p|
|
67
|
+
p.with("this is the command 2>/dev/null").never
|
68
|
+
end
|
69
|
+
assert_received(Paperclip, :`) do |p|
|
70
|
+
p.with("this is the command 2>/dev/null")
|
71
|
+
end
|
72
|
+
end
|
65
73
|
end
|
66
74
|
|
67
75
|
context "Paperclip.bit_bucket" do
|
@@ -86,6 +94,18 @@ class PaperclipTest < Test::Unit::TestCase
|
|
86
94
|
end
|
87
95
|
end
|
88
96
|
|
97
|
+
should "raise when sent #processor and the name of a class that exists but isn't a subclass of Processor" do
|
98
|
+
assert_raises(Paperclip::PaperclipError){ Paperclip.processor(:attachment) }
|
99
|
+
end
|
100
|
+
|
101
|
+
should "raise when sent #processor and the name of a class that doesn't exist" do
|
102
|
+
assert_raises(NameError){ Paperclip.processor(:boogey_man) }
|
103
|
+
end
|
104
|
+
|
105
|
+
should "return a class when sent #processor and the name of a class under Paperclip" do
|
106
|
+
assert_equal ::Paperclip::Thumbnail, Paperclip.processor(:thumbnail)
|
107
|
+
end
|
108
|
+
|
89
109
|
context "An ActiveRecord model with an 'avatar' attachment" do
|
90
110
|
setup do
|
91
111
|
rebuild_model :path => "tmp/:class/omg/:style.:extension"
|
@@ -139,7 +159,8 @@ class PaperclipTest < Test::Unit::TestCase
|
|
139
159
|
end
|
140
160
|
|
141
161
|
should "be able to see the attachment definition from the subclass's class" do
|
142
|
-
assert_equal "tmp/:class/omg/:style.:extension",
|
162
|
+
assert_equal "tmp/:class/omg/:style.:extension",
|
163
|
+
SubDummy.attachment_definitions[:avatar][:path]
|
143
164
|
end
|
144
165
|
|
145
166
|
teardown do
|
@@ -286,6 +307,21 @@ class PaperclipTest < Test::Unit::TestCase
|
|
286
307
|
|
287
308
|
should_validate validation, options, valid_file, invalid_file
|
288
309
|
end
|
310
|
+
|
311
|
+
context "with size validation and less_than 10240 option" do
|
312
|
+
context "and assigned an invalid file" do
|
313
|
+
setup do
|
314
|
+
Dummy.send(:"validates_attachment_size", :avatar, :less_than => 10240)
|
315
|
+
@dummy = Dummy.new
|
316
|
+
@dummy.avatar &&= File.open(File.join(FIXTURES_DIR, "12k.png"), "rb")
|
317
|
+
@dummy.valid?
|
318
|
+
end
|
319
|
+
|
320
|
+
should "have a file size min/max error message" do
|
321
|
+
assert_match /between 0 and 10240 bytes/, @dummy.errors.on(:avatar)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
289
325
|
|
290
326
|
end
|
291
327
|
end
|
data/test/storage_test.rb
CHANGED
@@ -1,8 +1,16 @@
|
|
1
1
|
require 'test/helper'
|
2
|
+
require 'aws/s3'
|
2
3
|
|
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
|
+
|
4
11
|
context "Parsing S3 credentials" do
|
5
12
|
setup do
|
13
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
6
14
|
rebuild_model :storage => :s3,
|
7
15
|
:bucket => "testing",
|
8
16
|
:s3_credentials => {:not => :important}
|
@@ -14,31 +22,32 @@ class StorageTest < Test::Unit::TestCase
|
|
14
22
|
end
|
15
23
|
|
16
24
|
teardown do
|
17
|
-
|
25
|
+
rails_env(@current_env)
|
18
26
|
end
|
19
27
|
|
20
28
|
should "get the correct credentials when RAILS_ENV is production" do
|
21
|
-
|
29
|
+
rails_env("production")
|
22
30
|
assert_equal({:key => "12345"},
|
23
31
|
@avatar.parse_credentials('production' => {:key => '12345'},
|
24
32
|
:development => {:key => "54321"}))
|
25
33
|
end
|
26
34
|
|
27
35
|
should "get the correct credentials when RAILS_ENV is development" do
|
28
|
-
|
36
|
+
rails_env("development")
|
29
37
|
assert_equal({:key => "54321"},
|
30
38
|
@avatar.parse_credentials('production' => {:key => '12345'},
|
31
39
|
:development => {:key => "54321"}))
|
32
40
|
end
|
33
41
|
|
34
42
|
should "return the argument if the key does not exist" do
|
35
|
-
|
43
|
+
rails_env("not really an env")
|
36
44
|
assert_equal({:test => "12345"}, @avatar.parse_credentials(:test => "12345"))
|
37
45
|
end
|
38
46
|
end
|
39
47
|
|
40
48
|
context "" do
|
41
49
|
setup do
|
50
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
42
51
|
rebuild_model :storage => :s3,
|
43
52
|
:s3_credentials => {},
|
44
53
|
:bucket => "bucket",
|
@@ -54,6 +63,7 @@ class StorageTest < Test::Unit::TestCase
|
|
54
63
|
end
|
55
64
|
context "" do
|
56
65
|
setup do
|
66
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
57
67
|
rebuild_model :storage => :s3,
|
58
68
|
:s3_credentials => {},
|
59
69
|
:bucket => "bucket",
|
@@ -69,6 +79,7 @@ class StorageTest < Test::Unit::TestCase
|
|
69
79
|
end
|
70
80
|
context "" do
|
71
81
|
setup do
|
82
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
72
83
|
rebuild_model :storage => :s3,
|
73
84
|
:s3_credentials => {
|
74
85
|
:production => { :bucket => "prod_bucket" },
|
@@ -88,6 +99,7 @@ class StorageTest < Test::Unit::TestCase
|
|
88
99
|
|
89
100
|
context "Parsing S3 credentials with a bucket in them" do
|
90
101
|
setup do
|
102
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
91
103
|
rebuild_model :storage => :s3,
|
92
104
|
:s3_credentials => {
|
93
105
|
:production => { :bucket => "prod_bucket" },
|
@@ -97,15 +109,15 @@ class StorageTest < Test::Unit::TestCase
|
|
97
109
|
@old_env = RAILS_ENV
|
98
110
|
end
|
99
111
|
|
100
|
-
teardown{
|
112
|
+
teardown{ rails_env(@old_env) }
|
101
113
|
|
102
114
|
should "get the right bucket in production" do
|
103
|
-
|
115
|
+
rails_env("production")
|
104
116
|
assert_equal "prod_bucket", @dummy.avatar.bucket_name
|
105
117
|
end
|
106
118
|
|
107
119
|
should "get the right bucket in development" do
|
108
|
-
|
120
|
+
rails_env("development")
|
109
121
|
assert_equal "dev_bucket", @dummy.avatar.bucket_name
|
110
122
|
end
|
111
123
|
end
|
@@ -146,14 +158,7 @@ class StorageTest < Test::Unit::TestCase
|
|
146
158
|
|
147
159
|
context "and saved" do
|
148
160
|
setup do
|
149
|
-
@
|
150
|
-
@bucket_mock = stub
|
151
|
-
RightAws::S3.expects(:new).with("12345", "54321", {}).returns(@s3_mock)
|
152
|
-
@s3_mock.expects(:bucket).with("testing", true, "public-read").returns(@bucket_mock)
|
153
|
-
@key_mock = stub
|
154
|
-
@bucket_mock.expects(:key).returns(@key_mock)
|
155
|
-
@key_mock.expects(:data=)
|
156
|
-
@key_mock.expects(:put).with(nil, 'public-read', 'Content-type' => 'image/png')
|
161
|
+
AWS::S3::S3Object.stubs(:store).with(@dummy.avatar.path, anything, 'testing', :content_type => 'image/png', :access => :public_read)
|
157
162
|
@dummy.save
|
158
163
|
end
|
159
164
|
|
@@ -164,13 +169,8 @@ class StorageTest < Test::Unit::TestCase
|
|
164
169
|
|
165
170
|
context "and remove" do
|
166
171
|
setup do
|
167
|
-
|
168
|
-
|
169
|
-
RightAws::S3.expects(:new).with("12345", "54321", {}).returns(@s3_mock)
|
170
|
-
@s3_mock.expects(:bucket).with("testing", true, "public-read").returns(@bucket_mock)
|
171
|
-
@key_mock = stub
|
172
|
-
@bucket_mock.expects(:key).at_least(2).returns(@key_mock)
|
173
|
-
@key_mock.expects(:delete)
|
172
|
+
AWS::S3::S3Object.stubs(:exists?).returns(true)
|
173
|
+
AWS::S3::S3Object.stubs(:delete)
|
174
174
|
@dummy.destroy_attached_files
|
175
175
|
end
|
176
176
|
|
@@ -183,6 +183,7 @@ class StorageTest < Test::Unit::TestCase
|
|
183
183
|
|
184
184
|
context "An attachment with S3 storage and bucket defined as a Proc" do
|
185
185
|
setup do
|
186
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
186
187
|
rebuild_model :storage => :s3,
|
187
188
|
:bucket => lambda { |attachment| "bucket_#{attachment.instance.other}" },
|
188
189
|
:s3_credentials => {:not => :important}
|
@@ -196,6 +197,7 @@ class StorageTest < Test::Unit::TestCase
|
|
196
197
|
|
197
198
|
context "An attachment with S3 storage and specific s3 headers set" do
|
198
199
|
setup do
|
200
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
199
201
|
rebuild_model :storage => :s3,
|
200
202
|
:bucket => "testing",
|
201
203
|
:path => ":attachment/:style/:basename.:extension",
|
@@ -217,17 +219,13 @@ class StorageTest < Test::Unit::TestCase
|
|
217
219
|
|
218
220
|
context "and saved" do
|
219
221
|
setup do
|
220
|
-
|
221
|
-
@
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
@key_mock.expects(:put).with(nil,
|
228
|
-
'public-read',
|
229
|
-
'Content-type' => 'image/png',
|
230
|
-
'Cache-Control' => 'max-age=31557600')
|
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')
|
231
229
|
@dummy.save
|
232
230
|
end
|
233
231
|
|
@@ -263,8 +261,8 @@ class StorageTest < Test::Unit::TestCase
|
|
263
261
|
|
264
262
|
teardown { @file.close }
|
265
263
|
|
266
|
-
should "still return a Tempfile when sent #
|
267
|
-
assert_equal Tempfile, @dummy.avatar.
|
264
|
+
should "still return a Tempfile when sent #to_file" do
|
265
|
+
assert_equal Tempfile, @dummy.avatar.to_file.class
|
268
266
|
end
|
269
267
|
|
270
268
|
context "and saved" do
|
data/test/thumbnail_test.rb
CHANGED
@@ -103,6 +103,44 @@ class ThumbnailTest < Test::Unit::TestCase
|
|
103
103
|
end
|
104
104
|
end
|
105
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
|
+
|
106
144
|
context "being thumbnailed with convert options set" do
|
107
145
|
setup do
|
108
146
|
@thumb = Paperclip::Thumbnail.new(@file,
|
@@ -140,6 +178,18 @@ class ThumbnailTest < Test::Unit::TestCase
|
|
140
178
|
end
|
141
179
|
end
|
142
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
|
143
193
|
end
|
144
194
|
|
145
195
|
context "A multipage PDF" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paperclip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Yurek
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-08-21 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|