Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

all tests pass

git-svn-id: http://svn.techno-weenie.net/projects/plugins/attachment_fu@2553 567b1171-46fb-0310-a4c9-b4bef9110e78
  • Loading branch information...
commit f83683b55e5d03c439b9ccaca185eac515bcc909 1 parent 54b1449
technoweenie authored
View
77 lib/technoweenie/attachment_fu.rb
@@ -1,4 +1,5 @@
require File.join(File.dirname(__FILE__), 'attachment_fu', 'backends')
+require File.join(File.dirname(__FILE__), 'attachment_fu', 'processors')
module Technoweenie # :nodoc:
module AttachmentFu # :nodoc:
@@ -46,20 +47,22 @@ def has_attachment(options = {})
unless included_modules.include? InstanceMethods
class_inheritable_accessor :attachment_options
+ options[:processor] ||= :rmagick
options[:storage] ||= options[:file_system_path] ? :file_system : :db_file
options[:file_system_path] ||= File.join("public", table_name)
options[:file_system_path] = options[:file_system_path][1..-1] if options[:file_system_path].first == '/'
- ##with_options :foreign_key => 'parent_id' do |m|
- ## m.has_many :thumbnails, :dependent => :destroy, :class_name => options[:thumbnail_class].to_s
- ## m.belongs_to :parent, :class_name => self.base_class.to_s
- ##end
-
- ##after_save :create_attachment_thumbnails # allows thumbnails with parent_id to be created
+ with_options :foreign_key => 'parent_id' do |m|
+ m.has_many :thumbnails, :dependent => :destroy, :class_name => options[:thumbnail_class].to_s
+ m.belongs_to :parent, :class_name => base_class.to_s
+ end
after_destroy :destroy_file
extend ClassMethods
- include InstanceMethods, Technoweenie::AttachmentFu::const_get("#{options[:storage].to_s.classify}Backend")
+ include InstanceMethods
+ include Technoweenie::AttachmentFu::const_get("#{options[:storage].to_s.classify}Backend")
+ include Technoweenie::AttachmentFu::const_get("#{options[:processor].to_s.classify}Processor")
+ before_save :process_attachment
end
options[:content_type] = [options[:content_type]].flatten.collect { |t| t == :image ? Technoweenie::ActsAsAttachment.content_types : t }.flatten unless options[:content_type].nil?
@@ -81,6 +84,18 @@ def image?(content_type)
content_types.include?(content_type)
end
+ # Callback after an image has been resized.
+ #
+ # class Foo < ActiveRecord::Base
+ # acts_as_attachment
+ # after_resize do |record, img|
+ # record.aspect_ratio = img.columns.to_f / img.rows.to_f
+ # end
+ # end
+ def after_resize(&block)
+ write_inheritable_array(:after_resize, [block])
+ end
+
# Callback after an attachment has been saved either to the file system or the DB.
# Only called if the file has been changed, not necessarily if the record is updated.
#
@@ -93,6 +108,25 @@ def image?(content_type)
def after_attachment_saved(&block)
write_inheritable_array(:after_attachment_saved, [block])
end
+
+ # Callback before a thumbnail is saved. Use this to pass any necessary extra attributes that may be required.
+ #
+ # class Foo < ActiveRecord::Base
+ # acts_as_attachment
+ # before_thumbnail_saved do |record, thumbnail|
+ # ...
+ # end
+ # end
+ def before_thumbnail_saved(&block)
+ write_inheritable_array(:before_thumbnail_saved, [block])
+ end
+
+ # Get the thumbnail class, which is the current attachment class by default.
+ # Configure this with the :thumbnail_class option.
+ def thumbnail_class
+ attachment_options[:thumbnail_class] = attachment_options[:thumbnail_class].constantize unless attachment_options[:thumbnail_class].is_a?(Class)
+ attachment_options[:thumbnail_class]
+ end
end
module InstanceMethods
@@ -152,7 +186,6 @@ def attachment_data=(data)
@attachment_data = nil
@save_attachment = false
self.size = 0
- return nil if data.nil?
if data
self.size = data.length
@@ -160,6 +193,26 @@ def attachment_data=(data)
@attachment_data = data
end
end
+
+ # sets a temporary location to the asset. Use this if the file is already on the local file system
+ # and if you do not need to load it into memory.
+ def attachment_file=(file)
+ @attachment_file = nil
+ @save_attachment = false
+ self.size = 0
+
+ if file && File.file?(file)
+ file_stat = File.stat(file)
+ self.size = file_stat.size
+ @save_attachment = true
+ @attachment_file = file
+ end
+ end
+
+ # Retrieve the temporary attachment file data if it exists, or return nil
+ def attachment_file_data
+ (@attachment_file && File.file?(@attachment_file)) ? File.read(@attachment_file) : nil
+ end
# Sets the content type.
def content_type=(new_type)
@@ -171,6 +224,11 @@ def filename=(new_name)
write_attribute :filename, sanitize_filename(new_name)
end
+ # Returns the width/height in a suitable format for the image_tag helper: (100x100)
+ def image_size
+ [width.to_s, height.to_s] * 'x'
+ end
+
protected
@@filename_basename_regex = /^.*(\\|\/)/
@@filename_character_regex = /[^\w\.\-]/
@@ -193,6 +251,9 @@ def attachment_attributes_valid?
end
end
+ # Stub for a #process_attachment method in a processor
+ def process_attachment() end
+
# Yanked from ActiveRecord::Callbacks, modified so I can pass args to the callbacks besides self.
# Only accept blocks, however
def callback_with_args(method, arg = self)
View
5 lib/technoweenie/attachment_fu/backends.rb
@@ -11,7 +11,7 @@ def self.included(base) #:nodoc:
def attachment_data
return @attachment_data if @attachment_data
- filename = full_filename
+ filename = @attachment_file || full_filename
File.open(filename, 'rb') do |file|
@attachment_data = file.read
end if File.file?(filename)
@@ -89,13 +89,14 @@ def save_to_storage
# Methods for DB backed attachments
module DbFileBackend
def self.included(base) #:nodoc:
+ Object.const_set(:DbFile, Class.new(ActiveRecord::Base)) unless Object.const_defined?(:DbFile)
base.belongs_to :db_file, :class_name => '::DbFile', :foreign_key => 'db_file_id'
base.before_save :save_to_storage # so the db_file_id can be set
end
# Gets the attachment data
def attachment_data
- @attachment_data ||= db_file.data
+ @attachment_data ||= (attachment_file_data || db_file.data)
end
# Destroys the file. Called in the after_destroy callback
View
106 lib/technoweenie/attachment_fu/processors.rb
@@ -0,0 +1,106 @@
+module Technoweenie # :nodoc:
+ module AttachmentFu # :nodoc:
+ module RmagickProcessor
+ def self.included(base)
+ begin
+ require 'RMagick'
+ rescue LoadError
+ # boo hoo no rmagick
+ end
+ base.after_save :create_attachment_thumbnails # allows thumbnails with parent_id to be created
+ base.send :extend, ClassMethods
+ end
+
+ module ClassMethods
+ # Yields a block containing an RMagick Image for the given binary data.
+ def with_image(data, &block)
+ begin
+ binary_data = data.is_a?(Magick::Image) ? data : Magick::Image::from_blob(data).first unless !Object.const_defined?(:Magick)
+ rescue
+ # Log the failure to load the image. This should match ::Magick::ImageMagickError
+ # but that would cause acts_as_attachment to require rmagick.
+ logger.debug("Exception working with image: #{$!}")
+ binary_data = nil
+ end
+ block.call binary_data if block && binary_data
+ ensure
+ !binary_data.nil?
+ end
+ end
+
+ # Allows you to work with an RMagick representation of the attachment in a block.
+ #
+ # @attachment.with_image do |img|
+ # self.data = img.thumbnail(100, 100).to_blob
+ # end
+ #
+ def with_image(data = self.attachment_data, &block)
+ self.class.with_image(data, &block)
+ end
+
+ # Creates or updates the thumbnail for the current attachment.
+ def create_or_update_thumbnail(file_name_suffix, *size)
+ thumbnailable? || raise(ThumbnailError.new("Can't create a thumbnail if the content type is not an image or there is no parent_id column"))
+ returning find_or_initialize_thumbnail(file_name_suffix) do |thumb|
+ resized_image = resize_image_to(size)
+ return if resized_image.nil?
+ thumb.attributes = {
+ :content_type => content_type,
+ :filename => thumbnail_name_for(file_name_suffix),
+ :attachment_data => resized_image.to_blob
+ }
+ callback_with_args :before_thumbnail_saved, thumb
+ thumb.save!
+ end
+ end
+
+ # Resizes a thumbnail.
+ def resize_image_to(size)
+ thumb = nil
+ with_image do |img|
+ thumb = thumbnail_for_image(img, size)
+ end
+ thumb
+ end
+
+ protected
+ def create_attachment_thumbnails
+ if thumbnailable? && @save_attachment && !attachment_options[:thumbnails].blank? && parent_id.nil?
+ attachment_options[:thumbnails].each { |suffix, size| create_or_update_thumbnail(suffix, size) }
+ end
+ if @save_attachment
+ @save_attachment = nil
+ callback :after_attachment_saved
+ end
+ end
+
+ # Performs the actual resizing operation for a thumbnail
+ def thumbnail_for_image(img, size)
+ size = size.first if size.is_a?(Array) && size.length == 1 && !size.first.is_a?(Fixnum)
+ if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))
+ size = [size, size] if size.is_a?(Fixnum)
+ img.thumbnail(size.first, size[1])
+ else
+ img.change_geometry(size.to_s) { |cols, rows, image| image.resize(cols, rows) }
+ end
+ end
+
+ def find_or_initialize_thumbnail(file_name_suffix)
+ respond_to?(:parent_id) ?
+ thumbnail_class.find_or_initialize_by_thumbnail_and_parent_id(file_name_suffix.to_s, id) :
+ thumbnail_class.find_or_initialize_by_thumbnail(file_name_suffix.to_s)
+ end
+
+ def process_attachment
+ with_image do |img|
+ resized_img = (attachment_options[:resize_to] && (!respond_to?(:parent_id) || parent_id.nil?)) ?
+ thumbnail_for_image(img, attachment_options[:resize_to]) : img
+ self.width = resized_img.columns if respond_to?(:width)
+ self.height = resized_img.rows if respond_to?(:height)
+ self.attachment_data = resized_img.to_blob
+ callback_with_args :after_resize, resized_img
+ end if image?
+ end
+ end
+ end
+end
View
16 test/backends/db_file_test.rb
@@ -0,0 +1,16 @@
+require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))
+
+class DbFileTest < Test::Unit::TestCase
+ include BaseAttachmentTests
+ attachment_model Attachment
+
+ def test_should_call_after_attachment_saved(klass = Attachment)
+ attachment_model.saves = 0
+ assert_created do
+ upload_file :filename => '/files/rails.png'
+ end
+ assert_equal 1, attachment_model.saves
+ end
+
+ test_against_subclass :test_should_call_after_attachment_saved, Attachment
+end
View
78 test/backends/file_system_test.rb
@@ -0,0 +1,78 @@
+require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))
+
+class FileSystemTest < Test::Unit::TestCase
+ include BaseAttachmentTests
+ attachment_model FileAttachment
+
+ def test_filesystem_size_for_file_attachment(klass = FileAttachment)
+ attachment_model klass
+ assert_created 1 do
+ attachment = upload_file :filename => '/files/rails.png'
+ assert_equal attachment.size, File.open(attachment.full_filename).stat.size
+ end
+ end
+
+ test_against_subclass :test_filesystem_size_for_file_attachment, FileAttachment
+
+ def test_should_not_overwrite_file_attachment(klass = FileAttachment)
+ attachment_model klass
+ assert_created 2 do
+ real = upload_file :filename => '/files/rails.png'
+ assert_valid real
+ assert !real.new_record?, real.errors.full_messages.join("\n")
+ assert !real.size.zero?
+
+ fake = upload_file :filename => '/files/fake/rails.png'
+ assert_valid fake
+ assert !fake.size.zero?
+
+ assert_not_equal File.open(real.full_filename).stat.size, File.open(fake.full_filename).stat.size
+ end
+ end
+
+ test_against_subclass :test_should_not_overwrite_file_attachment, FileAttachment
+
+ def test_should_store_file_attachment_in_filesystem(klass = FileAttachment)
+ attachment_model klass
+ attachment = nil
+ assert_created do
+ attachment = upload_file :filename => '/files/rails.png'
+ assert_valid attachment
+ assert File.exists?(attachment.full_filename), "#{attachment.full_filename} does not exist"
+ end
+ attachment
+ end
+
+ test_against_subclass :test_should_store_file_attachment_in_filesystem, FileAttachment
+
+ def test_should_delete_old_file_when_updating(klass = FileAttachment)
+ attachment_model klass
+ attachment = upload_file :filename => '/files/rails.png'
+ old_filename = attachment.full_filename
+ assert_not_created do
+ attachment.filename = 'rails2.png'
+ attachment.attachment_data = IO.read(File.join(Test::Unit::TestCase.fixture_path, 'files/rails.png'))
+ attachment.save
+ assert File.exists?(attachment.full_filename), "#{attachment.full_filename} does not exist"
+ assert !File.exists?(old_filename), "#{old_filename} still exists"
+ end
+ end
+
+ test_against_subclass :test_should_delete_old_file_when_updating, FileAttachment
+
+ def test_should_delete_old_file_when_renaming(klass = FileAttachment)
+ attachment_model klass
+ attachment = upload_file :filename => '/files/rails.png'
+ old_filename = attachment.full_filename
+ assert_not_created do
+ attachment.filename = 'rails2.png'
+ attachment.save
+ assert File.exists?(attachment.full_filename), "#{attachment.full_filename} does not exist"
+ assert !File.exists?(old_filename), "#{old_filename} still exists"
+ assert !attachment.reload.size.zero?
+ assert_equal 'rails2.png', attachment.filename
+ end
+ end
+
+ test_against_subclass :test_should_delete_old_file_when_renaming, FileAttachment
+end
View
47 test/base_attachment_tests.rb
@@ -0,0 +1,47 @@
+module BaseAttachmentTests
+ def test_should_create_file_from_uploaded_file
+ assert_created do
+ attachment = upload_file :filename => '/files/foo.txt'
+ assert_valid attachment
+ assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)
+ assert attachment.image?
+ assert !attachment.size.zero?
+ #assert_equal 3, attachment.size
+ assert_nil attachment.width
+ assert_nil attachment.height
+ end
+ end
+
+ def test_reassign_attribute_data
+ assert_created 1 do
+ attachment = upload_file :filename => '/files/rails.png'
+ assert_valid attachment
+ assert attachment.attachment_data.size > 0, "no data was set"
+
+ attachment.attachment_data = 'wtf'
+ attachment.save
+
+ assert_equal 'wtf', attachment_model.find(attachment.id).attachment_data
+ end
+ end
+
+ def test_no_reassign_attribute_data_on_nil
+ assert_created 1 do
+ attachment = upload_file :filename => '/files/rails.png'
+ assert_valid attachment
+ assert attachment.attachment_data.size > 0, "no data was set"
+
+ attachment.attachment_data = nil
+ assert !attachment.save_attachment?
+ end
+ end
+
+ def test_should_overwrite_old_contents_when_updating
+ attachment = upload_file :filename => '/files/rails.png'
+ assert_not_created do # no new db_file records
+ attachment.filename = 'rails2.png'
+ attachment.attachment_data = IO.read(File.join(Test::Unit::TestCase.fixture_path, 'files', 'rails.png'))
+ attachment.save
+ end
+ end
+end
View
2  test/basic_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.dirname(__FILE__), 'test_helper')
+require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
class BasicTest < Test::Unit::TestCase
def test_should_set_default_min_size
View
57 test/extra_attachment_test.rb
@@ -0,0 +1,57 @@
+require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
+
+class OrphanAttachmentTest < Test::Unit::TestCase
+ include BaseAttachmentTests
+ attachment_model OrphanAttachment
+
+ def test_should_create_image_from_uploaded_file
+ assert_created do
+ attachment = upload_file :filename => '/files/rails.png'
+ assert_valid attachment
+ assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)
+ assert attachment.image?
+ assert !attachment.size.zero?
+ end
+ end
+
+ def test_should_create_file_from_uploaded_file
+ assert_created do
+ attachment = upload_file :filename => '/files/foo.txt'
+ assert_valid attachment
+ assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)
+ assert attachment.image?
+ assert !attachment.size.zero?
+ end
+ end
+
+ def test_should_create_image_from_uploaded_file_with_custom_content_type
+ assert_created do
+ attachment = upload_file :content_type => 'foo/bar', :filename => '/files/rails.png'
+ assert_valid attachment
+ assert !attachment.image?
+ assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)
+ assert !attachment.size.zero?
+ #assert_equal 1784, attachment.size
+ end
+ end
+
+ def test_should_create_thumbnail
+ attachment = upload_file :filename => '/files/rails.png'
+
+ assert_raise Technoweenie::AttachmentFu::ThumbnailError do
+ attachment.create_or_update_thumbnail('thumb', 50, 50)
+ end
+ end
+
+ def test_should_create_thumbnail_with_geometry_string
+ attachment = upload_file :filename => '/files/rails.png'
+
+ assert_raise Technoweenie::AttachmentFu::ThumbnailError do
+ attachment.create_or_update_thumbnail('thumb', 'x50')
+ end
+ end
+end
+
+class MinimalAttachmentTest < OrphanAttachmentTest
+ attachment_model MinimalAttachment
+end
View
12 test/fixtures/attachment.rb
@@ -34,9 +34,9 @@ class ImageOrPdfAttachment < Attachment
class ImageWithThumbsAttachment < Attachment
has_attachment :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }, :resize_to => [55,55]
- #after_resize do |record, img|
- # record.aspect_ratio = img.columns.to_f / img.rows.to_f
- #end
+ after_resize do |record, img|
+ record.aspect_ratio = img.columns.to_f / img.rows.to_f
+ end
end
class FileAttachment < ActiveRecord::Base
@@ -52,9 +52,9 @@ class ImageFileAttachment < FileAttachment
class ImageWithThumbsFileAttachment < FileAttachment
has_attachment :file_system_path => 'vendor/plugins/attachment_fu/test/files',
:thumbnails => { :thumb => [50, 50], :geometry => 'x50' }, :resize_to => [55,55]
- #after_resize do |record, img|
- # record.aspect_ratio = img.columns.to_f / img.rows.to_f
- #end
+ after_resize do |record, img|
+ record.aspect_ratio = img.columns.to_f / img.rows.to_f
+ end
end
class ImageWithThumbsClassFileAttachment < FileAttachment
View
63 test/image_attachment_tests.rb
@@ -0,0 +1,63 @@
+module ImageAttachmentTests
+ def test_should_create_image_from_uploaded_file
+ assert_created do
+ attachment = upload_file :filename => '/files/rails.png'
+ assert_valid attachment
+ assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)
+ assert attachment.image?
+ assert !attachment.size.zero?
+ #assert_equal 1784, attachment.size
+ assert_equal 50, attachment.width
+ assert_equal 64, attachment.height
+ assert_equal '50x64', attachment.image_size
+ end
+ end
+
+ def test_should_create_image_from_uploaded_file_with_custom_content_type
+ assert_created do
+ attachment = upload_file :content_type => 'foo/bar', :filename => '/files/rails.png'
+ assert_valid attachment
+ assert !attachment.image?
+ assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)
+ assert !attachment.size.zero?
+ #assert_equal 1784, attachment.size
+ assert_nil attachment.width
+ assert_nil attachment.height
+ assert_equal [], attachment.thumbnails
+ end
+ end
+
+ def test_should_create_thumbnail
+ attachment = upload_file :filename => '/files/rails.png'
+
+ assert_created do
+ basename, ext = attachment.filename.split '.'
+ thumbnail = attachment.create_or_update_thumbnail('thumb', 50, 50)
+ assert_valid thumbnail
+ assert !thumbnail.size.zero?
+ #assert_in_delta 4673, thumbnail.size, 2
+ assert_equal 50, thumbnail.width
+ assert_equal 50, thumbnail.height
+ assert_equal [thumbnail.id], attachment.thumbnails.collect(&:id)
+ assert_equal attachment.id, thumbnail.parent_id if thumbnail.respond_to?(:parent_id)
+ assert_equal "#{basename}_thumb.#{ext}", thumbnail.filename
+ end
+ end
+
+ def test_should_create_thumbnail_with_geometry_string
+ attachment = upload_file :filename => '/files/rails.png'
+
+ assert_created do
+ basename, ext = attachment.filename.split '.'
+ thumbnail = attachment.create_or_update_thumbnail('thumb', 'x50')
+ assert_valid thumbnail
+ assert !thumbnail.size.zero?
+ #assert_equal 3915, thumbnail.size
+ assert_equal 39, thumbnail.width
+ assert_equal 50, thumbnail.height
+ assert_equal [thumbnail], attachment.thumbnails
+ assert_equal attachment.id, thumbnail.parent_id if thumbnail.respond_to?(:parent_id)
+ assert_equal "#{basename}_thumb.#{ext}", thumbnail.filename
+ end
+ end
+end
View
166 test/processors/rmagick_test.rb
@@ -0,0 +1,166 @@
+require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))
+
+class RmagickTest < Test::Unit::TestCase
+ include ImageAttachmentTests
+ attachment_model Attachment
+ def test_should_resize_image(klass = ImageAttachment)
+ attachment_model klass
+ assert_equal [50, 50], attachment_model.attachment_options[:resize_to]
+ attachment = upload_file :filename => '/files/rails.png'
+ assert_valid attachment
+ assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)
+ assert attachment.image?
+ assert !attachment.size.zero?
+ #assert_in_delta 4673, attachment.size, 2
+ assert_equal 50, attachment.width
+ assert_equal 50, attachment.height
+ end
+
+ test_against_subclass :test_should_resize_image, ImageAttachment
+
+ def test_should_resize_image_with_geometry(klass = ImageOrPdfAttachment)
+ attachment_model klass
+ assert_equal 'x50', attachment_model.attachment_options[:resize_to]
+ attachment = upload_file :filename => '/files/rails.png'
+ assert_valid attachment
+ assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)
+ assert attachment.image?
+ assert !attachment.size.zero?
+ #assert_equal 3915, attachment.size
+ assert_equal 39, attachment.width
+ assert_equal 50, attachment.height
+ end
+
+ test_against_subclass :test_should_resize_image_with_geometry, ImageOrPdfAttachment
+
+ def test_should_give_correct_thumbnail_filenames(klass = ImageWithThumbsFileAttachment)
+ attachment_model klass
+ assert_created 3 do
+ attachment = upload_file :filename => '/files/rails.png'
+ thumb = attachment.thumbnails.detect { |t| t.filename =~ /_thumb/ }
+ geo = attachment.thumbnails.detect { |t| t.filename =~ /_geometry/ }
+
+ [attachment, thumb, geo].each { |record| assert_valid record }
+
+ assert_match /rails\.png$/, attachment.full_filename
+ assert_match /rails_geometry\.png$/, attachment.full_filename(:geometry)
+ assert_match /rails_thumb\.png$/, attachment.full_filename(:thumb)
+ end
+ end
+
+ test_against_subclass :test_should_give_correct_thumbnail_filenames, ImageWithThumbsFileAttachment
+
+ def test_should_automatically_create_thumbnails(klass = ImageWithThumbsAttachment)
+ attachment_model klass
+ assert_created 3 do
+ attachment = upload_file :filename => '/files/rails.png'
+ assert_valid attachment
+ assert !attachment.size.zero?
+ #assert_equal 1784, attachment.size
+ assert_equal 55, attachment.width
+ assert_equal 55, attachment.height
+ assert_equal 2, attachment.thumbnails.length
+ assert_equal 1.0, attachment.aspect_ratio
+
+ thumb = attachment.thumbnails.detect { |t| t.filename =~ /_thumb/ }
+ assert !thumb.new_record?, thumb.errors.full_messages.join("\n")
+ assert !thumb.size.zero?
+ #assert_in_delta 4673, thumb.size, 2
+ assert_equal 50, thumb.width
+ assert_equal 50, thumb.height
+ assert_equal 1.0, thumb.aspect_ratio
+
+ geo = attachment.thumbnails.detect { |t| t.filename =~ /_geometry/ }
+ assert !geo.new_record?, geo.errors.full_messages.join("\n")
+ assert !geo.size.zero?
+ #assert_equal 3915, geo.size
+ assert_equal 50, geo.width
+ assert_equal 50, geo.height
+ assert_equal 1.0, geo.aspect_ratio
+ end
+ end
+
+ test_against_subclass :test_should_automatically_create_thumbnails, ImageWithThumbsAttachment
+
+ # same as above method, but test it on a file model
+ test_against_class :test_should_automatically_create_thumbnails, ImageWithThumbsFileAttachment
+ test_against_subclass :test_should_automatically_create_thumbnails_on_class, ImageWithThumbsFileAttachment
+
+ def test_should_use_thumbnail_subclass(klass = ImageWithThumbsClassFileAttachment)
+ attachment_model klass
+ assert_difference ImageThumbnail, :count do
+ attachment = upload_file :filename => '/files/rails.png'
+ assert_kind_of ImageThumbnail, attachment.thumbnails.first
+ assert_equal attachment.id, attachment.thumbnails.first.parent.id
+ assert_kind_of FileAttachment, attachment.thumbnails.first.parent
+ assert_equal 'rails_thumb.png', attachment.thumbnails.first.filename
+ assert_equal attachment.thumbnails.first.full_filename, attachment.full_filename(attachment.thumbnails.first.thumbnail),
+ "#full_filename does not use thumbnail class' path."
+ end
+ end
+
+ test_against_subclass :test_should_use_thumbnail_subclass, ImageWithThumbsClassFileAttachment
+
+ def test_should_remove_old_thumbnail_files_when_updating(klass = ImageWithThumbsFileAttachment)
+ attachment_model klass
+ attachment = nil
+ assert_created 3 do
+ attachment = upload_file :filename => '/files/rails.png'
+ end
+
+ old_filenames = [attachment.full_filename] + attachment.thumbnails.collect(&:full_filename)
+
+ assert_not_created do
+ attachment.filename = 'rails2.png'
+ attachment.attachment_data = IO.read(File.join(File.dirname(__FILE__), '../fixtures/files/rails.png'))
+ attachment.save
+ new_filenames = [attachment.reload.full_filename] + attachment.thumbnails.collect { |t| t.reload.full_filename }
+ new_filenames.each { |f| assert File.exists?(f), "#{f} does not exist" }
+ old_filenames.each { |f| assert !File.exists?(f), "#{f} still exists" }
+ end
+ end
+
+ test_against_subclass :test_should_remove_old_thumbnail_files_when_updating, ImageWithThumbsFileAttachment
+
+ def test_should_delete_file_when_in_file_system_when_attachment_record_destroyed(klass = ImageWithThumbsFileAttachment)
+ attachment_model klass
+ attachment = upload_file :filename => '/files/rails.png'
+ filenames = [attachment.full_filename] + attachment.thumbnails.collect(&:full_filename)
+ filenames.each { |f| assert File.exists?(f), "#{f} never existed to delete on destroy" }
+ attachment.destroy
+ filenames.each { |f| assert !File.exists?(f), "#{f} still exists" }
+ end
+
+ test_against_subclass :test_should_delete_file_when_in_file_system_when_attachment_record_destroyed, ImageWithThumbsFileAttachment
+
+ def test_should_overwrite_old_thumbnail_records_when_updating(klass = ImageWithThumbsAttachment)
+ attachment_model klass
+ attachment = nil
+ assert_created 3 do
+ attachment = upload_file :filename => '/files/rails.png'
+ end
+ assert_not_created do # no new db_file records
+ attachment.filename = 'rails2.png'
+ attachment.attachment_data = IO.read(File.join(File.dirname(__FILE__), '../fixtures/files/rails.png'))
+ attachment.save
+ end
+ end
+
+ test_against_subclass :test_should_overwrite_old_thumbnail_records_when_updating, ImageWithThumbsAttachment
+
+ def test_should_overwrite_old_thumbnail_records_when_renaming(klass = ImageWithThumbsAttachment)
+ attachment_model klass
+ attachment = nil
+ assert_created 3 do
+ attachment = upload_file :class => klass, :filename => '/files/rails.png'
+ end
+ assert_not_created do # no new db_file records
+ attachment.filename = 'rails2.png'
+ attachment.save
+ assert !attachment.reload.size.zero?
+ assert_equal 'rails2.png', attachment.filename
+ end
+ end
+
+ test_against_subclass :test_should_overwrite_old_thumbnail_records_when_renaming, ImageWithThumbsAttachment
+end
View
8 test/test_helper.rb
@@ -12,7 +12,7 @@
load(File.dirname(__FILE__) + "/schema.rb")
-Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"
+Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures"
$LOAD_PATH.unshift(Test::Unit::TestCase.fixture_path)
class Test::Unit::TestCase #:nodoc:
@@ -26,6 +26,8 @@ def create_fixtures(*table_names)
end
def setup
+ Attachment.saves = 0
+ DbFile.transaction { [Attachment, FileAttachment, OrphanAttachment, MinimalAttachment, DbFile].each { |klass| klass.delete_all } }
FileUtils.rm_rf File.join(File.dirname(__FILE__), 'files')
attachment_model self.class.attachment_model
end
@@ -99,4 +101,6 @@ def attachment_model(klass = nil)
end
end
-require File.join(File.dirname(__FILE__), 'fixtures/attachment')
+require File.join(File.dirname(__FILE__), 'fixtures/attachment')
+require File.join(File.dirname(__FILE__), 'base_attachment_tests')
+require File.join(File.dirname(__FILE__), 'image_attachment_tests')
View
2  test/validation_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.dirname(__FILE__), 'test_helper')
+require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
class ValidationTest < Test::Unit::TestCase
def test_should_invalidate_big_files
Please sign in to comment.
Something went wrong with that request. Please try again.