paperclip 4.3.7 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +17 -0
  3. data/.github/issue_template.md +3 -0
  4. data/.hound.yml +5 -16
  5. data/.travis.yml +15 -12
  6. data/Appraisals +4 -8
  7. data/CONTRIBUTING.md +16 -5
  8. data/Gemfile +3 -8
  9. data/LICENSE +1 -1
  10. data/MIGRATING-ES.md +317 -0
  11. data/MIGRATING.md +375 -0
  12. data/NEWS +126 -31
  13. data/README.md +264 -156
  14. data/Rakefile +1 -1
  15. data/UPGRADING +12 -9
  16. data/features/basic_integration.feature +3 -2
  17. data/features/migration.feature +0 -24
  18. data/features/step_definitions/attachment_steps.rb +14 -14
  19. data/features/step_definitions/rails_steps.rb +29 -28
  20. data/features/step_definitions/s3_steps.rb +2 -2
  21. data/features/support/env.rb +1 -0
  22. data/features/support/paths.rb +1 -1
  23. data/features/support/rails.rb +0 -24
  24. data/gemfiles/4.2.gemfile +3 -5
  25. data/gemfiles/{3.2.gemfile → 5.0.gemfile} +4 -6
  26. data/lib/generators/paperclip/paperclip_generator.rb +9 -1
  27. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +1 -1
  28. data/lib/paperclip.rb +14 -12
  29. data/lib/paperclip/attachment.rb +44 -20
  30. data/lib/paperclip/attachment_registry.rb +2 -1
  31. data/lib/paperclip/callbacks.rb +8 -6
  32. data/lib/paperclip/content_type_detector.rb +3 -2
  33. data/lib/paperclip/errors.rb +3 -1
  34. data/lib/paperclip/file_command_content_type_detector.rb +1 -1
  35. data/lib/paperclip/filename_cleaner.rb +0 -1
  36. data/lib/paperclip/geometry_detector_factory.rb +3 -3
  37. data/lib/paperclip/glue.rb +1 -1
  38. data/lib/paperclip/has_attached_file.rb +7 -1
  39. data/lib/paperclip/helpers.rb +15 -11
  40. data/lib/paperclip/interpolations.rb +7 -2
  41. data/lib/paperclip/io_adapters/abstract_adapter.rb +31 -4
  42. data/lib/paperclip/io_adapters/attachment_adapter.rb +17 -6
  43. data/lib/paperclip/io_adapters/data_uri_adapter.rb +8 -8
  44. data/lib/paperclip/io_adapters/empty_string_adapter.rb +5 -4
  45. data/lib/paperclip/io_adapters/file_adapter.rb +12 -6
  46. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +8 -7
  47. data/lib/paperclip/io_adapters/identity_adapter.rb +12 -6
  48. data/lib/paperclip/io_adapters/nil_adapter.rb +8 -5
  49. data/lib/paperclip/io_adapters/registry.rb +6 -2
  50. data/lib/paperclip/io_adapters/stringio_adapter.rb +9 -6
  51. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +10 -6
  52. data/lib/paperclip/io_adapters/uri_adapter.rb +22 -17
  53. data/lib/paperclip/logger.rb +1 -1
  54. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +4 -4
  55. data/lib/paperclip/media_type_spoof_detector.rb +11 -7
  56. data/lib/paperclip/processor.rb +15 -6
  57. data/lib/paperclip/schema.rb +3 -9
  58. data/lib/paperclip/storage/filesystem.rb +13 -2
  59. data/lib/paperclip/storage/fog.rb +21 -14
  60. data/lib/paperclip/storage/s3.rb +81 -61
  61. data/lib/paperclip/style.rb +0 -1
  62. data/lib/paperclip/thumbnail.rb +22 -9
  63. data/lib/paperclip/url_generator.rb +17 -13
  64. data/lib/paperclip/validators.rb +1 -1
  65. data/lib/paperclip/validators/attachment_size_validator.rb +1 -7
  66. data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +4 -0
  67. data/lib/paperclip/version.rb +3 -1
  68. data/lib/tasks/paperclip.rake +18 -4
  69. data/paperclip.gemspec +13 -10
  70. data/spec/paperclip/attachment_processing_spec.rb +2 -5
  71. data/spec/paperclip/attachment_registry_spec.rb +28 -0
  72. data/spec/paperclip/attachment_spec.rb +89 -20
  73. data/spec/paperclip/content_type_detector_spec.rb +1 -1
  74. data/spec/paperclip/file_command_content_type_detector_spec.rb +15 -1
  75. data/spec/paperclip/filename_cleaner_spec.rb +0 -1
  76. data/spec/paperclip/has_attached_file_spec.rb +24 -8
  77. data/spec/paperclip/integration_spec.rb +42 -5
  78. data/spec/paperclip/interpolations_spec.rb +9 -0
  79. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +104 -22
  80. data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +6 -3
  81. data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +7 -1
  82. data/spec/paperclip/io_adapters/file_adapter_spec.rb +2 -2
  83. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +47 -13
  84. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +1 -1
  85. data/spec/paperclip/io_adapters/registry_spec.rb +2 -2
  86. data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +1 -1
  87. data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +5 -5
  88. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +104 -11
  89. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +10 -0
  90. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +1 -1
  91. data/spec/paperclip/media_type_spoof_detector_spec.rb +41 -0
  92. data/spec/paperclip/paperclip_spec.rb +15 -45
  93. data/spec/paperclip/processor_spec.rb +4 -4
  94. data/spec/paperclip/schema_spec.rb +46 -46
  95. data/spec/paperclip/storage/fog_spec.rb +31 -0
  96. data/spec/paperclip/storage/s3_live_spec.rb +20 -14
  97. data/spec/paperclip/storage/s3_spec.rb +359 -192
  98. data/spec/paperclip/style_spec.rb +0 -1
  99. data/spec/paperclip/tempfile_spec.rb +35 -0
  100. data/spec/paperclip/thumbnail_spec.rb +43 -38
  101. data/spec/paperclip/url_generator_spec.rb +54 -44
  102. data/spec/paperclip/validators/attachment_size_validator_spec.rb +26 -20
  103. data/spec/paperclip/validators_spec.rb +5 -5
  104. data/spec/spec_helper.rb +5 -2
  105. data/spec/support/assertions.rb +12 -1
  106. data/spec/support/mock_attachment.rb +2 -0
  107. data/spec/support/mock_url_generator_builder.rb +2 -2
  108. data/spec/support/model_reconstruction.rb +11 -3
  109. data/spec/support/reporting.rb +11 -0
  110. metadata +64 -61
  111. data/cucumber/paperclip_steps.rb +0 -6
  112. data/gemfiles/4.1.gemfile +0 -19
  113. data/lib/paperclip/deprecations.rb +0 -42
  114. data/lib/paperclip/locales/de.yml +0 -18
  115. data/lib/paperclip/locales/es.yml +0 -18
  116. data/lib/paperclip/locales/ja.yml +0 -18
  117. data/lib/paperclip/locales/pt-BR.yml +0 -18
  118. data/lib/paperclip/locales/zh-CN.yml +0 -18
  119. data/lib/paperclip/locales/zh-HK.yml +0 -18
  120. data/lib/paperclip/locales/zh-TW.yml +0 -18
  121. data/spec/paperclip/deprecations_spec.rb +0 -65
  122. data/spec/support/deprecations.rb +0 -9
  123. data/spec/support/rails_helpers.rb +0 -7
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  module Paperclip
3
2
  # The Style class holds the definition of a thumbnail style, applying
4
3
  # whatever processing is required to normalize the definition and delaying
@@ -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,10 +78,18 @@ module Paperclip
76
78
 
77
79
  parameters = parameters.flatten.compact.join(" ").strip.squeeze(" ")
78
80
 
79
- success = convert(parameters, :source => "#{File.expand_path(src.path)}#{'[0]' unless animated?}", :dest => File.expand_path(dst.path))
80
- rescue Cocaine::ExitStatusError => e
81
- raise Paperclip::Error, "There was an error processing the thumbnail for #{@basename}" if @whiny
82
- rescue Cocaine::CommandNotFoundError => e
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
+ )
87
+ rescue Terrapin::ExitStatusError => e
88
+ if @whiny
89
+ message = "There was an error processing the thumbnail for #{@basename}:\n" + e.message
90
+ raise Paperclip::Error, message
91
+ end
92
+ rescue Terrapin::CommandNotFoundError => e
83
93
  raise Paperclip::Errors::CommandNotFoundError.new("Could not run the `convert` command. Please install ImageMagick.")
84
94
  end
85
95
 
@@ -101,7 +111,10 @@ module Paperclip
101
111
 
102
112
  protected
103
113
 
104
- # Return true if the format is animated
114
+ def multi_frame_format?
115
+ MULTI_FRAME_FORMATS.include? @current_format
116
+ end
117
+
105
118
  def animated?
106
119
  @animated && (ANIMATED_FORMATS.include?(@format.to_s) || @format.blank?) && identified_as_animated?
107
120
  end
@@ -112,9 +125,9 @@ module Paperclip
112
125
  @identified_as_animated = ANIMATED_FORMATS.include? identify("-format %m :file", :file => "#{@file.path}[0]").to_s.downcase.strip
113
126
  end
114
127
  @identified_as_animated
115
- rescue Cocaine::ExitStatusError => e
128
+ rescue Terrapin::ExitStatusError => e
116
129
  raise Paperclip::Error, "There was an error running `identify` for #{@basename}" if @whiny
117
- rescue Cocaine::CommandNotFoundError => e
130
+ rescue Terrapin::CommandNotFoundError => e
118
131
  raise Paperclip::Errors::CommandNotFoundError.new("Could not run the `identify` command. Please install ImageMagick.")
119
132
  end
120
133
  end
@@ -1,30 +1,34 @@
1
1
  require 'uri'
2
+ require 'active_support/core_ext/module/delegation'
2
3
 
3
4
  module Paperclip
4
5
  class UrlGenerator
5
- def initialize(attachment, attachment_options)
6
+ def initialize(attachment)
6
7
  @attachment = attachment
7
- @attachment_options = attachment_options
8
8
  end
9
9
 
10
10
  def for(style_name, options)
11
- timestamp_as_needed(
12
- escape_url_as_needed(
13
- @attachment_options[:interpolator].interpolate(most_appropriate_url, @attachment, style_name),
14
- options
15
- ), options)
11
+ interpolated = attachment_options[:interpolator].interpolate(
12
+ most_appropriate_url, @attachment, style_name
13
+ )
14
+
15
+ escaped = escape_url_as_needed(interpolated, options)
16
+ timestamp_as_needed(escaped, options)
16
17
  end
17
18
 
18
19
  private
19
20
 
21
+ attr_reader :attachment
22
+ delegate :options, to: :attachment, prefix: true
23
+
20
24
  # This method is all over the place.
21
25
  def default_url
22
- if @attachment_options[:default_url].respond_to?(:call)
23
- @attachment_options[:default_url].call(@attachment)
24
- elsif @attachment_options[:default_url].is_a?(Symbol)
25
- @attachment.instance.send(@attachment_options[:default_url])
26
+ if attachment_options[:default_url].respond_to?(:call)
27
+ attachment_options[:default_url].call(@attachment)
28
+ elsif attachment_options[:default_url].is_a?(Symbol)
29
+ @attachment.instance.send(attachment_options[:default_url])
26
30
  else
27
- @attachment_options[:default_url]
31
+ attachment_options[:default_url]
28
32
  end
29
33
  end
30
34
 
@@ -32,7 +36,7 @@ module Paperclip
32
36
  if @attachment.original_filename.nil?
33
37
  default_url
34
38
  else
35
- @attachment_options[:url]
39
+ attachment_options[:url]
36
40
  end
37
41
  end
38
42
 
@@ -36,7 +36,7 @@ module Paperclip
36
36
  options = attributes.extract_options!.dup
37
37
 
38
38
  Paperclip::Validators.constants.each do |constant|
39
- if constant.to_s =~ /\AAttachment(.+)Validator\Z/
39
+ if constant.to_s =~ /\AAttachment(.+)Validator\z/
40
40
  validator_kind = $1.underscore.to_sym
41
41
 
42
42
  if options.has_key?(validator_kind)
@@ -71,13 +71,7 @@ module Paperclip
71
71
  end
72
72
 
73
73
  def human_size(size)
74
- if defined?(ActiveSupport::NumberHelper) # Rails 4.0+
75
- ActiveSupport::NumberHelper.number_to_human_size(size)
76
- else
77
- storage_units_format = I18n.translate(:'number.human.storage_units.format', :locale => options[:locale], :raise => true)
78
- unit = I18n.translate(:'number.human.storage_units.units.byte', :locale => options[:locale], :count => size.to_i, :raise => true)
79
- storage_units_format.gsub(/%n/, size.to_i.to_s).gsub(/%u/, unit).html_safe
80
- end
74
+ ActiveSupport::NumberHelper.number_to_human_size(size)
81
75
  end
82
76
 
83
77
  def min_value_in_human_size(record)
@@ -8,6 +8,10 @@ module Paperclip
8
8
  if Paperclip::MediaTypeSpoofDetector.using(adapter, value.original_filename, value.content_type).spoofed?
9
9
  record.errors.add(attribute, :spoofed_media_type)
10
10
  end
11
+
12
+ if adapter.tempfile
13
+ adapter.tempfile.close(true)
14
+ end
11
15
  end
12
16
  end
13
17
 
@@ -1,3 +1,5 @@
1
1
  module Paperclip
2
- VERSION = "4.3.7".freeze unless defined? Paperclip::VERSION
2
+ unless defined?(Paperclip::VERSION)
3
+ VERSION = "6.1.0".freeze
4
+ end
3
5
  end
@@ -18,7 +18,7 @@ module Paperclip
18
18
  raise "Class #{klass.name} has no attachments specified"
19
19
  end
20
20
 
21
- if !name.blank? && attachment_names.map(&:to_s).include?(name.to_s)
21
+ if name.present? && attachment_names.map(&:to_s).include?(name.to_s)
22
22
  [ name ]
23
23
  else
24
24
  attachment_names
@@ -46,7 +46,7 @@ namespace :paperclip do
46
46
  attachment = instance.send(name)
47
47
  begin
48
48
  attachment.reprocess!(*styles)
49
- rescue Exception => e
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
- if file = Paperclip.io_adapters.for(instance.send(name))
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
- desc "find missing attachments. Useful to know which attachments are broken"
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
@@ -17,26 +17,30 @@ Gem::Specification.new do |s|
17
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
18
  s.require_paths = ["lib"]
19
19
 
20
+ if File.exist?('UPGRADING')
21
+ s.post_install_message = File.read("UPGRADING")
22
+ end
23
+
20
24
  s.requirements << "ImageMagick"
21
- s.required_ruby_version = ">= 1.9.2"
25
+ s.required_ruby_version = ">= 2.1.0"
22
26
 
23
- s.add_dependency('activemodel', '>= 3.2.0')
24
- s.add_dependency('activesupport', '>= 3.2.0')
25
- s.add_dependency('cocaine', '~> 0.5.5')
27
+ s.add_dependency('activemodel', '>= 4.2.0')
28
+ s.add_dependency('activesupport', '>= 4.2.0')
29
+ s.add_dependency('terrapin', '~> 0.6.0')
26
30
  s.add_dependency('mime-types')
27
- s.add_dependency('mimemagic', '0.3.0')
31
+ s.add_dependency('mimemagic', '~> 0.3.0')
28
32
 
29
- s.add_development_dependency('activerecord', '>= 3.2.0')
33
+ s.add_development_dependency('activerecord', '>= 4.2.0')
30
34
  s.add_development_dependency('shoulda')
31
35
  s.add_development_dependency('rspec', '~> 3.0')
32
36
  s.add_development_dependency('appraisal')
33
37
  s.add_development_dependency('mocha')
34
- s.add_development_dependency('aws-sdk', '>= 1.5.7', "<= 2.0")
38
+ s.add_development_dependency('aws-sdk-s3')
35
39
  s.add_development_dependency('bourne')
36
- s.add_development_dependency('cucumber', '~> 1.3.18')
40
+ s.add_development_dependency('cucumber-rails')
41
+ s.add_development_dependency('cucumber-expressions', '4.0.3') # TODO: investigate failures on 4.0.4
37
42
  s.add_development_dependency('aruba', '~> 0.9.0')
38
43
  s.add_development_dependency('nokogiri')
39
- # Ruby version < 1.9.3 can't install capybara > 2.0.3.
40
44
  s.add_development_dependency('capybara')
41
45
  s.add_development_dependency('bundler')
42
46
  s.add_development_dependency('fog-aws')
@@ -45,7 +49,6 @@ Gem::Specification.new do |s|
45
49
  s.add_development_dependency('rake')
46
50
  s.add_development_dependency('fakeweb')
47
51
  s.add_development_dependency('railties')
48
- s.add_development_dependency('actionmailer', '>= 3.2.0')
49
52
  s.add_development_dependency('generator_spec')
50
53
  s.add_development_dependency('timecop')
51
54
  end
@@ -1,12 +1,9 @@
1
- # encoding: utf-8
2
1
  require 'spec_helper'
3
2
 
4
3
  describe 'Attachment Processing' do
5
- context 'using validates_attachment_content_type' do
6
- before do
7
- rebuild_class
8
- end
4
+ before { rebuild_class }
9
5
 
6
+ context 'using validates_attachment_content_type' do
10
7
  it 'processes attachments given a valid assignment' do
11
8
  file = File.new(fixture_file("5k.png"))
12
9
  Dummy.validates_attachment_content_type :avatar, content_type: "image/png"
@@ -111,6 +111,34 @@ describe 'Attachment Registry' do
111
111
 
112
112
  assert_equal expected_definitions, definitions
113
113
  end
114
+
115
+ it 'allows subclasses to override attachment defitions' do
116
+ foo_definitions = { avatar: { yo: "greeting" } }
117
+ bar_definitions = { avatar: { yo: "hello" } }
118
+
119
+ expected_definitions = {
120
+ avatar: {
121
+ yo: "hello"
122
+ }
123
+ }
124
+
125
+ foo = Class.new
126
+ bar = Class.new(foo)
127
+ Paperclip::AttachmentRegistry.register(
128
+ foo,
129
+ :avatar,
130
+ foo_definitions[:avatar]
131
+ )
132
+ Paperclip::AttachmentRegistry.register(
133
+ bar,
134
+ :avatar,
135
+ bar_definitions[:avatar]
136
+ )
137
+
138
+ definitions = Paperclip::AttachmentRegistry.definitions_for(bar)
139
+
140
+ assert_equal expected_definitions, definitions
141
+ end
114
142
  end
115
143
 
116
144
  context '.clear' do
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  require 'spec_helper'
3
2
 
4
3
  describe Paperclip::Attachment do
@@ -54,6 +53,22 @@ describe Paperclip::Attachment do
54
53
  expect(dummy.avatar.path(:original)).to exist
55
54
  end
56
55
 
56
+ it "reprocess works with virtual content_type attribute" do
57
+ rebuild_class styles: { small: "100x>" }
58
+ modify_table { |t| t.remove :avatar_content_type }
59
+ Dummy.send :attr_accessor, :avatar_content_type
60
+ Dummy.validates_attachment_content_type(
61
+ :avatar,
62
+ content_type: %w(image/jpeg image/png)
63
+ )
64
+ Dummy.create!(avatar: File.new(fixture_file("50x50.png"), "rb"))
65
+
66
+ dummy = Dummy.first
67
+ dummy.avatar.reprocess!(:small)
68
+
69
+ expect(dummy.avatar.path(:small)).to exist
70
+ end
71
+
57
72
  context "having a not empty hash as a default option" do
58
73
  before do
59
74
  @old_default_options = Paperclip::Attachment.default_options.dup
@@ -222,9 +237,6 @@ describe Paperclip::Attachment do
222
237
  dummy.avatar_file_name = "fake.jpg"
223
238
  dummy.stubs(:new_record?).returns(false)
224
239
  expected_string = '{"avatar":"/system/dummies/avatars/000/001/234/original/fake.jpg"}'
225
- if ActiveRecord::Base.include_root_in_json # This is true by default in Rails 3, and false in 4
226
- expected_string = %({"dummy":#{expected_string}})
227
- end
228
240
  # active_model pre-3.2 checks only by calling any? on it, thus it doesn't work if it is empty
229
241
  assert_equal expected_string, dummy.to_json(only: [:dummy_key_for_old_active_model], methods: [:avatar])
230
242
  end
@@ -503,6 +515,7 @@ describe Paperclip::Attachment do
503
515
  @attachment.expects(:post_process).with(:thumb)
504
516
  @attachment.expects(:post_process).with(:large).never
505
517
  @attachment.assign(@file)
518
+ @attachment.save
506
519
  end
507
520
  end
508
521
 
@@ -700,9 +713,6 @@ describe Paperclip::Attachment do
700
713
 
701
714
  context "when assigned" do
702
715
  it "calls #make on all specified processors" do
703
- Paperclip::Thumbnail.stubs(:make).with(any_parameters).returns(@file)
704
- Paperclip::Test.stubs(:make).with(any_parameters).returns(@file)
705
-
706
716
  @dummy.avatar = @file
707
717
 
708
718
  expect(Paperclip::Thumbnail).to have_received(:make)
@@ -717,7 +727,6 @@ describe Paperclip::Attachment do
717
727
  convert_options: "",
718
728
  source_file_options: ""
719
729
  })
720
- Paperclip::Thumbnail.stubs(:make).returns(@file)
721
730
 
722
731
  @dummy.avatar = @file
723
732
 
@@ -725,12 +734,36 @@ describe Paperclip::Attachment do
725
734
  end
726
735
 
727
736
  it "calls #make with attachment passed as third argument" do
728
- Paperclip::Test.expects(:make).returns(@file)
729
-
730
737
  @dummy.avatar = @file
731
738
 
732
739
  expect(Paperclip::Test).to have_received(:make).with(anything, anything, @dummy.avatar)
733
740
  end
741
+
742
+ it "calls #make and unlinks intermediary files afterward" do
743
+ @dummy.avatar.expects(:unlink_files).with([@file, @file])
744
+
745
+ @dummy.avatar = @file
746
+ end
747
+ end
748
+ end
749
+
750
+ context "An attachment with a processor that returns original file" do
751
+ before do
752
+ class Paperclip::Test < Paperclip::Processor
753
+ def make; @file; end
754
+ end
755
+ rebuild_model processors: [:test], styles: { once: "100x100" }
756
+ @file = StringIO.new("...")
757
+ @file.stubs(:close)
758
+ @dummy = Dummy.new
759
+ end
760
+
761
+ context "when assigned" do
762
+ it "#calls #make and doesn't unlink the original file" do
763
+ @dummy.avatar.expects(:unlink_files).with([])
764
+
765
+ @dummy.avatar = @file
766
+ end
734
767
  end
735
768
  end
736
769
 
@@ -1104,7 +1137,7 @@ describe Paperclip::Attachment do
1104
1137
  context "with a file assigned but not saved yet" do
1105
1138
  it "clears out any attached files" do
1106
1139
  @attachment.assign(@file)
1107
- assert !@attachment.queued_for_write.blank?
1140
+ assert @attachment.queued_for_write.present?
1108
1141
  @attachment.clear
1109
1142
  assert @attachment.queued_for_write.blank?
1110
1143
  end
@@ -1354,6 +1387,12 @@ describe Paperclip::Attachment do
1354
1387
  end
1355
1388
 
1356
1389
  it "does not calculate fingerprint" do
1390
+ Digest::MD5.stubs(:file)
1391
+ @dummy.avatar = @file
1392
+ expect(Digest::MD5).to have_received(:file).never
1393
+ end
1394
+
1395
+ it "does not assign fingerprint" do
1357
1396
  @dummy.avatar = @file
1358
1397
  assert_nil @dummy.avatar.fingerprint
1359
1398
  end
@@ -1377,7 +1416,7 @@ describe Paperclip::Attachment do
1377
1416
 
1378
1417
  context "and avatar_file_size column" do
1379
1418
  before do
1380
- ActiveRecord::Base.connection.add_column :dummies, :avatar_file_size, :integer
1419
+ ActiveRecord::Base.connection.add_column :dummies, :avatar_file_size, :bigint
1381
1420
  rebuild_class
1382
1421
  @dummy = Dummy.new
1383
1422
  end
@@ -1410,16 +1449,46 @@ describe Paperclip::Attachment do
1410
1449
  assert_nothing_raised { @dummy.avatar = @file }
1411
1450
  end
1412
1451
 
1413
- it "returns the right value when sent #avatar_fingerprint" do
1414
- @dummy.avatar = @file
1415
- assert_equal 'aec488126c3b33c08a10c3fa303acf27', @dummy.avatar_fingerprint
1452
+ context "with explicitly set digest" do
1453
+ before do
1454
+ rebuild_class adapter_options: { hash_digest: Digest::SHA256 }
1455
+ @dummy = Dummy.new
1456
+ end
1457
+
1458
+ it "returns the right value when sent #avatar_fingerprint" do
1459
+ @dummy.avatar = @file
1460
+ assert_equal "734016d801a497f5579cdd4ef2ae1d020088c1db754dc434482d76dd5486520a",
1461
+ @dummy.avatar_fingerprint
1462
+ end
1463
+
1464
+ it "returns the right value when saved, reloaded, and sent #avatar_fingerprint" do
1465
+ @dummy.avatar = @file
1466
+ @dummy.save
1467
+ @dummy = Dummy.find(@dummy.id)
1468
+ assert_equal "734016d801a497f5579cdd4ef2ae1d020088c1db754dc434482d76dd5486520a",
1469
+ @dummy.avatar_fingerprint
1470
+ end
1416
1471
  end
1417
1472
 
1418
- it "returns the right value when saved, reloaded, and sent #avatar_fingerprint" do
1419
- @dummy.avatar = @file
1420
- @dummy.save
1421
- @dummy = Dummy.find(@dummy.id)
1422
- assert_equal 'aec488126c3b33c08a10c3fa303acf27', @dummy.avatar_fingerprint
1473
+ context "with the default digest" do
1474
+ before do
1475
+ rebuild_class # MD5 is the default
1476
+ @dummy = Dummy.new
1477
+ end
1478
+
1479
+ it "returns the right value when sent #avatar_fingerprint" do
1480
+ @dummy.avatar = @file
1481
+ assert_equal "aec488126c3b33c08a10c3fa303acf27",
1482
+ @dummy.avatar_fingerprint
1483
+ end
1484
+
1485
+ it "returns the right value when saved, reloaded, and sent #avatar_fingerprint" do
1486
+ @dummy.avatar = @file
1487
+ @dummy.save
1488
+ @dummy = Dummy.find(@dummy.id)
1489
+ assert_equal "aec488126c3b33c08a10c3fa303acf27",
1490
+ @dummy.avatar_fingerprint
1491
+ end
1423
1492
  end
1424
1493
  end
1425
1494
  end