thoughtbot-paperclip 2.3.0 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -44,7 +44,7 @@ end
44
44
  # documentation for Paperclip::ClassMethods for more useful information.
45
45
  module Paperclip
46
46
 
47
- VERSION = "2.3.0"
47
+ VERSION = "2.3.1"
48
48
 
49
49
  class << self
50
50
  # Provides configurability to Paperclip. There are a number of options available, such as:
@@ -93,7 +93,7 @@ module Paperclip
93
93
  # Paperclip.options[:log_command] is set to true (defaults to false). This
94
94
  # will only log if logging in general is set to true as well.
95
95
  def run cmd, params = "", expected_outcodes = 0
96
- command = %Q<#{%Q[#{path_for_command(cmd)} #{params}].gsub(/\s+/, " ")}>
96
+ command = %Q[#{path_for_command(cmd)} #{params}].gsub(/\s+/, " ")
97
97
  command = "#{command} 2>#{bit_bucket}" if Paperclip.options[:swallow_stderr]
98
98
  Paperclip.log(command) if Paperclip.options[:log_command]
99
99
  output = `#{command}`
@@ -257,7 +257,9 @@ module Paperclip
257
257
  range = (min..max)
258
258
  message = options[:message] || "file size must be between :min and :max bytes."
259
259
 
260
- attachment_definitions[name][:validations] << [:size, {:range => range,
260
+ attachment_definitions[name][:validations] << [:size, {:min => min,
261
+ :max => max,
262
+ :range => range,
261
263
  :message => message,
262
264
  :if => options[:if],
263
265
  :unless => options[:unless]}]
@@ -63,7 +63,10 @@ module Paperclip
63
63
 
64
64
  # Returns the underscored, pluralized version of the class name.
65
65
  # e.g. "users" for the User class.
66
- def class attachment, style
66
+ # NOTE: The arguments need to be optional, because some tools fetch
67
+ # all class names. Calling #class will return the expected class.
68
+ def class attachment = nil, style = nil
69
+ return super() if attachment.nil? && style.nil?
67
70
  attachment.instance.class.to_s.underscore.pluralize
68
71
  end
69
72
 
@@ -33,7 +33,6 @@ module Paperclip
33
33
  def to_file style = default_style
34
34
  @queued_for_write[style] || (File.new(path(style), 'rb') if exists?(style))
35
35
  end
36
- alias_method :to_io, :to_file
37
36
 
38
37
  def flush_writes #:nodoc:
39
38
  @queued_for_write.each do |style, file|
@@ -128,17 +127,27 @@ module Paperclip
128
127
  # separate parts of your file name.
129
128
  module S3
130
129
  def self.extended base
131
- require 'right_aws'
130
+ begin
131
+ require 'aws/s3'
132
+ rescue LoadError => e
133
+ e.message << " (You may need to install the aws-s3 gem)"
134
+ raise e
135
+ end
136
+
132
137
  base.instance_eval do
133
138
  @s3_credentials = parse_credentials(@options[:s3_credentials])
134
139
  @bucket = @options[:bucket] || @s3_credentials[:bucket]
135
140
  @bucket = @bucket.call(self) if @bucket.is_a?(Proc)
136
141
  @s3_options = @options[:s3_options] || {}
137
- @s3_permissions = @options[:s3_permissions] || 'public-read'
138
- @s3_protocol = @options[:s3_protocol] || (@s3_permissions == 'public-read' ? 'http' : 'https')
142
+ @s3_permissions = @options[:s3_permissions] || :public_read
143
+ @s3_protocol = @options[:s3_protocol] || (@s3_permissions == :public_read ? 'http' : 'https')
139
144
  @s3_headers = @options[:s3_headers] || {}
140
145
  @s3_host_alias = @options[:s3_host_alias]
141
146
  @url = ":s3_path_url" unless @url.to_s.match(/^:s3.*url$/)
147
+ AWS::S3::Base.establish_connection!( @s3_options.merge(
148
+ :access_key_id => @s3_credentials[:access_key_id],
149
+ :secret_access_key => @s3_credentials[:secret_access_key]
150
+ ))
142
151
  end
143
152
  Paperclip.interpolates(:s3_alias_url) do |attachment, style|
144
153
  "#{attachment.s3_protocol}://#{attachment.s3_host_alias}/#{attachment.path(style).gsub(%r{^/}, "")}"
@@ -151,16 +160,6 @@ module Paperclip
151
160
  end
152
161
  end
153
162
 
154
- def s3
155
- @s3 ||= RightAws::S3.new(@s3_credentials[:access_key_id],
156
- @s3_credentials[:secret_access_key],
157
- @s3_options)
158
- end
159
-
160
- def s3_bucket
161
- @s3_bucket ||= s3.bucket(@bucket, true, @s3_permissions)
162
- end
163
-
164
163
  def bucket_name
165
164
  @bucket
166
165
  end
@@ -175,7 +174,11 @@ module Paperclip
175
174
  end
176
175
 
177
176
  def exists?(style = default_style)
178
- s3_bucket.key(path(style)) ? true : false
177
+ if original_filename
178
+ AWS::S3::S3Object.exists?(path(style), bucket_name)
179
+ else
180
+ false
181
+ end
179
182
  end
180
183
 
181
184
  def s3_protocol
@@ -185,18 +188,24 @@ module Paperclip
185
188
  # Returns representation of the data of the file assigned to the given
186
189
  # style, in the format most representative of the current storage.
187
190
  def to_file style = default_style
188
- @queued_for_write[style] || s3_bucket.key(path(style))
191
+ return @queued_for_write[style] if @queued_for_write[style]
192
+ file = Tempfile.new(path(style))
193
+ file.write(AWS::S3::S3Object.value(path(style), bucket_name))
194
+ file.rewind
195
+ return file
189
196
  end
190
- alias_method :to_io, :to_file
191
197
 
192
198
  def flush_writes #:nodoc:
193
199
  @queued_for_write.each do |style, file|
194
200
  begin
195
201
  log("saving #{path(style)}")
196
- key = s3_bucket.key(path(style))
197
- key.data = file
198
- key.put(nil, @s3_permissions, {'Content-type' => instance_read(:content_type)}.merge(@s3_headers))
199
- rescue RightAws::AwsError => e
202
+ AWS::S3::S3Object.store(path(style),
203
+ file,
204
+ bucket_name,
205
+ {:content_type => instance_read(:content_type),
206
+ :access => @s3_permissions,
207
+ }.merge(@s3_headers))
208
+ rescue AWS::S3::ResponseError => e
200
209
  raise
201
210
  end
202
211
  end
@@ -207,10 +216,8 @@ module Paperclip
207
216
  @queued_for_delete.each do |path|
208
217
  begin
209
218
  log("deleting #{path}")
210
- if file = s3_bucket.key(path)
211
- file.delete
212
- end
213
- rescue RightAws::AwsError
219
+ AWS::S3::S3Object.delete(path, bucket_name)
220
+ rescue AWS::S3::ResponseError
214
221
  # Ignore this.
215
222
  end
216
223
  end
@@ -2,7 +2,7 @@ module Paperclip
2
2
  # Handles thumbnailing images that are uploaded.
3
3
  class Thumbnail < Processor
4
4
 
5
- attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options
5
+ attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options, :source_file_options
6
6
 
7
7
  # Creates a Thumbnail object set to work on the +file+ given. It
8
8
  # will attempt to transform the image into one defined by +target_geometry+
@@ -12,17 +12,18 @@ 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
- geometry = options[:geometry]
16
- @file = file
17
- @crop = geometry[-1,1] == '#'
18
- @target_geometry = Geometry.parse geometry
19
- @current_geometry = Geometry.from_file @file
20
- @convert_options = options[:convert_options]
21
- @whiny = options[:whiny].nil? ? true : options[:whiny]
22
- @format = options[:format]
15
+ geometry = options[:geometry]
16
+ @file = file
17
+ @crop = geometry[-1,1] == '#'
18
+ @target_geometry = Geometry.parse geometry
19
+ @current_geometry = Geometry.from_file @file
20
+ @source_file_options = options[:source_file_options]
21
+ @convert_options = options[:convert_options]
22
+ @whiny = options[:whiny].nil? ? true : options[:whiny]
23
+ @format = options[:format]
23
24
 
24
- @current_format = File.extname(@file.path)
25
- @basename = File.basename(@file.path, @current_format)
25
+ @current_format = File.extname(@file.path)
26
+ @basename = File.basename(@file.path, @current_format)
26
27
  end
27
28
 
28
29
  # Returns true if the +target_geometry+ is meant to crop.
@@ -32,7 +33,7 @@ module Paperclip
32
33
 
33
34
  # Returns true if the image is meant to make use of additional convert options.
34
35
  def convert_options?
35
- not @convert_options.blank?
36
+ !@convert_options.nil? && !@convert_options.empty?
36
37
  end
37
38
 
38
39
  # Performs the conversion of the +file+ into a thumbnail. Returns the Tempfile
@@ -43,6 +44,7 @@ module Paperclip
43
44
  dst.binmode
44
45
 
45
46
  command = <<-end_command
47
+ #{ source_file_options }
46
48
  "#{ File.expand_path(src.path) }[0]"
47
49
  #{ transformation_command }
48
50
  "#{ File.expand_path(dst.path) }"
@@ -61,7 +63,8 @@ module Paperclip
61
63
  # into the thumbnail.
62
64
  def transformation_command
63
65
  scale, crop = @current_geometry.transformation_to(@target_geometry, crop?)
64
- trans = "-resize \"#{scale}\""
66
+ trans = ""
67
+ trans << " -resize \"#{scale}\"" unless scale.nil? || scale.empty?
65
68
  trans << " -crop \"#{crop}\" +repage" if crop
66
69
  trans << " #{convert_options}" if convert_options?
67
70
  trans
@@ -14,6 +14,18 @@ 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
+
17
29
  context "Attachment default_options" do
18
30
  setup do
19
31
  rebuild_model
@@ -592,7 +604,7 @@ class AttachmentTest < Test::Unit::TestCase
592
604
 
593
605
  should "commit the files to disk" do
594
606
  [:large, :medium, :small].each do |style|
595
- io = @attachment.to_io(style)
607
+ io = @attachment.to_file(style)
596
608
  assert File.exists?(io)
597
609
  assert ! io.is_a?(::Tempfile)
598
610
  io.close
@@ -1,9 +1,11 @@
1
1
  require 'rubygems'
2
2
  require 'test/unit'
3
3
  require 'shoulda'
4
- require 'mocha'
5
4
  require 'tempfile'
6
5
 
6
+ gem 'jferris-mocha', '0.9.5.0.1241126838'
7
+ require 'mocha'
8
+
7
9
  gem 'sqlite3-ruby'
8
10
 
9
11
  require 'active_record'
@@ -97,3 +99,10 @@ end
97
99
  def attachment options
98
100
  Paperclip::Attachment.new(:avatar, FakeModel.new, options)
99
101
  end
102
+
103
+ def silence_warnings
104
+ old_verbose, $VERBOSE = $VERBOSE, nil
105
+ yield
106
+ ensure
107
+ $VERBOSE = old_verbose
108
+ end
@@ -379,6 +379,11 @@ class IntegrationTest < Test::Unit::TestCase
379
379
  @files_on_s3 = s3_files_for @dummy.avatar
380
380
  end
381
381
 
382
+ should "have the same contents as the original" do
383
+ @file.rewind
384
+ assert_equal @file.read, @files_on_s3[:original].read
385
+ end
386
+
382
387
  should "write and delete its files" do
383
388
  [["434x66", :original],
384
389
  ["300x46", :large],
@@ -403,10 +408,8 @@ class IntegrationTest < Test::Unit::TestCase
403
408
  assert @dummy.valid?
404
409
  assert @dummy.save
405
410
 
406
- saved_keys = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.to_file(s) }
407
-
408
- saved_keys.each do |key|
409
- assert key.exists?
411
+ [:thumb, :medium, :large, :original].each do |style|
412
+ assert @dummy.avatar.exists?(style)
410
413
  end
411
414
 
412
415
  @dummy.avatar.clear
@@ -414,8 +417,8 @@ class IntegrationTest < Test::Unit::TestCase
414
417
  assert @dummy.valid?
415
418
  assert @dummy.save
416
419
 
417
- saved_keys.each do |key|
418
- assert ! key.exists?
420
+ [:thumb, :medium, :large, :original].each do |style|
421
+ assert ! @dummy.avatar.exists?(style)
419
422
  end
420
423
 
421
424
  @d2 = Dummy.find(@dummy.id)
@@ -427,7 +430,7 @@ class IntegrationTest < Test::Unit::TestCase
427
430
 
428
431
  assert_equal @dummy.avatar_file_name, @d2.avatar_file_name
429
432
  [:thumb, :medium, :large, :original].each do |style|
430
- assert_equal @dummy.avatar.to_file(style).to_s, @d2.avatar.to_file(style).to_s
433
+ assert_equal @dummy.avatar.to_file(style).read, @d2.avatar.to_file(style).read
431
434
  end
432
435
 
433
436
  saved_keys = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.to_file(s) }
@@ -435,8 +438,8 @@ class IntegrationTest < Test::Unit::TestCase
435
438
  @d2.avatar.clear
436
439
  assert @d2.save
437
440
 
438
- saved_keys.each do |key|
439
- assert ! key.exists?
441
+ [:thumb, :medium, :large, :original].each do |style|
442
+ assert ! @dummy.avatar.exists?(style)
440
443
  end
441
444
  end
442
445
 
@@ -444,7 +447,7 @@ class IntegrationTest < Test::Unit::TestCase
444
447
  expected = @dummy.avatar.to_file
445
448
  @dummy.avatar = "not a file"
446
449
  assert @dummy.valid?
447
- assert_equal expected.full_name, @dummy.avatar.to_file.full_name
450
+ assert_equal expected.read, @dummy.avatar.to_file.read
448
451
 
449
452
  @dummy.avatar = @bad_file
450
453
  assert ! @dummy.valid?
@@ -472,7 +475,6 @@ class IntegrationTest < Test::Unit::TestCase
472
475
 
473
476
  should "have the right content type" do
474
477
  headers = s3_headers_for(@dummy.avatar, :original)
475
- p headers
476
478
  assert_equal 'image/png', headers['content-type']
477
479
  end
478
480
  end
@@ -7,7 +7,7 @@ class InterpolationsTest < Test::Unit::TestCase
7
7
  assert ! methods.include?(:[]=)
8
8
  assert ! methods.include?(:all)
9
9
  methods.each do |m|
10
- assert Paperclip::Interpolations.respond_to? m
10
+ assert Paperclip::Interpolations.respond_to?(m)
11
11
  end
12
12
  end
13
13
 
@@ -19,6 +19,10 @@ class InterpolationsTest < Test::Unit::TestCase
19
19
  assert_equal RAILS_ENV, Paperclip::Interpolations.rails_env(:attachment, :style)
20
20
  end
21
21
 
22
+ should "return the class of the Interpolations module when called with no params" do
23
+ assert_equal Module, Paperclip::Interpolations.class
24
+ end
25
+
22
26
  should "return the class of the instance" do
23
27
  attachment = mock
24
28
  attachment.expects(:instance).returns(attachment)
@@ -1,14 +1,18 @@
1
1
  require 'test/helper'
2
2
 
3
3
  class PaperclipTest < Test::Unit::TestCase
4
- [:image_magick_path, :convert_path].each do |path|
5
- context "Calling Paperclip.run with an #{path} specified" do
4
+ [:image_magick_path, :command_path].each do |path|
5
+ context "Calling Paperclip.run with #{path} specified" do
6
6
  setup do
7
7
  Paperclip.options[:image_magick_path] = nil
8
- Paperclip.options[:convert_path] = nil
8
+ Paperclip.options[:command_path] = nil
9
9
  Paperclip.options[path] = "/usr/bin"
10
10
  end
11
11
 
12
+ should "return the expected path for path_for_command" do
13
+ assert_equal "/usr/bin/convert", Paperclip.path_for_command("convert")
14
+ end
15
+
12
16
  should "execute the right command" do
13
17
  Paperclip.expects(:path_for_command).with("convert").returns("/usr/bin/convert")
14
18
  Paperclip.expects(:bit_bucket).returns("/dev/null")
@@ -21,7 +25,11 @@ class PaperclipTest < Test::Unit::TestCase
21
25
  context "Calling Paperclip.run with no path specified" do
22
26
  setup do
23
27
  Paperclip.options[:image_magick_path] = nil
24
- Paperclip.options[:convert_path] = nil
28
+ Paperclip.options[:command_path] = nil
29
+ end
30
+
31
+ should "return the expected path fro path_for_command" do
32
+ assert_equal "convert", Paperclip.path_for_command("convert")
25
33
  end
26
34
 
27
35
  should "execute the right command" do
@@ -30,38 +38,38 @@ class PaperclipTest < Test::Unit::TestCase
30
38
  Paperclip.expects(:"`").with("convert one.jpg two.jpg 2>/dev/null")
31
39
  Paperclip.run("convert", "one.jpg two.jpg")
32
40
  end
41
+ end
33
42
 
34
- should "log the command when :log_command is set" do
43
+ context "Calling Paperclip.run and logging" do
44
+ setup do
45
+ Paperclip.options[:image_magick_path] = nil
46
+ Paperclip.options[:command_path] = nil
47
+ Paperclip.stubs(:bit_bucket).returns("/dev/null")
48
+ Paperclip.stubs(:log)
49
+ Paperclip.stubs(:"`").with("this is the command 2>/dev/null")
50
+ end
51
+
52
+ should "log the command when :log_command is true" do
35
53
  Paperclip.options[:log_command] = true
36
- Paperclip.expects(:bit_bucket).returns("/dev/null")
37
- Paperclip.expects(:log).with("this is the command 2>/dev/null")
38
- Paperclip.expects(:"`").with("this is the command 2>/dev/null")
39
54
  Paperclip.run("this","is the command")
55
+ assert_received(Paperclip, :log) do |p|
56
+ p.with("this is the command 2>/dev/null")
57
+ end
58
+ assert_received(Paperclip, :`) do |p|
59
+ p.with("this is the command 2>/dev/null")
60
+ end
40
61
  end
41
- end
42
-
43
- should "raise when sent #processor and the name of a class that exists but isn't a subclass of Processor" do
44
- assert_raises(Paperclip::PaperclipError){ Paperclip.processor(:attachment) }
45
- end
46
-
47
- should "raise when sent #processor and the name of a class that doesn't exist" do
48
- assert_raises(NameError){ Paperclip.processor(:boogey_man) }
49
- end
50
-
51
- should "return a class when sent #processor and the name of a class under Paperclip" do
52
- assert_equal ::Paperclip::Thumbnail, Paperclip.processor(:thumbnail)
53
- end
54
62
 
55
- should "call a proc sent to check_guard" do
56
- @dummy = Dummy.new
57
- @dummy.expects(:one).returns(:one)
58
- assert_equal :one, @dummy.avatar.send(:check_guard, lambda{|x| x.one })
59
- end
60
-
61
- should "call a method name sent to check_guard" do
62
- @dummy = Dummy.new
63
- @dummy.expects(:one).returns(:one)
64
- assert_equal :one, @dummy.avatar.send(:check_guard, :one)
63
+ should "not log the command when :log_command is false" do
64
+ Paperclip.options[:log_command] = false
65
+ Paperclip.run("this","is the command")
66
+ assert_received(Paperclip, :log) do |p|
67
+ p.with("this is the command 2>/dev/null").never
68
+ end
69
+ assert_received(Paperclip, :`) do |p|
70
+ p.with("this is the command 2>/dev/null")
71
+ end
72
+ end
65
73
  end
66
74
 
67
75
  context "Paperclip.bit_bucket" do
@@ -86,6 +94,18 @@ class PaperclipTest < Test::Unit::TestCase
86
94
  end
87
95
  end
88
96
 
97
+ should "raise when sent #processor and the name of a class that exists but isn't a subclass of Processor" do
98
+ assert_raises(Paperclip::PaperclipError){ Paperclip.processor(:attachment) }
99
+ end
100
+
101
+ should "raise when sent #processor and the name of a class that doesn't exist" do
102
+ assert_raises(NameError){ Paperclip.processor(:boogey_man) }
103
+ end
104
+
105
+ should "return a class when sent #processor and the name of a class under Paperclip" do
106
+ assert_equal ::Paperclip::Thumbnail, Paperclip.processor(:thumbnail)
107
+ end
108
+
89
109
  context "An ActiveRecord model with an 'avatar' attachment" do
90
110
  setup do
91
111
  rebuild_model :path => "tmp/:class/omg/:style.:extension"
@@ -139,7 +159,8 @@ class PaperclipTest < Test::Unit::TestCase
139
159
  end
140
160
 
141
161
  should "be able to see the attachment definition from the subclass's class" do
142
- assert_equal "tmp/:class/omg/:style.:extension", SubDummy.attachment_definitions[:avatar][:path]
162
+ assert_equal "tmp/:class/omg/:style.:extension",
163
+ SubDummy.attachment_definitions[:avatar][:path]
143
164
  end
144
165
 
145
166
  teardown do
@@ -286,6 +307,21 @@ class PaperclipTest < Test::Unit::TestCase
286
307
 
287
308
  should_validate validation, options, valid_file, invalid_file
288
309
  end
310
+
311
+ context "with size validation and less_than 10240 option" do
312
+ context "and assigned an invalid file" do
313
+ setup do
314
+ Dummy.send(:"validates_attachment_size", :avatar, :less_than => 10240)
315
+ @dummy = Dummy.new
316
+ @dummy.avatar &&= File.open(File.join(FIXTURES_DIR, "12k.png"), "rb")
317
+ @dummy.valid?
318
+ end
319
+
320
+ should "have a file size min/max error message" do
321
+ assert_match /between 0 and 10240 bytes/, @dummy.errors.on(:avatar)
322
+ end
323
+ end
324
+ end
289
325
 
290
326
  end
291
327
  end
@@ -1,8 +1,16 @@
1
1
  require 'test/helper'
2
+ require 'aws/s3'
2
3
 
3
4
  class StorageTest < Test::Unit::TestCase
5
+ def rails_env(env)
6
+ silence_warnings do
7
+ Object.const_set(:RAILS_ENV, env)
8
+ end
9
+ end
10
+
4
11
  context "Parsing S3 credentials" do
5
12
  setup do
13
+ AWS::S3::Base.stubs(:establish_connection!)
6
14
  rebuild_model :storage => :s3,
7
15
  :bucket => "testing",
8
16
  :s3_credentials => {:not => :important}
@@ -14,31 +22,32 @@ class StorageTest < Test::Unit::TestCase
14
22
  end
15
23
 
16
24
  teardown do
17
- Object.const_set("RAILS_ENV", @current_env)
25
+ rails_env(@current_env)
18
26
  end
19
27
 
20
28
  should "get the correct credentials when RAILS_ENV is production" do
21
- Object.const_set('RAILS_ENV', "production")
29
+ rails_env("production")
22
30
  assert_equal({:key => "12345"},
23
31
  @avatar.parse_credentials('production' => {:key => '12345'},
24
32
  :development => {:key => "54321"}))
25
33
  end
26
34
 
27
35
  should "get the correct credentials when RAILS_ENV is development" do
28
- Object.const_set('RAILS_ENV', "development")
36
+ rails_env("development")
29
37
  assert_equal({:key => "54321"},
30
38
  @avatar.parse_credentials('production' => {:key => '12345'},
31
39
  :development => {:key => "54321"}))
32
40
  end
33
41
 
34
42
  should "return the argument if the key does not exist" do
35
- Object.const_set('RAILS_ENV', "not really an env")
43
+ rails_env("not really an env")
36
44
  assert_equal({:test => "12345"}, @avatar.parse_credentials(:test => "12345"))
37
45
  end
38
46
  end
39
47
 
40
48
  context "" do
41
49
  setup do
50
+ AWS::S3::Base.stubs(:establish_connection!)
42
51
  rebuild_model :storage => :s3,
43
52
  :s3_credentials => {},
44
53
  :bucket => "bucket",
@@ -54,6 +63,7 @@ class StorageTest < Test::Unit::TestCase
54
63
  end
55
64
  context "" do
56
65
  setup do
66
+ AWS::S3::Base.stubs(:establish_connection!)
57
67
  rebuild_model :storage => :s3,
58
68
  :s3_credentials => {},
59
69
  :bucket => "bucket",
@@ -69,6 +79,7 @@ class StorageTest < Test::Unit::TestCase
69
79
  end
70
80
  context "" do
71
81
  setup do
82
+ AWS::S3::Base.stubs(:establish_connection!)
72
83
  rebuild_model :storage => :s3,
73
84
  :s3_credentials => {
74
85
  :production => { :bucket => "prod_bucket" },
@@ -88,6 +99,7 @@ class StorageTest < Test::Unit::TestCase
88
99
 
89
100
  context "Parsing S3 credentials with a bucket in them" do
90
101
  setup do
102
+ AWS::S3::Base.stubs(:establish_connection!)
91
103
  rebuild_model :storage => :s3,
92
104
  :s3_credentials => {
93
105
  :production => { :bucket => "prod_bucket" },
@@ -97,15 +109,15 @@ class StorageTest < Test::Unit::TestCase
97
109
  @old_env = RAILS_ENV
98
110
  end
99
111
 
100
- teardown{ Object.const_set("RAILS_ENV", @old_env) }
112
+ teardown{ rails_env(@old_env) }
101
113
 
102
114
  should "get the right bucket in production" do
103
- Object.const_set("RAILS_ENV", "production")
115
+ rails_env("production")
104
116
  assert_equal "prod_bucket", @dummy.avatar.bucket_name
105
117
  end
106
118
 
107
119
  should "get the right bucket in development" do
108
- Object.const_set("RAILS_ENV", "development")
120
+ rails_env("development")
109
121
  assert_equal "dev_bucket", @dummy.avatar.bucket_name
110
122
  end
111
123
  end
@@ -146,14 +158,7 @@ class StorageTest < Test::Unit::TestCase
146
158
 
147
159
  context "and saved" do
148
160
  setup do
149
- @s3_mock = stub
150
- @bucket_mock = stub
151
- RightAws::S3.expects(:new).with("12345", "54321", {}).returns(@s3_mock)
152
- @s3_mock.expects(:bucket).with("testing", true, "public-read").returns(@bucket_mock)
153
- @key_mock = stub
154
- @bucket_mock.expects(:key).returns(@key_mock)
155
- @key_mock.expects(:data=)
156
- @key_mock.expects(:put).with(nil, 'public-read', 'Content-type' => 'image/png')
161
+ AWS::S3::S3Object.stubs(:store).with(@dummy.avatar.path, anything, 'testing', :content_type => 'image/png', :access => :public_read)
157
162
  @dummy.save
158
163
  end
159
164
 
@@ -164,13 +169,8 @@ class StorageTest < Test::Unit::TestCase
164
169
 
165
170
  context "and remove" do
166
171
  setup do
167
- @s3_mock = stub
168
- @bucket_mock = stub
169
- RightAws::S3.expects(:new).with("12345", "54321", {}).returns(@s3_mock)
170
- @s3_mock.expects(:bucket).with("testing", true, "public-read").returns(@bucket_mock)
171
- @key_mock = stub
172
- @bucket_mock.expects(:key).at_least(2).returns(@key_mock)
173
- @key_mock.expects(:delete)
172
+ AWS::S3::S3Object.stubs(:exists?).returns(true)
173
+ AWS::S3::S3Object.stubs(:delete)
174
174
  @dummy.destroy_attached_files
175
175
  end
176
176
 
@@ -183,6 +183,7 @@ class StorageTest < Test::Unit::TestCase
183
183
 
184
184
  context "An attachment with S3 storage and bucket defined as a Proc" do
185
185
  setup do
186
+ AWS::S3::Base.stubs(:establish_connection!)
186
187
  rebuild_model :storage => :s3,
187
188
  :bucket => lambda { |attachment| "bucket_#{attachment.instance.other}" },
188
189
  :s3_credentials => {:not => :important}
@@ -196,6 +197,7 @@ class StorageTest < Test::Unit::TestCase
196
197
 
197
198
  context "An attachment with S3 storage and specific s3 headers set" do
198
199
  setup do
200
+ AWS::S3::Base.stubs(:establish_connection!)
199
201
  rebuild_model :storage => :s3,
200
202
  :bucket => "testing",
201
203
  :path => ":attachment/:style/:basename.:extension",
@@ -217,17 +219,13 @@ class StorageTest < Test::Unit::TestCase
217
219
 
218
220
  context "and saved" do
219
221
  setup do
220
- @s3_mock = stub
221
- @bucket_mock = stub
222
- RightAws::S3.expects(:new).with("12345", "54321", {}).returns(@s3_mock)
223
- @s3_mock.expects(:bucket).with("testing", true, "public-read").returns(@bucket_mock)
224
- @key_mock = stub
225
- @bucket_mock.expects(:key).returns(@key_mock)
226
- @key_mock.expects(:data=)
227
- @key_mock.expects(:put).with(nil,
228
- 'public-read',
229
- 'Content-type' => 'image/png',
230
- 'Cache-Control' => 'max-age=31557600')
222
+ AWS::S3::Base.stubs(:establish_connection!)
223
+ AWS::S3::S3Object.stubs(:store).with(@dummy.avatar.path,
224
+ anything,
225
+ 'testing',
226
+ :content_type => 'image/png',
227
+ :access => :public_read,
228
+ 'Cache-Control' => 'max-age=31557600')
231
229
  @dummy.save
232
230
  end
233
231
 
@@ -263,8 +261,8 @@ class StorageTest < Test::Unit::TestCase
263
261
 
264
262
  teardown { @file.close }
265
263
 
266
- should "still return a Tempfile when sent #to_io" do
267
- assert_equal Tempfile, @dummy.avatar.to_io.class
264
+ should "still return a Tempfile when sent #to_file" do
265
+ assert_equal Tempfile, @dummy.avatar.to_file.class
268
266
  end
269
267
 
270
268
  context "and saved" do
@@ -103,6 +103,44 @@ class ThumbnailTest < Test::Unit::TestCase
103
103
  end
104
104
  end
105
105
 
106
+ context "being thumbnailed with source file options set" do
107
+ setup do
108
+ @thumb = Paperclip::Thumbnail.new(@file,
109
+ :geometry => "100x50#",
110
+ :source_file_options => "-strip")
111
+ end
112
+
113
+ should "have source_file_options value set" do
114
+ assert_equal "-strip", @thumb.source_file_options
115
+ end
116
+
117
+ should "send the right command to convert when sent #make" do
118
+ Paperclip.expects(:"`").with do |arg|
119
+ arg.match %r{convert\s+-strip\s+"#{File.expand_path(@thumb.file.path)}\[0\]"\s+-resize\s+"x50"\s+-crop\s+"100x50\+114\+0"\s+\+repage\s+".*?"}
120
+ end
121
+ @thumb.make
122
+ end
123
+
124
+ should "create the thumbnail when sent #make" do
125
+ dst = @thumb.make
126
+ assert_match /100x50/, `identify "#{dst.path}"`
127
+ end
128
+
129
+ context "redefined to have bad source_file_options setting" do
130
+ setup do
131
+ @thumb = Paperclip::Thumbnail.new(@file,
132
+ :geometry => "100x50#",
133
+ :source_file_options => "-this-aint-no-option")
134
+ end
135
+
136
+ should "error when trying to create the thumbnail" do
137
+ assert_raises(Paperclip::PaperclipError) do
138
+ @thumb.make
139
+ end
140
+ end
141
+ end
142
+ end
143
+
106
144
  context "being thumbnailed with convert options set" do
107
145
  setup do
108
146
  @thumb = Paperclip::Thumbnail.new(@file,
@@ -140,6 +178,18 @@ class ThumbnailTest < Test::Unit::TestCase
140
178
  end
141
179
  end
142
180
  end
181
+
182
+ context "being thumbnailed with a blank geometry string" do
183
+ setup do
184
+ @thumb = Paperclip::Thumbnail.new(@file,
185
+ :geometry => "",
186
+ :convert_options => "-gravity center -crop \"300x300+0-0\"")
187
+ end
188
+
189
+ should "not get resized by default" do
190
+ assert_no_match(/-resize/, @thumb.transformation_command)
191
+ end
192
+ end
143
193
  end
144
194
 
145
195
  context "A multipage PDF" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thoughtbot-paperclip
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Yurek
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-18 00:00:00 -07:00
12
+ date: 2009-08-21 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -95,6 +95,7 @@ files:
95
95
  - shoulda_macros/paperclip.rb
96
96
  has_rdoc: true
97
97
  homepage: http://www.thoughtbot.com/projects/paperclip
98
+ licenses:
98
99
  post_install_message:
99
100
  rdoc_options:
100
101
  - --line-numbers
@@ -116,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
117
  requirements:
117
118
  - ImageMagick
118
119
  rubyforge_project: paperclip
119
- rubygems_version: 1.2.0
120
+ rubygems_version: 1.3.5
120
121
  signing_key:
121
122
  specification_version: 2
122
123
  summary: File attachments as attributes for ActiveRecord