mirror of
https://github.com/kemko/paperclip.git
synced 2026-01-01 16:05:40 +03:00
492 lines
16 KiB
Ruby
492 lines
16 KiB
Ruby
require 'test_helper'
|
|
|
|
class Dummy
|
|
# This is a dummy class
|
|
end
|
|
|
|
class AttachmentTest < Test::Unit::TestCase
|
|
ATTACHMENT_OPTIONS_TO_VARIABLES_MAPPING = {
|
|
url: :url_template,
|
|
path: :path_template,
|
|
styles: :styles,
|
|
default_url: :default_url,
|
|
default_style: :default_style,
|
|
whiny: :whiny
|
|
}.freeze
|
|
|
|
should "return the path based on the url by default" do
|
|
@attachment = attachment :url => "/:class/:id/:basename"
|
|
@model = @attachment.instance
|
|
@model.id = 1234
|
|
@model.avatar_file_name = "fake.jpg"
|
|
assert_equal "#{Rails.root}/public/fake_models/1234/fake", @attachment.path
|
|
end
|
|
|
|
context "Attachment default_options" do
|
|
setup do
|
|
rebuild_model
|
|
@old_default_options = Paperclip::Attachment.default_options.dup
|
|
@new_default_options = @old_default_options.merge({
|
|
:path => "argle/bargle",
|
|
:url => "fooferon",
|
|
:default_url => "not here.png"
|
|
})
|
|
end
|
|
|
|
teardown do
|
|
Paperclip::Attachment.default_options.merge! @old_default_options
|
|
end
|
|
|
|
should "be overrideable" do
|
|
Paperclip::Attachment.default_options.merge!(@new_default_options)
|
|
@new_default_options.keys.each do |key|
|
|
assert_equal @new_default_options[key],
|
|
Paperclip::Attachment.default_options[key]
|
|
end
|
|
end
|
|
|
|
context "without an Attachment" do
|
|
setup do
|
|
@dummy = Dummy.new
|
|
end
|
|
|
|
should "return false when asked exists?" do
|
|
assert !@dummy.avatar.exists?
|
|
end
|
|
end
|
|
|
|
context "on an Attachment" do
|
|
setup do
|
|
@dummy = Dummy.new
|
|
@attachment = @dummy.avatar
|
|
end
|
|
|
|
ATTACHMENT_OPTIONS_TO_VARIABLES_MAPPING.each do |option, variable|
|
|
should "be the default_options for #{option}" do
|
|
assert_equal @old_default_options[option],
|
|
@attachment.class.instance_variable_get("@#{variable}")
|
|
end
|
|
end
|
|
|
|
context "when redefined" do
|
|
setup do
|
|
rebuild_class @new_default_options
|
|
@dummy = Dummy.new
|
|
@attachment = @dummy.avatar
|
|
end
|
|
|
|
ATTACHMENT_OPTIONS_TO_VARIABLES_MAPPING.each do |option, variable|
|
|
should "be the new default_options for #{option}" do
|
|
assert_equal @new_default_options[option],
|
|
@attachment.class.instance_variable_get("@#{variable}")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "An attachment with similarly named interpolations" do
|
|
setup do
|
|
rebuild_model :path => ":id.omg/:id-bbq/:id/what/:id_partition.wtf"
|
|
@dummy = Dummy.new
|
|
@dummy.stubs(:id).returns(1024)
|
|
@file = File.new(File.join(File.dirname(__FILE__),
|
|
"fixtures",
|
|
"5k.png"), 'rb')
|
|
@dummy.avatar = @file
|
|
end
|
|
|
|
teardown { @file.close }
|
|
|
|
should "make sure that they are interpolated correctly" do
|
|
assert_equal "1024.omg/1024-bbq/1024/what/000/001/024.wtf", @dummy.avatar.path
|
|
end
|
|
end
|
|
|
|
context "An attachment with a :rails_env interpolation" do
|
|
setup do
|
|
@rails_env = "blah"
|
|
@id = 1024
|
|
rebuild_model :path => ":rails_env/:id.png"
|
|
@dummy = Dummy.new
|
|
@dummy.stubs(:id).returns(@id)
|
|
@file = StringIO.new(".")
|
|
@dummy.avatar = @file
|
|
Rails.stubs(:env).returns(@rails_env)
|
|
end
|
|
|
|
should "return the proper path" do
|
|
assert_equal "#{@rails_env}/#{@id}.png", @dummy.avatar.path
|
|
end
|
|
end
|
|
|
|
context "An attachment with a default style and an extension interpolation" do
|
|
setup do
|
|
@attachment = attachment :path => ":basename.:extension",
|
|
:styles => { :default => ["100x100", :png] },
|
|
:default_style => :default
|
|
@attachment.post_processing = false
|
|
@file = StringIO.new("...")
|
|
@file.stubs(:original_filename).returns("file.jpg")
|
|
end
|
|
|
|
should "return the right extension for the path" do
|
|
@attachment.assign(@file)
|
|
assert_equal "file.png", @attachment.path
|
|
end
|
|
end
|
|
|
|
context "An attachment with both 'normal' and hash-style styles" do
|
|
setup do
|
|
rebuild_model :styles => {
|
|
:normal => ["50x50#", :png],
|
|
:hash => { :geometry => "50x50#", :format => :png }
|
|
}
|
|
@dummy = Dummy.new
|
|
@attachment = @dummy.avatar
|
|
end
|
|
|
|
[:processors, :whiny, :convert_options, :geometry, :format].each do |field|
|
|
should "have the same #{field} field" do
|
|
assert_equal @attachment.styles[:normal][field], @attachment.styles[:hash][field]
|
|
end
|
|
end
|
|
end
|
|
|
|
class Paperclip::Test < Paperclip::Processor; end
|
|
|
|
context "An attachment with multiple processors" do
|
|
setup do
|
|
@style_params = { :once => {:one => 1, :two => 2} }
|
|
rebuild_model :processors => [:thumbnail, :test], :styles => @style_params
|
|
@dummy = Dummy.new
|
|
@file = StringIO.new("...")
|
|
@file.stubs(:to_tempfile).returns(@file)
|
|
Paperclip::Test.stubs(:make).returns(@file)
|
|
Paperclip::Thumbnail.stubs(:make).returns(@file)
|
|
@dummy.avatar.stubs(:content_type).returns('image/wow')
|
|
end
|
|
|
|
context "when assigned" do
|
|
setup { @dummy.avatar = @file }
|
|
|
|
before_should "call #make on all specified processors" do
|
|
expected_params = @style_params[:once].merge({:processors => [:thumbnail, :test], :whiny => true, :convert_options => ""})
|
|
Paperclip::Thumbnail.expects(:make).with(@file, expected_params, @dummy.avatar).returns(@file)
|
|
Paperclip::Test.expects(:make).with(@file, expected_params, @dummy.avatar).returns(@file)
|
|
end
|
|
|
|
before_should "call #make with attachment passed as third argument" do
|
|
expected_params = @style_params[:once].merge({:processors => [:thumbnail, :test], :whiny => true, :convert_options => ""})
|
|
Paperclip::Test.expects(:make).with(@file, expected_params, @dummy.avatar).returns(@file)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "An attachment with no processors defined" do
|
|
setup do
|
|
rebuild_model :processors => [], :styles => {:something => 1}
|
|
@dummy = Dummy.new
|
|
@file = StringIO.new("...")
|
|
@dummy.avatar.stubs(:content_type).returns('image/wow')
|
|
end
|
|
should "raise when assigned to" do
|
|
assert_raises(RuntimeError){ @dummy.avatar = @file }
|
|
end
|
|
end
|
|
|
|
context "Assigning an attachment" do
|
|
setup do
|
|
rebuild_model :styles => { :something => "100x100#" }
|
|
@file = StringIO.new(".")
|
|
@file.expects(:original_filename).returns("5k.png\n\n")
|
|
@file.stubs(:content_type).returns("image/png\n\n")
|
|
@file.stubs(:to_tempfile).returns(@file)
|
|
@dummy = Dummy.new
|
|
Paperclip::Thumbnail.expects(:make).returns(@file)
|
|
@attachment = @dummy.avatar
|
|
@dummy.avatar = @file
|
|
@dummy.stubs(:content_type).returns('image/wow')
|
|
end
|
|
|
|
should "strip whitespace from original_filename field" do
|
|
assert_equal "5k.png", @dummy.avatar.original_filename
|
|
end
|
|
|
|
should "strip whitespace from content_type field" do
|
|
assert_equal "image/png", @dummy.avatar.instance.avatar_content_type
|
|
end
|
|
end
|
|
|
|
context "An attachment" do
|
|
setup do
|
|
@old_defaults = Paperclip::Attachment.default_options.dup
|
|
Paperclip::Attachment.default_options.merge!({
|
|
:path => "./tmp/:attachment/:class/:style/:id/:basename.:extension"
|
|
})
|
|
FileUtils.rm_rf("tmp")
|
|
rebuild_model
|
|
@instance = Dummy.new
|
|
@attachment = Paperclip::Attachment.build_class(:avatar).new(@instance)
|
|
@file = File.new(File.join(File.dirname(__FILE__),
|
|
"fixtures",
|
|
"5k.png"), 'rb')
|
|
end
|
|
|
|
teardown do
|
|
@file&.close
|
|
Paperclip::Attachment.default_options.merge!(@old_defaults)
|
|
end
|
|
|
|
should "raise if there are not the correct columns when you try to assign" do
|
|
@other_attachment = Paperclip::Attachment.build_class(:not_here).new(@instance)
|
|
assert_raises(Paperclip::PaperclipError) do
|
|
@other_attachment.assign(@file)
|
|
end
|
|
end
|
|
|
|
should "return its default_url when no file assigned" do
|
|
assert @attachment.to_file.nil?
|
|
assert_equal "/avatars/original/missing.png", @attachment.url
|
|
assert_equal "/avatars/blah/missing.png", @attachment.url(:blah)
|
|
end
|
|
|
|
should "return nil as path when no file assigned" do
|
|
assert @attachment.to_file.nil?
|
|
assert_equal nil, @attachment.path
|
|
assert_equal nil, @attachment.path(:blah)
|
|
end
|
|
|
|
context "with a file assigned in the database" do
|
|
setup do
|
|
@attachment.stubs(:instance_read).with(:file_name).returns("5k.png")
|
|
@attachment.stubs(:instance_read).with(:content_type).returns("image/png")
|
|
@attachment.stubs(:instance_read).with(:file_size).returns(12345)
|
|
now = Time.now
|
|
Time.stubs(:now).returns(now)
|
|
@attachment.stubs(:instance_read).with(:updated_at).returns(Time.now)
|
|
end
|
|
|
|
should "return a correct url even if the file does not exist" do
|
|
assert_nil @attachment.to_file
|
|
assert_match %r{^/system/avatars/#{@instance.id}/blah/5k\.png}, @attachment.url(:blah)
|
|
end
|
|
|
|
should "make sure the updated_at mtime is in the url if it is defined" do
|
|
assert_match %r{#{Time.now.to_i}$}, @attachment.url(:blah)
|
|
end
|
|
|
|
should "make sure the updated_at mtime is NOT in the url if false is passed to the url method" do
|
|
assert_no_match %r{#{Time.now.to_i}$}, @attachment.url(:blah, false)
|
|
end
|
|
|
|
context "with the updated_at field removed" do
|
|
setup do
|
|
@attachment.stubs(:instance_read).with(:updated_at).returns(nil)
|
|
end
|
|
|
|
should "only return the url without the updated_at when sent #url" do
|
|
assert_match "/avatars/#{@instance.id}/blah/5k.png", @attachment.url(:blah)
|
|
end
|
|
end
|
|
|
|
should "return the proper path when filename has a single .'s" do
|
|
assert_equal "./tmp/avatars/dummies/original/#{@instance.id}/5k.png", @attachment.path
|
|
end
|
|
|
|
should "return the proper path when filename has multiple .'s" do
|
|
@attachment.stubs(:instance_read).with(:file_name).returns("5k.old.png")
|
|
assert_equal "./tmp/avatars/dummies/original/#{@instance.id}/5k.old.png", @attachment.path
|
|
end
|
|
|
|
context "when expecting three styles" do
|
|
setup do
|
|
styles = {:styles => { :large => ["400x400", :png],
|
|
:medium => ["100x100", :gif],
|
|
:small => ["32x32#", :jpg]}}
|
|
@attachment = Paperclip::Attachment.build_class(:avatar, styles).new(@instance)
|
|
end
|
|
|
|
context "and assigned a file" do
|
|
setup do
|
|
now = Time.now
|
|
Time.stubs(:now).returns(now)
|
|
@attachment.assign(@file)
|
|
end
|
|
|
|
should "be dirty" do
|
|
assert @attachment.dirty?
|
|
end
|
|
|
|
context "and saved" do
|
|
setup do
|
|
@attachment.save
|
|
end
|
|
|
|
should "return the real url" do
|
|
file = @attachment.to_file
|
|
assert file
|
|
assert_match %r{^/system/avatars/#{@instance.id}/original/5k\.png}, @attachment.url
|
|
assert_match %r{^/system/avatars/#{@instance.id}/small/5k\.jpg}, @attachment.url(:small)
|
|
file.close
|
|
end
|
|
|
|
should "commit the files to disk" do
|
|
[:large, :medium, :small].each do |style|
|
|
io = @attachment.to_io(style)
|
|
assert File.exist?(io)
|
|
assert ! io.is_a?(::Tempfile)
|
|
io.close
|
|
end
|
|
end
|
|
|
|
should "save the files as the right formats and sizes" do
|
|
[[:large, 400, 61, "PNG"],
|
|
[:medium, 100, 15, "GIF"],
|
|
[:small, 32, 32, "JPEG"]].each do |style|
|
|
cmd = %Q[identify -format "%w %h %b %m" "#{@attachment.path(style.first)}"]
|
|
out = `#{cmd}`
|
|
width, height, _size, format = out.split(" ")
|
|
assert_equal style[1].to_s, width.to_s
|
|
assert_equal style[2].to_s, height.to_s
|
|
assert_equal style[3].to_s, format.to_s
|
|
end
|
|
end
|
|
|
|
should "still have its #file attribute not be nil" do
|
|
assert ! (file = @attachment.to_file).nil?
|
|
file.close
|
|
end
|
|
|
|
context "and trying to delete" do
|
|
setup do
|
|
@existing_names = @attachment.styles.keys.collect do |style|
|
|
@attachment.path(style)
|
|
end
|
|
end
|
|
|
|
should "delete the files after assigning nil" do
|
|
@attachment.assign nil
|
|
@attachment.save
|
|
@existing_names.each { |f| assert !File.exist?(f) }
|
|
end
|
|
|
|
should "delete the files when you call #clear and #save" do
|
|
@attachment.clear
|
|
@attachment.save
|
|
@existing_names.each { |f| assert !File.exist?(f) }
|
|
end
|
|
|
|
should "delete the files when you call #delete" do
|
|
@attachment.destroy
|
|
@existing_names.each { |f| assert !File.exist?(f) }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when trying a nonexistant storage type" do
|
|
should "not be able to find the module" do
|
|
assert_raise(NameError) { rebuild_model storage: :not_here }
|
|
end
|
|
end
|
|
end
|
|
|
|
context "An attachment with only a avatar_file_name column" do
|
|
setup do
|
|
ActiveRecord::Base.connection.create_table :dummies, :force => true do |table|
|
|
table.column :avatar_file_name, :string
|
|
end
|
|
rebuild_class
|
|
@dummy = Dummy.new
|
|
@file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png"), 'rb')
|
|
end
|
|
|
|
teardown { @file.close }
|
|
|
|
should "not error when assigned an attachment" do
|
|
assert_nothing_raised { @dummy.avatar = @file }
|
|
end
|
|
|
|
should "return the time when sent #avatar_updated_at" do
|
|
now = Time.now
|
|
Time.stubs(:now).returns(now)
|
|
@dummy.avatar = @file
|
|
assert now.to_s, @dummy.avatar.updated_at.to_s
|
|
end
|
|
|
|
should "return nil when reloaded and sent #avatar_updated_at" do
|
|
@dummy.save
|
|
@dummy.reload
|
|
assert_nil @dummy.avatar.updated_at
|
|
end
|
|
|
|
should "return the right value when sent #avatar_file_size" do
|
|
@dummy.avatar = @file
|
|
assert_equal @file.size, @dummy.avatar.size
|
|
end
|
|
|
|
context "and avatar_updated_at column" do
|
|
setup do
|
|
ActiveRecord::Base.connection.add_column :dummies, :avatar_updated_at, :timestamp
|
|
rebuild_class
|
|
@dummy = Dummy.new
|
|
end
|
|
|
|
should "not error when assigned an attachment" do
|
|
assert_nothing_raised { @dummy.avatar = @file }
|
|
end
|
|
|
|
should "return the right value when sent #avatar_updated_at" do
|
|
now = Time.now
|
|
Time.stubs(:now).returns(now)
|
|
@dummy.avatar = @file
|
|
assert_equal now.to_i, @dummy.avatar.updated_at
|
|
end
|
|
end
|
|
|
|
context "and avatar_content_type column" do
|
|
setup do
|
|
ActiveRecord::Base.connection.add_column :dummies, :avatar_content_type, :string
|
|
rebuild_class
|
|
@dummy = Dummy.new
|
|
end
|
|
|
|
should "not error when assigned an attachment" do
|
|
assert_nothing_raised { @dummy.avatar = @file }
|
|
end
|
|
|
|
should "return the right value when sent #avatar_content_type" do
|
|
@dummy.avatar = @file
|
|
assert_equal "image/png", @dummy.avatar.content_type
|
|
end
|
|
end
|
|
|
|
context "and avatar_file_size column" do
|
|
setup do
|
|
ActiveRecord::Base.connection.add_column :dummies, :avatar_file_size, :integer
|
|
rebuild_class
|
|
@dummy = Dummy.new
|
|
end
|
|
|
|
should "not error when assigned an attachment" do
|
|
assert_nothing_raised { @dummy.avatar = @file }
|
|
end
|
|
|
|
should "return the right value when sent #avatar_file_size" do
|
|
@dummy.avatar = @file
|
|
assert_equal @file.size, @dummy.avatar.size
|
|
end
|
|
|
|
should "return the right value when saved, reloaded, and sent #avatar_file_size" do
|
|
@dummy.avatar = @file
|
|
@dummy.save
|
|
@dummy = Dummy.find(@dummy.id)
|
|
assert_equal @file.size, @dummy.avatar.size
|
|
end
|
|
end
|
|
end
|
|
end
|