paperclip 5.1.0 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +17 -0
- data/.hound.yml +5 -16
- data/.travis.yml +14 -15
- data/Appraisals +3 -23
- data/Gemfile +1 -0
- data/NEWS +36 -1
- data/README.md +58 -10
- data/Rakefile +1 -1
- data/UPGRADING +1 -1
- data/features/step_definitions/attachment_steps.rb +6 -6
- data/features/step_definitions/rails_steps.rb +29 -22
- data/features/step_definitions/s3_steps.rb +1 -1
- data/features/support/env.rb +1 -0
- data/features/support/paths.rb +1 -1
- data/features/support/rails.rb +0 -24
- data/gemfiles/{4.2.awsv2.0.gemfile → 4.2.gemfile} +1 -1
- data/gemfiles/{5.0.awsv2.1.gemfile → 5.0.gemfile} +2 -2
- data/lib/paperclip.rb +12 -10
- data/lib/paperclip/attachment.rb +10 -4
- data/lib/paperclip/io_adapters/abstract_adapter.rb +24 -2
- data/lib/paperclip/io_adapters/attachment_adapter.rb +10 -5
- data/lib/paperclip/io_adapters/data_uri_adapter.rb +8 -8
- data/lib/paperclip/io_adapters/empty_string_adapter.rb +5 -4
- data/lib/paperclip/io_adapters/file_adapter.rb +12 -6
- data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +7 -7
- data/lib/paperclip/io_adapters/identity_adapter.rb +12 -6
- data/lib/paperclip/io_adapters/nil_adapter.rb +8 -5
- data/lib/paperclip/io_adapters/registry.rb +6 -2
- data/lib/paperclip/io_adapters/stringio_adapter.rb +9 -6
- data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +9 -5
- data/lib/paperclip/io_adapters/uri_adapter.rb +13 -11
- data/lib/paperclip/storage/filesystem.rb +13 -2
- data/lib/paperclip/storage/fog.rb +7 -4
- data/lib/paperclip/storage/s3.rb +31 -3
- data/lib/paperclip/thumbnail.rb +14 -4
- data/lib/paperclip/version.rb +1 -1
- data/lib/tasks/paperclip.rake +17 -3
- data/paperclip.gemspec +3 -3
- data/spec/paperclip/attachment_spec.rb +39 -8
- data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +44 -21
- data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +6 -3
- data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +7 -1
- data/spec/paperclip/io_adapters/file_adapter_spec.rb +2 -2
- data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +6 -1
- data/spec/paperclip/io_adapters/identity_adapter_spec.rb +1 -1
- data/spec/paperclip/io_adapters/registry_spec.rb +2 -2
- data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +1 -1
- data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +3 -3
- data/spec/paperclip/io_adapters/uri_adapter_spec.rb +6 -1
- data/spec/paperclip/storage/fog_spec.rb +16 -0
- data/spec/paperclip/storage/s3_live_spec.rb +12 -10
- data/spec/paperclip/storage/s3_spec.rb +85 -4
- data/spec/paperclip/tempfile_spec.rb +35 -0
- data/spec/paperclip/thumbnail_spec.rb +35 -32
- data/spec/spec_helper.rb +3 -1
- data/spec/support/assertions.rb +5 -1
- data/spec/support/conditional_filter_helper.rb +5 -0
- metadata +31 -135
- data/gemfiles/4.2.awsv2.1.gemfile +0 -17
- data/gemfiles/4.2.awsv2.gemfile +0 -20
- data/gemfiles/5.0.awsv2.0.gemfile +0 -17
- data/gemfiles/5.0.awsv2.gemfile +0 -20
@@ -1,7 +1,13 @@
|
|
1
1
|
module Paperclip
|
2
2
|
class UploadedFileAdapter < AbstractAdapter
|
3
|
-
def
|
4
|
-
|
3
|
+
def self.register
|
4
|
+
Paperclip.io_adapters.register self do |target|
|
5
|
+
target.class.name.include?("UploadedFile")
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(target, options = {})
|
10
|
+
super
|
5
11
|
cache_current_values
|
6
12
|
|
7
13
|
if @target.respond_to?(:tempfile)
|
@@ -37,6 +43,4 @@ module Paperclip
|
|
37
43
|
end
|
38
44
|
end
|
39
45
|
|
40
|
-
Paperclip.
|
41
|
-
target.class.name.include?("UploadedFile")
|
42
|
-
end
|
46
|
+
Paperclip::UploadedFileAdapter.register
|
@@ -1,11 +1,17 @@
|
|
1
|
-
require
|
1
|
+
require "open-uri"
|
2
2
|
|
3
3
|
module Paperclip
|
4
4
|
class UriAdapter < AbstractAdapter
|
5
5
|
attr_writer :content_type
|
6
6
|
|
7
|
-
def
|
8
|
-
|
7
|
+
def self.register
|
8
|
+
Paperclip.io_adapters.register self do |target|
|
9
|
+
target.is_a?(URI)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(target, options = {})
|
14
|
+
super
|
9
15
|
@content = download_content
|
10
16
|
cache_current_values
|
11
17
|
@tempfile = copy_to_tempfile(@content)
|
@@ -28,9 +34,9 @@ module Paperclip
|
|
28
34
|
end
|
29
35
|
|
30
36
|
def filename_from_content_disposition
|
31
|
-
if @content.meta.
|
32
|
-
@content.meta["content-disposition"].
|
33
|
-
|
37
|
+
if @content.meta.key?("content-disposition")
|
38
|
+
matches = @content.meta["content-disposition"].match(/filename="([^"]*)"/)
|
39
|
+
matches[1] if matches
|
34
40
|
end
|
35
41
|
end
|
36
42
|
|
@@ -49,7 +55,7 @@ module Paperclip
|
|
49
55
|
end
|
50
56
|
|
51
57
|
def copy_to_tempfile(src)
|
52
|
-
while data = src.read(16*1024)
|
58
|
+
while data = src.read(16 * 1024)
|
53
59
|
destination.write(data)
|
54
60
|
end
|
55
61
|
src.close
|
@@ -58,7 +64,3 @@ module Paperclip
|
|
58
64
|
end
|
59
65
|
end
|
60
66
|
end
|
61
|
-
|
62
|
-
Paperclip.io_adapters.register Paperclip::UriAdapter do |target|
|
63
|
-
target.kind_of?(URI)
|
64
|
-
end
|
@@ -37,7 +37,7 @@ module Paperclip
|
|
37
37
|
@queued_for_write.each do |style_name, file|
|
38
38
|
FileUtils.mkdir_p(File.dirname(path(style_name)))
|
39
39
|
begin
|
40
|
-
|
40
|
+
move_file(file.path, path(style_name))
|
41
41
|
rescue SystemCallError
|
42
42
|
File.open(path(style_name), "wb") do |new_file|
|
43
43
|
while chunk = file.read(16 * 1024)
|
@@ -46,7 +46,7 @@ module Paperclip
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
unless @options[:override_file_permissions] == false
|
49
|
-
resolved_chmod = (@options[:override_file_permissions]
|
49
|
+
resolved_chmod = (@options[:override_file_permissions] & ~0111) || (0666 & ~File.umask)
|
50
50
|
FileUtils.chmod( resolved_chmod, path(style_name) )
|
51
51
|
end
|
52
52
|
file.rewind
|
@@ -84,6 +84,17 @@ module Paperclip
|
|
84
84
|
def copy_to_local_file(style, local_dest_path)
|
85
85
|
FileUtils.cp(path(style), local_dest_path)
|
86
86
|
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def move_file(src, dest)
|
91
|
+
# Support hardlinked files
|
92
|
+
if File.identical?(src, dest)
|
93
|
+
File.unlink(src)
|
94
|
+
else
|
95
|
+
FileUtils.mv(src, dest)
|
96
|
+
end
|
97
|
+
end
|
87
98
|
end
|
88
99
|
|
89
100
|
end
|
@@ -86,11 +86,14 @@ module Paperclip
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def fog_public(style = default_style)
|
89
|
-
if @options.
|
90
|
-
|
91
|
-
|
89
|
+
if @options.key?(:fog_public)
|
90
|
+
value = @options[:fog_public]
|
91
|
+
if value.respond_to?(:key?) && value.key?(style)
|
92
|
+
value[style]
|
93
|
+
elsif value.respond_to?(:call)
|
94
|
+
value.call(self)
|
92
95
|
else
|
93
|
-
|
96
|
+
value
|
94
97
|
end
|
95
98
|
else
|
96
99
|
true
|
data/lib/paperclip/storage/s3.rb
CHANGED
@@ -45,10 +45,10 @@ module Paperclip
|
|
45
45
|
#
|
46
46
|
# You can set permission on a per style bases by doing the following:
|
47
47
|
# :s3_permissions => {
|
48
|
-
# :original =>
|
48
|
+
# :original => "private"
|
49
49
|
# }
|
50
50
|
# Or globally:
|
51
|
-
# :s3_permissions =>
|
51
|
+
# :s3_permissions => "private"
|
52
52
|
#
|
53
53
|
# * +s3_protocol+: The protocol for the URLs generated to your S3 assets.
|
54
54
|
# Can be either 'http', 'https', or an empty string to generate
|
@@ -65,6 +65,9 @@ module Paperclip
|
|
65
65
|
# * +s3_host_alias+: The fully-qualified domain name (FQDN) that is the alias to the
|
66
66
|
# S3 domain of your bucket. Used with the :s3_alias_url url interpolation. See the
|
67
67
|
# link in the +url+ entry for more information about S3 domains and buckets.
|
68
|
+
# * +s3_prefixes_in_alias+: The number of prefixes that is prepended by
|
69
|
+
# s3_host_alias. This will remove the prefixes from the path in
|
70
|
+
# :s3_alias_url url interpolation
|
68
71
|
# * +url+: There are four options for the S3 url. You can choose to have the bucket's name
|
69
72
|
# placed domain-style (bucket.s3.amazonaws.com) or path-style (s3.amazonaws.com/bucket).
|
70
73
|
# You can also specify a CNAME (which requires the CNAME to be specified as
|
@@ -102,6 +105,8 @@ module Paperclip
|
|
102
105
|
# Redundancy Storage. RRS enables customers to reduce their
|
103
106
|
# costs by storing non-critical, reproducible data at lower
|
104
107
|
# levels of redundancy than Amazon S3's standard storage.
|
108
|
+
# * +use_accelerate_endpoint+: Use accelerate endpoint
|
109
|
+
# http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html
|
105
110
|
#
|
106
111
|
# You can set storage class on a per style bases by doing the following:
|
107
112
|
# :s3_storage_class => {
|
@@ -152,10 +157,23 @@ module Paperclip
|
|
152
157
|
@options[:url] = @options[:url].inspect if @options[:url].is_a?(Symbol)
|
153
158
|
|
154
159
|
@http_proxy = @options[:http_proxy] || nil
|
160
|
+
|
161
|
+
if @options.has_key?(:use_accelerate_endpoint) &&
|
162
|
+
Gem::Version.new(Aws::VERSION) < Gem::Version.new("2.3.0")
|
163
|
+
raise LoadError, ":use_accelerate_endpoint is only available from aws-sdk version 2.3.0. Please upgrade aws-sdk to a newer version."
|
164
|
+
end
|
165
|
+
|
166
|
+
@use_accelerate_endpoint = @options[:use_accelerate_endpoint]
|
155
167
|
end
|
156
168
|
|
157
169
|
Paperclip.interpolates(:s3_alias_url) do |attachment, style|
|
158
|
-
|
170
|
+
protocol = attachment.s3_protocol(style, true)
|
171
|
+
host = attachment.s3_host_alias
|
172
|
+
path = attachment.path(style).
|
173
|
+
split("/")[attachment.s3_prefixes_in_alias..-1].
|
174
|
+
join("/").
|
175
|
+
sub(%r{\A/}, "".freeze)
|
176
|
+
"#{protocol}//#{host}/#{path}"
|
159
177
|
end unless Paperclip::Interpolations.respond_to? :s3_alias_url
|
160
178
|
Paperclip.interpolates(:s3_path_url) do |attachment, style|
|
161
179
|
"#{attachment.s3_protocol(style, true)}//#{attachment.s3_host_name}/#{attachment.bucket_name}/#{attachment.path(style).sub(%r{\A/}, "".freeze)}"
|
@@ -204,6 +222,10 @@ module Paperclip
|
|
204
222
|
@s3_host_alias
|
205
223
|
end
|
206
224
|
|
225
|
+
def s3_prefixes_in_alias
|
226
|
+
@s3_prefixes_in_alias ||= @options[:s3_prefixes_in_alias].to_i
|
227
|
+
end
|
228
|
+
|
207
229
|
def s3_url_options
|
208
230
|
s3_url_options = @options[:s3_url_options] || {}
|
209
231
|
s3_url_options = s3_url_options.call(instance) if s3_url_options.respond_to?(:call)
|
@@ -232,6 +254,8 @@ module Paperclip
|
|
232
254
|
config[:proxy_uri] = URI::HTTP.build(proxy_opts)
|
233
255
|
end
|
234
256
|
|
257
|
+
config[:use_accelerate_endpoint] = use_accelerate_endpoint?
|
258
|
+
|
235
259
|
[:access_key_id, :secret_access_key, :credential_provider, :credentials].each do |opt|
|
236
260
|
config[opt] = s3_credentials[opt] if s3_credentials[opt]
|
237
261
|
end
|
@@ -257,6 +281,10 @@ module Paperclip
|
|
257
281
|
s3_bucket.object style_name_as_path(style_name)
|
258
282
|
end
|
259
283
|
|
284
|
+
def use_accelerate_endpoint?
|
285
|
+
!!@use_accelerate_endpoint
|
286
|
+
end
|
287
|
+
|
260
288
|
def using_http_proxy?
|
261
289
|
!!@http_proxy
|
262
290
|
end
|
data/lib/paperclip/thumbnail.rb
CHANGED
@@ -3,10 +3,11 @@ module Paperclip
|
|
3
3
|
class Thumbnail < Processor
|
4
4
|
|
5
5
|
attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options,
|
6
|
-
:source_file_options, :animated, :auto_orient
|
6
|
+
:source_file_options, :animated, :auto_orient, :frame_index
|
7
7
|
|
8
8
|
# List of formats that we need to preserve animation
|
9
9
|
ANIMATED_FORMATS = %w(gif)
|
10
|
+
MULTI_FRAME_FORMATS = %w(.mkv .avi .mp4 .mov .mpg .mpeg .gif)
|
10
11
|
|
11
12
|
# Creates a Thumbnail object set to work on the +file+ given. It
|
12
13
|
# will attempt to transform the image into one defined by +target_geometry+
|
@@ -25,6 +26,7 @@ module Paperclip
|
|
25
26
|
# +whiny+ - whether to raise an error when processing fails. Defaults to true
|
26
27
|
# +format+ - the desired filename extension
|
27
28
|
# +animated+ - whether to merge all the layers in the image. Defaults to true
|
29
|
+
# +frame_index+ - the frame index of the source file to render as the thumbnail
|
28
30
|
def initialize(file, options = {}, attachment = nil)
|
29
31
|
super
|
30
32
|
|
@@ -41,12 +43,12 @@ module Paperclip
|
|
41
43
|
if @auto_orient && @current_geometry.respond_to?(:auto_orient)
|
42
44
|
@current_geometry.auto_orient
|
43
45
|
end
|
44
|
-
|
45
46
|
@source_file_options = @source_file_options.split(/\s+/) if @source_file_options.respond_to?(:split)
|
46
47
|
@convert_options = @convert_options.split(/\s+/) if @convert_options.respond_to?(:split)
|
47
48
|
|
48
49
|
@current_format = File.extname(@file.path)
|
49
50
|
@basename = File.basename(@file.path, @current_format)
|
51
|
+
@frame_index = multi_frame_format? ? options.fetch(:frame_index, 0) : 0
|
50
52
|
end
|
51
53
|
|
52
54
|
# Returns true if the +target_geometry+ is meant to crop.
|
@@ -76,7 +78,12 @@ module Paperclip
|
|
76
78
|
|
77
79
|
parameters = parameters.flatten.compact.join(" ").strip.squeeze(" ")
|
78
80
|
|
79
|
-
|
81
|
+
frame = animated? ? "" : "[#{@frame_index}]"
|
82
|
+
convert(
|
83
|
+
parameters,
|
84
|
+
source: "#{File.expand_path(src.path)}#{frame}",
|
85
|
+
dest: File.expand_path(dst.path),
|
86
|
+
)
|
80
87
|
rescue Cocaine::ExitStatusError => e
|
81
88
|
raise Paperclip::Error, "There was an error processing the thumbnail for #{@basename}" if @whiny
|
82
89
|
rescue Cocaine::CommandNotFoundError => e
|
@@ -101,7 +108,10 @@ module Paperclip
|
|
101
108
|
|
102
109
|
protected
|
103
110
|
|
104
|
-
|
111
|
+
def multi_frame_format?
|
112
|
+
MULTI_FRAME_FORMATS.include? @current_format
|
113
|
+
end
|
114
|
+
|
105
115
|
def animated?
|
106
116
|
@animated && (ANIMATED_FORMATS.include?(@format.to_s) || @format.blank?) && identified_as_animated?
|
107
117
|
end
|
data/lib/paperclip/version.rb
CHANGED
data/lib/tasks/paperclip.rake
CHANGED
@@ -46,7 +46,7 @@ namespace :paperclip do
|
|
46
46
|
attachment = instance.send(name)
|
47
47
|
begin
|
48
48
|
attachment.reprocess!(*styles)
|
49
|
-
rescue
|
49
|
+
rescue StandardError => e
|
50
50
|
Paperclip::Task.log_error("exception while processing #{klass} ID #{instance.id}:")
|
51
51
|
Paperclip::Task.log_error(" " + e.message + "\n")
|
52
52
|
end
|
@@ -64,7 +64,8 @@ namespace :paperclip do
|
|
64
64
|
names = Paperclip::Task.obtain_attachments(klass)
|
65
65
|
names.each do |name|
|
66
66
|
Paperclip.each_instance_with_attachment(klass, name) do |instance|
|
67
|
-
|
67
|
+
attachment = instance.send(name)
|
68
|
+
if file = Paperclip.io_adapters.for(attachment, attachment.options[:adapter_options])
|
68
69
|
instance.send("#{name}_file_name=", instance.send("#{name}_file_name").strip)
|
69
70
|
instance.send("#{name}_content_type=", file.content_type.to_s.strip)
|
70
71
|
instance.send("#{name}_file_size=", file.size) if instance.respond_to?("#{name}_file_size")
|
@@ -90,6 +91,19 @@ namespace :paperclip do
|
|
90
91
|
end
|
91
92
|
Paperclip.save_current_attachments_styles!
|
92
93
|
end
|
94
|
+
|
95
|
+
desc "Regenerates fingerprints for a given CLASS (and optional ATTACHMENT). Useful when changing digest."
|
96
|
+
task :fingerprints => :environment do
|
97
|
+
klass = Paperclip::Task.obtain_class
|
98
|
+
names = Paperclip::Task.obtain_attachments(klass)
|
99
|
+
names.each do |name|
|
100
|
+
Paperclip.each_instance_with_attachment(klass, name) do |instance|
|
101
|
+
attachment = instance.send(name)
|
102
|
+
attachment.assign(attachment)
|
103
|
+
instance.save(:validate => false)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
93
107
|
end
|
94
108
|
|
95
109
|
desc "Cleans out invalid attachments. Useful after you've added new validations."
|
@@ -109,7 +123,7 @@ namespace :paperclip do
|
|
109
123
|
end
|
110
124
|
end
|
111
125
|
|
112
|
-
|
126
|
+
desc "find missing attachments. Useful to know which attachments are broken"
|
113
127
|
task :find_broken_attachments => :environment do
|
114
128
|
klass = Paperclip::Task.obtain_class
|
115
129
|
names = Paperclip::Task.obtain_attachments(klass)
|
data/paperclip.gemspec
CHANGED
@@ -35,9 +35,10 @@ Gem::Specification.new do |s|
|
|
35
35
|
s.add_development_dependency('rspec', '~> 3.0')
|
36
36
|
s.add_development_dependency('appraisal')
|
37
37
|
s.add_development_dependency('mocha')
|
38
|
-
s.add_development_dependency('aws-sdk', '>= 2.0
|
38
|
+
s.add_development_dependency('aws-sdk', '>= 2.3.0', '< 3.0')
|
39
39
|
s.add_development_dependency('bourne')
|
40
|
-
s.add_development_dependency('cucumber'
|
40
|
+
s.add_development_dependency('cucumber-rails')
|
41
|
+
s.add_development_dependency('cucumber-expressions', '4.0.3') # TODO: investigate failures on 4.0.4
|
41
42
|
s.add_development_dependency('aruba', '~> 0.9.0')
|
42
43
|
s.add_development_dependency('nokogiri')
|
43
44
|
s.add_development_dependency('capybara')
|
@@ -48,7 +49,6 @@ Gem::Specification.new do |s|
|
|
48
49
|
s.add_development_dependency('rake')
|
49
50
|
s.add_development_dependency('fakeweb')
|
50
51
|
s.add_development_dependency('railties')
|
51
|
-
s.add_development_dependency('actionmailer', '>= 4.2.0')
|
52
52
|
s.add_development_dependency('generator_spec')
|
53
53
|
s.add_development_dependency('timecop')
|
54
54
|
end
|
@@ -500,6 +500,7 @@ describe Paperclip::Attachment do
|
|
500
500
|
@attachment.expects(:post_process).with(:thumb)
|
501
501
|
@attachment.expects(:post_process).with(:large).never
|
502
502
|
@attachment.assign(@file)
|
503
|
+
@attachment.save
|
503
504
|
end
|
504
505
|
end
|
505
506
|
|
@@ -1433,16 +1434,46 @@ describe Paperclip::Attachment do
|
|
1433
1434
|
assert_nothing_raised { @dummy.avatar = @file }
|
1434
1435
|
end
|
1435
1436
|
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1437
|
+
context "with explicitly set digest" do
|
1438
|
+
before do
|
1439
|
+
rebuild_class adapter_options: { hash_digest: Digest::SHA256 }
|
1440
|
+
@dummy = Dummy.new
|
1441
|
+
end
|
1442
|
+
|
1443
|
+
it "returns the right value when sent #avatar_fingerprint" do
|
1444
|
+
@dummy.avatar = @file
|
1445
|
+
assert_equal "734016d801a497f5579cdd4ef2ae1d020088c1db754dc434482d76dd5486520a",
|
1446
|
+
@dummy.avatar_fingerprint
|
1447
|
+
end
|
1448
|
+
|
1449
|
+
it "returns the right value when saved, reloaded, and sent #avatar_fingerprint" do
|
1450
|
+
@dummy.avatar = @file
|
1451
|
+
@dummy.save
|
1452
|
+
@dummy = Dummy.find(@dummy.id)
|
1453
|
+
assert_equal "734016d801a497f5579cdd4ef2ae1d020088c1db754dc434482d76dd5486520a",
|
1454
|
+
@dummy.avatar_fingerprint
|
1455
|
+
end
|
1439
1456
|
end
|
1440
1457
|
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1458
|
+
context "with the default digest" do
|
1459
|
+
before do
|
1460
|
+
rebuild_class # MD5 is the default
|
1461
|
+
@dummy = Dummy.new
|
1462
|
+
end
|
1463
|
+
|
1464
|
+
it "returns the right value when sent #avatar_fingerprint" do
|
1465
|
+
@dummy.avatar = @file
|
1466
|
+
assert_equal "aec488126c3b33c08a10c3fa303acf27",
|
1467
|
+
@dummy.avatar_fingerprint
|
1468
|
+
end
|
1469
|
+
|
1470
|
+
it "returns the right value when saved, reloaded, and sent #avatar_fingerprint" do
|
1471
|
+
@dummy.avatar = @file
|
1472
|
+
@dummy.save
|
1473
|
+
@dummy = Dummy.find(@dummy.id)
|
1474
|
+
assert_equal "aec488126c3b33c08a10c3fa303acf27",
|
1475
|
+
@dummy.avatar_fingerprint
|
1476
|
+
end
|
1446
1477
|
end
|
1447
1478
|
end
|
1448
1479
|
end
|
@@ -9,70 +9,93 @@ describe Paperclip::AbstractAdapter do
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
subject { TestAdapter.new(nil) }
|
13
|
+
|
12
14
|
context "content type from file contents" do
|
13
15
|
before do
|
14
|
-
|
15
|
-
@adapter.stubs(:path).returns("image.png")
|
16
|
+
subject.stubs(:path).returns("image.png")
|
16
17
|
Paperclip.stubs(:run).returns("image/png\n")
|
17
18
|
Paperclip::ContentTypeDetector.any_instance.stubs(:type_from_mime_magic).returns("image/png")
|
18
19
|
end
|
19
20
|
|
20
21
|
it "returns the content type without newline" do
|
21
|
-
assert_equal "image/png",
|
22
|
+
assert_equal "image/png", subject.content_type
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
25
26
|
context "nil?" do
|
26
27
|
it "returns false" do
|
27
|
-
assert !
|
28
|
+
assert !subject.nil?
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
31
32
|
context "delegation" do
|
32
33
|
before do
|
33
|
-
|
34
|
-
@adapter.tempfile = stub("Tempfile")
|
34
|
+
subject.tempfile = stub("Tempfile")
|
35
35
|
end
|
36
36
|
|
37
37
|
[:binmode, :binmode?, :close, :close!, :closed?, :eof?, :path, :readbyte, :rewind, :unlink].each do |method|
|
38
38
|
it "delegates #{method} to @tempfile" do
|
39
|
-
|
40
|
-
|
41
|
-
assert_received
|
39
|
+
subject.tempfile.stubs(method)
|
40
|
+
subject.public_send(method)
|
41
|
+
assert_received subject.tempfile, method
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'gets rid of slashes and colons in filenames' do
|
47
|
-
|
48
|
-
@adapter.original_filename = "awesome/file:name.png"
|
47
|
+
subject.original_filename = "awesome/file:name.png"
|
49
48
|
|
50
|
-
assert_equal "awesome_file_name.png",
|
49
|
+
assert_equal "awesome_file_name.png", subject.original_filename
|
51
50
|
end
|
52
51
|
|
53
52
|
it 'is an assignment' do
|
54
|
-
assert
|
53
|
+
assert subject.assignment?
|
55
54
|
end
|
56
55
|
|
57
56
|
it 'is not nil' do
|
58
|
-
assert !
|
57
|
+
assert !subject.nil?
|
59
58
|
end
|
60
59
|
|
61
60
|
it "generates a destination filename with no original filename" do
|
62
|
-
|
63
|
-
expect(@adapter.send(:destination).path).to_not be_nil
|
61
|
+
expect(subject.send(:destination).path).to_not be_nil
|
64
62
|
end
|
65
63
|
|
66
64
|
it 'uses the original filename to generate the tempfile' do
|
67
|
-
|
68
|
-
|
69
|
-
|
65
|
+
subject.original_filename = "file.png"
|
66
|
+
expect(subject.send(:destination).path).to end_with(".png")
|
67
|
+
end
|
68
|
+
|
69
|
+
context "generates a fingerprint" do
|
70
|
+
subject { TestAdapter.new(nil, options) }
|
71
|
+
|
72
|
+
before do
|
73
|
+
subject.stubs(:path).returns(fixture_file("50x50.png"))
|
74
|
+
end
|
75
|
+
|
76
|
+
context "MD5" do
|
77
|
+
let(:options) { { hash_digest: Digest::MD5 } }
|
78
|
+
|
79
|
+
it "returns a fingerprint" do
|
80
|
+
expect(subject.fingerprint).to be_a String
|
81
|
+
expect(subject.fingerprint).to eq "a790b00c9b5d58a8fd17a1ec5a187129"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "SHA256" do
|
86
|
+
let(:options) { { hash_digest: Digest::SHA256 } }
|
87
|
+
|
88
|
+
it "returns a fingerprint" do
|
89
|
+
expect(subject.fingerprint).to be_a String
|
90
|
+
expect(subject.fingerprint).
|
91
|
+
to eq "243d7ce1099719df25f600f1c369c629fb979f88d5a01dbe7d0d48c8e6715bb1"
|
92
|
+
end
|
93
|
+
end
|
70
94
|
end
|
71
95
|
|
72
96
|
context "#original_filename=" do
|
73
97
|
it "should not fail with a nil original filename" do
|
74
|
-
|
75
|
-
expect{ adapter.original_filename = nil }.not_to raise_error
|
98
|
+
expect { subject.original_filename = nil }.not_to raise_error
|
76
99
|
end
|
77
100
|
end
|
78
101
|
end
|