paperclip 2.4.5 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of paperclip might be problematic. Click here for more details.
- data/.gitignore +22 -0
- data/.travis.yml +13 -0
- data/Appraisals +14 -0
- data/CONTRIBUTING.md +38 -0
- data/Gemfile +5 -0
- data/NEWS +23 -0
- data/README.md +72 -42
- data/Rakefile +1 -46
- data/cucumber/paperclip_steps.rb +6 -0
- data/features/basic_integration.feature +46 -0
- data/features/rake_tasks.feature +63 -0
- data/features/step_definitions/attachment_steps.rb +65 -0
- data/features/step_definitions/html_steps.rb +15 -0
- data/features/step_definitions/rails_steps.rb +182 -0
- data/features/step_definitions/s3_steps.rb +14 -0
- data/features/step_definitions/web_steps.rb +209 -0
- data/features/support/env.rb +8 -0
- data/features/support/fakeweb.rb +3 -0
- data/features/support/fixtures/.boot_config.rb.swo +0 -0
- data/features/support/fixtures/boot_config.txt +15 -0
- data/features/support/fixtures/gemfile.txt +5 -0
- data/features/support/fixtures/preinitializer.txt +20 -0
- data/features/support/paths.rb +28 -0
- data/features/support/rails.rb +46 -0
- data/features/support/selectors.rb +19 -0
- data/gemfiles/rails2.gemfile +9 -0
- data/gemfiles/rails3.gemfile +9 -0
- data/gemfiles/rails3_1.gemfile +9 -0
- data/lib/paperclip.rb +26 -19
- data/lib/paperclip/attachment.rb +123 -109
- data/lib/paperclip/interpolations.rb +7 -4
- data/lib/paperclip/matchers.rb +33 -2
- data/lib/paperclip/missing_attachment_styles.rb +1 -1
- data/lib/paperclip/railtie.rb +5 -0
- data/lib/paperclip/schema.rb +39 -0
- data/lib/paperclip/storage/fog.rb +21 -10
- data/lib/paperclip/storage/s3.rb +107 -40
- data/lib/paperclip/style.rb +13 -5
- data/lib/paperclip/url_generator.rb +64 -0
- data/lib/paperclip/version.rb +1 -1
- data/lib/tasks/paperclip.rake +1 -1
- data/paperclip.gemspec +41 -0
- data/test/.gitignore +1 -0
- data/test/attachment_test.rb +155 -168
- data/test/fixtures/question?mark.png +0 -0
- data/test/helper.rb +24 -1
- data/test/interpolations_test.rb +16 -2
- data/test/paperclip_missing_attachment_styles_test.rb +16 -0
- data/test/paperclip_test.rb +72 -22
- data/test/schema_test.rb +98 -0
- data/test/storage/filesystem_test.rb +2 -2
- data/test/{fog_test.rb → storage/fog_test.rb} +35 -8
- data/test/storage/s3_live_test.rb +63 -13
- data/test/storage/s3_test.rb +394 -91
- data/test/style_test.rb +50 -21
- data/test/support/mock_attachment.rb +22 -0
- data/test/support/mock_interpolator.rb +24 -0
- data/test/support/mock_model.rb +2 -0
- data/test/support/mock_url_generator_builder.rb +27 -0
- data/test/url_generator_test.rb +187 -0
- metadata +307 -125
- data/lib/paperclip/options.rb +0 -78
- data/test/options_test.rb +0 -75
data/lib/paperclip/style.rb
CHANGED
@@ -18,7 +18,13 @@ module Paperclip
|
|
18
18
|
@geometry = definition.delete(:geometry)
|
19
19
|
@format = definition.delete(:format)
|
20
20
|
@processors = definition.delete(:processors)
|
21
|
+
@convert_options = definition.delete(:convert_options)
|
22
|
+
@source_file_options = definition.delete(:source_file_options)
|
21
23
|
@other_args = definition
|
24
|
+
elsif definition.is_a? String
|
25
|
+
@geometry = definition
|
26
|
+
@format = nil
|
27
|
+
@other_args = {}
|
22
28
|
else
|
23
29
|
@geometry, @format = [definition, nil].flatten[0..1]
|
24
30
|
@other_args = {}
|
@@ -32,12 +38,12 @@ module Paperclip
|
|
32
38
|
# by default we behave as before, though.
|
33
39
|
# if a proc has been supplied, we call it here
|
34
40
|
def processors
|
35
|
-
@processors.respond_to?(:call) ? @processors.call(attachment.instance) : (@processors || attachment.
|
41
|
+
@processors.respond_to?(:call) ? @processors.call(attachment.instance) : (@processors || attachment.processors)
|
36
42
|
end
|
37
43
|
|
38
44
|
# retrieves from the attachment the whiny setting
|
39
45
|
def whiny
|
40
|
-
attachment.
|
46
|
+
attachment.whiny
|
41
47
|
end
|
42
48
|
|
43
49
|
# returns true if we're inclined to grumble
|
@@ -46,11 +52,13 @@ module Paperclip
|
|
46
52
|
end
|
47
53
|
|
48
54
|
def convert_options
|
49
|
-
|
55
|
+
@convert_options.respond_to?(:call) ? @convert_options.call(attachment.instance) :
|
56
|
+
(@convert_options || attachment.send(:extra_options_for, name))
|
50
57
|
end
|
51
58
|
|
52
59
|
def source_file_options
|
53
|
-
|
60
|
+
@source_file_options.respond_to?(:call) ? @source_file_options.call(attachment.instance) :
|
61
|
+
(@source_file_options || attachment.send(:extra_source_file_options_for, name))
|
54
62
|
end
|
55
63
|
|
56
64
|
# returns the geometry string for this style
|
@@ -74,7 +82,7 @@ module Paperclip
|
|
74
82
|
end
|
75
83
|
|
76
84
|
# Supports getting and setting style properties with hash notation to ensure backwards-compatibility
|
77
|
-
# eg. @attachment.
|
85
|
+
# eg. @attachment.styles[:large][:geometry]@ will still work
|
78
86
|
def [](key)
|
79
87
|
if [:name, :convert_options, :whiny, :processors, :geometry, :format, :animated, :source_file_options].include?(key)
|
80
88
|
send(key)
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Paperclip
|
4
|
+
class UrlGenerator
|
5
|
+
def initialize(attachment, attachment_options)
|
6
|
+
@attachment = attachment
|
7
|
+
@attachment_options = attachment_options
|
8
|
+
end
|
9
|
+
|
10
|
+
def for(style_name, options)
|
11
|
+
escape_url_as_needed(
|
12
|
+
timestamp_as_needed(
|
13
|
+
@attachment_options[:interpolator].interpolate(most_appropriate_url, @attachment, style_name),
|
14
|
+
options
|
15
|
+
), options)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
# This method is all over the place.
|
21
|
+
def default_url
|
22
|
+
if @attachment_options[:default_url].respond_to?(:call)
|
23
|
+
@attachment_options[:default_url].call(@attachment)
|
24
|
+
elsif @attachment_options[:default_url].is_a?(Symbol)
|
25
|
+
@attachment.instance.send(@attachment_options[:default_url])
|
26
|
+
else
|
27
|
+
@attachment_options[:default_url]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def most_appropriate_url
|
32
|
+
if @attachment.original_filename.nil?
|
33
|
+
default_url
|
34
|
+
else
|
35
|
+
@attachment_options[:url]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def timestamp_as_needed(url, options)
|
40
|
+
if options[:timestamp] && timestamp_possible?
|
41
|
+
delimiter_char = url.match(/\?.+=/) ? '&' : '?'
|
42
|
+
"#{url}#{delimiter_char}#{@attachment.updated_at.to_s}"
|
43
|
+
else
|
44
|
+
url
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def timestamp_possible?
|
49
|
+
@attachment.respond_to?(:updated_at) && @attachment.updated_at.present?
|
50
|
+
end
|
51
|
+
|
52
|
+
def escape_url_as_needed(url, options)
|
53
|
+
if options[:escape]
|
54
|
+
escape_url(url)
|
55
|
+
else
|
56
|
+
url
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def escape_url(url)
|
61
|
+
(url.respond_to?(:escape) ? url.escape : URI.escape(url)).gsub(/(\/.+)\?(.+\.)/, '\1%3F\2')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/paperclip/version.rb
CHANGED
data/lib/tasks/paperclip.rake
CHANGED
@@ -47,7 +47,7 @@ namespace :paperclip do
|
|
47
47
|
Paperclip.each_instance_with_attachment(klass, name) do |instance|
|
48
48
|
if file = instance.send(name).to_file(:original)
|
49
49
|
instance.send("#{name}_file_name=", instance.send("#{name}_file_name").strip)
|
50
|
-
instance.send("#{name}_content_type=", file.content_type.strip)
|
50
|
+
instance.send("#{name}_content_type=", file.content_type.to_s.strip)
|
51
51
|
instance.send("#{name}_file_size=", file.size) if instance.respond_to?("#{name}_file_size")
|
52
52
|
if Rails.version >= "3.0.0"
|
53
53
|
instance.save(:validate => false)
|
data/paperclip.gemspec
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
$LOAD_PATH.push File.expand_path("../lib", __FILE__)
|
2
|
+
require 'paperclip/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "paperclip"
|
6
|
+
s.version = Paperclip::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.author = "Jon Yurek"
|
9
|
+
s.email = ["jyurek@thoughtbot.com"]
|
10
|
+
s.homepage = "https://github.com/thoughtbot/paperclip"
|
11
|
+
s.summary = "File attachments as attributes for ActiveRecord"
|
12
|
+
s.description = "Easy upload management for ActiveRecord"
|
13
|
+
|
14
|
+
s.rubyforge_project = "paperclip"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.requirements << "ImageMagick"
|
22
|
+
|
23
|
+
s.add_dependency('activerecord', '>= 2.3.0')
|
24
|
+
s.add_dependency('activesupport', '>= 2.3.2')
|
25
|
+
s.add_dependency('cocaine', '>= 0.0.2')
|
26
|
+
s.add_dependency('mime-types')
|
27
|
+
|
28
|
+
s.add_development_dependency('shoulda')
|
29
|
+
s.add_development_dependency('appraisal', '~> 0.4.0')
|
30
|
+
s.add_development_dependency('mocha')
|
31
|
+
s.add_development_dependency('aws-sdk')
|
32
|
+
s.add_development_dependency('sqlite3', '~> 1.3.4')
|
33
|
+
s.add_development_dependency('cucumber', '~> 1.1.0')
|
34
|
+
s.add_development_dependency('aruba')
|
35
|
+
s.add_development_dependency('capybara')
|
36
|
+
s.add_development_dependency('bundler')
|
37
|
+
s.add_development_dependency('cocaine', '~> 0.2')
|
38
|
+
s.add_development_dependency('fog')
|
39
|
+
s.add_development_dependency('rake')
|
40
|
+
s.add_development_dependency('fakeweb')
|
41
|
+
end
|
data/test/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
debug.log
|
data/test/attachment_test.rb
CHANGED
@@ -1,46 +1,106 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require './test/helper'
|
3
|
+
require 'paperclip/attachment'
|
3
4
|
|
4
|
-
class Dummy
|
5
|
-
# This is a dummy class
|
6
|
-
end
|
5
|
+
class Dummy; end
|
7
6
|
|
8
7
|
class AttachmentTest < Test::Unit::TestCase
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
|
9
|
+
should "process :original style first" do
|
10
|
+
file = File.new(File.join(File.dirname(__FILE__), "fixtures", "50x50.png"), 'rb')
|
11
|
+
rebuild_class :styles => { :small => '100x>', :original => '42x42#' }
|
12
|
+
dummy = Dummy.new
|
13
|
+
dummy.avatar = file
|
14
|
+
dummy.save
|
15
|
+
|
16
|
+
# :small avatar should be 42px wide (processed original), not 50px (preprocessed original)
|
17
|
+
assert_equal `identify -format "%w" "#{dummy.avatar.path(:small)}"`.strip, "42"
|
18
|
+
|
19
|
+
file.close
|
15
20
|
end
|
16
21
|
|
17
|
-
should "
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
should "handle a boolean second argument to #url" do
|
23
|
+
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
24
|
+
attachment = Paperclip::Attachment.new(:name, :instance, :url_generator => mock_url_generator_builder)
|
25
|
+
|
26
|
+
attachment.url(:style_name, true)
|
27
|
+
assert mock_url_generator_builder.has_generated_url_with_options?(:timestamp => true, :escape => true)
|
28
|
+
|
29
|
+
attachment.url(:style_name, false)
|
30
|
+
assert mock_url_generator_builder.has_generated_url_with_options?(:timestamp => false, :escape => true)
|
22
31
|
end
|
23
32
|
|
24
|
-
should "
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
33
|
+
should "pass the style and options through to the URL generator on #url" do
|
34
|
+
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
35
|
+
attachment = Paperclip::Attachment.new(:name, :instance, :url_generator => mock_url_generator_builder)
|
36
|
+
|
37
|
+
attachment.url(:style_name, :options => :values)
|
38
|
+
assert mock_url_generator_builder.has_generated_url_with_options?(:options => :values)
|
29
39
|
end
|
30
40
|
|
31
|
-
should "
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
41
|
+
should "pass default options through when #url is given one argument" do
|
42
|
+
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
43
|
+
attachment = Paperclip::Attachment.new(:name,
|
44
|
+
:instance,
|
45
|
+
:url_generator => mock_url_generator_builder,
|
46
|
+
:use_timestamp => true)
|
47
|
+
|
48
|
+
attachment.url(:style_name)
|
49
|
+
assert mock_url_generator_builder.has_generated_url_with_options?(:escape => true, :timestamp => true)
|
50
|
+
end
|
51
|
+
|
52
|
+
should "pass default style and options through when #url is given no arguments" do
|
53
|
+
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
54
|
+
attachment = Paperclip::Attachment.new(:name,
|
55
|
+
:instance,
|
56
|
+
:default_style => 'default style',
|
57
|
+
:url_generator => mock_url_generator_builder,
|
58
|
+
:use_timestamp => true)
|
59
|
+
|
60
|
+
attachment.url
|
61
|
+
assert mock_url_generator_builder.has_generated_url_with_options?(:escape => true, :timestamp => true)
|
62
|
+
assert mock_url_generator_builder.has_generated_url_with_style_name?('default style')
|
63
|
+
end
|
64
|
+
|
65
|
+
should "pass the option :timestamp => true if :use_timestamp is true and :timestamp is not passed" do
|
66
|
+
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
67
|
+
attachment = Paperclip::Attachment.new(:name,
|
68
|
+
:instance,
|
69
|
+
:url_generator => mock_url_generator_builder,
|
70
|
+
:use_timestamp => true)
|
71
|
+
|
72
|
+
attachment.url(:style_name)
|
73
|
+
assert mock_url_generator_builder.has_generated_url_with_options?(:escape => true, :timestamp => true)
|
74
|
+
end
|
75
|
+
|
76
|
+
should "pass the option :timestamp => false if :use_timestamp is false and :timestamp is not passed" do
|
77
|
+
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
78
|
+
attachment = Paperclip::Attachment.new(:name,
|
79
|
+
:instance,
|
80
|
+
:url_generator => mock_url_generator_builder,
|
81
|
+
:use_timestamp => false)
|
82
|
+
|
83
|
+
attachment.url(:style_name)
|
84
|
+
assert mock_url_generator_builder.has_generated_url_with_options?(:escape => true, :timestamp => false)
|
85
|
+
end
|
86
|
+
|
87
|
+
should "not change the :timestamp if :timestamp is passed" do
|
88
|
+
mock_url_generator_builder = MockUrlGeneratorBuilder.new
|
89
|
+
attachment = Paperclip::Attachment.new(:name,
|
90
|
+
:instance,
|
91
|
+
:url_generator => mock_url_generator_builder,
|
92
|
+
:use_timestamp => false)
|
93
|
+
|
94
|
+
attachment.url(:style_name, :timestamp => true)
|
95
|
+
assert mock_url_generator_builder.has_generated_url_with_options?(:escape => true, :timestamp => true)
|
37
96
|
end
|
38
97
|
|
39
|
-
should "return the
|
40
|
-
@attachment = attachment :
|
98
|
+
should "return the path based on the url by default" do
|
99
|
+
@attachment = attachment :url => "/:class/:id/:basename"
|
41
100
|
@model = @attachment.instance
|
42
|
-
@model.
|
43
|
-
|
101
|
+
@model.id = 1234
|
102
|
+
@model.avatar_file_name = "fake.jpg"
|
103
|
+
assert_equal "#{Rails.root}/public/fake_models/1234/fake", @attachment.path
|
44
104
|
end
|
45
105
|
|
46
106
|
context "Attachment default_options" do
|
@@ -85,7 +145,7 @@ class AttachmentTest < Test::Unit::TestCase
|
|
85
145
|
Paperclip::Attachment.default_options.keys.each do |key|
|
86
146
|
should "be the default_options for #{key}" do
|
87
147
|
assert_equal @old_default_options[key],
|
88
|
-
@attachment.options
|
148
|
+
@attachment.instance_variable_get("@options")[key],
|
89
149
|
key
|
90
150
|
end
|
91
151
|
end
|
@@ -100,7 +160,7 @@ class AttachmentTest < Test::Unit::TestCase
|
|
100
160
|
Paperclip::Attachment.default_options.keys.each do |key|
|
101
161
|
should "be the new default_options for #{key}" do
|
102
162
|
assert_equal @new_default_options[key],
|
103
|
-
@attachment.options
|
163
|
+
@attachment.instance_variable_get("@options")[key],
|
104
164
|
key
|
105
165
|
end
|
106
166
|
end
|
@@ -160,36 +220,6 @@ class AttachmentTest < Test::Unit::TestCase
|
|
160
220
|
end
|
161
221
|
end
|
162
222
|
|
163
|
-
context "An attachment" do
|
164
|
-
setup do
|
165
|
-
@file = StringIO.new("...")
|
166
|
-
end
|
167
|
-
|
168
|
-
context "using default time zone" do
|
169
|
-
setup do
|
170
|
-
rebuild_model :url => "X"
|
171
|
-
@dummy = Dummy.new
|
172
|
-
@dummy.avatar = @file
|
173
|
-
end
|
174
|
-
|
175
|
-
should "generate a url with a timestamp when passing true" do
|
176
|
-
assert_equal "X?#{@dummy.avatar_updated_at.to_i.to_s}", @dummy.avatar.url(:style, true)
|
177
|
-
end
|
178
|
-
|
179
|
-
should "not generate a url with a timestamp when passing false" do
|
180
|
-
assert_equal "X", @dummy.avatar.url(:style, false)
|
181
|
-
end
|
182
|
-
|
183
|
-
should "generate a url with a timestamp when setting a timestamp option" do
|
184
|
-
assert_equal "X?#{@dummy.avatar_updated_at.to_i.to_s}", @dummy.avatar.url(:style, :timestamp => true)
|
185
|
-
end
|
186
|
-
|
187
|
-
should "not generate a url with a timestamp when setting a timestamp option to false" do
|
188
|
-
assert_equal "X", @dummy.avatar.url(:style, :timestamp => false)
|
189
|
-
end
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
223
|
context "An attachment with :hash interpolations" do
|
194
224
|
setup do
|
195
225
|
@file = StringIO.new("...")
|
@@ -214,12 +244,12 @@ class AttachmentTest < Test::Unit::TestCase
|
|
214
244
|
end
|
215
245
|
|
216
246
|
should "interpolate the hash data" do
|
217
|
-
@attachment.expects(:interpolate).with(@attachment.options
|
218
|
-
@attachment.
|
247
|
+
@attachment.expects(:interpolate).with(@attachment.options[:hash_data],anything).returns("interpolated_stuff")
|
248
|
+
@attachment.hash_key
|
219
249
|
end
|
220
250
|
|
221
251
|
should "result in the correct interpolation" do
|
222
|
-
assert_equal "fake_models/avatars/1234/original/1234567890", @attachment.send(:interpolate,@attachment.options
|
252
|
+
assert_equal "fake_models/avatars/1234/original/1234567890", @attachment.send(:interpolate,@attachment.options[:hash_data])
|
223
253
|
end
|
224
254
|
|
225
255
|
should "result in a correct hash" do
|
@@ -302,7 +332,7 @@ class AttachmentTest < Test::Unit::TestCase
|
|
302
332
|
end
|
303
333
|
|
304
334
|
should "report the correct options when sent #extra_source_file_options_for(:thumb)" do
|
305
|
-
assert_equal "-depth 8 -density 400", @dummy.avatar.send(:extra_source_file_options_for, :thumb), @dummy.avatar.
|
335
|
+
assert_equal "-depth 8 -density 400", @dummy.avatar.send(:extra_source_file_options_for, :thumb), @dummy.avatar.source_file_options.inspect
|
306
336
|
end
|
307
337
|
|
308
338
|
should "report the correct options when sent #extra_source_file_options_for(:large)" do
|
@@ -384,10 +414,10 @@ class AttachmentTest < Test::Unit::TestCase
|
|
384
414
|
end
|
385
415
|
|
386
416
|
should "have the correct geometry" do
|
387
|
-
assert_equal "50x50#", @attachment.
|
417
|
+
assert_equal "50x50#", @attachment.styles[:thumb][:geometry]
|
388
418
|
end
|
389
419
|
end
|
390
|
-
|
420
|
+
|
391
421
|
context "An attachment with conditional :styles that is a proc" do
|
392
422
|
setup do
|
393
423
|
rebuild_model :styles => lambda{ |attachment| attachment.instance.other == 'a' ? {:thumb => "50x50#"} : {:large => "400x400"} }
|
@@ -396,34 +426,13 @@ class AttachmentTest < Test::Unit::TestCase
|
|
396
426
|
end
|
397
427
|
|
398
428
|
should "have the correct styles for the assigned instance values" do
|
399
|
-
assert_equal "50x50#", @dummy.avatar.
|
400
|
-
assert_nil @dummy.avatar.
|
429
|
+
assert_equal "50x50#", @dummy.avatar.styles[:thumb][:geometry]
|
430
|
+
assert_nil @dummy.avatar.styles[:large]
|
401
431
|
|
402
432
|
@dummy.other = 'b'
|
403
|
-
|
404
|
-
assert_equal "400x400", @dummy.avatar.options.styles[:large][:geometry]
|
405
|
-
assert_nil @dummy.avatar.options.styles[:thumb]
|
406
|
-
end
|
407
|
-
end
|
408
|
-
|
409
|
-
context "An attachment with :url that is a proc" do
|
410
|
-
setup do
|
411
|
-
rebuild_model :url => lambda{ |attachment| "path/#{attachment.instance.other}.:extension" }
|
412
|
-
|
413
|
-
@file = File.new(File.join(File.dirname(__FILE__),
|
414
|
-
"fixtures",
|
415
|
-
"5k.png"), 'rb')
|
416
|
-
@dummyA = Dummy.new(:other => 'a')
|
417
|
-
@dummyA.avatar = @file
|
418
|
-
@dummyB = Dummy.new(:other => 'b')
|
419
|
-
@dummyB.avatar = @file
|
420
|
-
end
|
421
433
|
|
422
|
-
|
423
|
-
|
424
|
-
should "return correct url" do
|
425
|
-
assert_equal "path/a.png", @dummyA.avatar.url(:original, false)
|
426
|
-
assert_equal "path/b.png", @dummyB.avatar.url(:original, false)
|
434
|
+
assert_equal "400x400", @dummy.avatar.styles[:large][:geometry]
|
435
|
+
assert_nil @dummy.avatar.styles[:thumb]
|
427
436
|
end
|
428
437
|
end
|
429
438
|
|
@@ -446,7 +455,7 @@ class AttachmentTest < Test::Unit::TestCase
|
|
446
455
|
end
|
447
456
|
|
448
457
|
should "have the correct geometry" do
|
449
|
-
assert_equal "50x50#", @attachment.
|
458
|
+
assert_equal "50x50#", @attachment.styles[:normal][:geometry]
|
450
459
|
end
|
451
460
|
end
|
452
461
|
end
|
@@ -464,7 +473,7 @@ class AttachmentTest < Test::Unit::TestCase
|
|
464
473
|
|
465
474
|
[:processors, :whiny, :convert_options, :geometry, :format].each do |field|
|
466
475
|
should "have the same #{field} field" do
|
467
|
-
assert_equal @attachment.
|
476
|
+
assert_equal @attachment.styles[:normal][field], @attachment.styles[:hash][field]
|
468
477
|
end
|
469
478
|
end
|
470
479
|
end
|
@@ -485,7 +494,7 @@ class AttachmentTest < Test::Unit::TestCase
|
|
485
494
|
end
|
486
495
|
|
487
496
|
should "have the correct processors" do
|
488
|
-
assert_equal [ :test ], @attachment.
|
497
|
+
assert_equal [ :test ], @attachment.styles[:normal][:processors]
|
489
498
|
end
|
490
499
|
end
|
491
500
|
end
|
@@ -552,16 +561,16 @@ class AttachmentTest < Test::Unit::TestCase
|
|
552
561
|
rebuild_model :storage => :FileSystem
|
553
562
|
@dummy = Dummy.new
|
554
563
|
assert @dummy.avatar.is_a?(Paperclip::Storage::Filesystem)
|
555
|
-
|
564
|
+
|
556
565
|
rebuild_model :storage => :Filesystem
|
557
566
|
@dummy = Dummy.new
|
558
567
|
assert @dummy.avatar.is_a?(Paperclip::Storage::Filesystem)
|
559
568
|
end
|
560
|
-
|
569
|
+
|
561
570
|
should "convert underscored storage name to camelcase" do
|
562
571
|
rebuild_model :storage => :not_here
|
563
572
|
@dummy = Dummy.new
|
564
|
-
exception = assert_raises(Paperclip::StorageMethodNotFound) do
|
573
|
+
exception = assert_raises(Paperclip::StorageMethodNotFound) do
|
565
574
|
@dummy.avatar
|
566
575
|
end
|
567
576
|
assert exception.message.include?("NotHere")
|
@@ -770,12 +779,6 @@ class AttachmentTest < Test::Unit::TestCase
|
|
770
779
|
end
|
771
780
|
end
|
772
781
|
|
773
|
-
should "return its default_url when no file assigned" do
|
774
|
-
assert @attachment.to_file.nil?
|
775
|
-
assert_equal "/avatars/original/missing.png", @attachment.url
|
776
|
-
assert_equal "/avatars/blah/missing.png", @attachment.url(:blah)
|
777
|
-
end
|
778
|
-
|
779
782
|
should "return nil as path when no file assigned" do
|
780
783
|
assert @attachment.to_file.nil?
|
781
784
|
assert_equal nil, @attachment.path
|
@@ -802,29 +805,6 @@ class AttachmentTest < Test::Unit::TestCase
|
|
802
805
|
@attachment.stubs(:instance_read).with(:updated_at).returns(dtnow)
|
803
806
|
end
|
804
807
|
|
805
|
-
should "return a correct url even if the file does not exist" do
|
806
|
-
assert_nil @attachment.to_file
|
807
|
-
assert_match %r{^/system/avatars/#{@instance.id}/blah/5k\.png}, @attachment.url(:blah)
|
808
|
-
end
|
809
|
-
|
810
|
-
should "make sure the updated_at mtime is in the url if it is defined" do
|
811
|
-
assert_match %r{#{@now.to_i}$}, @attachment.url(:blah)
|
812
|
-
end
|
813
|
-
|
814
|
-
should "make sure the updated_at mtime is NOT in the url if false is passed to the url method" do
|
815
|
-
assert_no_match %r{#{@now.to_i}$}, @attachment.url(:blah, false)
|
816
|
-
end
|
817
|
-
|
818
|
-
context "with the updated_at field removed" do
|
819
|
-
setup do
|
820
|
-
@attachment.stubs(:instance_read).with(:updated_at).returns(nil)
|
821
|
-
end
|
822
|
-
|
823
|
-
should "only return the url without the updated_at when sent #url" do
|
824
|
-
assert_match "/avatars/#{@instance.id}/blah/5k.png", @attachment.url(:blah)
|
825
|
-
end
|
826
|
-
end
|
827
|
-
|
828
808
|
should "return the proper path when filename has a single .'s" do
|
829
809
|
assert_equal File.expand_path("./test/../tmp/avatars/dummies/original/#{@instance.id}/5k.png"), File.expand_path(@attachment.path)
|
830
810
|
end
|
@@ -864,14 +844,6 @@ class AttachmentTest < Test::Unit::TestCase
|
|
864
844
|
@attachment.save
|
865
845
|
end
|
866
846
|
|
867
|
-
should "return the real url" do
|
868
|
-
file = @attachment.to_file
|
869
|
-
assert file
|
870
|
-
assert_match %r{^/system/avatars/#{@instance.id}/original/5k\.png}, @attachment.url
|
871
|
-
assert_match %r{^/system/avatars/#{@instance.id}/small/5k\.jpg}, @attachment.url(:small)
|
872
|
-
file.close
|
873
|
-
end
|
874
|
-
|
875
847
|
should "commit the files to disk" do
|
876
848
|
[:large, :medium, :small].each do |style|
|
877
849
|
io = @attachment.to_file(style)
|
@@ -902,7 +874,7 @@ class AttachmentTest < Test::Unit::TestCase
|
|
902
874
|
|
903
875
|
context "and trying to delete" do
|
904
876
|
setup do
|
905
|
-
@existing_names = @attachment.
|
877
|
+
@existing_names = @attachment.styles.keys.collect do |style|
|
906
878
|
@attachment.path(style)
|
907
879
|
end
|
908
880
|
end
|
@@ -935,28 +907,47 @@ class AttachmentTest < Test::Unit::TestCase
|
|
935
907
|
@attachment.destroy
|
936
908
|
@existing_names.each{|f| assert ! File.exists?(f) }
|
937
909
|
end
|
910
|
+
|
911
|
+
context "when keeping old files" do
|
912
|
+
setup do
|
913
|
+
@attachment.options[:keep_old_files] = true
|
914
|
+
end
|
915
|
+
|
916
|
+
should "keep the files after assigning nil" do
|
917
|
+
@attachment.expects(:instance_write).with(:file_name, nil)
|
918
|
+
@attachment.expects(:instance_write).with(:content_type, nil)
|
919
|
+
@attachment.expects(:instance_write).with(:file_size, nil)
|
920
|
+
@attachment.expects(:instance_write).with(:updated_at, nil)
|
921
|
+
@attachment.assign nil
|
922
|
+
@attachment.save
|
923
|
+
@existing_names.each{|f| assert File.exists?(f) }
|
924
|
+
end
|
925
|
+
|
926
|
+
should "keep the files when you call #clear and #save" do
|
927
|
+
@attachment.expects(:instance_write).with(:file_name, nil)
|
928
|
+
@attachment.expects(:instance_write).with(:content_type, nil)
|
929
|
+
@attachment.expects(:instance_write).with(:file_size, nil)
|
930
|
+
@attachment.expects(:instance_write).with(:updated_at, nil)
|
931
|
+
@attachment.clear
|
932
|
+
@attachment.save
|
933
|
+
@existing_names.each{|f| assert File.exists?(f) }
|
934
|
+
end
|
935
|
+
|
936
|
+
should "keep the files when you call #delete" do
|
937
|
+
@attachment.expects(:instance_write).with(:file_name, nil)
|
938
|
+
@attachment.expects(:instance_write).with(:content_type, nil)
|
939
|
+
@attachment.expects(:instance_write).with(:file_size, nil)
|
940
|
+
@attachment.expects(:instance_write).with(:updated_at, nil)
|
941
|
+
@attachment.destroy
|
942
|
+
@existing_names.each{|f| assert File.exists?(f) }
|
943
|
+
end
|
944
|
+
end
|
938
945
|
end
|
939
946
|
end
|
940
947
|
end
|
941
948
|
end
|
942
949
|
end
|
943
950
|
|
944
|
-
context "with a file that has space in file name" do
|
945
|
-
setup do
|
946
|
-
@attachment.stubs(:instance_read).with(:file_name).returns("spaced file.png")
|
947
|
-
@attachment.stubs(:instance_read).with(:content_type).returns("image/png")
|
948
|
-
@attachment.stubs(:instance_read).with(:file_size).returns(12345)
|
949
|
-
dtnow = DateTime.now
|
950
|
-
@now = Time.now
|
951
|
-
Time.stubs(:now).returns(@now)
|
952
|
-
@attachment.stubs(:instance_read).with(:updated_at).returns(dtnow)
|
953
|
-
end
|
954
|
-
|
955
|
-
should "returns an escaped version of the URL" do
|
956
|
-
assert_match /\/spaced%20file\.png/, @attachment.url
|
957
|
-
end
|
958
|
-
end
|
959
|
-
|
960
951
|
context "when trying a nonexistant storage type" do
|
961
952
|
setup do
|
962
953
|
rebuild_model :storage => :not_here
|
@@ -1020,7 +1011,18 @@ class AttachmentTest < Test::Unit::TestCase
|
|
1020
1011
|
assert_equal now.to_i, @dummy.avatar.updated_at
|
1021
1012
|
end
|
1022
1013
|
end
|
1023
|
-
|
1014
|
+
|
1015
|
+
should "not calculate fingerprint after save" do
|
1016
|
+
@dummy.avatar = @file
|
1017
|
+
@dummy.save
|
1018
|
+
assert_nil @dummy.avatar.fingerprint
|
1019
|
+
end
|
1020
|
+
|
1021
|
+
should "not calculate fingerprint before saving" do
|
1022
|
+
@dummy.avatar = @file
|
1023
|
+
assert_nil @dummy.avatar.fingerprint
|
1024
|
+
end
|
1025
|
+
|
1024
1026
|
context "and avatar_content_type column" do
|
1025
1027
|
setup do
|
1026
1028
|
ActiveRecord::Base.connection.add_column :dummies, :avatar_content_type, :string
|
@@ -1109,21 +1111,6 @@ class AttachmentTest < Test::Unit::TestCase
|
|
1109
1111
|
end
|
1110
1112
|
end
|
1111
1113
|
|
1112
|
-
context "setting an interpolation class" do
|
1113
|
-
should "produce the URL with the given interpolations" do
|
1114
|
-
Interpolator = Class.new do
|
1115
|
-
def self.interpolate(pattern, attachment, style_name)
|
1116
|
-
"hello"
|
1117
|
-
end
|
1118
|
-
end
|
1119
|
-
|
1120
|
-
instance = Dummy.new
|
1121
|
-
attachment = Paperclip::Attachment.new(:avatar, instance, :interpolator => Interpolator)
|
1122
|
-
|
1123
|
-
assert_equal "hello", attachment.url
|
1124
|
-
end
|
1125
|
-
end
|
1126
|
-
|
1127
1114
|
context "An attached file" do
|
1128
1115
|
setup do
|
1129
1116
|
rebuild_model
|