paperclip 3.5.4 → 4.0.0
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.
Potentially problematic release.
This version of paperclip might be problematic. Click here for more details.
- checksums.yaml +4 -4
 - data/Gemfile +1 -0
 - data/LICENSE +1 -3
 - data/NEWS +25 -21
 - data/README.md +35 -1
 - data/features/step_definitions/attachment_steps.rb +2 -0
 - data/features/step_definitions/rails_steps.rb +1 -0
 - data/lib/paperclip.rb +1 -0
 - data/lib/paperclip/attachment.rb +25 -1
 - data/lib/paperclip/callbacks.rb +1 -1
 - data/lib/paperclip/content_type_detector.rb +1 -13
 - data/lib/paperclip/errors.rb +5 -0
 - data/lib/paperclip/has_attached_file.rb +5 -0
 - data/lib/paperclip/io_adapters/abstract_adapter.rb +1 -1
 - data/lib/paperclip/io_adapters/attachment_adapter.rb +4 -4
 - data/lib/paperclip/io_adapters/data_uri_adapter.rb +4 -9
 - data/lib/paperclip/io_adapters/stringio_adapter.rb +10 -8
 - data/lib/paperclip/media_type_spoof_detector.rb +36 -0
 - data/lib/paperclip/tempfile_factory.rb +5 -1
 - data/lib/paperclip/validators.rb +6 -1
 - data/lib/paperclip/validators/attachment_content_type_validator.rb +4 -0
 - data/lib/paperclip/validators/attachment_file_name_validator.rb +80 -0
 - data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +29 -0
 - data/lib/paperclip/validators/attachment_presence_validator.rb +4 -0
 - data/lib/paperclip/validators/attachment_size_validator.rb +4 -0
 - data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +27 -0
 - data/lib/paperclip/version.rb +1 -1
 - data/test/attachment_definitions_test.rb +1 -0
 - data/test/attachment_test.rb +40 -43
 - data/test/content_type_detector_test.rb +0 -10
 - data/test/fixtures/empty.html +1 -0
 - data/test/has_attached_file_test.rb +3 -1
 - data/test/helper.rb +11 -4
 - data/test/io_adapters/abstract_adapter_test.rb +1 -0
 - data/test/io_adapters/attachment_adapter_test.rb +1 -1
 - data/test/io_adapters/data_uri_adapter_test.rb +2 -2
 - data/test/io_adapters/file_adapter_test.rb +0 -11
 - data/test/io_adapters/http_url_proxy_adapter_test.rb +2 -3
 - data/test/io_adapters/stringio_adapter_test.rb +1 -1
 - data/test/matchers/have_attached_file_matcher_test.rb +3 -2
 - data/test/matchers/validate_attachment_content_type_matcher_test.rb +13 -12
 - data/test/matchers/validate_attachment_presence_matcher_test.rb +8 -7
 - data/test/matchers/validate_attachment_size_matcher_test.rb +12 -11
 - data/test/media_type_spoof_detector_test.rb +28 -0
 - data/test/meta_class_test.rb +2 -2
 - data/test/schema_test.rb +6 -0
 - data/test/storage/fog_test.rb +4 -4
 - data/test/storage/s3_test.rb +32 -31
 - data/test/tempfile_factory_test.rb +13 -1
 - data/test/validators/attachment_file_name_validator_test.rb +162 -0
 - data/test/validators/attachment_presence_validator_test.rb +1 -1
 - data/test/validators/media_type_spoof_detection_validator_test.rb +12 -0
 - data/test/validators_test.rb +43 -3
 - metadata +14 -2
 
    
        data/lib/paperclip/validators.rb
    CHANGED
    
    | 
         @@ -1,8 +1,11 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'active_model'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'active_support/concern'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require 'paperclip/validators/attachment_content_type_validator'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'paperclip/validators/attachment_file_name_validator'
         
     | 
| 
       4 
5 
     | 
    
         
             
            require 'paperclip/validators/attachment_presence_validator'
         
     | 
| 
       5 
6 
     | 
    
         
             
            require 'paperclip/validators/attachment_size_validator'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'paperclip/validators/media_type_spoof_detection_validator'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'paperclip/validators/attachment_file_type_ignorance_validator'
         
     | 
| 
       6 
9 
     | 
    
         | 
| 
       7 
10 
     | 
    
         
             
            module Paperclip
         
     | 
| 
       8 
11 
     | 
    
         
             
              module Validators
         
     | 
| 
         @@ -13,6 +16,8 @@ module Paperclip 
     | 
|
| 
       13 
16 
     | 
    
         
             
                  include HelperMethods
         
     | 
| 
       14 
17 
     | 
    
         
             
                end
         
     | 
| 
       15 
18 
     | 
    
         | 
| 
      
 19 
     | 
    
         
            +
                ::Paperclip::REQUIRED_VALIDATORS = [AttachmentFileNameValidator, AttachmentContentTypeValidator, AttachmentFileTypeIgnoranceValidator]
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
       16 
21 
     | 
    
         
             
                module ClassMethods
         
     | 
| 
       17 
22 
     | 
    
         
             
                  # This method is a shortcut to validator classes that is in
         
     | 
| 
       18 
23 
     | 
    
         
             
                  # "Attachment...Validator" format. It is almost the same thing as the
         
     | 
| 
         @@ -39,7 +44,7 @@ module Paperclip 
     | 
|
| 
       39 
44 
     | 
    
         
             
                          local_options = attributes + [validator_options]
         
     | 
| 
       40 
45 
     | 
    
         
             
                          conditional_options = options.slice(:if, :unless)
         
     | 
| 
       41 
46 
     | 
    
         
             
                          local_options.last.merge!(conditional_options)
         
     | 
| 
       42 
     | 
    
         
            -
                          send( 
     | 
| 
      
 47 
     | 
    
         
            +
                          send(Paperclip::Validators.const_get(constant.to_s).helper_method_name, *local_options)
         
     | 
| 
       43 
48 
     | 
    
         
             
                        end
         
     | 
| 
       44 
49 
     | 
    
         
             
                      end
         
     | 
| 
       45 
50 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -0,0 +1,80 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Paperclip
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Validators
         
     | 
| 
      
 3 
     | 
    
         
            +
                class AttachmentFileNameValidator < ActiveModel::EachValidator
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def initialize(options)
         
     | 
| 
      
 5 
     | 
    
         
            +
                    options[:allow_nil] = true unless options.has_key?(:allow_nil)
         
     | 
| 
      
 6 
     | 
    
         
            +
                    super
         
     | 
| 
      
 7 
     | 
    
         
            +
                  end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  def self.helper_method_name
         
     | 
| 
      
 10 
     | 
    
         
            +
                    :validates_attachment_file_name
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def validate_each(record, attribute, value)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    base_attribute = attribute.to_sym
         
     | 
| 
      
 15 
     | 
    
         
            +
                    attribute = "#{attribute}_file_name".to_sym
         
     | 
| 
      
 16 
     | 
    
         
            +
                    value = record.send :read_attribute_for_validation, attribute
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    return if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    validate_whitelist(record, attribute, value)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    validate_blacklist(record, attribute, value)
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                    if record.errors.include? attribute
         
     | 
| 
      
 24 
     | 
    
         
            +
                      record.errors[attribute].each do |error|
         
     | 
| 
      
 25 
     | 
    
         
            +
                        record.errors.add base_attribute, error
         
     | 
| 
      
 26 
     | 
    
         
            +
                      end
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  def validate_whitelist(record, attribute, value)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    if allowed.present? && allowed.none? { |type| type === value }
         
     | 
| 
      
 32 
     | 
    
         
            +
                      mark_invalid record, attribute, allowed
         
     | 
| 
      
 33 
     | 
    
         
            +
                    end
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  def validate_blacklist(record, attribute, value)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    if forbidden.present? && forbidden.any? { |type| type === value }
         
     | 
| 
      
 38 
     | 
    
         
            +
                      mark_invalid record, attribute, forbidden
         
     | 
| 
      
 39 
     | 
    
         
            +
                    end
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  def mark_invalid(record, attribute, patterns)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    record.errors.add attribute, :invalid, options.merge(:names => patterns.join(', '))
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  def allowed
         
     | 
| 
      
 47 
     | 
    
         
            +
                    [options[:matches]].flatten.compact
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  def forbidden
         
     | 
| 
      
 51 
     | 
    
         
            +
                    [options[:not]].flatten.compact
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  def check_validity!
         
     | 
| 
      
 55 
     | 
    
         
            +
                    unless options.has_key?(:matches) || options.has_key?(:not)
         
     | 
| 
      
 56 
     | 
    
         
            +
                      raise ArgumentError, "You must pass in either :matches or :not to the validator"
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                module HelperMethods
         
     | 
| 
      
 62 
     | 
    
         
            +
                  # Places ActiveModel validations on the name of the file
         
     | 
| 
      
 63 
     | 
    
         
            +
                  # assigned. The possible options are:
         
     | 
| 
      
 64 
     | 
    
         
            +
                  # * +matches+: Allowed filename patterns as Regexps. Can be a single one
         
     | 
| 
      
 65 
     | 
    
         
            +
                  #   or an array.
         
     | 
| 
      
 66 
     | 
    
         
            +
                  # * +not+: Forbidden file name patterns, specified the same was as +matches+.
         
     | 
| 
      
 67 
     | 
    
         
            +
                  # * +message+: The message to display when the uploaded file has an invalid
         
     | 
| 
      
 68 
     | 
    
         
            +
                  #   name.
         
     | 
| 
      
 69 
     | 
    
         
            +
                  # * +if+: A lambda or name of an instance method. Validation will only
         
     | 
| 
      
 70 
     | 
    
         
            +
                  #   be run is this lambda or method returns true.
         
     | 
| 
      
 71 
     | 
    
         
            +
                  # * +unless+: Same as +if+ but validates if lambda or method returns false.
         
     | 
| 
      
 72 
     | 
    
         
            +
                  def validates_attachment_file_name(*attr_names)
         
     | 
| 
      
 73 
     | 
    
         
            +
                    options = _merge_attributes(attr_names)
         
     | 
| 
      
 74 
     | 
    
         
            +
                    validates_with AttachmentFileNameValidator, options.dup
         
     | 
| 
      
 75 
     | 
    
         
            +
                    validate_before_processing AttachmentFileNameValidator, options.dup
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
            end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_model/validations/presence'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Paperclip
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Validators
         
     | 
| 
      
 5 
     | 
    
         
            +
                class AttachmentFileTypeIgnoranceValidator < ActiveModel::EachValidator
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def validate_each(record, attribute, value)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    # This doesn't do anything. It's just to mark that you don't care about
         
     | 
| 
      
 8 
     | 
    
         
            +
                    # the file_names or content_types of your incoming attachments.
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def self.helper_method_name
         
     | 
| 
      
 12 
     | 
    
         
            +
                    :do_not_validate_attachment_file_type
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                module HelperMethods
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # Places ActiveModel validations on the presence of a file.
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # Options:
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # * +if+: A lambda or name of an instance method. Validation will only
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #   be run if this lambda or method returns true.
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # * +unless+: Same as +if+ but validates if lambda or method returns false.
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def do_not_validate_attachment_file_type(*attr_names)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    options = _merge_attributes(attr_names)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    validates_with AttachmentFileTypeIgnoranceValidator, options.dup
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_model/validations/presence'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Paperclip
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Validators
         
     | 
| 
      
 5 
     | 
    
         
            +
                class MediaTypeSpoofDetectionValidator < ActiveModel::EachValidator
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def validate_each(record, attribute, value)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    adapter = Paperclip.io_adapters.for(value)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    if Paperclip::MediaTypeSpoofDetector.using(adapter, value.original_filename).spoofed?
         
     | 
| 
      
 9 
     | 
    
         
            +
                      record.errors.add(attribute, :spoofed_media_type)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    end
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                module HelperMethods
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # Places ActiveModel validations on the presence of a file.
         
     | 
| 
      
 16 
     | 
    
         
            +
                  # Options:
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # * +if+: A lambda or name of an instance method. Validation will only
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #   be run if this lambda or method returns true.
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # * +unless+: Same as +if+ but validates if lambda or method returns false.
         
     | 
| 
      
 20 
     | 
    
         
            +
                  def validates_media_type_spoof_detection(*attr_names)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    options = _merge_attributes(attr_names)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    validates_with MediaTypeSpoofDetectionValidator, options.dup
         
     | 
| 
      
 23 
     | 
    
         
            +
                    validate_before_processing MediaTypeSpoofDetectionValidator, options.dup
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/paperclip/version.rb
    CHANGED
    
    
| 
         @@ -5,6 +5,7 @@ class AttachmentDefinitionsTest < Test::Unit::TestCase 
     | 
|
| 
       5 
5 
     | 
    
         
             
                reset_class "Dummy"
         
     | 
| 
       6 
6 
     | 
    
         
             
                Dummy.has_attached_file :avatar, {:path => "abc"}
         
     | 
| 
       7 
7 
     | 
    
         
             
                Dummy.has_attached_file :other_attachment, {:url => "123"}
         
     | 
| 
      
 8 
     | 
    
         
            +
                Dummy.do_not_validate_attachment_file_type :avatar
         
     | 
| 
       8 
9 
     | 
    
         
             
                expected = {:avatar => {:path => "abc"}, :other_attachment => {:url => "123"}}
         
     | 
| 
       9 
10 
     | 
    
         | 
| 
       10 
11 
     | 
    
         
             
                assert_equal expected, Dummy.attachment_definitions
         
     | 
    
        data/test/attachment_test.rb
    CHANGED
    
    | 
         @@ -165,7 +165,7 @@ class AttachmentTest < Test::Unit::TestCase 
     | 
|
| 
       165 
165 
     | 
    
         
             
                                                       :default_style => 'default style',
         
     | 
| 
       166 
166 
     | 
    
         
             
                                                       :url_generator => mock_url_generator_builder)
         
     | 
| 
       167 
167 
     | 
    
         | 
| 
       168 
     | 
    
         
            -
                 
     | 
| 
      
 168 
     | 
    
         
            +
                attachment.as_json
         
     | 
| 
       169 
169 
     | 
    
         
             
                assert mock_url_generator_builder.has_generated_url_with_style_name?('default style')
         
     | 
| 
       170 
170 
     | 
    
         
             
              end
         
     | 
| 
       171 
171 
     | 
    
         | 
| 
         @@ -346,11 +346,12 @@ class AttachmentTest < Test::Unit::TestCase 
     | 
|
| 
       346 
346 
     | 
    
         | 
| 
       347 
347 
     | 
    
         
             
              context "An attachment with :hash interpolations" do
         
     | 
| 
       348 
348 
     | 
    
         
             
                setup do
         
     | 
| 
       349 
     | 
    
         
            -
                  @file = StringIO.new(" 
     | 
| 
      
 349 
     | 
    
         
            +
                  @file = StringIO.new("...\n")
         
     | 
| 
       350 
350 
     | 
    
         
             
                end
         
     | 
| 
       351 
351 
     | 
    
         | 
| 
       352 
352 
     | 
    
         
             
                should "raise if no secret is provided" do
         
     | 
| 
       353 
     | 
    
         
            -
                   
     | 
| 
      
 353 
     | 
    
         
            +
                  rebuild_model :path => ":hash"
         
     | 
| 
      
 354 
     | 
    
         
            +
                  @attachment = Dummy.new.avatar
         
     | 
| 
       354 
355 
     | 
    
         
             
                  @attachment.assign @file
         
     | 
| 
       355 
356 
     | 
    
         | 
| 
       356 
357 
     | 
    
         
             
                  assert_raise ArgumentError do
         
     | 
| 
         @@ -360,29 +361,23 @@ class AttachmentTest < Test::Unit::TestCase 
     | 
|
| 
       360 
361 
     | 
    
         | 
| 
       361 
362 
     | 
    
         
             
                context "when secret is set" do
         
     | 
| 
       362 
363 
     | 
    
         
             
                  setup do
         
     | 
| 
       363 
     | 
    
         
            -
                     
     | 
| 
       364 
     | 
    
         
            -
             
     | 
| 
       365 
     | 
    
         
            -
             
     | 
| 
       366 
     | 
    
         
            -
                    @attachment 
     | 
| 
      
 364 
     | 
    
         
            +
                    rebuild_model :path => ":hash",
         
     | 
| 
      
 365 
     | 
    
         
            +
                      :hash_secret => "w00t",
         
     | 
| 
      
 366 
     | 
    
         
            +
                      :hash_data => ":class/:attachment/:style/:filename"
         
     | 
| 
      
 367 
     | 
    
         
            +
                    @attachment = Dummy.new.avatar
         
     | 
| 
       367 
368 
     | 
    
         
             
                    @attachment.assign @file
         
     | 
| 
       368 
369 
     | 
    
         
             
                  end
         
     | 
| 
       369 
370 
     | 
    
         | 
| 
       370 
     | 
    
         
            -
                  should "interpolate the hash data" do
         
     | 
| 
       371 
     | 
    
         
            -
                    @attachment.expects(:interpolate).with(@attachment.options[:hash_data],anything).returns("interpolated_stuff")
         
     | 
| 
       372 
     | 
    
         
            -
                    @attachment.hash_key
         
     | 
| 
       373 
     | 
    
         
            -
                  end
         
     | 
| 
       374 
     | 
    
         
            -
             
     | 
| 
       375 
371 
     | 
    
         
             
                  should "result in the correct interpolation" do
         
     | 
| 
       376 
     | 
    
         
            -
                    assert_equal " 
     | 
| 
      
 372 
     | 
    
         
            +
                    assert_equal "dummies/avatars/original/data.txt",
         
     | 
| 
      
 373 
     | 
    
         
            +
                      @attachment.send(:interpolate, @attachment.options[:hash_data])
         
     | 
| 
      
 374 
     | 
    
         
            +
                    assert_equal "dummies/avatars/thumb/data.txt",
         
     | 
| 
      
 375 
     | 
    
         
            +
                      @attachment.send(:interpolate, @attachment.options[:hash_data], :thumb)
         
     | 
| 
       377 
376 
     | 
    
         
             
                  end
         
     | 
| 
       378 
377 
     | 
    
         | 
| 
       379 
378 
     | 
    
         
             
                  should "result in a correct hash" do
         
     | 
| 
       380 
     | 
    
         
            -
                    assert_equal " 
     | 
| 
       381 
     | 
    
         
            -
             
     | 
| 
       382 
     | 
    
         
            -
             
     | 
| 
       383 
     | 
    
         
            -
                  should "generate a hash digest with the correct style" do
         
     | 
| 
       384 
     | 
    
         
            -
                    OpenSSL::HMAC.expects(:hexdigest).with(anything, anything, "fake_models/avatars/1234/medium/1234567890")
         
     | 
| 
       385 
     | 
    
         
            -
                    @attachment.path("medium")
         
     | 
| 
      
 379 
     | 
    
         
            +
                    assert_equal "e1079a5c34ddbd197ebd0280d07952d98a57fb30", @attachment.path
         
     | 
| 
      
 380 
     | 
    
         
            +
                    assert_equal "d740189bd3e49ef226fab84c8d45f7ae4126d043", @attachment.path(:thumb)
         
     | 
| 
       386 
381 
     | 
    
         
             
                  end
         
     | 
| 
       387 
382 
     | 
    
         
             
                end
         
     | 
| 
       388 
383 
     | 
    
         
             
              end
         
     | 
| 
         @@ -406,15 +401,16 @@ class AttachmentTest < Test::Unit::TestCase 
     | 
|
| 
       406 
401 
     | 
    
         | 
| 
       407 
402 
     | 
    
         
             
              context "An attachment with a default style and an extension interpolation" do
         
     | 
| 
       408 
403 
     | 
    
         
             
                setup do
         
     | 
| 
       409 
     | 
    
         
            -
                   
     | 
| 
       410 
     | 
    
         
            -
             
     | 
| 
       411 
     | 
    
         
            -
             
     | 
| 
       412 
     | 
    
         
            -
                  @ 
     | 
| 
       413 
     | 
    
         
            -
                  @file. 
     | 
| 
      
 404 
     | 
    
         
            +
                  rebuild_model :path => ":basename.:extension",
         
     | 
| 
      
 405 
     | 
    
         
            +
                    :styles => { :default => ["100x100", :jpg] },
         
     | 
| 
      
 406 
     | 
    
         
            +
                    :default_style => :default
         
     | 
| 
      
 407 
     | 
    
         
            +
                  @attachment = Dummy.new.avatar
         
     | 
| 
      
 408 
     | 
    
         
            +
                  @file = File.open(fixture_file("5k.png"))
         
     | 
| 
      
 409 
     | 
    
         
            +
                  @file.stubs(:original_filename).returns("file.png")
         
     | 
| 
       414 
410 
     | 
    
         
             
                end
         
     | 
| 
       415 
411 
     | 
    
         
             
                should "return the right extension for the path" do
         
     | 
| 
       416 
412 
     | 
    
         
             
                  @attachment.assign(@file)
         
     | 
| 
       417 
     | 
    
         
            -
                  assert_equal "file. 
     | 
| 
      
 413 
     | 
    
         
            +
                  assert_equal "file.jpg", @attachment.path
         
     | 
| 
       418 
414 
     | 
    
         
             
                end
         
     | 
| 
       419 
415 
     | 
    
         
             
              end
         
     | 
| 
       420 
416 
     | 
    
         | 
| 
         @@ -983,19 +979,16 @@ class AttachmentTest < Test::Unit::TestCase 
     | 
|
| 
       983 
979 
     | 
    
         
             
                    :path => ":rails_root/:attachment/:class/:style/:id/:basename.:extension"
         
     | 
| 
       984 
980 
     | 
    
         
             
                  })
         
     | 
| 
       985 
981 
     | 
    
         
             
                  FileUtils.rm_rf("tmp")
         
     | 
| 
       986 
     | 
    
         
            -
                  rebuild_model
         
     | 
| 
      
 982 
     | 
    
         
            +
                  rebuild_model :styles => { :large  => ["400x400", :jpg],
         
     | 
| 
      
 983 
     | 
    
         
            +
                                         :medium => ["100x100", :jpg],
         
     | 
| 
      
 984 
     | 
    
         
            +
                                         :small => ["32x32#", :jpg]},
         
     | 
| 
      
 985 
     | 
    
         
            +
                                :default_style => :small
         
     | 
| 
       987 
986 
     | 
    
         
             
                  @instance = Dummy.new
         
     | 
| 
       988 
987 
     | 
    
         
             
                  @instance.stubs(:id).returns 123
         
     | 
| 
       989 
     | 
    
         
            -
             
     | 
| 
       990 
988 
     | 
    
         
             
                  @file = File.new(fixture_file("uppercase.PNG"), 'rb')
         
     | 
| 
       991 
989 
     | 
    
         | 
| 
       992 
     | 
    
         
            -
                   
     | 
| 
       993 
     | 
    
         
            -
             
     | 
| 
       994 
     | 
    
         
            -
                                         :small => ["32x32#", :jpg]},
         
     | 
| 
       995 
     | 
    
         
            -
                            :default_style => :small}
         
     | 
| 
       996 
     | 
    
         
            -
                  @attachment = Paperclip::Attachment.new(:avatar,
         
     | 
| 
       997 
     | 
    
         
            -
                                                          @instance,
         
     | 
| 
       998 
     | 
    
         
            -
                                                          styles)
         
     | 
| 
      
 990 
     | 
    
         
            +
                  @attachment = @instance.avatar
         
     | 
| 
      
 991 
     | 
    
         
            +
             
     | 
| 
       999 
992 
     | 
    
         
             
                  now = Time.now
         
     | 
| 
       1000 
993 
     | 
    
         
             
                  Time.stubs(:now).returns(now)
         
     | 
| 
       1001 
994 
     | 
    
         
             
                  @attachment.assign(@file)
         
     | 
| 
         @@ -1027,7 +1020,8 @@ class AttachmentTest < Test::Unit::TestCase 
     | 
|
| 
       1027 
1020 
     | 
    
         
             
                  rebuild_model
         
     | 
| 
       1028 
1021 
     | 
    
         
             
                  @instance = Dummy.new
         
     | 
| 
       1029 
1022 
     | 
    
         
             
                  @instance.stubs(:id).returns 123
         
     | 
| 
       1030 
     | 
    
         
            -
                  @attachment = Paperclip::Attachment.new(:avatar, @instance)
         
     | 
| 
      
 1023 
     | 
    
         
            +
                  # @attachment = Paperclip::Attachment.new(:avatar, @instance)
         
     | 
| 
      
 1024 
     | 
    
         
            +
                  @attachment = @instance.avatar
         
     | 
| 
       1031 
1025 
     | 
    
         
             
                  @file = File.new(fixture_file("5k.png"), 'rb')
         
     | 
| 
       1032 
1026 
     | 
    
         
             
                end
         
     | 
| 
       1033 
1027 
     | 
    
         | 
| 
         @@ -1045,7 +1039,7 @@ class AttachmentTest < Test::Unit::TestCase 
     | 
|
| 
       1045 
1039 
     | 
    
         | 
| 
       1046 
1040 
     | 
    
         
             
                should 'clear out the previous assignment when assigned nil' do
         
     | 
| 
       1047 
1041 
     | 
    
         
             
                  @attachment.assign(@file)
         
     | 
| 
       1048 
     | 
    
         
            -
                   
     | 
| 
      
 1042 
     | 
    
         
            +
                  @attachment.queued_for_write[:original]
         
     | 
| 
       1049 
1043 
     | 
    
         
             
                  @attachment.assign(nil)
         
     | 
| 
       1050 
1044 
     | 
    
         
             
                  assert_nil @attachment.queued_for_write[:original]
         
     | 
| 
       1051 
1045 
     | 
    
         
             
                end
         
     | 
| 
         @@ -1093,12 +1087,15 @@ class AttachmentTest < Test::Unit::TestCase 
     | 
|
| 
       1093 
1087 
     | 
    
         | 
| 
       1094 
1088 
     | 
    
         
             
                  context "when expecting three styles" do
         
     | 
| 
       1095 
1089 
     | 
    
         
             
                    setup do
         
     | 
| 
       1096 
     | 
    
         
            -
                       
     | 
| 
       1097 
     | 
    
         
            -
             
     | 
| 
       1098 
     | 
    
         
            -
             
     | 
| 
       1099 
     | 
    
         
            -
             
     | 
| 
       1100 
     | 
    
         
            -
             
     | 
| 
       1101 
     | 
    
         
            -
             
     | 
| 
      
 1090 
     | 
    
         
            +
                      rebuild_class :styles => {
         
     | 
| 
      
 1091 
     | 
    
         
            +
                        :large  => ["400x400", :png],
         
     | 
| 
      
 1092 
     | 
    
         
            +
                        :medium => ["100x100", :gif],
         
     | 
| 
      
 1093 
     | 
    
         
            +
                        :small => ["32x32#", :jpg]
         
     | 
| 
      
 1094 
     | 
    
         
            +
                      }
         
     | 
| 
      
 1095 
     | 
    
         
            +
                      @instance = Dummy.new
         
     | 
| 
      
 1096 
     | 
    
         
            +
                      @instance.stubs(:id).returns 123
         
     | 
| 
      
 1097 
     | 
    
         
            +
                      @file = File.new(fixture_file("5k.png"), 'rb')
         
     | 
| 
      
 1098 
     | 
    
         
            +
                      @attachment = @instance.avatar
         
     | 
| 
       1102 
1099 
     | 
    
         
             
                    end
         
     | 
| 
       1103 
1100 
     | 
    
         | 
| 
       1104 
1101 
     | 
    
         
             
                    context "and assigned a file" do
         
     | 
| 
         @@ -1129,7 +1126,7 @@ class AttachmentTest < Test::Unit::TestCase 
     | 
|
| 
       1129 
1126 
     | 
    
         
             
                           [:small, 32, 32, "JPEG"]].each do |style|
         
     | 
| 
       1130 
1127 
     | 
    
         
             
                            cmd = %Q[identify -format "%w %h %b %m" "#{@attachment.path(style.first)}"]
         
     | 
| 
       1131 
1128 
     | 
    
         
             
                            out = `#{cmd}`
         
     | 
| 
       1132 
     | 
    
         
            -
                            width, height,  
     | 
| 
      
 1129 
     | 
    
         
            +
                            width, height, _size, format = out.split(" ")
         
     | 
| 
       1133 
1130 
     | 
    
         
             
                            assert_equal style[1].to_s, width.to_s
         
     | 
| 
       1134 
1131 
     | 
    
         
             
                            assert_equal style[2].to_s, height.to_s
         
     | 
| 
       1135 
1132 
     | 
    
         
             
                            assert_equal style[3].to_s, format.to_s
         
     | 
| 
         @@ -18,16 +18,6 @@ class ContentTypeDetectorTest < Test::Unit::TestCase 
     | 
|
| 
       18 
18 
     | 
    
         
             
                assert_equal "video/mp4", Paperclip::ContentTypeDetector.new(@filename).detect
         
     | 
| 
       19 
19 
     | 
    
         
             
              end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
              should 'find the first result that matches from the official types' do
         
     | 
| 
       22 
     | 
    
         
            -
                @filename = "/path/to/something.bmp"
         
     | 
| 
       23 
     | 
    
         
            -
                assert_equal "image/bmp", Paperclip::ContentTypeDetector.new(@filename).detect
         
     | 
| 
       24 
     | 
    
         
            -
              end
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
              should 'find the first unofficial result for this filename if no official ones exist' do
         
     | 
| 
       27 
     | 
    
         
            -
                @filename = "/path/to/something.aiff"
         
     | 
| 
       28 
     | 
    
         
            -
                assert_equal "audio/x-aiff", Paperclip::ContentTypeDetector.new(@filename).detect
         
     | 
| 
       29 
     | 
    
         
            -
              end
         
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
21 
     | 
    
         
             
              should 'find the right type in the list via the file command' do
         
     | 
| 
       32 
22 
     | 
    
         
             
                @filename = "#{Dir.tmpdir}/something.hahalolnotreal"
         
     | 
| 
       33 
23 
     | 
    
         
             
                File.open(@filename, "w+") do |file|
         
     | 
| 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            <html></html>
         
     | 
    
        data/test/helper.rb
    CHANGED
    
    | 
         @@ -40,6 +40,7 @@ class Test::Unit::TestCase 
     | 
|
| 
       40 
40 
     | 
    
         
             
                  Rails.stubs(:root).returns(Pathname.new(ROOT).join('tmp'))
         
     | 
| 
       41 
41 
     | 
    
         
             
                  Rails.stubs(:env).returns('test')
         
     | 
| 
       42 
42 
     | 
    
         
             
                  Rails.stubs(:const_defined?).with(:Railtie).returns(false)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  ActiveSupport::Deprecation.silenced = true
         
     | 
| 
       43 
44 
     | 
    
         
             
                end
         
     | 
| 
       44 
45 
     | 
    
         
             
              end
         
     | 
| 
       45 
46 
     | 
    
         | 
| 
         @@ -125,6 +126,7 @@ end 
     | 
|
| 
       125 
126 
     | 
    
         
             
            def rebuild_class options = {}
         
     | 
| 
       126 
127 
     | 
    
         
             
              reset_class("Dummy").tap do |klass|
         
     | 
| 
       127 
128 
     | 
    
         
             
                klass.has_attached_file :avatar, options
         
     | 
| 
      
 129 
     | 
    
         
            +
                klass.do_not_validate_attachment_file_type :avatar
         
     | 
| 
       128 
130 
     | 
    
         
             
                Paperclip.reset_duplicate_clash_check!
         
     | 
| 
       129 
131 
     | 
    
         
             
              end
         
     | 
| 
       130 
132 
     | 
    
         
             
            end
         
     | 
| 
         @@ -132,6 +134,7 @@ end 
     | 
|
| 
       132 
134 
     | 
    
         
             
            def rebuild_meta_class_of obj, options = {}
         
     | 
| 
       133 
135 
     | 
    
         
             
              (class << obj; self; end).tap do |metaklass|
         
     | 
| 
       134 
136 
     | 
    
         
             
                metaklass.has_attached_file :avatar, options
         
     | 
| 
      
 137 
     | 
    
         
            +
                metaklass.do_not_validate_attachment_file_type :avatar
         
     | 
| 
       135 
138 
     | 
    
         
             
                Paperclip.reset_duplicate_clash_check!
         
     | 
| 
       136 
139 
     | 
    
         
             
              end
         
     | 
| 
       137 
140 
     | 
    
         
             
            end
         
     | 
| 
         @@ -169,21 +172,21 @@ end 
     | 
|
| 
       169 
172 
     | 
    
         | 
| 
       170 
173 
     | 
    
         
             
            def should_accept_dummy_class
         
     | 
| 
       171 
174 
     | 
    
         
             
              should "accept the class" do
         
     | 
| 
       172 
     | 
    
         
            -
                assert_accepts @matcher,  
     | 
| 
      
 175 
     | 
    
         
            +
                assert_accepts @matcher, Dummy
         
     | 
| 
       173 
176 
     | 
    
         
             
              end
         
     | 
| 
       174 
177 
     | 
    
         | 
| 
       175 
178 
     | 
    
         
             
              should "accept an instance of that class" do
         
     | 
| 
       176 
     | 
    
         
            -
                assert_accepts @matcher,  
     | 
| 
      
 179 
     | 
    
         
            +
                assert_accepts @matcher, Dummy.new
         
     | 
| 
       177 
180 
     | 
    
         
             
              end
         
     | 
| 
       178 
181 
     | 
    
         
             
            end
         
     | 
| 
       179 
182 
     | 
    
         | 
| 
       180 
183 
     | 
    
         
             
            def should_reject_dummy_class
         
     | 
| 
       181 
184 
     | 
    
         
             
              should "reject the class" do
         
     | 
| 
       182 
     | 
    
         
            -
                assert_rejects @matcher,  
     | 
| 
      
 185 
     | 
    
         
            +
                assert_rejects @matcher, Dummy
         
     | 
| 
       183 
186 
     | 
    
         
             
              end
         
     | 
| 
       184 
187 
     | 
    
         | 
| 
       185 
188 
     | 
    
         
             
              should "reject an instance of that class" do
         
     | 
| 
       186 
     | 
    
         
            -
                assert_rejects @matcher,  
     | 
| 
      
 189 
     | 
    
         
            +
                assert_rejects @matcher, Dummy.new
         
     | 
| 
       187 
190 
     | 
    
         
             
              end
         
     | 
| 
       188 
191 
     | 
    
         
             
            end
         
     | 
| 
       189 
192 
     | 
    
         | 
| 
         @@ -197,6 +200,10 @@ def with_exitstatus_returning(code) 
     | 
|
| 
       197 
200 
     | 
    
         
             
              end
         
     | 
| 
       198 
201 
     | 
    
         
             
            end
         
     | 
| 
       199 
202 
     | 
    
         | 
| 
      
 203 
     | 
    
         
            +
            def stringy_file
         
     | 
| 
      
 204 
     | 
    
         
            +
              StringIO.new('.\n')
         
     | 
| 
      
 205 
     | 
    
         
            +
            end
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
       200 
207 
     | 
    
         
             
            def fixture_file(filename)
         
     | 
| 
       201 
208 
     | 
    
         
             
              File.join(File.dirname(__FILE__), 'fixtures', filename)
         
     | 
| 
       202 
209 
     | 
    
         
             
            end
         
     |