This repository has been archived by the owner on Jul 13, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
152 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
lib/paperclip/validators/attachment_content_type_validator.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
module Paperclip | ||
module Validators | ||
class AttachmentContentTypeValidator < ActiveModel::EachValidator | ||
def validate_each(record, attribute, value) | ||
attribute = "#{attribute}_content_type".to_sym | ||
value = record.send(:read_attribute_for_validation, attribute) | ||
allowed_types = [options[:content_type]].flatten | ||
|
||
unless value.blank? | ||
allowed_types.any? do |type| | ||
unless type === value | ||
record.errors.add(attribute, :invalid, options.merge( | ||
:types => allowed_types.join(', ') | ||
)) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
module HelperMethods | ||
# Places ActiveRecord-style validations on the content type of the file | ||
# assigned. The possible options are: | ||
# * +content_type+: Allowed content types. Can be a single content type | ||
# or an array. Each type can be a String or a Regexp. It should be | ||
# noted that Internet Explorer uploads files with content_types that you | ||
# may not expect. For example, JPEG images are given image/pjpeg and | ||
# PNGs are image/x-png, so keep that in mind when determining how you | ||
# match. Allows all by default. | ||
# * +message+: The message to display when the uploaded file has an invalid | ||
# content type. | ||
# * +if+: A lambda or name of an instance method. Validation will only | ||
# be run is this lambda or method returns true. | ||
# * +unless+: Same as +if+ but validates if lambda or method returns false. | ||
# NOTE: If you do not specify an [attachment]_content_type field on your | ||
# model, content_type validation will work _ONLY upon assignment_ and | ||
# re-validation after the instance has been reloaded will always succeed. | ||
# You'll still need to have a virtual attribute (created by +attr_accessor+) | ||
# name +[attachment]_content_type+ to be able to use this validator. | ||
def validates_attachment_content_type(*attr_names) | ||
validates_with AttachmentContentTypeValidator, _merge_attributes(attr_names) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
test/validators/attachment_content_type_validator_test.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
require './test/helper' | ||
|
||
class AttachmentContentTypeValidatorTest < Test::Unit::TestCase | ||
def setup | ||
rebuild_model | ||
@dummy = Dummy.new | ||
end | ||
|
||
def build_validator(options) | ||
@validator = Paperclip::Validators::AttachmentContentTypeValidator.new(options.merge( | ||
:attributes => :avatar | ||
)) | ||
end | ||
|
||
context "with a nil content type" do | ||
setup do | ||
build_validator :content_type => "image/jpg" | ||
@dummy.stubs(:avatar_content_type => nil) | ||
@validator.validate(@dummy) | ||
end | ||
|
||
should "not set an error message" do | ||
assert @dummy.errors[:avatar_content_type].blank? | ||
end | ||
end | ||
|
||
context "with an allowed type" do | ||
context "as a string" do | ||
setup do | ||
build_validator :content_type => "image/jpg" | ||
@dummy.stubs(:avatar_content_type => "image/jpg") | ||
@validator.validate(@dummy) | ||
end | ||
|
||
should "not set an error message" do | ||
assert @dummy.errors[:avatar_content_type].blank? | ||
end | ||
end | ||
|
||
context "as an regexp" do | ||
setup do | ||
build_validator :content_type => /^image\/.*/ | ||
@dummy.stubs(:avatar_content_type => "image/jpg") | ||
@validator.validate(@dummy) | ||
end | ||
|
||
should "not set an error message" do | ||
assert @dummy.errors[:avatar_content_type].blank? | ||
end | ||
end | ||
end | ||
|
||
context "with a disallowed type" do | ||
context "as a string" do | ||
setup do | ||
build_validator :content_type => "image/png" | ||
@dummy.stubs(:avatar_content_type => "image/jpg") | ||
@validator.validate(@dummy) | ||
end | ||
|
||
should "set a correct default error message" do | ||
assert @dummy.errors[:avatar_content_type].present? | ||
assert_includes @dummy.errors[:avatar_content_type], "is invalid" | ||
end | ||
end | ||
|
||
context "as a regexp" do | ||
setup do | ||
build_validator :content_type => /^text\/.*/ | ||
@dummy.stubs(:avatar_content_type => "image/jpg") | ||
@validator.validate(@dummy) | ||
end | ||
|
||
should "set a correct default error message" do | ||
assert @dummy.errors[:avatar_content_type].present? | ||
assert_includes @dummy.errors[:avatar_content_type], "is invalid" | ||
end | ||
end | ||
|
||
context "with :message option" do | ||
context "without interpolation" do | ||
setup do | ||
build_validator :content_type => "image/png", :message => "should be a PNG image" | ||
@dummy.stubs(:avatar_content_type => "image/jpg") | ||
@validator.validate(@dummy) | ||
end | ||
|
||
should "set a correct error message" do | ||
assert_includes @dummy.errors[:avatar_content_type], "should be a PNG image" | ||
end | ||
end | ||
|
||
context "with interpolation" do | ||
setup do | ||
build_validator :content_type => "image/png", :message => "should have content type %{types}" | ||
@dummy.stubs(:avatar_content_type => "image/jpg") | ||
@validator.validate(@dummy) | ||
end | ||
|
||
should "set a correct error message" do | ||
assert_includes @dummy.errors[:avatar_content_type], "should have content type image/png" | ||
end | ||
end | ||
end | ||
end | ||
end |