miloops-attachment_fu 3.2.5

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.
Files changed (49) hide show
  1. data/CHANGELOG +63 -0
  2. data/LICENSE +20 -0
  3. data/README +253 -0
  4. data/Rakefile +22 -0
  5. data/amazon_s3.yml.tpl +17 -0
  6. data/install.rb +7 -0
  7. data/lib/geometry.rb +96 -0
  8. data/lib/pothoven-attachment_fu.rb +23 -0
  9. data/lib/technoweenie/attachment_fu.rb +578 -0
  10. data/lib/technoweenie/attachment_fu/backends/cloud_file_backend.rb +211 -0
  11. data/lib/technoweenie/attachment_fu/backends/db_file_backend.rb +39 -0
  12. data/lib/technoweenie/attachment_fu/backends/file_system_backend.rb +126 -0
  13. data/lib/technoweenie/attachment_fu/backends/s3_backend.rb +394 -0
  14. data/lib/technoweenie/attachment_fu/processors/core_image_processor.rb +66 -0
  15. data/lib/technoweenie/attachment_fu/processors/gd2_processor.rb +59 -0
  16. data/lib/technoweenie/attachment_fu/processors/image_science_processor.rb +80 -0
  17. data/lib/technoweenie/attachment_fu/processors/mini_magick_processor.rb +142 -0
  18. data/lib/technoweenie/attachment_fu/processors/rmagick_processor.rb +66 -0
  19. data/rackspace_cloudfiles.yml.tpl +14 -0
  20. data/test/backends/db_file_test.rb +16 -0
  21. data/test/backends/file_system_test.rb +143 -0
  22. data/test/backends/remote/cloudfiles_test.rb +102 -0
  23. data/test/backends/remote/s3_test.rb +119 -0
  24. data/test/base_attachment_tests.rb +77 -0
  25. data/test/basic_test.rb +120 -0
  26. data/test/database.yml +18 -0
  27. data/test/extra_attachment_test.rb +67 -0
  28. data/test/fixtures/attachment.rb +304 -0
  29. data/test/fixtures/files/fake/rails.png +0 -0
  30. data/test/fixtures/files/foo.txt +1 -0
  31. data/test/fixtures/files/rails.jpg +0 -0
  32. data/test/fixtures/files/rails.png +0 -0
  33. data/test/geometry_test.rb +114 -0
  34. data/test/processors/core_image_test.rb +58 -0
  35. data/test/processors/gd2_test.rb +51 -0
  36. data/test/processors/image_science_test.rb +54 -0
  37. data/test/processors/mini_magick_test.rb +122 -0
  38. data/test/processors/rmagick_test.rb +272 -0
  39. data/test/schema.rb +136 -0
  40. data/test/test_helper.rb +180 -0
  41. data/test/validation_test.rb +55 -0
  42. data/vendor/red_artisan/core_image/filters/color.rb +27 -0
  43. data/vendor/red_artisan/core_image/filters/effects.rb +31 -0
  44. data/vendor/red_artisan/core_image/filters/perspective.rb +25 -0
  45. data/vendor/red_artisan/core_image/filters/quality.rb +25 -0
  46. data/vendor/red_artisan/core_image/filters/scale.rb +47 -0
  47. data/vendor/red_artisan/core_image/filters/watermark.rb +32 -0
  48. data/vendor/red_artisan/core_image/processor.rb +123 -0
  49. metadata +98 -0
@@ -0,0 +1,143 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))
2
+ require 'digest/sha2'
3
+
4
+ class FileSystemTest < Test::Unit::TestCase
5
+ include BaseAttachmentTests
6
+ attachment_model FileAttachment
7
+
8
+ def test_filesystem_size_for_file_attachment(klass = FileAttachment)
9
+ attachment_model klass
10
+ assert_created 1 do
11
+ attachment = upload_file :filename => '/files/rails.png'
12
+ assert_equal attachment.size, File.open(attachment.full_filename).stat.size
13
+ end
14
+ end
15
+
16
+ test_against_subclass :test_filesystem_size_for_file_attachment, FileAttachment
17
+
18
+ def test_should_not_overwrite_file_attachment(klass = FileAttachment)
19
+ attachment_model klass
20
+ assert_created 2 do
21
+ real = upload_file :filename => '/files/rails.png'
22
+ assert_valid real
23
+ assert !real.new_record?, real.errors.full_messages.join("\n")
24
+ assert !real.size.zero?
25
+
26
+ fake = upload_file :filename => '/files/fake/rails.png'
27
+ assert_valid fake
28
+ assert !fake.size.zero?
29
+
30
+ assert_not_equal File.open(real.full_filename).stat.size, File.open(fake.full_filename).stat.size
31
+ end
32
+ end
33
+
34
+ test_against_subclass :test_should_not_overwrite_file_attachment, FileAttachment
35
+
36
+ def test_should_store_file_attachment_in_filesystem(klass = FileAttachment)
37
+ attachment_model klass
38
+ attachment = nil
39
+ assert_created do
40
+ attachment = upload_file :filename => '/files/rails.png'
41
+ assert_valid attachment
42
+ assert File.exists?(attachment.full_filename), "#{attachment.full_filename} does not exist"
43
+ end
44
+ attachment
45
+ end
46
+
47
+ test_against_subclass :test_should_store_file_attachment_in_filesystem, FileAttachment
48
+
49
+ def test_should_delete_old_file_when_updating(klass = FileAttachment)
50
+ attachment_model klass
51
+ attachment = upload_file :filename => '/files/rails.png'
52
+ old_filename = attachment.full_filename
53
+ assert_not_created do
54
+ use_temp_file 'files/rails.png' do |file|
55
+ attachment.filename = 'rails2.png'
56
+ attachment.temp_paths.unshift File.join(FIXTURE_PATH, file)
57
+ attachment.save!
58
+ assert File.exists?(attachment.full_filename), "#{attachment.full_filename} does not exist"
59
+ assert !File.exists?(old_filename), "#{old_filename} still exists"
60
+ end
61
+ end
62
+ end
63
+
64
+ test_against_subclass :test_should_delete_old_file_when_updating, FileAttachment
65
+
66
+ def test_should_delete_old_file_when_renaming(klass = FileAttachment)
67
+ attachment_model klass
68
+ attachment = upload_file :filename => '/files/rails.png'
69
+ old_filename = attachment.full_filename
70
+ assert_not_created do
71
+ attachment.filename = 'rails2.png'
72
+ attachment.save
73
+ assert File.exists?(attachment.full_filename), "#{attachment.full_filename} does not exist"
74
+ assert !File.exists?(old_filename), "#{old_filename} still exists"
75
+ assert !attachment.reload.size.zero?
76
+ assert_equal 'rails2.png', attachment.filename
77
+ end
78
+ end
79
+
80
+ test_against_subclass :test_should_delete_old_file_when_renaming, FileAttachment
81
+
82
+ def test_path_partitioning_works_on_integer_id(klass = FileAttachment)
83
+ attachment_model klass
84
+
85
+ # Create a random attachment object, doesn't matter what.
86
+ attachment = upload_file :filename => '/files/rails.png'
87
+ old_id = attachment.id
88
+ attachment.id = 1
89
+
90
+ begin
91
+ assert_equal ["0000", "0001", "bar.txt"], attachment.send(:partitioned_path, "bar.txt")
92
+ ensure
93
+ attachment.id = old_id
94
+ end
95
+ end
96
+
97
+ test_against_subclass :test_path_partitioning_works_on_integer_id, FileAttachment
98
+
99
+ def test_path_partitioning_with_string_id_works_by_generating_hash(klass = FileAttachmentWithStringId)
100
+ attachment_model klass
101
+
102
+ # Create a random attachment object, doesn't matter what.
103
+ attachment = upload_file :filename => '/files/rails.png'
104
+ old_id = attachment.id
105
+ attachment.id = "hello world some long string"
106
+ hash = Digest::SHA512.hexdigest("hello world some long string")
107
+
108
+ begin
109
+ assert_equal [
110
+ hash[0..31],
111
+ hash[32..63],
112
+ hash[64..95],
113
+ hash[96..127],
114
+ "bar.txt"
115
+ ], attachment.send(:partitioned_path, "bar.txt")
116
+ ensure
117
+ attachment.id = old_id
118
+ end
119
+ end
120
+
121
+ test_against_subclass :test_path_partitioning_with_string_id_works_by_generating_hash, FileAttachmentWithStringId
122
+
123
+ def test_path_partition_string_id_hashing_is_turned_off_if_id_is_uuid(klass = FileAttachmentWithUuid)
124
+ attachment_model klass
125
+
126
+ # Create a random attachment object, doesn't matter what.
127
+ attachment = upload_file :filename => '/files/rails.png'
128
+ old_id = attachment.id
129
+ attachment.id = "0c0743b698483569dc65909a8cdb3bf9"
130
+
131
+ begin
132
+ assert_equal [
133
+ "0c0743b698483569",
134
+ "dc65909a8cdb3bf9",
135
+ "bar.txt"
136
+ ], attachment.send(:partitioned_path, "bar.txt")
137
+ ensure
138
+ attachment.id = old_id
139
+ end
140
+ end
141
+
142
+ test_against_subclass :test_path_partition_string_id_hashing_is_turned_off_if_id_is_uuid, FileAttachmentWithUuid
143
+ end
@@ -0,0 +1,102 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper'))
2
+ require 'net/http'
3
+
4
+ class CloudfilesTest < Test::Unit::TestCase
5
+ def self.test_CloudFiles?
6
+ true unless ENV["TEST_CLOUDFILES"] == "false"
7
+ end
8
+
9
+ if test_CloudFiles? && File.exist?(File.join(File.dirname(__FILE__), '../../rackspace_cloudfiles.yml'))
10
+ include BaseAttachmentTests
11
+ attachment_model CloudFilesAttachment
12
+
13
+ def test_should_create_correct_container_name(klass = CloudFilesAttachment)
14
+ attachment_model klass
15
+ attachment = upload_file :filename => '/files/rails.png'
16
+ assert_equal attachment.cloudfiles_config[:container_name], attachment.container_name
17
+ end
18
+
19
+ test_against_subclass :test_should_create_correct_container_name, CloudFilesAttachment
20
+
21
+ def test_should_create_default_path_prefix(klass = CloudFilesAttachment)
22
+ attachment_model klass
23
+ attachment = upload_file :filename => '/files/rails.png'
24
+ assert_equal File.join(attachment_model.table_name, attachment.attachment_path_id), attachment.base_path
25
+ end
26
+
27
+ test_against_subclass :test_should_create_default_path_prefix, CloudFilesAttachment
28
+
29
+ def test_should_create_custom_path_prefix(klass = CloudFilesWithPathPrefixAttachment)
30
+ attachment_model klass
31
+ attachment = upload_file :filename => '/files/rails.png'
32
+ assert_equal File.join('some/custom/path/prefix', attachment.attachment_path_id), attachment.base_path
33
+ end
34
+
35
+ test_against_subclass :test_should_create_custom_path_prefix, CloudFilesWithPathPrefixAttachment
36
+
37
+
38
+ def test_should_create_valid_url(klass = CloudFilesAttachment)
39
+ attachment_model klass
40
+ attachment = upload_file :filename => '/files/rails.png'
41
+ assert_match(%r!http://cdn.cloudfiles.mosso.com/(.*?)/cloud_files_attachments/1/rails.png!, attachment.cloudfiles_url)
42
+ end
43
+
44
+ test_against_subclass :test_should_create_valid_url, CloudFilesAttachment
45
+
46
+ def test_should_save_attachment(klass = CloudFilesAttachment)
47
+ attachment_model klass
48
+ assert_created do
49
+ attachment = upload_file :filename => '/files/rails.png'
50
+ assert_valid attachment
51
+ assert attachment.image?
52
+ assert !attachment.size.zero?
53
+ assert_kind_of Net::HTTPOK, http_response_for(attachment.cloudfiles_url)
54
+ end
55
+ end
56
+
57
+ test_against_subclass :test_should_save_attachment, CloudFilesAttachment
58
+
59
+ def test_should_delete_attachment_from_cloud_files_when_attachment_record_destroyed(klass = CloudFilesAttachment)
60
+ attachment_model klass
61
+ attachment = upload_file :filename => '/files/rails.png'
62
+
63
+ urls = [attachment.cloudfiles_url] + attachment.thumbnails.collect(&:cloudfiles_url)
64
+
65
+ urls.each {|url| assert_kind_of Net::HTTPOK, http_response_for(url) }
66
+ attachment.destroy
67
+ urls.each do |url|
68
+ begin
69
+ http_response_for(url)
70
+ rescue Net::HTTPForbidden, Net::HTTPNotFound
71
+ nil
72
+ end
73
+ end
74
+ end
75
+
76
+ test_against_subclass :test_should_delete_attachment_from_cloud_files_when_attachment_record_destroyed, CloudFilesAttachment
77
+
78
+
79
+
80
+ protected
81
+ def http_response_for(url)
82
+ url = URI.parse(url)
83
+ Net::HTTP.start(url.host, url.port) {|http| http.request_head(url.path) }
84
+ end
85
+
86
+ def s3_protocol
87
+ Technoweenie::AttachmentFu::Backends::S3Backend.protocol
88
+ end
89
+
90
+ def s3_hostname
91
+ Technoweenie::AttachmentFu::Backends::S3Backend.hostname
92
+ end
93
+
94
+ def s3_port_string
95
+ Technoweenie::AttachmentFu::Backends::S3Backend.port_string
96
+ end
97
+ else
98
+ def test_flunk_s3
99
+ puts "s3 config file not loaded, tests not running"
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,119 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper'))
2
+ require 'net/http'
3
+
4
+ class S3Test < Test::Unit::TestCase
5
+ def self.test_S3?
6
+ true unless ENV["TEST_S3"] == "false"
7
+ end
8
+
9
+ if test_S3? && File.exist?(File.join(File.dirname(__FILE__), '../../amazon_s3.yml'))
10
+ include BaseAttachmentTests
11
+ attachment_model S3Attachment
12
+
13
+ def test_should_create_correct_bucket_name(klass = S3Attachment)
14
+ attachment_model klass
15
+ attachment = upload_file :filename => '/files/rails.png'
16
+ assert_equal attachment.s3_config[:bucket_name], attachment.bucket_name
17
+ end
18
+
19
+ test_against_subclass :test_should_create_correct_bucket_name, S3Attachment
20
+
21
+ def test_should_create_default_path_prefix(klass = S3Attachment)
22
+ attachment_model klass
23
+ attachment = upload_file :filename => '/files/rails.png'
24
+ assert_equal File.join(attachment_model.table_name, attachment.attachment_path_id), attachment.base_path
25
+ end
26
+
27
+ test_against_subclass :test_should_create_default_path_prefix, S3Attachment
28
+
29
+ def test_should_create_custom_path_prefix(klass = S3WithPathPrefixAttachment)
30
+ attachment_model klass
31
+ attachment = upload_file :filename => '/files/rails.png'
32
+ assert_equal File.join('some/custom/path/prefix', attachment.attachment_path_id), attachment.base_path
33
+ end
34
+
35
+ test_against_subclass :test_should_create_custom_path_prefix, S3WithPathPrefixAttachment
36
+
37
+ def test_should_create_valid_url(klass = S3Attachment)
38
+ attachment_model klass
39
+ attachment = upload_file :filename => '/files/rails.png'
40
+ assert_equal "#{s3_protocol}#{s3_hostname}#{s3_port_string}/#{attachment.bucket_name}/#{attachment.full_filename}", attachment.s3_url
41
+ end
42
+
43
+ test_against_subclass :test_should_create_valid_url, S3Attachment
44
+
45
+ def test_should_create_authenticated_url(klass = S3Attachment)
46
+ attachment_model klass
47
+ attachment = upload_file :filename => '/files/rails.png'
48
+ assert_match /^http.+AWSAccessKeyId.+Expires.+Signature.+/, attachment.authenticated_s3_url(:use_ssl => true)
49
+ end
50
+
51
+ test_against_subclass :test_should_create_authenticated_url, S3Attachment
52
+
53
+ def test_should_create_authenticated_url_for_thumbnail(klass = S3Attachment)
54
+ attachment_model klass
55
+ attachment = upload_file :filename => '/files/rails.png'
56
+ ['large', :large].each do |thumbnail|
57
+ assert_match(
58
+ /^http.+rails_large\.png.+AWSAccessKeyId.+Expires.+Signature/,
59
+ attachment.authenticated_s3_url(thumbnail),
60
+ "authenticated_s3_url failed with #{thumbnail.class} parameter"
61
+ )
62
+ end
63
+ end
64
+
65
+ def test_should_save_attachment(klass = S3Attachment)
66
+ attachment_model klass
67
+ assert_created do
68
+ attachment = upload_file :filename => '/files/rails.png'
69
+ assert_valid attachment
70
+ assert attachment.image?
71
+ assert !attachment.size.zero?
72
+ assert_kind_of Net::HTTPOK, http_response_for(attachment.s3_url)
73
+ end
74
+ end
75
+
76
+ test_against_subclass :test_should_save_attachment, S3Attachment
77
+
78
+ def test_should_delete_attachment_from_s3_when_attachment_record_destroyed(klass = S3Attachment)
79
+ attachment_model klass
80
+ attachment = upload_file :filename => '/files/rails.png'
81
+
82
+ urls = [attachment.s3_url] + attachment.thumbnails.collect(&:s3_url)
83
+
84
+ urls.each {|url| assert_kind_of Net::HTTPOK, http_response_for(url) }
85
+ attachment.destroy
86
+ urls.each do |url|
87
+ begin
88
+ http_response_for(url)
89
+ rescue Net::HTTPForbidden, Net::HTTPNotFound
90
+ nil
91
+ end
92
+ end
93
+ end
94
+
95
+ test_against_subclass :test_should_delete_attachment_from_s3_when_attachment_record_destroyed, S3Attachment
96
+
97
+ protected
98
+ def http_response_for(url)
99
+ url = URI.parse(url)
100
+ Net::HTTP.start(url.host, url.port) {|http| http.request_head(url.path) }
101
+ end
102
+
103
+ def s3_protocol
104
+ Technoweenie::AttachmentFu::Backends::S3Backend.protocol
105
+ end
106
+
107
+ def s3_hostname
108
+ Technoweenie::AttachmentFu::Backends::S3Backend.hostname
109
+ end
110
+
111
+ def s3_port_string
112
+ Technoweenie::AttachmentFu::Backends::S3Backend.port_string
113
+ end
114
+ else
115
+ def test_flunk_s3
116
+ puts "s3 config file not loaded, tests not running"
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,77 @@
1
+ module BaseAttachmentTests
2
+ def test_should_create_file_from_uploaded_file
3
+ assert_created do
4
+ attachment = upload_file :filename => '/files/foo.txt', :content_type => 'text/plain'
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_should_create_file_from_merb_temp_file
16
+ assert_created do
17
+ attachment = upload_merb_file :filename => '/files/foo.txt', :content_type => 'text/plain'
18
+ assert_valid attachment
19
+ assert !attachment.db_file.new_record? if attachment.respond_to?(:db_file)
20
+ assert !attachment.image?
21
+ assert !attachment.size.zero?
22
+ #assert_equal 3, attachment.size
23
+ assert_nil attachment.width
24
+ assert_nil attachment.height
25
+ end
26
+ end
27
+
28
+ def test_reassign_attribute_data
29
+ assert_created 1 do
30
+ attachment = upload_file :filename => '/files/rails.png'
31
+ assert_valid attachment
32
+ assert attachment.size > 0, "no data was set"
33
+
34
+ attachment.set_temp_data 'wtf'
35
+ assert attachment.save_attachment?
36
+ attachment.save!
37
+
38
+ assert_equal 'wtf', attachment_model.find(attachment.id).send(:current_data)
39
+ end
40
+ end
41
+
42
+ def test_no_reassign_attribute_data_on_nil
43
+ assert_created 1 do
44
+ attachment = upload_file :filename => '/files/rails.png'
45
+ assert_valid attachment
46
+ assert attachment.size > 0, "no data was set"
47
+
48
+ attachment.set_temp_data nil
49
+ assert !attachment.save_attachment?
50
+ end
51
+ end
52
+
53
+ def test_should_overwrite_old_contents_when_updating
54
+ attachment = upload_file :filename => '/files/rails.png'
55
+ assert_not_created do # no new db_file records
56
+ use_temp_file 'files/rails.png' do |file|
57
+ attachment.filename = 'rails2.png'
58
+ attachment.temp_paths.unshift File.join(FIXTURE_PATH, file)
59
+ attachment.save!
60
+ end
61
+ end
62
+ end
63
+
64
+ def test_should_save_without_updating_file
65
+ attachment = upload_file :filename => '/files/foo.txt'
66
+ assert_valid attachment
67
+ assert !attachment.save_attachment?
68
+ assert_nothing_raised { attachment.save! }
69
+ end
70
+
71
+ def test_should_handle_nil_file_upload
72
+ attachment = attachment_model.create :uploaded_data => ''
73
+ assert_raise ActiveRecord::RecordInvalid do
74
+ attachment.save!
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,120 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
2
+
3
+ class BasicTest < Test::Unit::TestCase
4
+ def test_should_set_default_min_size
5
+ assert_equal 1, Attachment.attachment_options[:min_size]
6
+ end
7
+
8
+ def test_should_set_default_max_size
9
+ assert_equal 1.megabyte, Attachment.attachment_options[:max_size]
10
+ end
11
+
12
+ def test_should_set_default_size
13
+ assert_equal (1..1.megabyte), Attachment.attachment_options[:size]
14
+ end
15
+
16
+ def test_should_set_default_thumbnails_option
17
+ assert_equal Hash.new, Attachment.attachment_options[:thumbnails]
18
+ end
19
+
20
+ def test_should_set_default_thumbnail_class
21
+ assert_equal Attachment, Attachment.attachment_options[:thumbnail_class]
22
+ end
23
+
24
+ def test_should_normalize_content_types_to_array
25
+ assert_equal %w(pdf), PdfAttachment.attachment_options[:content_type]
26
+ assert_equal %w(pdf doc txt), DocAttachment.attachment_options[:content_type]
27
+ assert_equal Technoweenie::AttachmentFu.content_types, ImageAttachment.attachment_options[:content_type]
28
+ assert_equal ['pdf'] + Technoweenie::AttachmentFu.content_types, ImageOrPdfAttachment.attachment_options[:content_type]
29
+ end
30
+
31
+ def test_should_sanitize_content_type
32
+ @attachment = Attachment.new :content_type => ' foo '
33
+ assert_equal 'foo', @attachment.content_type
34
+ end
35
+
36
+ def test_should_sanitize_filenames
37
+ @attachment = Attachment.new :filename => 'blah/foo.bar'
38
+ assert_equal 'foo.bar', @attachment.filename
39
+
40
+ @attachment.filename = 'blah\\foo.bar'
41
+ assert_equal 'foo.bar', @attachment.filename
42
+
43
+ @attachment.filename = 'f o!O-.bar'
44
+ assert_equal 'f_o_O-.bar', @attachment.filename
45
+
46
+ @attachment.filename = 'sheeps_says_bææ'
47
+ assert_equal 'sheeps_says_b__', @attachment.filename
48
+
49
+ @attachment.filename = nil
50
+ assert_nil @attachment.filename
51
+ end
52
+
53
+ def test_should_convert_thumbnail_name
54
+ @attachment = FileAttachment.new :filename => 'foo.bar'
55
+ assert_equal 'foo.bar', @attachment.thumbnail_name_for(nil)
56
+ assert_equal 'foo.bar', @attachment.thumbnail_name_for('')
57
+ assert_equal 'foo_blah.bar', @attachment.thumbnail_name_for(:blah)
58
+ assert_equal 'foo_blah.blah.bar', @attachment.thumbnail_name_for('blah.blah')
59
+
60
+ @attachment.filename = 'foo.bar.baz'
61
+ assert_equal 'foo.bar_blah.baz', @attachment.thumbnail_name_for(:blah)
62
+ end
63
+
64
+ def test_should_require_valid_thumbnails_option
65
+ klass = Class.new(ActiveRecord::Base)
66
+ assert_raise ArgumentError do
67
+ klass.has_attachment :thumbnails => []
68
+ end
69
+ end
70
+
71
+ class ::ImageWithPolymorphicThumbsAttachment
72
+ cattr_accessor :thumbnail_creations
73
+
74
+ def create_or_update_thumbnail(path, thumb, *size)
75
+ @@thumbnail_creations[thumb] = size.size == 1 ? size.first : size
76
+ end
77
+
78
+ def self.reset_creations
79
+ @@thumbnail_creations = {}
80
+ end
81
+ end
82
+
83
+ def test_should_handle_polymorphic_thumbnails_option
84
+ assert_polymorphic_thumb_creation nil,
85
+ :thumb => [50, 50], :geometry => 'x50'
86
+ assert_polymorphic_thumb_creation 'Product',
87
+ :thumb => [50, 50], :geometry => 'x50', :large_thumb => '169x169!', :zoomed => '500x500>'
88
+ assert_polymorphic_thumb_creation 'Editorial',
89
+ :thumb => [50, 50], :geometry => 'x50', :fullsize => '150x100>'
90
+ assert_polymorphic_thumb_creation 'User',
91
+ :thumb => [50, 50], :geometry => 'x50', :avatar => '64x64!'
92
+ end
93
+
94
+ def test_should_compute_per_thumbnail_jpeg_quality
95
+ assert_jpeg_quality :thumb, 90
96
+ assert_jpeg_quality :avatar, 85
97
+ assert_jpeg_quality :large, 75
98
+ assert_jpeg_quality :large, 0x200 | 75, false
99
+ assert_jpeg_quality nil, 75
100
+ end
101
+
102
+ private
103
+ def assert_jpeg_quality(thumbnail, quality, require_0_to_100 = true)
104
+ klass = ImageWithPerThumbJpegAttachment
105
+ w, h = if thumbnail
106
+ klass.attachment_options[:thumbnails][thumbnail].scan(/\d+/)
107
+ else
108
+ klass.attachment_options[:resize_to].scan(/\d+/)
109
+ end
110
+ attachment = klass.new(:thumbnail => thumbnail, :width => w, :height => h)
111
+ assert_equal quality, attachment.send(:get_jpeg_quality, require_0_to_100)
112
+ end
113
+
114
+ def assert_polymorphic_thumb_creation(parent, defs)
115
+ attachment_model ImageWithPolymorphicThumbsAttachment
116
+ attachment_model.reset_creations
117
+ attachment = upload_file :filename => '/files/rails.png', :imageable_type => parent.to_s.classify, :imageable_id => nil
118
+ assert_equal defs, attachment_model.thumbnail_creations
119
+ end
120
+ end