bteitelb-paperclip 2.3.1.11 → 2.3.1.12
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/Rakefile +2 -2
- data/lib/paperclip.rb +18 -14
- data/lib/paperclip/attachment.rb +46 -134
- data/lib/paperclip/interpolations.rb +17 -17
- data/lib/paperclip/iostream.rb +2 -1
- data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +2 -3
- data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +6 -6
- data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +5 -3
- data/lib/paperclip/storage.rb +13 -9
- data/lib/paperclip/thumbnail.rb +2 -0
- data/test/attachment_test.rb +22 -38
- data/test/helper.rb +1 -1
- data/test/iostream_test.rb +9 -2
- data/test/matchers/validate_attachment_content_type_matcher_test.rb +1 -0
- data/test/matchers/validate_attachment_presence_matcher_test.rb +3 -1
- data/test/matchers/validate_attachment_size_matcher_test.rb +1 -0
- data/test/paperclip_test.rb +12 -41
- data/test/storage_test.rb +27 -0
- data/test/thumbnail_test.rb +1 -1
- metadata +1 -1
data/Rakefile
CHANGED
|
@@ -75,8 +75,8 @@ spec = Gem::Specification.new do |s|
|
|
|
75
75
|
s.extra_rdoc_files = FileList["README*"].to_a
|
|
76
76
|
s.rdoc_options << '--line-numbers' << '--inline-source'
|
|
77
77
|
s.requirements << "ImageMagick"
|
|
78
|
-
s.add_development_dependency '
|
|
79
|
-
s.add_development_dependency 'jferris-mocha', '
|
|
78
|
+
s.add_development_dependency 'shoulda'
|
|
79
|
+
s.add_development_dependency 'jferris-mocha', '>= 0.9.5.0.1241126838'
|
|
80
80
|
s.add_development_dependency 'aws-s3'
|
|
81
81
|
s.add_development_dependency 'sqlite3-ruby'
|
|
82
82
|
s.add_development_dependency 'activerecord'
|
data/lib/paperclip.rb
CHANGED
|
@@ -34,6 +34,7 @@ require 'paperclip/processor'
|
|
|
34
34
|
require 'paperclip/thumbnail'
|
|
35
35
|
require 'paperclip/storage'
|
|
36
36
|
require 'paperclip/interpolations'
|
|
37
|
+
require 'paperclip/style'
|
|
37
38
|
require 'paperclip/attachment'
|
|
38
39
|
if defined? RAILS_ROOT
|
|
39
40
|
Dir.glob(File.join(File.expand_path(RAILS_ROOT), "lib", "paperclip_processors", "*.rb")).each do |processor|
|
|
@@ -239,7 +240,7 @@ module Paperclip
|
|
|
239
240
|
|
|
240
241
|
validates_each(name) do |record, attr, value|
|
|
241
242
|
attachment = record.attachment_for(name)
|
|
242
|
-
attachment.send(:flush_errors)
|
|
243
|
+
attachment.send(:flush_errors)
|
|
243
244
|
end
|
|
244
245
|
end
|
|
245
246
|
|
|
@@ -257,13 +258,13 @@ module Paperclip
|
|
|
257
258
|
max = options[:less_than] || (options[:in] && options[:in].last) || (1.0/0)
|
|
258
259
|
range = (min..max)
|
|
259
260
|
message = options[:message] || "file size must be between :min and :max bytes."
|
|
261
|
+
message = message.gsub(/:min/, min.to_s).gsub(/:max/, max.to_s)
|
|
260
262
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
:unless => options[:unless]}]
|
|
263
|
+
validates_inclusion_of :"#{name}_file_size",
|
|
264
|
+
:in => range,
|
|
265
|
+
:message => message,
|
|
266
|
+
:if => options[:if],
|
|
267
|
+
:unless => options[:unless]
|
|
267
268
|
end
|
|
268
269
|
|
|
269
270
|
# Adds errors if thumbnail creation fails. The same as specifying :whiny_thumbnails => true.
|
|
@@ -281,9 +282,10 @@ module Paperclip
|
|
|
281
282
|
# * +unless+: Same as +if+ but validates if lambda or method returns false.
|
|
282
283
|
def validates_attachment_presence name, options = {}
|
|
283
284
|
message = options[:message] || "must be set."
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
285
|
+
validates_presence_of :"#{name}_file_name",
|
|
286
|
+
:message => message,
|
|
287
|
+
:if => options[:if],
|
|
288
|
+
:unless => options[:unless]
|
|
287
289
|
end
|
|
288
290
|
|
|
289
291
|
# Places ActiveRecord-style validations on the content type of the file
|
|
@@ -303,10 +305,12 @@ module Paperclip
|
|
|
303
305
|
# model, content_type validation will work _ONLY upon assignment_ and
|
|
304
306
|
# re-validation after the instance has been reloaded will always succeed.
|
|
305
307
|
def validates_attachment_content_type name, options = {}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
308
|
+
types = [options.delete(:content_type)].flatten
|
|
309
|
+
validates_each(:"#{name}_content_type", options) do |record, attr, value|
|
|
310
|
+
unless types.any?{|t| t === value }
|
|
311
|
+
record.errors.add(:"#{name}_content_type", :inclusion, :default => options[:message], :value => value)
|
|
312
|
+
end
|
|
313
|
+
end
|
|
310
314
|
end
|
|
311
315
|
|
|
312
316
|
# Returns the attachment definitions defined by each call to
|
data/lib/paperclip/attachment.rb
CHANGED
|
@@ -9,18 +9,19 @@ module Paperclip
|
|
|
9
9
|
|
|
10
10
|
def self.default_options
|
|
11
11
|
@default_options ||= {
|
|
12
|
-
:url
|
|
13
|
-
:path
|
|
14
|
-
:styles
|
|
15
|
-
:
|
|
16
|
-
:
|
|
17
|
-
:
|
|
18
|
-
:
|
|
19
|
-
:
|
|
12
|
+
:url => "/system/:attachment/:id/:style/:filename",
|
|
13
|
+
:path => ":rails_root/public:url",
|
|
14
|
+
:styles => {},
|
|
15
|
+
:processors => [:thumbnail],
|
|
16
|
+
:convert_options => {},
|
|
17
|
+
:default_url => "/:attachment/:style/missing.png",
|
|
18
|
+
:default_style => :original,
|
|
19
|
+
:storage => :filesystem,
|
|
20
|
+
:whiny => Paperclip.options[:whiny] || Paperclip.options[:whiny_thumbnails]
|
|
20
21
|
}
|
|
21
22
|
end
|
|
22
23
|
|
|
23
|
-
attr_reader :name, :instance, :
|
|
24
|
+
attr_reader :name, :instance, :default_style, :convert_options, :queued_for_write, :whiny, :options
|
|
24
25
|
|
|
25
26
|
# Creates an Attachment object. +name+ is the name of the attachment,
|
|
26
27
|
# +instance+ is the ActiveRecord object instance it's attached to, and
|
|
@@ -36,14 +37,13 @@ module Paperclip
|
|
|
36
37
|
@path = options[:path]
|
|
37
38
|
@path = @path.call(self) if @path.is_a?(Proc)
|
|
38
39
|
@styles = options[:styles]
|
|
39
|
-
@
|
|
40
|
+
@normalized_styles = nil
|
|
40
41
|
@default_url = options[:default_url]
|
|
41
|
-
@validations = options[:validations]
|
|
42
42
|
@default_style = options[:default_style]
|
|
43
43
|
@storage = options[:storage]
|
|
44
44
|
@whiny = options[:whiny_thumbnails] || options[:whiny]
|
|
45
|
-
@convert_options = options[:convert_options]
|
|
46
|
-
@processors = options[:processors]
|
|
45
|
+
@convert_options = options[:convert_options]
|
|
46
|
+
@processors = options[:processors]
|
|
47
47
|
@options = options
|
|
48
48
|
@queued_for_delete = []
|
|
49
49
|
@queued_for_write = {}
|
|
@@ -52,18 +52,29 @@ module Paperclip
|
|
|
52
52
|
@validation_errors = nil
|
|
53
53
|
@dirty = false
|
|
54
54
|
|
|
55
|
-
normalize_style_definition
|
|
56
55
|
initialize_storage
|
|
57
56
|
end
|
|
57
|
+
|
|
58
|
+
def styles
|
|
59
|
+
unless @normalized_styles
|
|
60
|
+
@normalized_styles = {}
|
|
61
|
+
(@styles.respond_to?(:call) ? @styles.call(self) : @styles).each do |name, args|
|
|
62
|
+
@normalized_styles[name] = Paperclip::Style.new(name, args, self)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
@normalized_styles
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def processors
|
|
69
|
+
@processors.respond_to?(:call) ? @processors.call(instance) : @processors
|
|
70
|
+
end
|
|
58
71
|
|
|
59
72
|
# What gets called when you call instance.attachment = File. It clears
|
|
60
|
-
# errors, assigns attributes, processes the file
|
|
73
|
+
# errors, assigns attributes, and processes the file. It
|
|
61
74
|
# also queues up the previous file for deletion, to be flushed away on
|
|
62
75
|
# #save of its host. In addition to form uploads, you can also assign
|
|
63
76
|
# another Paperclip attachment:
|
|
64
77
|
# new_user.avatar = old_user.avatar
|
|
65
|
-
# If the file that is assigned is not valid, the processing (i.e.
|
|
66
|
-
# thumbnailing, etc) will NOT be run.
|
|
67
78
|
def assign uploaded_file
|
|
68
79
|
ensure_required_accessors!
|
|
69
80
|
|
|
@@ -93,7 +104,7 @@ module Paperclip
|
|
|
93
104
|
|
|
94
105
|
@dirty = true
|
|
95
106
|
|
|
96
|
-
post_process
|
|
107
|
+
post_process
|
|
97
108
|
|
|
98
109
|
# Reset the file size if the original file was reprocessed.
|
|
99
110
|
instance_write(:file_size, @queued_for_write[:original].size.to_i)
|
|
@@ -115,7 +126,6 @@ module Paperclip
|
|
|
115
126
|
end
|
|
116
127
|
ensure
|
|
117
128
|
uploaded_file.close if close_uploaded_file
|
|
118
|
-
validate
|
|
119
129
|
end
|
|
120
130
|
|
|
121
131
|
# Returns the public URL of the attachment, with a given style. Note that
|
|
@@ -125,8 +135,8 @@ module Paperclip
|
|
|
125
135
|
# security, however, for performance reasons. set
|
|
126
136
|
# include_updated_timestamp to false if you want to stop the attachment
|
|
127
137
|
# update time appended to the url
|
|
128
|
-
def url
|
|
129
|
-
url = original_filename.nil? ? interpolate(@default_url,
|
|
138
|
+
def url style_name = default_style, include_updated_timestamp = true
|
|
139
|
+
url = original_filename.nil? ? interpolate(@default_url, style_name) : interpolate(@url, style_name)
|
|
130
140
|
include_updated_timestamp && updated_at ? [url, updated_at].compact.join(url.include?("?") ? "&" : "?") : url
|
|
131
141
|
end
|
|
132
142
|
|
|
@@ -134,19 +144,13 @@ module Paperclip
|
|
|
134
144
|
# file is stored in the filesystem the path refers to the path of the file
|
|
135
145
|
# on disk. If the file is stored in S3, the path is the "key" part of the
|
|
136
146
|
# URL, and the :bucket option refers to the S3 bucket.
|
|
137
|
-
def path
|
|
138
|
-
original_filename.nil? ? nil : interpolate(@path,
|
|
147
|
+
def path style_name = default_style
|
|
148
|
+
original_filename.nil? ? nil : interpolate(@path, style_name)
|
|
139
149
|
end
|
|
140
150
|
|
|
141
151
|
# Alias to +url+
|
|
142
|
-
def to_s
|
|
143
|
-
url(
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
# Returns true if there are no errors on this attachment.
|
|
147
|
-
def valid?
|
|
148
|
-
validate
|
|
149
|
-
errors.empty?
|
|
152
|
+
def to_s style_name = nil
|
|
153
|
+
url(style_name)
|
|
150
154
|
end
|
|
151
155
|
|
|
152
156
|
# Returns an array containing the errors on this attachment.
|
|
@@ -162,15 +166,10 @@ module Paperclip
|
|
|
162
166
|
# Saves the file, if there are no errors. If there are, it flushes them to
|
|
163
167
|
# the instance's errors and returns false, cancelling the save.
|
|
164
168
|
def save
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
true
|
|
170
|
-
else
|
|
171
|
-
flush_errors
|
|
172
|
-
false
|
|
173
|
-
end
|
|
169
|
+
flush_deletes
|
|
170
|
+
flush_writes
|
|
171
|
+
@dirty = false
|
|
172
|
+
true
|
|
174
173
|
end
|
|
175
174
|
|
|
176
175
|
# Clears out the attachment. Has the same effect as previously assigning
|
|
@@ -179,7 +178,6 @@ module Paperclip
|
|
|
179
178
|
def clear
|
|
180
179
|
queue_existing_for_delete
|
|
181
180
|
@errors = {}
|
|
182
|
-
@validation_errors = nil
|
|
183
181
|
end
|
|
184
182
|
|
|
185
183
|
# Destroys the attachment. Has the same effect as previously assigning
|
|
@@ -271,15 +269,6 @@ module Paperclip
|
|
|
271
269
|
# Determines whether or not the attachment is an image based on the content_type
|
|
272
270
|
def image?
|
|
273
271
|
!content_type.nil? and !!content_type.match(%r{\Aimage/})
|
|
274
|
-
|
|
275
|
-
# Fix content type when it's application/octet-stream
|
|
276
|
-
if content_type.to_s.strip == 'application/octet-stream'
|
|
277
|
-
mime_type = MIME::Types.type_for(uploaded_file.original_filename.strip).to_s
|
|
278
|
-
end
|
|
279
|
-
instance_write(:content_type, uploaded_file.content_type.to_s.strip)
|
|
280
|
-
instance_write(:file_size, uploaded_file.size.to_i)
|
|
281
|
-
instance_write(:updated_at, Time.now)
|
|
282
|
-
|
|
283
272
|
end
|
|
284
273
|
|
|
285
274
|
# Writes the attachment-specific attribute on the instance. For example,
|
|
@@ -320,82 +309,6 @@ module Paperclip
|
|
|
320
309
|
file.nil? || (file.respond_to?(:original_filename) && file.respond_to?(:content_type))
|
|
321
310
|
end
|
|
322
311
|
|
|
323
|
-
def validate #:nodoc:
|
|
324
|
-
unless @validation_errors
|
|
325
|
-
@validation_errors = @validations.inject({}) do |errors, validation|
|
|
326
|
-
name, options = validation
|
|
327
|
-
errors[name] = send(:"validate_#{name}", options) if allow_validation?(options)
|
|
328
|
-
errors
|
|
329
|
-
end
|
|
330
|
-
@validation_errors.reject!{|k,v| v == nil }
|
|
331
|
-
@errors.merge!(@validation_errors)
|
|
332
|
-
end
|
|
333
|
-
@validation_errors
|
|
334
|
-
end
|
|
335
|
-
|
|
336
|
-
def allow_validation? options #:nodoc:
|
|
337
|
-
(options[:if].nil? || check_guard(options[:if])) && (options[:unless].nil? || !check_guard(options[:unless]))
|
|
338
|
-
end
|
|
339
|
-
|
|
340
|
-
def check_guard guard #:nodoc:
|
|
341
|
-
if guard.respond_to? :call
|
|
342
|
-
guard.call(instance)
|
|
343
|
-
elsif ! guard.blank?
|
|
344
|
-
instance.send(guard.to_s)
|
|
345
|
-
end
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
def validate_size options #:nodoc:
|
|
349
|
-
if file? && !options[:range].include?(size.to_i)
|
|
350
|
-
options[:message].gsub(/:min/, options[:min].to_s).gsub(/:max/, options[:max].to_s)
|
|
351
|
-
end
|
|
352
|
-
end
|
|
353
|
-
|
|
354
|
-
def validate_presence options #:nodoc:
|
|
355
|
-
options[:message] unless file?
|
|
356
|
-
end
|
|
357
|
-
|
|
358
|
-
def validate_content_type options #:nodoc:
|
|
359
|
-
valid_types = [options[:content_type]].flatten
|
|
360
|
-
unless original_filename.blank?
|
|
361
|
-
unless valid_types.blank?
|
|
362
|
-
content_type = instance_read(:content_type)
|
|
363
|
-
unless valid_types.any?{|t| content_type.nil? || t === content_type }
|
|
364
|
-
options[:message] || "is not one of the allowed file types."
|
|
365
|
-
end
|
|
366
|
-
end
|
|
367
|
-
end
|
|
368
|
-
end
|
|
369
|
-
|
|
370
|
-
def normalize_style_definition #:nodoc:
|
|
371
|
-
@styles.each do |name, args|
|
|
372
|
-
unless args.is_a? Hash
|
|
373
|
-
dimensions, format = [args, nil].flatten[0..1]
|
|
374
|
-
format = nil if format.blank?
|
|
375
|
-
@styles[name] = {
|
|
376
|
-
:processors => @processors,
|
|
377
|
-
:geometry => dimensions,
|
|
378
|
-
:format => format,
|
|
379
|
-
:whiny => @whiny,
|
|
380
|
-
:convert_options => extra_options_for(name)
|
|
381
|
-
}
|
|
382
|
-
else
|
|
383
|
-
@styles[name] = {
|
|
384
|
-
:processors => @processors,
|
|
385
|
-
:whiny => @whiny,
|
|
386
|
-
:convert_options => extra_options_for(name)
|
|
387
|
-
}.merge(@styles[name])
|
|
388
|
-
end
|
|
389
|
-
end
|
|
390
|
-
end
|
|
391
|
-
|
|
392
|
-
def solidify_style_definitions #:nodoc:
|
|
393
|
-
@styles.each do |name, args|
|
|
394
|
-
@styles[name][:geometry] = @styles[name][:geometry].call(instance) if @styles[name][:geometry].respond_to?(:call)
|
|
395
|
-
@styles[name][:processors] = @styles[name][:processors].call(instance) if @styles[name][:processors].respond_to?(:call)
|
|
396
|
-
end
|
|
397
|
-
end
|
|
398
|
-
|
|
399
312
|
def initialize_storage #:nodoc:
|
|
400
313
|
@storage_module = Paperclip::Storage.const_get(@storage.to_s.capitalize)
|
|
401
314
|
self.extend(@storage_module)
|
|
@@ -412,7 +325,6 @@ module Paperclip
|
|
|
412
325
|
|
|
413
326
|
def post_process #:nodoc:
|
|
414
327
|
return if @queued_for_write[:original].nil?
|
|
415
|
-
solidify_style_definitions
|
|
416
328
|
return if fire_events(:before)
|
|
417
329
|
post_process_styles
|
|
418
330
|
return if fire_events(:after)
|
|
@@ -428,11 +340,11 @@ module Paperclip
|
|
|
428
340
|
end
|
|
429
341
|
|
|
430
342
|
def post_process_styles #:nodoc:
|
|
431
|
-
|
|
343
|
+
styles.each do |name, style|
|
|
432
344
|
begin
|
|
433
|
-
raise RuntimeError.new("Style #{name} has no processors defined.") if
|
|
434
|
-
@queued_for_write[name] =
|
|
435
|
-
Paperclip.processor(processor).make(file,
|
|
345
|
+
raise RuntimeError.new("Style #{name} has no processors defined.") if style.processors.blank?
|
|
346
|
+
@queued_for_write[name] = style.processors.inject(@queued_for_write[:original]) do |file, processor|
|
|
347
|
+
Paperclip.processor(processor).make(file, style.processor_options, self)
|
|
436
348
|
end
|
|
437
349
|
rescue PaperclipError => e
|
|
438
350
|
log("An error was received while processing: #{e.inspect}")
|
|
@@ -441,8 +353,8 @@ module Paperclip
|
|
|
441
353
|
end
|
|
442
354
|
end
|
|
443
355
|
|
|
444
|
-
def interpolate pattern,
|
|
445
|
-
Paperclip::Interpolations.interpolate(pattern, self,
|
|
356
|
+
def interpolate pattern, style_name = default_style #:nodoc:
|
|
357
|
+
Paperclip::Interpolations.interpolate(pattern, self, style_name)
|
|
446
358
|
end
|
|
447
359
|
|
|
448
360
|
def mime_type
|
|
@@ -469,7 +381,7 @@ module Paperclip
|
|
|
469
381
|
|
|
470
382
|
def queue_existing_for_delete #:nodoc:
|
|
471
383
|
return unless file?
|
|
472
|
-
@queued_for_delete += [:original,
|
|
384
|
+
@queued_for_delete += [:original, *styles.keys].uniq.map do |style|
|
|
473
385
|
path(style) if exists?(style)
|
|
474
386
|
end.compact
|
|
475
387
|
instance_write(:file_name, nil)
|
|
@@ -34,30 +34,30 @@ module Paperclip
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
# Returns the filename, the same way as ":basename.:extension" would.
|
|
37
|
-
def filename attachment,
|
|
38
|
-
"#{basename(attachment,
|
|
37
|
+
def filename attachment, style_name
|
|
38
|
+
"#{basename(attachment, style_name)}.#{extension(attachment, style_name)}"
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
# Returns the interpolated URL. Will raise an error if the url itself
|
|
42
42
|
# contains ":url" to prevent infinite recursion. This interpolation
|
|
43
43
|
# is used in the default :path to ease default specifications.
|
|
44
|
-
def url attachment,
|
|
44
|
+
def url attachment, style_name
|
|
45
45
|
raise InfiniteInterpolationError if attachment.options[:url].include?(":url")
|
|
46
|
-
attachment.url(
|
|
46
|
+
attachment.url(style_name, false)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
# Returns the timestamp as defined by the <attachment>_updated_at field
|
|
50
|
-
def timestamp attachment,
|
|
50
|
+
def timestamp attachment, style_name
|
|
51
51
|
attachment.instance_read(:updated_at).to_s
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
# Returns the RAILS_ROOT constant.
|
|
55
|
-
def rails_root attachment,
|
|
55
|
+
def rails_root attachment, style_name
|
|
56
56
|
RAILS_ROOT
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
# Returns the RAILS_ENV constant.
|
|
60
|
-
def rails_env attachment,
|
|
60
|
+
def rails_env attachment, style_name
|
|
61
61
|
RAILS_ENV
|
|
62
62
|
end
|
|
63
63
|
|
|
@@ -65,44 +65,44 @@ module Paperclip
|
|
|
65
65
|
# e.g. "users" for the User class.
|
|
66
66
|
# NOTE: The arguments need to be optional, because some tools fetch
|
|
67
67
|
# all class names. Calling #class will return the expected class.
|
|
68
|
-
def class attachment = nil,
|
|
69
|
-
return super() if attachment.nil? &&
|
|
68
|
+
def class attachment = nil, style_name = nil
|
|
69
|
+
return super() if attachment.nil? && style_name.nil?
|
|
70
70
|
attachment.instance.class.to_s.underscore.pluralize
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
# Returns the basename of the file. e.g. "file" for "file.jpg"
|
|
74
|
-
def basename attachment,
|
|
74
|
+
def basename attachment, style_name
|
|
75
75
|
attachment.original_filename.gsub(/#{File.extname(attachment.original_filename)}$/, "")
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
# Returns the extension of the file. e.g. "jpg" for "file.jpg"
|
|
79
79
|
# If the style has a format defined, it will return the format instead
|
|
80
80
|
# of the actual extension.
|
|
81
|
-
def extension attachment,
|
|
82
|
-
((style = attachment.styles[
|
|
81
|
+
def extension attachment, style_name
|
|
82
|
+
((style = attachment.styles[style_name]) && style[:format]) ||
|
|
83
83
|
File.extname(attachment.original_filename).gsub(/^\.+/, "")
|
|
84
84
|
end
|
|
85
85
|
|
|
86
86
|
# Returns the id of the instance.
|
|
87
|
-
def id attachment,
|
|
87
|
+
def id attachment, style_name
|
|
88
88
|
attachment.instance.id
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
# Returns the id of the instance in a split path form. e.g. returns
|
|
92
92
|
# 000/001/234 for an id of 1234.
|
|
93
|
-
def id_partition attachment,
|
|
93
|
+
def id_partition attachment, style_name
|
|
94
94
|
("%09d" % attachment.instance.id).scan(/\d{3}/).join("/")
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
# Returns the pluralized form of the attachment name. e.g.
|
|
98
98
|
# "avatars" for an attachment of :avatar
|
|
99
|
-
def attachment attachment,
|
|
99
|
+
def attachment attachment, style_name
|
|
100
100
|
attachment.name.to_s.downcase.pluralize
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
# Returns the style, or the default style if nil is supplied.
|
|
104
|
-
def style attachment,
|
|
105
|
-
|
|
104
|
+
def style attachment, style_name
|
|
105
|
+
style_name || attachment.default_style
|
|
106
106
|
end
|
|
107
107
|
end
|
|
108
108
|
end
|
data/lib/paperclip/iostream.rb
CHANGED
|
@@ -4,7 +4,8 @@ module IOStream
|
|
|
4
4
|
|
|
5
5
|
# Returns a Tempfile containing the contents of the readable object.
|
|
6
6
|
def to_tempfile
|
|
7
|
-
|
|
7
|
+
name = respond_to?(:original_filename) ? original_filename : (respond_to?(:path) ? path : "stream")
|
|
8
|
+
tempfile = Paperclip::Tempfile.new(File.basename(name))
|
|
8
9
|
tempfile.binmode
|
|
9
10
|
self.stream_to(tempfile)
|
|
10
11
|
end
|
|
@@ -46,9 +46,8 @@ module Paperclip
|
|
|
46
46
|
types.all? do |type|
|
|
47
47
|
file = StringIO.new(".")
|
|
48
48
|
file.content_type = type
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
attachment.errors[:content_type].nil?
|
|
49
|
+
(subject = @subject.new).attachment_for(@attachment_name).assign(file)
|
|
50
|
+
subject.valid? && subject.errors.on(:"#{@attachment_name}_content_type").blank?
|
|
52
51
|
end
|
|
53
52
|
end
|
|
54
53
|
|
|
@@ -30,16 +30,16 @@ module Paperclip
|
|
|
30
30
|
protected
|
|
31
31
|
|
|
32
32
|
def error_when_not_valid?
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
not
|
|
33
|
+
(subject = @subject.new).send(@attachment_name).assign(nil)
|
|
34
|
+
subject.valid?
|
|
35
|
+
not subject.errors.on(:"#{@attachment_name}_file_name").blank?
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def no_error_when_valid?
|
|
39
39
|
@file = StringIO.new(".")
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
(subject = @subject.new).send(@attachment_name).assign(@file)
|
|
41
|
+
subject.valid?
|
|
42
|
+
subject.errors.on(:"#{@attachment_name}_file_name").blank?
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
end
|
|
@@ -54,9 +54,11 @@ module Paperclip
|
|
|
54
54
|
def passes_validation_with_size(new_size)
|
|
55
55
|
file = StringIO.new(".")
|
|
56
56
|
override_method(file, :size){ new_size }
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
override_method(file, :to_tempfile){ file }
|
|
58
|
+
|
|
59
|
+
(subject = @subject.new).send(@attachment_name).assign(file)
|
|
60
|
+
subject.valid?
|
|
61
|
+
subject.errors.on(:"#{@attachment_name}_file_size").blank?
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
def lower_than_low?
|
data/lib/paperclip/storage.rb
CHANGED
|
@@ -20,9 +20,9 @@ module Paperclip
|
|
|
20
20
|
def self.extended base
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
def exists?(
|
|
23
|
+
def exists?(style_name = default_style)
|
|
24
24
|
if original_filename
|
|
25
|
-
File.exist?(path(
|
|
25
|
+
File.exist?(path(style_name))
|
|
26
26
|
else
|
|
27
27
|
false
|
|
28
28
|
end
|
|
@@ -30,17 +30,17 @@ module Paperclip
|
|
|
30
30
|
|
|
31
31
|
# Returns representation of the data of the file assigned to the given
|
|
32
32
|
# style, in the format most representative of the current storage.
|
|
33
|
-
def to_file
|
|
34
|
-
@queued_for_write[
|
|
33
|
+
def to_file style_name = default_style
|
|
34
|
+
@queued_for_write[style_name] || (File.new(path(style_name), 'rb') if exists?(style_name))
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def flush_writes #:nodoc:
|
|
38
|
-
@queued_for_write.each do |
|
|
38
|
+
@queued_for_write.each do |style_name, file|
|
|
39
39
|
file.close
|
|
40
|
-
FileUtils.mkdir_p(File.dirname(path(
|
|
41
|
-
log("saving #{path(
|
|
42
|
-
FileUtils.mv(file.path, path(
|
|
43
|
-
FileUtils.chmod(0644, path(
|
|
40
|
+
FileUtils.mkdir_p(File.dirname(path(style_name)))
|
|
41
|
+
log("saving #{path(style_name)}")
|
|
42
|
+
FileUtils.mv(file.path, path(style_name))
|
|
43
|
+
FileUtils.chmod(0644, path(style_name))
|
|
44
44
|
end
|
|
45
45
|
@queued_for_write = {}
|
|
46
46
|
end
|
|
@@ -159,6 +159,10 @@ module Paperclip
|
|
|
159
159
|
"#{attachment.s3_protocol}://#{attachment.bucket_name}.s3.amazonaws.com/#{attachment.path(style).gsub(%r{^/}, "")}"
|
|
160
160
|
end
|
|
161
161
|
end
|
|
162
|
+
|
|
163
|
+
def expiring_url(time = 3600)
|
|
164
|
+
AWS::S3::S3Object.url_for(path, bucket_name, :expires_in => time )
|
|
165
|
+
end
|
|
162
166
|
|
|
163
167
|
def bucket_name
|
|
164
168
|
@bucket
|
data/lib/paperclip/thumbnail.rb
CHANGED
|
@@ -12,6 +12,7 @@ module Paperclip
|
|
|
12
12
|
# set, the options will be appended to the convert command upon image conversion
|
|
13
13
|
def initialize file, options = {}, attachment = nil
|
|
14
14
|
super
|
|
15
|
+
|
|
15
16
|
geometry = options[:geometry]
|
|
16
17
|
@file = file
|
|
17
18
|
@crop = geometry[-1,1] == '#'
|
|
@@ -24,6 +25,7 @@ module Paperclip
|
|
|
24
25
|
|
|
25
26
|
@current_format = File.extname(@file.path)
|
|
26
27
|
@basename = File.basename(@file.path, @current_format)
|
|
28
|
+
|
|
27
29
|
end
|
|
28
30
|
|
|
29
31
|
# Returns true if the +target_geometry+ is meant to crop.
|
data/test/attachment_test.rb
CHANGED
|
@@ -14,18 +14,6 @@ class AttachmentTest < Test::Unit::TestCase
|
|
|
14
14
|
assert_equal "#{RAILS_ROOT}/public/fake_models/1234/fake", @attachment.path
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
should "call a proc sent to check_guard" do
|
|
18
|
-
@dummy = Dummy.new
|
|
19
|
-
@dummy.expects(:one).returns(:one)
|
|
20
|
-
assert_equal :one, @dummy.avatar.send(:check_guard, lambda{|x| x.one })
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
should "call a method name sent to check_guard" do
|
|
24
|
-
@dummy = Dummy.new
|
|
25
|
-
@dummy.expects(:one).returns(:one)
|
|
26
|
-
assert_equal :one, @dummy.avatar.send(:check_guard, :one)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
17
|
context "Attachment default_options" do
|
|
30
18
|
setup do
|
|
31
19
|
rebuild_model
|
|
@@ -133,7 +121,7 @@ class AttachmentTest < Test::Unit::TestCase
|
|
|
133
121
|
:styles => { :default => ["100x100", :png] },
|
|
134
122
|
:default_style => :default
|
|
135
123
|
@file = StringIO.new("...")
|
|
136
|
-
@file.
|
|
124
|
+
@file.stubs(:original_filename).returns("file.jpg")
|
|
137
125
|
end
|
|
138
126
|
should "return the right extension for the path" do
|
|
139
127
|
@attachment.assign(@file)
|
|
@@ -162,11 +150,6 @@ class AttachmentTest < Test::Unit::TestCase
|
|
|
162
150
|
should "report the correct options when sent #extra_options_for(:large)" do
|
|
163
151
|
assert_equal "-do_stuff", @dummy.avatar.send(:extra_options_for, :large)
|
|
164
152
|
end
|
|
165
|
-
|
|
166
|
-
before_should "call extra_options_for(:thumb/:large)" do
|
|
167
|
-
Paperclip::Attachment.any_instance.expects(:extra_options_for).with(:thumb)
|
|
168
|
-
Paperclip::Attachment.any_instance.expects(:extra_options_for).with(:large)
|
|
169
|
-
end
|
|
170
153
|
end
|
|
171
154
|
|
|
172
155
|
context "An attachment with :convert_options that is a proc" do
|
|
@@ -194,11 +177,6 @@ class AttachmentTest < Test::Unit::TestCase
|
|
|
194
177
|
should "report the correct options when sent #extra_options_for(:large)" do
|
|
195
178
|
assert_equal "-all", @dummy.avatar.send(:extra_options_for, :large)
|
|
196
179
|
end
|
|
197
|
-
|
|
198
|
-
before_should "call extra_options_for(:thumb/:large)" do
|
|
199
|
-
Paperclip::Attachment.any_instance.expects(:extra_options_for).with(:thumb)
|
|
200
|
-
Paperclip::Attachment.any_instance.expects(:extra_options_for).with(:large)
|
|
201
|
-
end
|
|
202
180
|
end
|
|
203
181
|
|
|
204
182
|
context "An attachment with :path that is a proc" do
|
|
@@ -267,10 +245,6 @@ class AttachmentTest < Test::Unit::TestCase
|
|
|
267
245
|
@attachment = Dummy.new.avatar
|
|
268
246
|
end
|
|
269
247
|
|
|
270
|
-
should "not run the procs immediately" do
|
|
271
|
-
assert_kind_of Proc, @attachment.styles[:normal][:geometry]
|
|
272
|
-
end
|
|
273
|
-
|
|
274
248
|
context "when assigned" do
|
|
275
249
|
setup do
|
|
276
250
|
@file = StringIO.new(".")
|
|
@@ -307,10 +281,6 @@ class AttachmentTest < Test::Unit::TestCase
|
|
|
307
281
|
@attachment = Dummy.new.avatar
|
|
308
282
|
end
|
|
309
283
|
|
|
310
|
-
should "not run the proc immediately" do
|
|
311
|
-
assert_kind_of Proc, @attachment.styles[:normal][:processors]
|
|
312
|
-
end
|
|
313
|
-
|
|
314
284
|
context "when assigned" do
|
|
315
285
|
setup do
|
|
316
286
|
@attachment.assign(StringIO.new("."))
|
|
@@ -354,19 +324,22 @@ class AttachmentTest < Test::Unit::TestCase
|
|
|
354
324
|
setup { @dummy.avatar = @file }
|
|
355
325
|
|
|
356
326
|
before_should "call #make on all specified processors" do
|
|
327
|
+
Paperclip::Thumbnail.expects(:make).with(any_parameters).returns(@file)
|
|
328
|
+
Paperclip::Test.expects(:make).with(any_parameters).returns(@file)
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
before_should "call #make with the right parameters passed as second argument" do
|
|
357
332
|
expected_params = @style_params[:once].merge({:processors => [:thumbnail, :test], :whiny => true, :convert_options => ""})
|
|
358
|
-
Paperclip::Thumbnail.expects(:make).with(
|
|
359
|
-
Paperclip::Test.expects(:make).with(@file, expected_params, @dummy.avatar).returns(@file)
|
|
333
|
+
Paperclip::Thumbnail.expects(:make).with(anything, expected_params, anything).returns(@file)
|
|
360
334
|
end
|
|
361
335
|
|
|
362
336
|
before_should "call #make with attachment passed as third argument" do
|
|
363
|
-
|
|
364
|
-
Paperclip::Test.expects(:make).with(@file, expected_params, @dummy.avatar).returns(@file)
|
|
337
|
+
Paperclip::Test.expects(:make).with(anything, anything, @dummy.avatar).returns(@file)
|
|
365
338
|
end
|
|
366
339
|
end
|
|
367
340
|
end
|
|
368
341
|
|
|
369
|
-
context "An attachment with no processors defined" do
|
|
342
|
+
context "An attachment with styles but no processors defined" do
|
|
370
343
|
setup do
|
|
371
344
|
rebuild_model :processors => [], :styles => {:something => 1}
|
|
372
345
|
@dummy = Dummy.new
|
|
@@ -377,6 +350,17 @@ class AttachmentTest < Test::Unit::TestCase
|
|
|
377
350
|
end
|
|
378
351
|
end
|
|
379
352
|
|
|
353
|
+
context "An attachment without styles and with no processors defined" do
|
|
354
|
+
setup do
|
|
355
|
+
rebuild_model :processors => [], :styles => {}
|
|
356
|
+
@dummy = Dummy.new
|
|
357
|
+
@file = StringIO.new("...")
|
|
358
|
+
end
|
|
359
|
+
should "not raise when assigned to" do
|
|
360
|
+
@dummy.avatar = @file
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
|
|
380
364
|
context "Assigning an attachment with post_process hooks" do
|
|
381
365
|
setup do
|
|
382
366
|
rebuild_model :styles => { :something => "100x100#" }
|
|
@@ -478,8 +462,6 @@ class AttachmentTest < Test::Unit::TestCase
|
|
|
478
462
|
@attachment.expects(:valid_assignment?).with(@not_file).returns(true)
|
|
479
463
|
@attachment.expects(:queue_existing_for_delete)
|
|
480
464
|
@attachment.expects(:post_process)
|
|
481
|
-
@attachment.expects(:valid?).returns(true)
|
|
482
|
-
@attachment.expects(:validate)
|
|
483
465
|
@dummy.avatar = @not_file
|
|
484
466
|
end
|
|
485
467
|
|
|
@@ -498,6 +480,7 @@ class AttachmentTest < Test::Unit::TestCase
|
|
|
498
480
|
FileUtils.rm_rf("tmp")
|
|
499
481
|
rebuild_model
|
|
500
482
|
@instance = Dummy.new
|
|
483
|
+
@instance.stubs(:id).returns 123
|
|
501
484
|
@attachment = Paperclip::Attachment.new(:avatar, @instance)
|
|
502
485
|
@file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png"), 'rb')
|
|
503
486
|
end
|
|
@@ -606,6 +589,7 @@ class AttachmentTest < Test::Unit::TestCase
|
|
|
606
589
|
should "commit the files to disk" do
|
|
607
590
|
[:large, :medium, :small].each do |style|
|
|
608
591
|
io = @attachment.to_file(style)
|
|
592
|
+
# p "in commit to disk test, io is #{io.inspect} and @instance.id is #{@instance.id}"
|
|
609
593
|
assert File.exists?(io)
|
|
610
594
|
assert ! io.is_a?(::Tempfile)
|
|
611
595
|
io.close
|
data/test/helper.rb
CHANGED
data/test/iostream_test.rb
CHANGED
|
@@ -58,8 +58,15 @@ class IOStreamTest < Test::Unit::TestCase
|
|
|
58
58
|
assert @tempfile = @file.to_tempfile
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
should "convert it to a Tempfile" do
|
|
62
|
-
assert @tempfile.is_a?(Tempfile)
|
|
61
|
+
should "convert it to a Paperclip Tempfile" do
|
|
62
|
+
assert @tempfile.is_a?(Paperclip::Tempfile)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
should "have the name be based on the original_filename" do
|
|
66
|
+
name = File.basename(@file.path)
|
|
67
|
+
extension = File.extname(name)
|
|
68
|
+
basename = File.basename(name, extension)
|
|
69
|
+
assert_match %r[^#{Regexp.quote(basename)}.*?#{Regexp.quote(extension)}], File.basename(@tempfile.path)
|
|
63
70
|
end
|
|
64
71
|
|
|
65
72
|
should "have the Tempfile contain the same data as the file" do
|
|
@@ -3,7 +3,9 @@ require 'test/helper'
|
|
|
3
3
|
class ValidateAttachmentPresenceMatcherTest < Test::Unit::TestCase
|
|
4
4
|
context "validate_attachment_presence" do
|
|
5
5
|
setup do
|
|
6
|
-
reset_table("dummies")
|
|
6
|
+
reset_table("dummies") do |d|
|
|
7
|
+
d.string :avatar_file_name
|
|
8
|
+
end
|
|
7
9
|
@dummy_class = reset_class "Dummy"
|
|
8
10
|
@dummy_class.has_attached_file :avatar
|
|
9
11
|
@matcher = self.class.validate_attachment_presence(:avatar)
|
data/test/paperclip_test.rb
CHANGED
|
@@ -185,45 +185,23 @@ class PaperclipTest < Test::Unit::TestCase
|
|
|
185
185
|
should "be valid" do
|
|
186
186
|
assert @dummy.valid?
|
|
187
187
|
end
|
|
188
|
-
|
|
189
|
-
context "then has a validation added that makes it invalid" do
|
|
190
|
-
setup do
|
|
191
|
-
assert @dummy.save
|
|
192
|
-
Dummy.class_eval do
|
|
193
|
-
validates_attachment_content_type :avatar, :content_type => ["text/plain"]
|
|
194
|
-
end
|
|
195
|
-
@dummy2 = Dummy.find(@dummy.id)
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
should "be invalid when reloaded" do
|
|
199
|
-
assert ! @dummy2.valid?, @dummy2.errors.inspect
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
should "be able to call #valid? twice without having duplicate errors" do
|
|
203
|
-
@dummy2.avatar.valid?
|
|
204
|
-
first_errors = @dummy2.avatar.errors
|
|
205
|
-
@dummy2.avatar.valid?
|
|
206
|
-
assert_equal first_errors, @dummy2.avatar.errors
|
|
207
|
-
end
|
|
208
|
-
end
|
|
209
188
|
end
|
|
210
189
|
|
|
211
190
|
context "a validation with an if guard clause" do
|
|
212
191
|
setup do
|
|
213
192
|
Dummy.send(:"validates_attachment_presence", :avatar, :if => lambda{|i| i.foo })
|
|
214
193
|
@dummy = Dummy.new
|
|
194
|
+
@dummy.stubs(:avatar_file_name).returns(nil)
|
|
215
195
|
end
|
|
216
196
|
|
|
217
197
|
should "attempt validation if the guard returns true" do
|
|
218
198
|
@dummy.expects(:foo).returns(true)
|
|
219
|
-
@dummy.
|
|
220
|
-
@dummy.valid?
|
|
199
|
+
assert ! @dummy.valid?
|
|
221
200
|
end
|
|
222
201
|
|
|
223
202
|
should "not attempt validation if the guard returns false" do
|
|
224
203
|
@dummy.expects(:foo).returns(false)
|
|
225
|
-
@dummy.
|
|
226
|
-
@dummy.valid?
|
|
204
|
+
assert @dummy.valid?
|
|
227
205
|
end
|
|
228
206
|
end
|
|
229
207
|
|
|
@@ -231,18 +209,17 @@ class PaperclipTest < Test::Unit::TestCase
|
|
|
231
209
|
setup do
|
|
232
210
|
Dummy.send(:"validates_attachment_presence", :avatar, :unless => lambda{|i| i.foo })
|
|
233
211
|
@dummy = Dummy.new
|
|
212
|
+
@dummy.stubs(:avatar_file_name).returns(nil)
|
|
234
213
|
end
|
|
235
214
|
|
|
236
215
|
should "attempt validation if the guard returns true" do
|
|
237
216
|
@dummy.expects(:foo).returns(false)
|
|
238
|
-
@dummy.
|
|
239
|
-
@dummy.valid?
|
|
217
|
+
assert ! @dummy.valid?
|
|
240
218
|
end
|
|
241
219
|
|
|
242
220
|
should "not attempt validation if the guard returns false" do
|
|
243
221
|
@dummy.expects(:foo).returns(true)
|
|
244
|
-
@dummy.
|
|
245
|
-
@dummy.valid?
|
|
222
|
+
assert @dummy.valid?
|
|
246
223
|
end
|
|
247
224
|
end
|
|
248
225
|
|
|
@@ -259,11 +236,11 @@ class PaperclipTest < Test::Unit::TestCase
|
|
|
259
236
|
end
|
|
260
237
|
if validation == :presence
|
|
261
238
|
should "have an error on the attachment" do
|
|
262
|
-
assert @dummy.errors.on(:
|
|
239
|
+
assert @dummy.errors.on(:avatar_file_name)
|
|
263
240
|
end
|
|
264
241
|
else
|
|
265
242
|
should "not have an error on the attachment" do
|
|
266
|
-
assert_nil @dummy.errors.on(:
|
|
243
|
+
assert_nil @dummy.errors.on(:avatar_file_name), @dummy.errors.full_messages.join(", ")
|
|
267
244
|
end
|
|
268
245
|
end
|
|
269
246
|
end
|
|
@@ -273,10 +250,7 @@ class PaperclipTest < Test::Unit::TestCase
|
|
|
273
250
|
@dummy.valid?
|
|
274
251
|
end
|
|
275
252
|
should "not have an error when assigned a valid file" do
|
|
276
|
-
|
|
277
|
-
end
|
|
278
|
-
should "not have an error on the attachment" do
|
|
279
|
-
assert_nil @dummy.errors.on(:avatar)
|
|
253
|
+
assert_equal 0, @dummy.errors.length, @dummy.errors.full_messages.join(", ")
|
|
280
254
|
end
|
|
281
255
|
end
|
|
282
256
|
context "and assigned an invalid file" do
|
|
@@ -285,17 +259,14 @@ class PaperclipTest < Test::Unit::TestCase
|
|
|
285
259
|
@dummy.valid?
|
|
286
260
|
end
|
|
287
261
|
should "have an error when assigned a valid file" do
|
|
288
|
-
|
|
289
|
-
end
|
|
290
|
-
should "have an error on the attachment" do
|
|
291
|
-
assert @dummy.errors.on(:avatar)
|
|
262
|
+
assert @dummy.errors.length > 0
|
|
292
263
|
end
|
|
293
264
|
end
|
|
294
265
|
end
|
|
295
266
|
end
|
|
296
267
|
|
|
297
268
|
[[:presence, {}, "5k.png", nil],
|
|
298
|
-
[:size, {:in => 1..10240},
|
|
269
|
+
[:size, {:in => 1..10240}, "5k.png", "12k.png"],
|
|
299
270
|
[:size, {:less_than => 10240}, "5k.png", "12k.png"],
|
|
300
271
|
[:size, {:greater_than => 8096}, "12k.png", "5k.png"],
|
|
301
272
|
[:content_type, {:content_type => "image/png"}, "5k.png", "text.txt"],
|
|
@@ -318,7 +289,7 @@ class PaperclipTest < Test::Unit::TestCase
|
|
|
318
289
|
end
|
|
319
290
|
|
|
320
291
|
should "have a file size min/max error message" do
|
|
321
|
-
assert_match /between 0 and 10240 bytes/, @dummy.errors.on(:
|
|
292
|
+
assert_match %r/between 0 and 10240 bytes/, @dummy.errors.on(:avatar_file_size)
|
|
322
293
|
end
|
|
323
294
|
end
|
|
324
295
|
end
|
data/test/storage_test.rb
CHANGED
|
@@ -96,6 +96,33 @@ class StorageTest < Test::Unit::TestCase
|
|
|
96
96
|
assert_match %r{^http://something.something.com/avatars/stringio.txt}, @dummy.avatar.url
|
|
97
97
|
end
|
|
98
98
|
end
|
|
99
|
+
|
|
100
|
+
context "Generating a url with an expiration" do
|
|
101
|
+
setup do
|
|
102
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
|
103
|
+
rebuild_model :storage => :s3,
|
|
104
|
+
:s3_credentials => {
|
|
105
|
+
:production => { :bucket => "prod_bucket" },
|
|
106
|
+
:development => { :bucket => "dev_bucket" }
|
|
107
|
+
},
|
|
108
|
+
:s3_host_alias => "something.something.com",
|
|
109
|
+
:path => ":attachment/:basename.:extension",
|
|
110
|
+
:url => ":s3_alias_url"
|
|
111
|
+
|
|
112
|
+
rails_env("production")
|
|
113
|
+
|
|
114
|
+
@dummy = Dummy.new
|
|
115
|
+
@dummy.avatar = StringIO.new(".")
|
|
116
|
+
|
|
117
|
+
AWS::S3::S3Object.expects(:url_for).with("avatars/stringio.txt", "prod_bucket", { :expires_in => 3600 })
|
|
118
|
+
|
|
119
|
+
@dummy.avatar.expiring_url
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
should "should succeed" do
|
|
123
|
+
assert true
|
|
124
|
+
end
|
|
125
|
+
end
|
|
99
126
|
|
|
100
127
|
context "Parsing S3 credentials with a bucket in them" do
|
|
101
128
|
setup do
|
data/test/thumbnail_test.rb
CHANGED
|
@@ -200,7 +200,7 @@ class ThumbnailTest < Test::Unit::TestCase
|
|
|
200
200
|
teardown { @file.close }
|
|
201
201
|
|
|
202
202
|
should "start with two pages with dimensions 612x792" do
|
|
203
|
-
cmd = %Q[identify -format "%wx%h" "#{@file.path}"]
|
|
203
|
+
cmd = %Q[identify -format "%wx%h" "#{@file.path}"]
|
|
204
204
|
assert_equal "612x792"*2, `#{cmd}`.chomp
|
|
205
205
|
end
|
|
206
206
|
|