tristandunn-paperclip 2.3.1 → 2.3.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/test/fixtures/s3.yml CHANGED
@@ -2,3 +2,7 @@ development:
2
2
  key: 54321
3
3
  production:
4
4
  key: 12345
5
+ test:
6
+ bucket: <%= ENV['S3_BUCKET'] %>
7
+ access_key_id: <%= ENV['S3_KEY'] %>
8
+ secret_access_key: <%= ENV['S3_SECRET'] %>
data/test/helper.rb CHANGED
@@ -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'
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
@@ -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)
@@ -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
@@ -5,6 +5,7 @@ class ValidateAttachmentContentTypeMatcherTest < Test::Unit::TestCase
5
5
  setup do
6
6
  reset_table("dummies") do |d|
7
7
  d.string :avatar_file_name
8
+ d.string :avatar_content_type
8
9
  end
9
10
  @dummy_class = reset_class "Dummy"
10
11
  @dummy_class.has_attached_file :avatar
@@ -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"){|d| d.string :avatar_file_name }
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)
@@ -5,6 +5,7 @@ class ValidateAttachmentSizeMatcherTest < Test::Unit::TestCase
5
5
  setup do
6
6
  reset_table("dummies") do |d|
7
7
  d.string :avatar_file_name
8
+ d.integer :avatar_file_size
8
9
  end
9
10
  @dummy_class = reset_class "Dummy"
10
11
  @dummy_class.has_attached_file :avatar
@@ -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.avatar.expects(:validate_presence).returns(nil)
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.avatar.expects(:validate_presence).never
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.avatar.expects(:validate_presence).returns(nil)
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.avatar.expects(:validate_presence).never
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(:avatar)
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(:avatar)
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
- assert ! @dummy.avatar.errors.key?(validation)
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
- assert_not_nil @dummy.avatar.errors[validation]
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}, nil, "12k.png"],
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"],
@@ -307,6 +278,21 @@ class PaperclipTest < Test::Unit::TestCase
307
278
 
308
279
  should_validate validation, options, valid_file, invalid_file
309
280
  end
281
+
282
+ context "with size validation and less_than 10240 option" do
283
+ context "and assigned an invalid file" do
284
+ setup do
285
+ Dummy.send(:"validates_attachment_size", :avatar, :less_than => 10240)
286
+ @dummy = Dummy.new
287
+ @dummy.avatar &&= File.open(File.join(FIXTURES_DIR, "12k.png"), "rb")
288
+ @dummy.valid?
289
+ end
290
+
291
+ should "have a file size min/max error message" do
292
+ assert_match %r/between 0 and 10240 bytes/, @dummy.errors.on(:avatar_file_size)
293
+ end
294
+ end
295
+ end
310
296
 
311
297
  end
312
298
  end
data/test/storage_test.rb CHANGED
@@ -1,6 +1,13 @@
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
6
13
  AWS::S3::Base.stubs(:establish_connection!)
@@ -15,25 +22,25 @@ class StorageTest < Test::Unit::TestCase
15
22
  end
16
23
 
17
24
  teardown do
18
- Object.const_set("RAILS_ENV", @current_env)
25
+ rails_env(@current_env)
19
26
  end
20
27
 
21
28
  should "get the correct credentials when RAILS_ENV is production" do
22
- Object.const_set('RAILS_ENV', "production")
29
+ rails_env("production")
23
30
  assert_equal({:key => "12345"},
24
31
  @avatar.parse_credentials('production' => {:key => '12345'},
25
32
  :development => {:key => "54321"}))
26
33
  end
27
34
 
28
35
  should "get the correct credentials when RAILS_ENV is development" do
29
- Object.const_set('RAILS_ENV', "development")
36
+ rails_env("development")
30
37
  assert_equal({:key => "54321"},
31
38
  @avatar.parse_credentials('production' => {:key => '12345'},
32
39
  :development => {:key => "54321"}))
33
40
  end
34
41
 
35
42
  should "return the argument if the key does not exist" do
36
- Object.const_set('RAILS_ENV', "not really an env")
43
+ rails_env("not really an env")
37
44
  assert_equal({:test => "12345"}, @avatar.parse_credentials(:test => "12345"))
38
45
  end
39
46
  end
@@ -89,6 +96,33 @@ class StorageTest < Test::Unit::TestCase
89
96
  assert_match %r{^http://something.something.com/avatars/stringio.txt}, @dummy.avatar.url
90
97
  end
91
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
92
126
 
93
127
  context "Parsing S3 credentials with a bucket in them" do
94
128
  setup do
@@ -102,15 +136,15 @@ class StorageTest < Test::Unit::TestCase
102
136
  @old_env = RAILS_ENV
103
137
  end
104
138
 
105
- teardown{ Object.const_set("RAILS_ENV", @old_env) }
139
+ teardown{ rails_env(@old_env) }
106
140
 
107
141
  should "get the right bucket in production" do
108
- Object.const_set("RAILS_ENV", "production")
142
+ rails_env("production")
109
143
  assert_equal "prod_bucket", @dummy.avatar.bucket_name
110
144
  end
111
145
 
112
146
  should "get the right bucket in development" do
113
- Object.const_set("RAILS_ENV", "development")
147
+ rails_env("development")
114
148
  assert_equal "dev_bucket", @dummy.avatar.bucket_name
115
149
  end
116
150
  end
@@ -229,6 +263,29 @@ class StorageTest < Test::Unit::TestCase
229
263
  end
230
264
  end
231
265
 
266
+ context "with S3 credentials in a YAML file" do
267
+ setup do
268
+ ENV['S3_KEY'] = 'env_key'
269
+ ENV['S3_BUCKET'] = 'env_bucket'
270
+ ENV['S3_SECRET'] = 'env_secret'
271
+
272
+ rails_env('test')
273
+
274
+ rebuild_model :storage => :s3,
275
+ :s3_credentials => File.new(File.join(File.dirname(__FILE__), "fixtures/s3.yml"))
276
+
277
+ Dummy.delete_all
278
+
279
+ @dummy = Dummy.new
280
+ end
281
+
282
+ should "run it the file through ERB" do
283
+ assert_equal 'env_bucket', @dummy.avatar.bucket_name
284
+ assert_equal 'env_key', AWS::S3::Base.connection.options[:access_key_id]
285
+ assert_equal 'env_secret', AWS::S3::Base.connection.options[:secret_access_key]
286
+ end
287
+ end
288
+
232
289
  unless ENV["S3_TEST_BUCKET"].blank?
233
290
  context "Using S3 for real, an attachment with S3 storage" do
234
291
  setup do
@@ -0,0 +1,141 @@
1
+ # encoding: utf-8
2
+ require 'test/helper'
3
+
4
+ class StyleTest < Test::Unit::TestCase
5
+
6
+ context "A style rule" do
7
+ setup do
8
+ @attachment = attachment :path => ":basename.:extension",
9
+ :styles => { :foo => {:geometry => "100x100#", :format => :png} }
10
+ @style = @attachment.styles[:foo]
11
+ end
12
+
13
+ should "be held as a Style object" do
14
+ assert_kind_of Paperclip::Style, @style
15
+ end
16
+
17
+ should "get processors from the attachment definition" do
18
+ assert_equal [:thumbnail], @style.processors
19
+ end
20
+
21
+ should "have the right geometry" do
22
+ assert_equal "100x100#", @style.geometry
23
+ end
24
+
25
+ should "be whiny if the attachment is" do
26
+ @attachment.expects(:whiny).returns(true)
27
+ assert @style.whiny?
28
+ end
29
+
30
+ should "respond to hash notation" do
31
+ assert_equal [:thumbnail], @style[:processors]
32
+ assert_equal "100x100#", @style[:geometry]
33
+ end
34
+ end
35
+
36
+ context "A style rule with properties supplied as procs" do
37
+ setup do
38
+ @attachment = attachment :path => ":basename.:extension",
39
+ :whiny_thumbnails => true,
40
+ :processors => lambda {|a| [:test]},
41
+ :styles => {
42
+ :foo => lambda{|a| "300x300#"},
43
+ :bar => {
44
+ :geometry => lambda{|a| "300x300#"}
45
+ }
46
+ }
47
+ end
48
+
49
+ should "defer processing of procs until they are needed" do
50
+ assert_kind_of Proc, @attachment.styles[:foo].instance_variable_get("@geometry")
51
+ assert_kind_of Proc, @attachment.styles[:bar].instance_variable_get("@geometry")
52
+ assert_kind_of Proc, @attachment.instance_variable_get("@processors")
53
+ end
54
+
55
+ should "call procs when they are needed" do
56
+ assert_equal "300x300#", @attachment.styles[:foo].geometry
57
+ assert_equal "300x300#", @attachment.styles[:bar].geometry
58
+ assert_equal [:test], @attachment.styles[:foo].processors
59
+ assert_equal [:test], @attachment.styles[:bar].processors
60
+ end
61
+ end
62
+
63
+ context "An attachment with style rules in various forms" do
64
+ setup do
65
+ @attachment = attachment :path => ":basename.:extension",
66
+ :styles => {
67
+ :aslist => ["100x100", :png],
68
+ :ashash => {:geometry => "100x100", :format => :png},
69
+ :asstring => "100x100"
70
+ }
71
+ end
72
+ should "have the right number of styles" do
73
+ assert_kind_of Hash, @attachment.styles
74
+ assert_equal 3, @attachment.styles.size
75
+ end
76
+
77
+ should "have styles as Style objects" do
78
+ [:aslist, :ashash, :aslist].each do |s|
79
+ assert_kind_of Paperclip::Style, @attachment.styles[s]
80
+ end
81
+ end
82
+
83
+ should "have the right geometries" do
84
+ [:aslist, :ashash, :aslist].each do |s|
85
+ assert_equal @attachment.styles[s].geometry, "100x100"
86
+ end
87
+ end
88
+
89
+ should "have the right formats" do
90
+ assert_equal @attachment.styles[:aslist].format, :png
91
+ assert_equal @attachment.styles[:ashash].format, :png
92
+ assert_nil @attachment.styles[:asstring].format
93
+ end
94
+
95
+ end
96
+
97
+ context "An attachment with :convert_options" do
98
+ setup do
99
+ @attachment = attachment :path => ":basename.:extension",
100
+ :styles => {:thumb => "100x100", :large => "400x400"},
101
+ :convert_options => {:all => "-do_stuff", :thumb => "-thumbnailize"}
102
+ @style = @attachment.styles[:thumb]
103
+ @file = StringIO.new("...")
104
+ @file.stubs(:original_filename).returns("file.jpg")
105
+ end
106
+
107
+ before_should "not have called extra_options_for(:thumb/:large) on initialization" do
108
+ @attachment.expects(:extra_options_for).never
109
+ end
110
+
111
+ should "call extra_options_for(:thumb/:large) when convert options are requested" do
112
+ @attachment.expects(:extra_options_for).with(:thumb)
113
+ @attachment.styles[:thumb].convert_options
114
+ end
115
+ end
116
+
117
+ context "A style rule with its own :processors" do
118
+ setup do
119
+ @attachment = attachment :path => ":basename.:extension",
120
+ :styles => {
121
+ :foo => {
122
+ :geometry => "100x100#",
123
+ :format => :png,
124
+ :processors => [:test]
125
+ }
126
+ },
127
+ :processors => [:thumbnail]
128
+ @style = @attachment.styles[:foo]
129
+ end
130
+
131
+ should "not get processors from the attachment" do
132
+ @attachment.expects(:processors).never
133
+ assert_not_equal [:thumbnail], @style.processors
134
+ end
135
+
136
+ should "report its own processors" do
137
+ assert_equal [:test], @style.processors
138
+ end
139
+
140
+ end
141
+ end