paperclip 2.1.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/LICENSE +26 -0
- data/README +48 -0
- data/Rakefile +84 -0
- data/generators/paperclip/USAGE +5 -0
- data/generators/paperclip/paperclip_generator.rb +27 -0
- data/generators/paperclip/templates/paperclip_migration.rb +17 -0
- data/init.rb +1 -0
- data/lib/paperclip.rb +209 -0
- data/lib/paperclip/attachment.rb +244 -0
- data/lib/paperclip/geometry.rb +109 -0
- data/lib/paperclip/iostream.rb +43 -0
- data/lib/paperclip/storage.rb +113 -0
- data/lib/paperclip/thumbnail.rb +80 -0
- data/lib/paperclip/upfile.rb +32 -0
- data/tasks/paperclip_tasks.rake +36 -0
- data/test/database.yml +5 -0
- data/test/debug.log +676 -0
- data/test/fixtures/12k.png +0 -0
- data/test/fixtures/50x50.png +0 -0
- data/test/fixtures/5k.png +0 -0
- data/test/fixtures/bad.png +1 -0
- data/test/helper.rb +44 -0
- data/test/s3.yml +2 -0
- data/test/test_attachment.rb +207 -0
- data/test/test_geometry.rb +142 -0
- data/test/test_integration.rb +238 -0
- data/test/test_iostream.rb +60 -0
- data/test/test_paperclip.rb +103 -0
- data/test/test_storage.rb +140 -0
- data/test/test_thumbnail.rb +107 -0
- metadata +93 -0
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
This is not an image.
|
data/test/helper.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
require 'mocha'
|
5
|
+
require 'tempfile'
|
6
|
+
|
7
|
+
require 'active_record'
|
8
|
+
begin
|
9
|
+
require 'ruby-debug'
|
10
|
+
rescue LoadError
|
11
|
+
puts "ruby-debug not loaded"
|
12
|
+
end
|
13
|
+
|
14
|
+
ROOT = File.join(File.dirname(__FILE__), '..')
|
15
|
+
RAILS_ROOT = ROOT
|
16
|
+
|
17
|
+
$LOAD_PATH << File.join(ROOT, 'lib')
|
18
|
+
$LOAD_PATH << File.join(ROOT, 'lib', 'paperclip')
|
19
|
+
|
20
|
+
require File.join(ROOT, 'lib', 'paperclip.rb')
|
21
|
+
|
22
|
+
ENV['RAILS_ENV'] ||= 'test'
|
23
|
+
|
24
|
+
FIXTURES_DIR = File.join(File.dirname(__FILE__), "fixtures")
|
25
|
+
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
|
26
|
+
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
27
|
+
ActiveRecord::Base.establish_connection(config[ENV['RAILS_ENV'] || 'test'])
|
28
|
+
|
29
|
+
def rebuild_model options = {}
|
30
|
+
ActiveRecord::Base.connection.create_table :dummies, :force => true do |table|
|
31
|
+
table.column :other, :string
|
32
|
+
table.column :avatar_file_name, :string
|
33
|
+
table.column :avatar_content_type, :string
|
34
|
+
table.column :avatar_file_size, :integer
|
35
|
+
end
|
36
|
+
|
37
|
+
ActiveRecord::Base.send(:include, Paperclip)
|
38
|
+
Object.send(:remove_const, "Dummy") rescue nil
|
39
|
+
Object.const_set("Dummy", Class.new(ActiveRecord::Base))
|
40
|
+
Dummy.class_eval do
|
41
|
+
include Paperclip
|
42
|
+
has_attached_file :avatar, options
|
43
|
+
end
|
44
|
+
end
|
data/test/s3.yml
ADDED
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'test/helper'
|
2
|
+
|
3
|
+
class Dummy
|
4
|
+
# This is a dummy class
|
5
|
+
end
|
6
|
+
|
7
|
+
class AttachmentTest < Test::Unit::TestCase
|
8
|
+
context "Attachment default_options" do
|
9
|
+
setup do
|
10
|
+
rebuild_model
|
11
|
+
@old_default_options = Paperclip::Attachment.default_options.dup
|
12
|
+
@new_default_options = @old_default_options.merge({
|
13
|
+
:path => "argle/bargle",
|
14
|
+
:url => "fooferon",
|
15
|
+
:default_url => "not here.png"
|
16
|
+
})
|
17
|
+
end
|
18
|
+
|
19
|
+
teardown do
|
20
|
+
Paperclip::Attachment.default_options.merge! @old_default_options
|
21
|
+
end
|
22
|
+
|
23
|
+
should "be overrideable" do
|
24
|
+
Paperclip::Attachment.default_options.merge!(@new_default_options)
|
25
|
+
@new_default_options.keys.each do |key|
|
26
|
+
assert_equal @new_default_options[key],
|
27
|
+
Paperclip::Attachment.default_options[key]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "on an Attachment" do
|
32
|
+
setup do
|
33
|
+
@dummy = Dummy.new
|
34
|
+
@attachment = @dummy.avatar
|
35
|
+
end
|
36
|
+
|
37
|
+
Paperclip::Attachment.default_options.keys.each do |key|
|
38
|
+
should "be the default_options for #{key}" do
|
39
|
+
assert_equal @old_default_options[key],
|
40
|
+
@attachment.instance_variable_get("@#{key}"),
|
41
|
+
key
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when redefined" do
|
46
|
+
setup do
|
47
|
+
Paperclip::Attachment.default_options.merge!(@new_default_options)
|
48
|
+
@dummy = Dummy.new
|
49
|
+
@attachment = @dummy.avatar
|
50
|
+
end
|
51
|
+
|
52
|
+
Paperclip::Attachment.default_options.keys.each do |key|
|
53
|
+
should "be the new default_options for #{key}" do
|
54
|
+
assert_equal @new_default_options[key],
|
55
|
+
@attachment.instance_variable_get("@#{key}"),
|
56
|
+
key
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "An attachment with similarly named interpolations" do
|
64
|
+
setup do
|
65
|
+
rebuild_model :path => ":id.omg/:id-bbq/:idwhat/:id_partition.wtf"
|
66
|
+
@dummy = Dummy.new
|
67
|
+
@dummy.stubs(:id).returns(1024)
|
68
|
+
@file = File.new(File.join(File.dirname(__FILE__),
|
69
|
+
"fixtures",
|
70
|
+
"5k.png"))
|
71
|
+
@dummy.avatar = @file
|
72
|
+
end
|
73
|
+
|
74
|
+
should "make sure that they are interpolated correctly" do
|
75
|
+
assert_equal "1024.omg/1024-bbq/:idwhat/000/001/024.wtf", @dummy.avatar.path
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "An attachment" do
|
80
|
+
setup do
|
81
|
+
Paperclip::Attachment.default_options.merge!({
|
82
|
+
:path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
|
83
|
+
})
|
84
|
+
FileUtils.rm_rf("tmp")
|
85
|
+
@instance = stub
|
86
|
+
@instance.stubs(:id).returns(41)
|
87
|
+
@instance.stubs(:class).returns(Dummy)
|
88
|
+
@instance.stubs(:[]).with(:test_file_name).returns("5k.png")
|
89
|
+
@instance.stubs(:[]).with(:test_content_type).returns("image/png")
|
90
|
+
@instance.stubs(:[]).with(:test_file_size).returns(12345)
|
91
|
+
@attachment = Paperclip::Attachment.new(:test,
|
92
|
+
@instance)
|
93
|
+
@file = File.new(File.join(File.dirname(__FILE__),
|
94
|
+
"fixtures",
|
95
|
+
"5k.png"))
|
96
|
+
end
|
97
|
+
|
98
|
+
should "return its default_url when no file assigned" do
|
99
|
+
assert @attachment.file.nil?
|
100
|
+
assert_equal "/tests/original/missing.png", @attachment.url
|
101
|
+
assert_equal "/tests/blah/missing.png", @attachment.url(:blah)
|
102
|
+
end
|
103
|
+
|
104
|
+
context "when expecting three styles" do
|
105
|
+
setup do
|
106
|
+
styles = {:styles => { :large => ["400x400", :png],
|
107
|
+
:medium => ["100x100", :gif],
|
108
|
+
:small => ["32x32#", :jpg]}}
|
109
|
+
@attachment = Paperclip::Attachment.new(:test,
|
110
|
+
@instance,
|
111
|
+
styles)
|
112
|
+
end
|
113
|
+
|
114
|
+
context "and assigned a file" do
|
115
|
+
setup do
|
116
|
+
@instance.expects(:[]=).with(:test_file_name,
|
117
|
+
File.basename(@file.path))
|
118
|
+
@instance.expects(:[]=).with(:test_content_type, "image/png")
|
119
|
+
@instance.expects(:[]=).with(:test_file_size, @file.size)
|
120
|
+
@instance.expects(:[]=).with(:test_file_name, nil)
|
121
|
+
@instance.expects(:[]=).with(:test_content_type, nil)
|
122
|
+
@instance.expects(:[]=).with(:test_file_size, nil)
|
123
|
+
@attachment.assign(@file)
|
124
|
+
end
|
125
|
+
|
126
|
+
should "return the real url" do
|
127
|
+
assert @attachment.file
|
128
|
+
assert_equal "/tests/41/original/5k.png", @attachment.url
|
129
|
+
assert_equal "/tests/41/blah/5k.png", @attachment.url(:blah)
|
130
|
+
end
|
131
|
+
|
132
|
+
should "be dirty" do
|
133
|
+
assert @attachment.dirty?
|
134
|
+
end
|
135
|
+
|
136
|
+
should "have its image and attachments as tempfiles" do
|
137
|
+
[nil, :large, :medium, :small].each do |style|
|
138
|
+
assert File.exists?(@attachment.to_io(style))
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "and saved" do
|
143
|
+
setup do
|
144
|
+
@attachment.save
|
145
|
+
end
|
146
|
+
|
147
|
+
should "commit the files to disk" do
|
148
|
+
[nil, :large, :medium, :small].each do |style|
|
149
|
+
io = @attachment.to_io(style)
|
150
|
+
assert File.exists?(io)
|
151
|
+
assert ! io.is_a?(::Tempfile)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
should "save the files as the right formats and sizes" do
|
156
|
+
[[:large, 400, 61, "PNG"],
|
157
|
+
[:medium, 100, 15, "GIF"],
|
158
|
+
[:small, 32, 32, "JPEG"]].each do |style|
|
159
|
+
cmd = "identify -format '%w %h %b %m' " +
|
160
|
+
"#{@attachment.to_io(style.first).path}"
|
161
|
+
out = `#{cmd}`
|
162
|
+
width, height, size, format = out.split(" ")
|
163
|
+
assert_equal style[1].to_s, width.to_s
|
164
|
+
assert_equal style[2].to_s, height.to_s
|
165
|
+
assert_equal style[3].to_s, format.to_s
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
should "have #file be equal #to_io(:original)" do
|
170
|
+
assert_equal @attachment.file, @attachment.to_io(:original)
|
171
|
+
end
|
172
|
+
|
173
|
+
should "still have its #file attribute not be nil" do
|
174
|
+
assert ! @attachment.file.nil?
|
175
|
+
end
|
176
|
+
|
177
|
+
context "and deleted" do
|
178
|
+
setup do
|
179
|
+
@existing_names = @attachment.styles.keys.collect do |style|
|
180
|
+
@attachment.path(style)
|
181
|
+
end
|
182
|
+
@instance.expects(:[]=).with(:test_file_name, nil)
|
183
|
+
@instance.expects(:[]=).with(:test_content_type, nil)
|
184
|
+
@instance.expects(:[]=).with(:test_file_size, nil)
|
185
|
+
@attachment.assign nil
|
186
|
+
@attachment.save
|
187
|
+
end
|
188
|
+
|
189
|
+
should "delete the files" do
|
190
|
+
@existing_names.each{|f| assert ! File.exists?(f) }
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context "when trying a nonexistant storage type" do
|
198
|
+
setup do
|
199
|
+
rebuild_model :storage => :not_here
|
200
|
+
end
|
201
|
+
|
202
|
+
should "not be able to find the module" do
|
203
|
+
assert_raise(NameError){ Dummy.new.avatar }
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
|
5
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'paperclip', 'geometry.rb')
|
6
|
+
|
7
|
+
class GeometryTest < Test::Unit::TestCase
|
8
|
+
context "Paperclip::Geometry" do
|
9
|
+
should "correctly report its given dimensions" do
|
10
|
+
assert @geo = Paperclip::Geometry.new(1024, 768)
|
11
|
+
assert_equal 1024, @geo.width
|
12
|
+
assert_equal 768, @geo.height
|
13
|
+
end
|
14
|
+
|
15
|
+
should "correctly create a square if the height dimension is missing" do
|
16
|
+
assert @geo = Paperclip::Geometry.new(1024)
|
17
|
+
assert_equal 1024, @geo.width
|
18
|
+
assert_equal 1024, @geo.height
|
19
|
+
end
|
20
|
+
|
21
|
+
should "correctly create a square if the width dimension is missing" do
|
22
|
+
assert @geo = Paperclip::Geometry.new(nil, 768)
|
23
|
+
assert_equal 768, @geo.width
|
24
|
+
assert_equal 768, @geo.height
|
25
|
+
end
|
26
|
+
|
27
|
+
should "be generated from a WxH-formatted string" do
|
28
|
+
assert @geo = Paperclip::Geometry.parse("800x600")
|
29
|
+
assert_equal 800, @geo.width
|
30
|
+
assert_equal 600, @geo.height
|
31
|
+
end
|
32
|
+
|
33
|
+
should "be generated from a xH-formatted string" do
|
34
|
+
assert @geo = Paperclip::Geometry.parse("x600")
|
35
|
+
assert_equal 600, @geo.width
|
36
|
+
assert_equal 600, @geo.height
|
37
|
+
end
|
38
|
+
|
39
|
+
should "be generated from a Wx-formatted string" do
|
40
|
+
assert @geo = Paperclip::Geometry.parse("800x")
|
41
|
+
assert_equal 800, @geo.width
|
42
|
+
assert_equal 800, @geo.height
|
43
|
+
end
|
44
|
+
|
45
|
+
should "ensure the modifier is nil if only one dimension present" do
|
46
|
+
assert @geo = Paperclip::Geometry.parse("123x")
|
47
|
+
assert_nil @geo.modifier
|
48
|
+
end
|
49
|
+
|
50
|
+
should "ensure the modifier is nil if not present" do
|
51
|
+
assert @geo = Paperclip::Geometry.parse("123x456")
|
52
|
+
assert_nil @geo.modifier
|
53
|
+
end
|
54
|
+
|
55
|
+
['>', '<', '#', '@', '%', '^', '!'].each do |mod|
|
56
|
+
should "ensure the modifier #{mod} is preserved" do
|
57
|
+
assert @geo = Paperclip::Geometry.parse("123x456#{mod}")
|
58
|
+
assert_equal mod, @geo.modifier
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
should "make sure the modifier gets passed during transformation_to" do
|
63
|
+
assert @src = Paperclip::Geometry.parse("123x456")
|
64
|
+
assert @dst = Paperclip::Geometry.parse("123x456>")
|
65
|
+
assert_equal "123x456>", @src.transformation_to(@dst).to_s
|
66
|
+
end
|
67
|
+
|
68
|
+
should "be generated from a file" do
|
69
|
+
file = File.join(File.dirname(__FILE__), "fixtures", "5k.png")
|
70
|
+
file = File.new(file)
|
71
|
+
assert_nothing_raised{ @geo = Paperclip::Geometry.from_file(file) }
|
72
|
+
assert @geo.height > 0
|
73
|
+
assert @geo.width > 0
|
74
|
+
end
|
75
|
+
|
76
|
+
should "be generated from a file path" do
|
77
|
+
file = File.join(File.dirname(__FILE__), "fixtures", "5k.png")
|
78
|
+
assert_nothing_raised{ @geo = Paperclip::Geometry.from_file(file) }
|
79
|
+
assert @geo.height > 0
|
80
|
+
assert @geo.width > 0
|
81
|
+
end
|
82
|
+
|
83
|
+
should "not generate from a bad file" do
|
84
|
+
file = "/home/This File Does Not Exist.omg"
|
85
|
+
assert_raise(Errno::ENOENT){ @geo = Paperclip::Geometry.from_file(file) }
|
86
|
+
end
|
87
|
+
|
88
|
+
[['vertical', 900, 1440, true, false, false, 1440, 900, 0.625],
|
89
|
+
['horizontal', 1024, 768, false, true, false, 1024, 768, 1.3333],
|
90
|
+
['square', 100, 100, false, false, true, 100, 100, 1]].each do |args|
|
91
|
+
context "performing calculations on a #{args[0]} viewport" do
|
92
|
+
setup do
|
93
|
+
@geo = Paperclip::Geometry.new(args[1], args[2])
|
94
|
+
end
|
95
|
+
|
96
|
+
should "#{args[3] ? "" : "not"} be vertical" do
|
97
|
+
assert_equal args[3], @geo.vertical?
|
98
|
+
end
|
99
|
+
|
100
|
+
should "#{args[4] ? "" : "not"} be horizontal" do
|
101
|
+
assert_equal args[4], @geo.horizontal?
|
102
|
+
end
|
103
|
+
|
104
|
+
should "#{args[5] ? "" : "not"} be square" do
|
105
|
+
assert_equal args[5], @geo.square?
|
106
|
+
end
|
107
|
+
|
108
|
+
should "report that #{args[6]} is the larger dimension" do
|
109
|
+
assert_equal args[6], @geo.larger
|
110
|
+
end
|
111
|
+
|
112
|
+
should "report that #{args[7]} is the smaller dimension" do
|
113
|
+
assert_equal args[7], @geo.smaller
|
114
|
+
end
|
115
|
+
|
116
|
+
should "have an aspect ratio of #{args[8]}" do
|
117
|
+
assert_in_delta args[8], @geo.aspect, 0.0001
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
[[ [1000, 100], [64, 64], "x64", "64x64+288+0" ],
|
123
|
+
[ [100, 1000], [50, 950], "x950", "50x950+22+0" ],
|
124
|
+
[ [100, 1000], [50, 25], "50x", "50x25+0+237" ]]. each do |args|
|
125
|
+
context "of #{args[0].inspect} and given a Geometry #{args[1].inspect} and sent transform_to" do
|
126
|
+
setup do
|
127
|
+
@geo = Paperclip::Geometry.new(*args[0])
|
128
|
+
@dst = Paperclip::Geometry.new(*args[1])
|
129
|
+
@scale, @crop = @geo.transformation_to @dst, true
|
130
|
+
end
|
131
|
+
|
132
|
+
should "be able to return the correct scaling transformation geometry #{args[2]}" do
|
133
|
+
assert_equal args[2], @scale
|
134
|
+
end
|
135
|
+
|
136
|
+
should "be able to return the correct crop transformation geometry #{args[3]}" do
|
137
|
+
assert_equal args[3], @crop
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,238 @@
|
|
1
|
+
require 'test/helper.rb'
|
2
|
+
|
3
|
+
class IntegrationTest < Test::Unit::TestCase
|
4
|
+
context "A model with a filesystem attachment" do
|
5
|
+
setup do
|
6
|
+
rebuild_model :styles => { :large => "300x300>",
|
7
|
+
:medium => "100x100",
|
8
|
+
:thumb => ["32x32#", :gif] },
|
9
|
+
:default_style => :medium,
|
10
|
+
:url => "/:attachment/:class/:style/:id/:basename.:extension",
|
11
|
+
:path => ":rails_root/tmp/:attachment/:class/:style/:id/:basename.:extension"
|
12
|
+
@dummy = Dummy.new
|
13
|
+
@file = File.new(File.join(FIXTURES_DIR, "5k.png"))
|
14
|
+
@bad_file = File.new(File.join(FIXTURES_DIR, "bad.png"))
|
15
|
+
|
16
|
+
assert @dummy.avatar = @file
|
17
|
+
assert @dummy.valid?
|
18
|
+
assert @dummy.save
|
19
|
+
end
|
20
|
+
|
21
|
+
should "write and delete its files" do
|
22
|
+
[["100x15", nil],
|
23
|
+
["434x66", :original],
|
24
|
+
["300x46", :large],
|
25
|
+
["100x15", :medium],
|
26
|
+
["32x32", :thumb]].each do |geo, style|
|
27
|
+
cmd = %Q[identify -format "%wx%h" #{@dummy.avatar.to_file(style).path}]
|
28
|
+
assert_equal geo, `#{cmd}`.chomp, cmd
|
29
|
+
end
|
30
|
+
|
31
|
+
saved_paths = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.to_file(s).path }
|
32
|
+
|
33
|
+
@d2 = Dummy.find(@dummy.id)
|
34
|
+
assert_equal "100x15", `identify -format "%wx%h" #{@d2.avatar.to_file.path}`.chomp
|
35
|
+
assert_equal "434x66", `identify -format "%wx%h" #{@d2.avatar.to_file(:original).path}`.chomp
|
36
|
+
assert_equal "300x46", `identify -format "%wx%h" #{@d2.avatar.to_file(:large).path}`.chomp
|
37
|
+
assert_equal "100x15", `identify -format "%wx%h" #{@d2.avatar.to_file(:medium).path}`.chomp
|
38
|
+
assert_equal "32x32", `identify -format "%wx%h" #{@d2.avatar.to_file(:thumb).path}`.chomp
|
39
|
+
|
40
|
+
@dummy.avatar = "not a valid file but not nil"
|
41
|
+
assert_equal File.basename(@file.path), @dummy.avatar_file_name
|
42
|
+
assert @dummy.valid?
|
43
|
+
assert @dummy.save
|
44
|
+
|
45
|
+
saved_paths.each do |p|
|
46
|
+
assert File.exists?(p)
|
47
|
+
end
|
48
|
+
|
49
|
+
@dummy.avatar = nil
|
50
|
+
assert_nil @dummy.avatar_file_name
|
51
|
+
assert @dummy.valid?
|
52
|
+
assert @dummy.save
|
53
|
+
|
54
|
+
saved_paths.each do |p|
|
55
|
+
assert ! File.exists?(p)
|
56
|
+
end
|
57
|
+
|
58
|
+
@d2 = Dummy.find(@dummy.id)
|
59
|
+
assert_nil @d2.avatar_file_name
|
60
|
+
end
|
61
|
+
|
62
|
+
should "work exactly the same when new as when reloaded" do
|
63
|
+
@d2 = Dummy.find(@dummy.id)
|
64
|
+
|
65
|
+
assert_equal @dummy.avatar_file_name, @d2.avatar_file_name
|
66
|
+
[:thumb, :medium, :large, :original].each do |style|
|
67
|
+
assert_equal @dummy.avatar.to_file(style).path, @d2.avatar.to_file(style).path
|
68
|
+
end
|
69
|
+
|
70
|
+
saved_paths = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.to_file(s).path }
|
71
|
+
|
72
|
+
@d2.avatar = nil
|
73
|
+
assert @d2.save
|
74
|
+
|
75
|
+
saved_paths.each do |p|
|
76
|
+
assert ! File.exists?(p)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
should "know the difference between good files, bad files, not files, and nil" do
|
81
|
+
expected = @dummy.avatar.file
|
82
|
+
@dummy.avatar = "not a file"
|
83
|
+
assert @dummy.valid?
|
84
|
+
assert_equal expected.path, @dummy.avatar.file.path
|
85
|
+
|
86
|
+
@dummy.avatar = @bad_file
|
87
|
+
assert ! @dummy.valid?
|
88
|
+
@dummy.avatar = nil
|
89
|
+
assert @dummy.valid?
|
90
|
+
|
91
|
+
Dummy.validates_attachment_presence :avatar
|
92
|
+
@d2 = Dummy.find(@dummy.id)
|
93
|
+
@d2.avatar = @file
|
94
|
+
assert @d2.valid?
|
95
|
+
@d2.avatar = @bad_file
|
96
|
+
assert ! @d2.valid?
|
97
|
+
@d2.avatar = nil
|
98
|
+
assert ! @d2.valid?
|
99
|
+
end
|
100
|
+
|
101
|
+
should "be able to reload without saving an not have the file disappear" do
|
102
|
+
@dummy.avatar = @file
|
103
|
+
assert @dummy.save
|
104
|
+
@dummy.avatar = nil
|
105
|
+
assert_nil @dummy.avatar_file_name
|
106
|
+
@dummy.reload
|
107
|
+
assert_equal "5k.png", @dummy.avatar_file_name
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
if ENV['S3_TEST_BUCKET']
|
112
|
+
def s3_files_for attachment
|
113
|
+
[:thumb, :medium, :large, :original].inject({}) do |files, style|
|
114
|
+
data = `curl '#{attachment.url(style)}' 2>/dev/null`.chomp
|
115
|
+
t = Tempfile.new("paperclip-test")
|
116
|
+
t.write(data)
|
117
|
+
t.rewind
|
118
|
+
files[style] = t
|
119
|
+
files
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "A model with an S3 attachment" do
|
124
|
+
setup do
|
125
|
+
rebuild_model :styles => { :large => "300x300>",
|
126
|
+
:medium => "100x100",
|
127
|
+
:thumb => ["32x32#", :gif] },
|
128
|
+
:storage => :s3,
|
129
|
+
# :s3_options => {:logger => Logger.new(StringIO.new)},
|
130
|
+
:s3_credentials => File.new(File.join(File.dirname(__FILE__), "s3.yml")),
|
131
|
+
:default_style => :medium,
|
132
|
+
:bucket => ENV['S3_TEST_BUCKET'],
|
133
|
+
:path => ":class/:attachment/:id/:style/:basename.:extension"
|
134
|
+
@dummy = Dummy.new
|
135
|
+
@file = File.new(File.join(FIXTURES_DIR, "5k.png"))
|
136
|
+
@bad_file = File.new(File.join(FIXTURES_DIR, "bad.png"))
|
137
|
+
|
138
|
+
assert @dummy.avatar = @file
|
139
|
+
assert @dummy.valid?
|
140
|
+
assert @dummy.save
|
141
|
+
|
142
|
+
@files_on_s3 = s3_files_for @dummy.avatar
|
143
|
+
end
|
144
|
+
|
145
|
+
should "write and delete its files" do
|
146
|
+
[["434x66", :original],
|
147
|
+
["300x46", :large],
|
148
|
+
["100x15", :medium],
|
149
|
+
["32x32", :thumb]].each do |geo, style|
|
150
|
+
cmd = %Q[identify -format "%wx%h" #{@files_on_s3[style].path}]
|
151
|
+
assert_equal geo, `#{cmd}`.chomp, cmd
|
152
|
+
end
|
153
|
+
|
154
|
+
@d2 = Dummy.find(@dummy.id)
|
155
|
+
@d2_files = s3_files_for @d2.avatar
|
156
|
+
[["434x66", :original],
|
157
|
+
["300x46", :large],
|
158
|
+
["100x15", :medium],
|
159
|
+
["32x32", :thumb]].each do |geo, style|
|
160
|
+
cmd = %Q[identify -format "%wx%h" #{@d2_files[style].path}]
|
161
|
+
assert_equal geo, `#{cmd}`.chomp, cmd
|
162
|
+
end
|
163
|
+
|
164
|
+
@dummy.avatar = "not a valid file but not nil"
|
165
|
+
assert_equal File.basename(@file.path), @dummy.avatar_file_name
|
166
|
+
assert @dummy.valid?
|
167
|
+
assert @dummy.save
|
168
|
+
|
169
|
+
saved_keys = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.to_file(s) }
|
170
|
+
|
171
|
+
saved_keys.each do |key|
|
172
|
+
assert key.exists?
|
173
|
+
end
|
174
|
+
|
175
|
+
@dummy.avatar = nil
|
176
|
+
assert_nil @dummy.avatar_file_name
|
177
|
+
assert @dummy.valid?
|
178
|
+
assert @dummy.save
|
179
|
+
|
180
|
+
saved_keys.each do |key|
|
181
|
+
assert ! key.exists?
|
182
|
+
end
|
183
|
+
|
184
|
+
@d2 = Dummy.find(@dummy.id)
|
185
|
+
assert_nil @d2.avatar_file_name
|
186
|
+
end
|
187
|
+
|
188
|
+
should "work exactly the same when new as when reloaded" do
|
189
|
+
@d2 = Dummy.find(@dummy.id)
|
190
|
+
|
191
|
+
assert_equal @dummy.avatar_file_name, @d2.avatar_file_name
|
192
|
+
[:thumb, :medium, :large, :original].each do |style|
|
193
|
+
assert_equal @dummy.avatar.to_file(style).to_s, @d2.avatar.to_file(style).to_s
|
194
|
+
end
|
195
|
+
|
196
|
+
saved_keys = [:thumb, :medium, :large, :original].collect{|s| @dummy.avatar.to_file(s) }
|
197
|
+
|
198
|
+
@d2.avatar = nil
|
199
|
+
assert @d2.save
|
200
|
+
|
201
|
+
saved_keys.each do |key|
|
202
|
+
assert ! key.exists?
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
should "know the difference between good files, bad files, not files, and nil" do
|
207
|
+
expected = @dummy.avatar.file
|
208
|
+
@dummy.avatar = "not a file"
|
209
|
+
assert @dummy.valid?
|
210
|
+
assert_equal expected, @dummy.avatar.file
|
211
|
+
|
212
|
+
@dummy.avatar = @bad_file
|
213
|
+
assert ! @dummy.valid?
|
214
|
+
@dummy.avatar = nil
|
215
|
+
assert @dummy.valid?
|
216
|
+
|
217
|
+
Dummy.validates_attachment_presence :avatar
|
218
|
+
@d2 = Dummy.find(@dummy.id)
|
219
|
+
@d2.avatar = @file
|
220
|
+
assert @d2.valid?
|
221
|
+
@d2.avatar = @bad_file
|
222
|
+
assert ! @d2.valid?
|
223
|
+
@d2.avatar = nil
|
224
|
+
assert ! @d2.valid?
|
225
|
+
end
|
226
|
+
|
227
|
+
should "be able to reload without saving an not have the file disappear" do
|
228
|
+
@dummy.avatar = @file
|
229
|
+
assert @dummy.save
|
230
|
+
@dummy.avatar = nil
|
231
|
+
assert_nil @dummy.avatar_file_name
|
232
|
+
@dummy.reload
|
233
|
+
assert_equal "5k.png", @dummy.avatar_file_name
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|