attachmerb_fu 0.0.1
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.
- data/LICENSE +22 -0
- data/README +166 -0
- data/Rakefile +35 -0
- data/TODO +5 -0
- data/lib/amazon_s3.yml.tpl +14 -0
- data/lib/attachment_fu.rb +431 -0
- data/lib/attachmerb_fu.rb +446 -0
- data/lib/attachmerb_fu/backends/db_file_backend.rb +37 -0
- data/lib/attachmerb_fu/backends/file_system_backend.rb +95 -0
- data/lib/attachmerb_fu/backends/s3_backend.rb +307 -0
- data/lib/attachmerb_fu/merbtasks.rb +6 -0
- data/lib/attachmerb_fu/processors/image_science_processor.rb +60 -0
- data/lib/attachmerb_fu/processors/mini_magick_processor.rb +54 -0
- data/lib/attachmerb_fu/processors/rmagick_processor.rb +51 -0
- data/lib/geometry.rb +93 -0
- data/lib/tempfile_ext.rb +9 -0
- data/lib/test/amazon_s3.yml +6 -0
- data/lib/test/backends/db_file_test.rb +16 -0
- data/lib/test/backends/file_system_test.rb +80 -0
- data/lib/test/backends/remote/s3_test.rb +103 -0
- data/lib/test/base_attachment_tests.rb +57 -0
- data/lib/test/basic_test.rb +64 -0
- data/lib/test/database.yml +18 -0
- data/lib/test/extra_attachment_test.rb +57 -0
- data/lib/test/fixtures/attachment.rb +127 -0
- data/lib/test/fixtures/files/fake/rails.png +0 -0
- data/lib/test/fixtures/files/foo.txt +1 -0
- data/lib/test/fixtures/files/rails.png +0 -0
- data/lib/test/geometry_test.rb +101 -0
- data/lib/test/processors/image_science_test.rb +31 -0
- data/lib/test/processors/mini_magick_test.rb +31 -0
- data/lib/test/processors/rmagick_test.rb +241 -0
- data/lib/test/schema.rb +86 -0
- data/lib/test/test_helper.rb +142 -0
- data/lib/test/validation_test.rb +55 -0
- metadata +107 -0
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'mini_magick'
|
2
|
+
module AttachmerbFu # :nodoc:
|
3
|
+
module Processors
|
4
|
+
module MiniMagickProcessor
|
5
|
+
def self.included(base)
|
6
|
+
base.send :extend, ClassMethods
|
7
|
+
base.alias_method_chain :process_attachment, :processing
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
# Yields a block containing an MiniMagick Image for the given binary data.
|
12
|
+
def with_image(file, &block)
|
13
|
+
begin
|
14
|
+
binary_data = file.is_a?(MiniMagick::Image) ? file : MiniMagick::Image.from_file(file) unless !Object.const_defined?(:MiniMagick)
|
15
|
+
rescue
|
16
|
+
# Log the failure to load the image.
|
17
|
+
logger.debug("Exception working with image: #{$!}")
|
18
|
+
binary_data = nil
|
19
|
+
end
|
20
|
+
block.call binary_data if block && binary_data
|
21
|
+
ensure
|
22
|
+
!binary_data.nil?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
def process_attachment_with_processing
|
28
|
+
return unless process_attachment_without_processing
|
29
|
+
with_image do |img|
|
30
|
+
resize_image_or_thumbnail! img
|
31
|
+
self.width = img[:width] if respond_to?(:width)
|
32
|
+
self.height = img[:height] if respond_to?(:height)
|
33
|
+
callback_with_args :after_resize, img
|
34
|
+
end if image?
|
35
|
+
end
|
36
|
+
|
37
|
+
# Performs the actual resizing operation for a thumbnail
|
38
|
+
def resize_image(img, size)
|
39
|
+
size = size.first if size.is_a?(Array) && size.length == 1
|
40
|
+
if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))
|
41
|
+
if size.is_a?(Fixnum)
|
42
|
+
size = [size, size]
|
43
|
+
img.resize(size.join('x'))
|
44
|
+
else
|
45
|
+
img.resize(size.join('x') + '!')
|
46
|
+
end
|
47
|
+
else
|
48
|
+
img.resize(size.to_s)
|
49
|
+
end
|
50
|
+
self.temp_path = img
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'RMagick'
|
2
|
+
module AttachmerbFu # :nodoc:
|
3
|
+
module Processors
|
4
|
+
module RmagickProcessor
|
5
|
+
def self.included(base)
|
6
|
+
base.send :extend, ClassMethods
|
7
|
+
base.alias_method_chain :process_attachment, :processing
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
# Yields a block containing an RMagick Image for the given binary data.
|
12
|
+
def with_image(file, &block)
|
13
|
+
begin
|
14
|
+
binary_data = file.is_a?(Magick::Image) ? file : Magick::Image.read(file).first unless !Object.const_defined?(:Magick)
|
15
|
+
rescue
|
16
|
+
# Log the failure to load the image. This should match ::Magick::ImageMagickError
|
17
|
+
# but that would cause acts_as_attachment to require rmagick.
|
18
|
+
logger.debug("Exception working with image: #{$!}")
|
19
|
+
binary_data = nil
|
20
|
+
end
|
21
|
+
block.call binary_data if block && binary_data
|
22
|
+
ensure
|
23
|
+
!binary_data.nil?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
def process_attachment_with_processing
|
29
|
+
return unless process_attachment_without_processing
|
30
|
+
with_image do |img|
|
31
|
+
resize_image_or_thumbnail! img
|
32
|
+
self.width = img.columns if respond_to?(:width)
|
33
|
+
self.height = img.rows if respond_to?(:height)
|
34
|
+
callback_with_args :after_resize, img
|
35
|
+
end if image?
|
36
|
+
end
|
37
|
+
|
38
|
+
# Performs the actual resizing operation for a thumbnail
|
39
|
+
def resize_image(img, size)
|
40
|
+
size = size.first if size.is_a?(Array) && size.length == 1 && !size.first.is_a?(Fixnum)
|
41
|
+
if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))
|
42
|
+
size = [size, size] if size.is_a?(Fixnum)
|
43
|
+
img.thumbnail!(*size)
|
44
|
+
else
|
45
|
+
img.change_geometry(size.to_s) { |cols, rows, image| image.resize!(cols, rows) }
|
46
|
+
end
|
47
|
+
self.temp_path = write_to_temp_file(img.to_blob)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/geometry.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# This Geometry class was yanked from RMagick. However, it lets ImageMagick handle the actual change_geometry.
|
2
|
+
# Use #new_dimensions_for to get new dimensons
|
3
|
+
# Used so I can use spiffy RMagick geometry strings with ImageScience
|
4
|
+
class Geometry
|
5
|
+
# ! and @ are removed until support for them is added
|
6
|
+
FLAGS = ['', '%', '<', '>']#, '!', '@']
|
7
|
+
RFLAGS = { '%' => :percent,
|
8
|
+
'!' => :aspect,
|
9
|
+
'<' => :>,
|
10
|
+
'>' => :<,
|
11
|
+
'@' => :area }
|
12
|
+
|
13
|
+
attr_accessor :width, :height, :x, :y, :flag
|
14
|
+
|
15
|
+
def initialize(width=nil, height=nil, x=nil, y=nil, flag=nil)
|
16
|
+
# Support floating-point width and height arguments so Geometry
|
17
|
+
# objects can be used to specify Image#density= arguments.
|
18
|
+
raise ArgumentError, "width must be >= 0: #{width}" if width < 0
|
19
|
+
raise ArgumentError, "height must be >= 0: #{height}" if height < 0
|
20
|
+
@width = width.to_f
|
21
|
+
@height = height.to_f
|
22
|
+
@x = x.to_i
|
23
|
+
@y = y.to_i
|
24
|
+
@flag = flag
|
25
|
+
end
|
26
|
+
|
27
|
+
# Construct an object from a geometry string
|
28
|
+
RE = /\A(\d*)(?:x(\d+))?([-+]\d+)?([-+]\d+)?([%!<>@]?)\Z/
|
29
|
+
|
30
|
+
def self.from_s(str)
|
31
|
+
raise(ArgumentError, "no geometry string specified") unless str
|
32
|
+
|
33
|
+
if m = RE.match(str)
|
34
|
+
new(m[1].to_i, m[2].to_i, m[3].to_i, m[4].to_i, RFLAGS[m[5]])
|
35
|
+
else
|
36
|
+
raise ArgumentError, "invalid geometry format"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Convert object to a geometry string
|
41
|
+
def to_s
|
42
|
+
str = ''
|
43
|
+
str << "%g" % @width if @width > 0
|
44
|
+
str << 'x' if (@width > 0 || @height > 0)
|
45
|
+
str << "%g" % @height if @height > 0
|
46
|
+
str << "%+d%+d" % [@x, @y] if (@x != 0 || @y != 0)
|
47
|
+
str << FLAGS[@flag.to_i]
|
48
|
+
end
|
49
|
+
|
50
|
+
# attempts to get new dimensions for the current geometry string given these old dimensions.
|
51
|
+
# This doesn't implement the aspect flag (!) or the area flag (@). PDI
|
52
|
+
def new_dimensions_for(orig_width, orig_height)
|
53
|
+
new_width = orig_width
|
54
|
+
new_height = orig_height
|
55
|
+
|
56
|
+
case @flag
|
57
|
+
when :percent
|
58
|
+
scale_x = @width.zero? ? 100 : @width
|
59
|
+
scale_y = @height.zero? ? @width : @height
|
60
|
+
new_width = scale_x.to_f * (orig_width.to_f / 100.0)
|
61
|
+
new_height = scale_y.to_f * (orig_height.to_f / 100.0)
|
62
|
+
when :<, :>, nil
|
63
|
+
scale_factor =
|
64
|
+
if new_width.zero? || new_height.zero?
|
65
|
+
1.0
|
66
|
+
else
|
67
|
+
if @width.nonzero? && @height.nonzero?
|
68
|
+
[@width.to_f / new_width.to_f, @height.to_f / new_height.to_f].min
|
69
|
+
else
|
70
|
+
@width.nonzero? ? (@width.to_f / new_width.to_f) : (@height.to_f / new_height.to_f)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
new_width = scale_factor * new_width.to_f
|
74
|
+
new_height = scale_factor * new_height.to_f
|
75
|
+
new_width = orig_width if @flag && orig_width.send(@flag, new_width)
|
76
|
+
new_height = orig_height if @flag && orig_height.send(@flag, new_height)
|
77
|
+
end
|
78
|
+
|
79
|
+
[new_width, new_height].collect! { |v| v.round }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class Array
|
84
|
+
# allows you to get new dimensions for the current array of dimensions with a given geometry string
|
85
|
+
#
|
86
|
+
# [50, 64] / '40>' # => [40, 51]
|
87
|
+
def /(geometry)
|
88
|
+
raise ArgumentError, "Only works with a [width, height] pair" if size != 2
|
89
|
+
raise ArgumentError, "Must pass a valid geometry string or object" unless geometry.is_a?(String) || geometry.is_a?(Geometry)
|
90
|
+
geometry = Geometry.from_s(geometry) if geometry.is_a?(String)
|
91
|
+
geometry.new_dimensions_for first, last
|
92
|
+
end
|
93
|
+
end
|
data/lib/tempfile_ext.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
Tempfile.class_eval do
|
4
|
+
# overwrite so tempfiles use the extension of the basename. important for rmagick and image science
|
5
|
+
def make_tmpname(basename, n)
|
6
|
+
ext = nil
|
7
|
+
sprintf("%s%d-%d%s", basename.to_s.gsub(/\.\w+$/) { |s| ext = s; '' }, $$, n, ext)
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))
|
2
|
+
|
3
|
+
class DbFileTest < Test::Unit::TestCase
|
4
|
+
include BaseAttachmentTests
|
5
|
+
attachment_model Attachment
|
6
|
+
|
7
|
+
def test_should_call_after_attachment_saved(klass = Attachment)
|
8
|
+
attachment_model.saves = 0
|
9
|
+
assert_created do
|
10
|
+
upload_file :filename => '/files/rails.png'
|
11
|
+
end
|
12
|
+
assert_equal 1, attachment_model.saves
|
13
|
+
end
|
14
|
+
|
15
|
+
test_against_subclass :test_should_call_after_attachment_saved, Attachment
|
16
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))
|
2
|
+
|
3
|
+
class FileSystemTest < Test::Unit::TestCase
|
4
|
+
include BaseAttachmentTests
|
5
|
+
attachment_model FileAttachment
|
6
|
+
|
7
|
+
def test_filesystem_size_for_file_attachment(klass = FileAttachment)
|
8
|
+
attachment_model klass
|
9
|
+
assert_created 1 do
|
10
|
+
attachment = upload_file :filename => '/files/rails.png'
|
11
|
+
assert_equal attachment.size, File.open(attachment.full_filename).stat.size
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
test_against_subclass :test_filesystem_size_for_file_attachment, FileAttachment
|
16
|
+
|
17
|
+
def test_should_not_overwrite_file_attachment(klass = FileAttachment)
|
18
|
+
attachment_model klass
|
19
|
+
assert_created 2 do
|
20
|
+
real = upload_file :filename => '/files/rails.png'
|
21
|
+
assert_valid real
|
22
|
+
assert !real.new_record?, real.errors.full_messages.join("\n")
|
23
|
+
assert !real.size.zero?
|
24
|
+
|
25
|
+
fake = upload_file :filename => '/files/fake/rails.png'
|
26
|
+
assert_valid fake
|
27
|
+
assert !fake.size.zero?
|
28
|
+
|
29
|
+
assert_not_equal File.open(real.full_filename).stat.size, File.open(fake.full_filename).stat.size
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
test_against_subclass :test_should_not_overwrite_file_attachment, FileAttachment
|
34
|
+
|
35
|
+
def test_should_store_file_attachment_in_filesystem(klass = FileAttachment)
|
36
|
+
attachment_model klass
|
37
|
+
attachment = nil
|
38
|
+
assert_created do
|
39
|
+
attachment = upload_file :filename => '/files/rails.png'
|
40
|
+
assert_valid attachment
|
41
|
+
assert File.exists?(attachment.full_filename), "#{attachment.full_filename} does not exist"
|
42
|
+
end
|
43
|
+
attachment
|
44
|
+
end
|
45
|
+
|
46
|
+
test_against_subclass :test_should_store_file_attachment_in_filesystem, FileAttachment
|
47
|
+
|
48
|
+
def test_should_delete_old_file_when_updating(klass = FileAttachment)
|
49
|
+
attachment_model klass
|
50
|
+
attachment = upload_file :filename => '/files/rails.png'
|
51
|
+
old_filename = attachment.full_filename
|
52
|
+
assert_not_created do
|
53
|
+
use_temp_file 'files/rails.png' do |file|
|
54
|
+
attachment.filename = 'rails2.png'
|
55
|
+
attachment.temp_path = File.join(fixture_path, file)
|
56
|
+
attachment.save!
|
57
|
+
assert File.exists?(attachment.full_filename), "#{attachment.full_filename} does not exist"
|
58
|
+
assert !File.exists?(old_filename), "#{old_filename} still exists"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
test_against_subclass :test_should_delete_old_file_when_updating, FileAttachment
|
64
|
+
|
65
|
+
def test_should_delete_old_file_when_renaming(klass = FileAttachment)
|
66
|
+
attachment_model klass
|
67
|
+
attachment = upload_file :filename => '/files/rails.png'
|
68
|
+
old_filename = attachment.full_filename
|
69
|
+
assert_not_created do
|
70
|
+
attachment.filename = 'rails2.png'
|
71
|
+
attachment.save
|
72
|
+
assert File.exists?(attachment.full_filename), "#{attachment.full_filename} does not exist"
|
73
|
+
assert !File.exists?(old_filename), "#{old_filename} still exists"
|
74
|
+
assert !attachment.reload.size.zero?
|
75
|
+
assert_equal 'rails2.png', attachment.filename
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
test_against_subclass :test_should_delete_old_file_when_renaming, FileAttachment
|
80
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper'))
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
class S3Test < Test::Unit::TestCase
|
5
|
+
if File.exist?(File.join(File.dirname(__FILE__), '../../amazon_s3.yml'))
|
6
|
+
include BaseAttachmentTests
|
7
|
+
attachment_model S3Attachment
|
8
|
+
|
9
|
+
def test_should_create_correct_bucket_name(klass = S3Attachment)
|
10
|
+
attachment_model klass
|
11
|
+
attachment = upload_file :filename => '/files/rails.png'
|
12
|
+
assert_equal attachment.s3_config[:bucket_name], attachment.bucket_name
|
13
|
+
end
|
14
|
+
|
15
|
+
test_against_subclass :test_should_create_correct_bucket_name, S3Attachment
|
16
|
+
|
17
|
+
def test_should_create_default_path_prefix(klass = S3Attachment)
|
18
|
+
attachment_model klass
|
19
|
+
attachment = upload_file :filename => '/files/rails.png'
|
20
|
+
assert_equal File.join(attachment_model.table_name, attachment.attachment_path_id), attachment.base_path
|
21
|
+
end
|
22
|
+
|
23
|
+
test_against_subclass :test_should_create_default_path_prefix, S3Attachment
|
24
|
+
|
25
|
+
def test_should_create_custom_path_prefix(klass = S3WithPathPrefixAttachment)
|
26
|
+
attachment_model klass
|
27
|
+
attachment = upload_file :filename => '/files/rails.png'
|
28
|
+
assert_equal File.join('some/custom/path/prefix', attachment.attachment_path_id), attachment.base_path
|
29
|
+
end
|
30
|
+
|
31
|
+
test_against_subclass :test_should_create_custom_path_prefix, S3WithPathPrefixAttachment
|
32
|
+
|
33
|
+
def test_should_create_valid_url(klass = S3Attachment)
|
34
|
+
attachment_model klass
|
35
|
+
attachment = upload_file :filename => '/files/rails.png'
|
36
|
+
assert_equal "#{s3_protocol}#{s3_hostname}#{s3_port_string}/#{attachment.bucket_name}/#{attachment.full_filename}", attachment.s3_url
|
37
|
+
end
|
38
|
+
|
39
|
+
test_against_subclass :test_should_create_valid_url, S3Attachment
|
40
|
+
|
41
|
+
def test_should_create_authenticated_url(klass = S3Attachment)
|
42
|
+
attachment_model klass
|
43
|
+
attachment = upload_file :filename => '/files/rails.png'
|
44
|
+
assert_match /^http.+AWSAccessKeyId.+Expires.+Signature.+/, attachment.authenticated_s3_url(:use_ssl => true)
|
45
|
+
end
|
46
|
+
|
47
|
+
test_against_subclass :test_should_create_authenticated_url, S3Attachment
|
48
|
+
|
49
|
+
def test_should_save_attachment(klass = S3Attachment)
|
50
|
+
attachment_model klass
|
51
|
+
assert_created do
|
52
|
+
attachment = upload_file :filename => '/files/rails.png'
|
53
|
+
assert_valid attachment
|
54
|
+
assert attachment.image?
|
55
|
+
assert !attachment.size.zero?
|
56
|
+
assert_kind_of Net::HTTPOK, http_response_for(attachment.s3_url)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
test_against_subclass :test_should_save_attachment, S3Attachment
|
61
|
+
|
62
|
+
def test_should_delete_attachment_from_s3_when_attachment_record_destroyed(klass = S3Attachment)
|
63
|
+
attachment_model klass
|
64
|
+
attachment = upload_file :filename => '/files/rails.png'
|
65
|
+
|
66
|
+
urls = [attachment.s3_url] + attachment.thumbnails.collect(&:s3_url)
|
67
|
+
|
68
|
+
urls.each {|url| assert_kind_of Net::HTTPOK, http_response_for(url) }
|
69
|
+
attachment.destroy
|
70
|
+
urls.each do |url|
|
71
|
+
begin
|
72
|
+
http_response_for(url)
|
73
|
+
rescue Net::HTTPForbidden, Net::HTTPNotFound
|
74
|
+
nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
test_against_subclass :test_should_delete_attachment_from_s3_when_attachment_record_destroyed, S3Attachment
|
80
|
+
|
81
|
+
protected
|
82
|
+
def http_response_for(url)
|
83
|
+
url = URI.parse(url)
|
84
|
+
Net::HTTP.start(url.host, url.port) {|http| http.request_head(url.path) }
|
85
|
+
end
|
86
|
+
|
87
|
+
def s3_protocol
|
88
|
+
Technoweenie::AttachmentFu::Backends::S3Backend.protocol
|
89
|
+
end
|
90
|
+
|
91
|
+
def s3_hostname
|
92
|
+
Technoweenie::AttachmentFu::Backends::S3Backend.hostname
|
93
|
+
end
|
94
|
+
|
95
|
+
def s3_port_string
|
96
|
+
Technoweenie::AttachmentFu::Backends::S3Backend.port_string
|
97
|
+
end
|
98
|
+
else
|
99
|
+
def test_flunk_s3
|
100
|
+
puts "s3 config file not loaded, tests not running"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module BaseAttachmentTests
|
2
|
+
def test_should_create_file_from_uploaded_file
|
3
|
+
assert_created do
|
4
|
+
attachment = upload_file :filename => '/files/foo.txt'
|
5
|
+
assert_valid attachment
|
6
|
+
assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)
|
7
|
+
assert attachment.image?
|
8
|
+
assert !attachment.size.zero?
|
9
|
+
#assert_equal 3, attachment.size
|
10
|
+
assert_nil attachment.width
|
11
|
+
assert_nil attachment.height
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_reassign_attribute_data
|
16
|
+
assert_created 1 do
|
17
|
+
attachment = upload_file :filename => '/files/rails.png'
|
18
|
+
assert_valid attachment
|
19
|
+
assert attachment.size > 0, "no data was set"
|
20
|
+
|
21
|
+
attachment.temp_data = 'wtf'
|
22
|
+
assert attachment.save_attachment?
|
23
|
+
attachment.save!
|
24
|
+
|
25
|
+
assert_equal 'wtf', attachment_model.find(attachment.id).send(:current_data)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_no_reassign_attribute_data_on_nil
|
30
|
+
assert_created 1 do
|
31
|
+
attachment = upload_file :filename => '/files/rails.png'
|
32
|
+
assert_valid attachment
|
33
|
+
assert attachment.size > 0, "no data was set"
|
34
|
+
|
35
|
+
attachment.temp_data = nil
|
36
|
+
assert !attachment.save_attachment?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_should_overwrite_old_contents_when_updating
|
41
|
+
attachment = upload_file :filename => '/files/rails.png'
|
42
|
+
assert_not_created do # no new db_file records
|
43
|
+
use_temp_file 'files/rails.png' do |file|
|
44
|
+
attachment.filename = 'rails2.png'
|
45
|
+
attachment.temp_path = File.join(fixture_path, file)
|
46
|
+
attachment.save!
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_should_save_without_updating_file
|
52
|
+
attachment = upload_file :filename => '/files/foo.txt'
|
53
|
+
assert_valid attachment
|
54
|
+
assert !attachment.save_attachment?
|
55
|
+
assert_nothing_raised { attachment.save! }
|
56
|
+
end
|
57
|
+
end
|