paperclip-youtube 2.3.8.1

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.
Files changed (62) hide show
  1. data/LICENSE +26 -0
  2. data/README.md +91 -0
  3. data/Rakefile +80 -0
  4. data/generators/paperclip/USAGE +5 -0
  5. data/generators/paperclip/paperclip_generator.rb +27 -0
  6. data/generators/paperclip/templates/paperclip_migration.rb.erb +19 -0
  7. data/init.rb +1 -0
  8. data/lib/generators/paperclip/USAGE +8 -0
  9. data/lib/generators/paperclip/paperclip_generator.rb +31 -0
  10. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +19 -0
  11. data/lib/paperclip.rb +378 -0
  12. data/lib/paperclip/attachment.rb +376 -0
  13. data/lib/paperclip/callback_compatability.rb +61 -0
  14. data/lib/paperclip/command_line.rb +86 -0
  15. data/lib/paperclip/geometry.rb +115 -0
  16. data/lib/paperclip/interpolations.rb +130 -0
  17. data/lib/paperclip/iostream.rb +45 -0
  18. data/lib/paperclip/matchers.rb +33 -0
  19. data/lib/paperclip/matchers/have_attached_file_matcher.rb +57 -0
  20. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +75 -0
  21. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +54 -0
  22. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +95 -0
  23. data/lib/paperclip/processor.rb +58 -0
  24. data/lib/paperclip/railtie.rb +24 -0
  25. data/lib/paperclip/storage.rb +3 -0
  26. data/lib/paperclip/storage/filesystem.rb +73 -0
  27. data/lib/paperclip/storage/s3.rb +192 -0
  28. data/lib/paperclip/storage/youtube.rb +331 -0
  29. data/lib/paperclip/style.rb +90 -0
  30. data/lib/paperclip/thumbnail.rb +79 -0
  31. data/lib/paperclip/upfile.rb +55 -0
  32. data/lib/paperclip/version.rb +3 -0
  33. data/lib/tasks/paperclip.rake +72 -0
  34. data/rails/init.rb +2 -0
  35. data/shoulda_macros/paperclip.rb +118 -0
  36. data/test/attachment_test.rb +921 -0
  37. data/test/command_line_test.rb +138 -0
  38. data/test/database.yml +4 -0
  39. data/test/fixtures/12k.png +0 -0
  40. data/test/fixtures/50x50.png +0 -0
  41. data/test/fixtures/5k.png +0 -0
  42. data/test/fixtures/bad.png +1 -0
  43. data/test/fixtures/s3.yml +8 -0
  44. data/test/fixtures/text.txt +0 -0
  45. data/test/fixtures/twopage.pdf +0 -0
  46. data/test/fixtures/uppercase.PNG +0 -0
  47. data/test/geometry_test.rb +177 -0
  48. data/test/helper.rb +146 -0
  49. data/test/integration_test.rb +570 -0
  50. data/test/interpolations_test.rb +143 -0
  51. data/test/iostream_test.rb +71 -0
  52. data/test/matchers/have_attached_file_matcher_test.rb +24 -0
  53. data/test/matchers/validate_attachment_content_type_matcher_test.rb +47 -0
  54. data/test/matchers/validate_attachment_presence_matcher_test.rb +26 -0
  55. data/test/matchers/validate_attachment_size_matcher_test.rb +51 -0
  56. data/test/paperclip_test.rb +301 -0
  57. data/test/processor_test.rb +10 -0
  58. data/test/storage_test.rb +386 -0
  59. data/test/style_test.rb +141 -0
  60. data/test/thumbnail_test.rb +227 -0
  61. data/test/upfile_test.rb +36 -0
  62. metadata +195 -0
@@ -0,0 +1,143 @@
1
+ require './test/helper'
2
+
3
+ class InterpolationsTest < Test::Unit::TestCase
4
+ should "return all methods but the infrastructure when sent #all" do
5
+ methods = Paperclip::Interpolations.all
6
+ assert ! methods.include?(:[])
7
+ assert ! methods.include?(:[]=)
8
+ assert ! methods.include?(:all)
9
+ methods.each do |m|
10
+ assert Paperclip::Interpolations.respond_to?(m)
11
+ end
12
+ end
13
+
14
+ should "return the Rails.root" do
15
+ assert_equal Rails.root, Paperclip::Interpolations.rails_root(:attachment, :style)
16
+ end
17
+
18
+ should "return the Rails.env" do
19
+ assert_equal Rails.env, Paperclip::Interpolations.rails_env(:attachment, :style)
20
+ end
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
+
26
+ should "return the class of the instance" do
27
+ attachment = mock
28
+ attachment.expects(:instance).returns(attachment)
29
+ attachment.expects(:class).returns("Thing")
30
+ assert_equal "things", Paperclip::Interpolations.class(attachment, :style)
31
+ end
32
+
33
+ should "return the basename of the file" do
34
+ attachment = mock
35
+ attachment.expects(:original_filename).returns("one.jpg").times(2)
36
+ assert_equal "one", Paperclip::Interpolations.basename(attachment, :style)
37
+ end
38
+
39
+ should "return the extension of the file" do
40
+ attachment = mock
41
+ attachment.expects(:original_filename).returns("one.jpg")
42
+ attachment.expects(:styles).returns({})
43
+ assert_equal "jpg", Paperclip::Interpolations.extension(attachment, :style)
44
+ end
45
+
46
+ should "return the extension of the file as the format if defined in the style" do
47
+ attachment = mock
48
+ attachment.expects(:original_filename).never
49
+ attachment.expects(:styles).returns({:style => {:format => "png"}})
50
+ assert_equal "png", Paperclip::Interpolations.extension(attachment, :style)
51
+ end
52
+
53
+ should "return the id of the attachment" do
54
+ attachment = mock
55
+ attachment.expects(:id).returns(23)
56
+ attachment.expects(:instance).returns(attachment)
57
+ assert_equal 23, Paperclip::Interpolations.id(attachment, :style)
58
+ end
59
+
60
+ should "return the partitioned id of the attachment" do
61
+ attachment = mock
62
+ attachment.expects(:id).returns(23)
63
+ attachment.expects(:instance).returns(attachment)
64
+ assert_equal "000/000/023", Paperclip::Interpolations.id_partition(attachment, :style)
65
+ end
66
+
67
+ should "return the name of the attachment" do
68
+ attachment = mock
69
+ attachment.expects(:name).returns("file")
70
+ assert_equal "files", Paperclip::Interpolations.attachment(attachment, :style)
71
+ end
72
+
73
+ should "return the style" do
74
+ assert_equal :style, Paperclip::Interpolations.style(:attachment, :style)
75
+ end
76
+
77
+ should "return the default style" do
78
+ attachment = mock
79
+ attachment.expects(:default_style).returns(:default_style)
80
+ assert_equal :default_style, Paperclip::Interpolations.style(attachment, nil)
81
+ end
82
+
83
+ should "reinterpolate :url" do
84
+ attachment = mock
85
+ attachment.expects(:url).with(:style, false).returns("1234")
86
+ assert_equal "1234", Paperclip::Interpolations.url(attachment, :style)
87
+ end
88
+
89
+ should "raise if infinite loop detcted reinterpolating :url" do
90
+ attachment = Object.new
91
+ class << attachment
92
+ def url(*args)
93
+ Paperclip::Interpolations.url(self, :style)
94
+ end
95
+ end
96
+ assert_raises(Paperclip::InfiniteInterpolationError){ Paperclip::Interpolations.url(attachment, :style) }
97
+ end
98
+
99
+ should "return the filename as basename.extension" do
100
+ attachment = mock
101
+ attachment.expects(:styles).returns({})
102
+ attachment.expects(:original_filename).returns("one.jpg").times(3)
103
+ assert_equal "one.jpg", Paperclip::Interpolations.filename(attachment, :style)
104
+ end
105
+
106
+ should "return the filename as basename.extension when format supplied" do
107
+ attachment = mock
108
+ attachment.expects(:styles).returns({:style => {:format => :png}})
109
+ attachment.expects(:original_filename).returns("one.jpg").times(2)
110
+ assert_equal "one.png", Paperclip::Interpolations.filename(attachment, :style)
111
+ end
112
+
113
+ should "return the timestamp" do
114
+ now = Time.now
115
+ zone = 'UTC'
116
+ attachment = mock
117
+ attachment.expects(:instance_read).with(:updated_at).returns(now)
118
+ attachment.expects(:time_zone).returns(zone)
119
+ assert_equal now.in_time_zone(zone).to_s, Paperclip::Interpolations.timestamp(attachment, :style)
120
+ end
121
+
122
+ should "return updated_at" do
123
+ attachment = mock
124
+ seconds_since_epoch = 1234567890
125
+ attachment.expects(:updated_at).returns(seconds_since_epoch)
126
+ assert_equal seconds_since_epoch, Paperclip::Interpolations.updated_at(attachment, :style)
127
+ end
128
+
129
+ should "return hash" do
130
+ attachment = mock
131
+ fake_hash = "a_wicked_secure_hash"
132
+ attachment.expects(:hash).returns(fake_hash)
133
+ assert_equal fake_hash, Paperclip::Interpolations.hash(attachment, :style)
134
+ end
135
+
136
+ should "call all expected interpolations with the given arguments" do
137
+ Paperclip::Interpolations.expects(:id).with(:attachment, :style).returns(1234)
138
+ Paperclip::Interpolations.expects(:attachment).with(:attachment, :style).returns("attachments")
139
+ Paperclip::Interpolations.expects(:notreal).never
140
+ value = Paperclip::Interpolations.interpolate(":notreal/:id/:attachment", :attachment, :style)
141
+ assert_equal ":notreal/1234/attachments", value
142
+ end
143
+ end
@@ -0,0 +1,71 @@
1
+ require './test/helper'
2
+
3
+ class IOStreamTest < Test::Unit::TestCase
4
+ include IOStream
5
+ context "A file" do
6
+ setup do
7
+ @file = File.new(File.join(File.dirname(__FILE__), "fixtures", "5k.png"), 'rb')
8
+ end
9
+
10
+ teardown { @file.close }
11
+
12
+ context "that is sent #stream_to" do
13
+
14
+ context "and given a String" do
15
+ setup do
16
+ FileUtils.mkdir_p(File.join(ROOT, 'tmp'))
17
+ assert @result = stream_to(@file, File.join(ROOT, 'tmp', 'iostream.string.test'))
18
+ end
19
+
20
+ should "return a File" do
21
+ assert @result.is_a?(File)
22
+ end
23
+
24
+ should "contain the same data as the original file" do
25
+ @file.rewind; @result.rewind
26
+ assert_equal @file.read, @result.read
27
+ end
28
+ end
29
+
30
+ context "and given a Tempfile" do
31
+ setup do
32
+ tempfile = Tempfile.new('iostream.test')
33
+ tempfile.binmode
34
+ assert @result = stream_to(@file, tempfile)
35
+ end
36
+
37
+ should "return a Tempfile" do
38
+ assert @result.is_a?(Tempfile)
39
+ end
40
+
41
+ should "contain the same data as the original file" do
42
+ @file.rewind; @result.rewind
43
+ assert_equal @file.read, @result.read
44
+ end
45
+ end
46
+
47
+ end
48
+
49
+ context "that is converted #to_tempfile" do
50
+ setup do
51
+ assert @tempfile = to_tempfile(@file)
52
+ end
53
+
54
+ should "convert it to a Paperclip Tempfile" do
55
+ assert @tempfile.is_a?(Paperclip::Tempfile)
56
+ end
57
+
58
+ should "have the name be based on the original_filename" do
59
+ name = File.basename(@file.path)
60
+ extension = File.extname(name)
61
+ basename = File.basename(name, extension)
62
+ assert_match %r[^stream.*?#{Regexp.quote(extension)}], File.basename(@tempfile.path)
63
+ end
64
+
65
+ should "have the Tempfile contain the same data as the file" do
66
+ @file.rewind; @tempfile.rewind
67
+ assert_equal @file.read, @tempfile.read
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,24 @@
1
+ require './test/helper'
2
+
3
+ class HaveAttachedFileMatcherTest < Test::Unit::TestCase
4
+ context "have_attached_file" do
5
+ setup do
6
+ @dummy_class = reset_class "Dummy"
7
+ reset_table "dummies"
8
+ @matcher = self.class.have_attached_file(:avatar)
9
+ end
10
+
11
+ context "given a class with no attachment" do
12
+ should_reject_dummy_class
13
+ end
14
+
15
+ context "given a class with an attachment" do
16
+ setup do
17
+ modify_table("dummies"){|d| d.string :avatar_file_name }
18
+ @dummy_class.has_attached_file :avatar
19
+ end
20
+
21
+ should_accept_dummy_class
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,47 @@
1
+ require './test/helper'
2
+
3
+ class ValidateAttachmentContentTypeMatcherTest < Test::Unit::TestCase
4
+ context "validate_attachment_content_type" do
5
+ setup do
6
+ reset_table("dummies") do |d|
7
+ d.string :title
8
+ d.string :avatar_file_name
9
+ d.string :avatar_content_type
10
+ end
11
+ @dummy_class = reset_class "Dummy"
12
+ @dummy_class.has_attached_file :avatar
13
+ @matcher = self.class.validate_attachment_content_type(:avatar).
14
+ allowing(%w(image/png image/jpeg)).
15
+ rejecting(%w(audio/mp3 application/octet-stream))
16
+ end
17
+
18
+ context "given a class with no validation" do
19
+ should_reject_dummy_class
20
+ end
21
+
22
+ context "given a class with a validation that doesn't match" do
23
+ setup do
24
+ @dummy_class.validates_attachment_content_type :avatar, :content_type => %r{audio/.*}
25
+ end
26
+
27
+ should_reject_dummy_class
28
+ end
29
+
30
+ context "given a class with a matching validation" do
31
+ setup do
32
+ @dummy_class.validates_attachment_content_type :avatar, :content_type => %r{image/.*}
33
+ end
34
+
35
+ should_accept_dummy_class
36
+ end
37
+
38
+ context "given a class with other validations but matching types" do
39
+ setup do
40
+ @dummy_class.validates_presence_of :title
41
+ @dummy_class.validates_attachment_content_type :avatar, :content_type => %r{image/.*}
42
+ end
43
+
44
+ should_accept_dummy_class
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,26 @@
1
+ require './test/helper'
2
+
3
+ class ValidateAttachmentPresenceMatcherTest < Test::Unit::TestCase
4
+ context "validate_attachment_presence" do
5
+ setup do
6
+ reset_table("dummies") do |d|
7
+ d.string :avatar_file_name
8
+ end
9
+ @dummy_class = reset_class "Dummy"
10
+ @dummy_class.has_attached_file :avatar
11
+ @matcher = self.class.validate_attachment_presence(:avatar)
12
+ end
13
+
14
+ context "given a class with no validation" do
15
+ should_reject_dummy_class
16
+ end
17
+
18
+ context "given a class with a matching validation" do
19
+ setup do
20
+ @dummy_class.validates_attachment_presence :avatar
21
+ end
22
+
23
+ should_accept_dummy_class
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,51 @@
1
+ require './test/helper'
2
+
3
+ class ValidateAttachmentSizeMatcherTest < Test::Unit::TestCase
4
+ context "validate_attachment_size" do
5
+ setup do
6
+ reset_table("dummies") do |d|
7
+ d.string :avatar_file_name
8
+ d.integer :avatar_file_size
9
+ end
10
+ @dummy_class = reset_class "Dummy"
11
+ @dummy_class.has_attached_file :avatar
12
+ end
13
+
14
+ context "of limited size" do
15
+ setup{ @matcher = self.class.validate_attachment_size(:avatar).in(256..1024) }
16
+
17
+ context "given a class with no validation" do
18
+ should_reject_dummy_class
19
+ end
20
+
21
+ context "given a class with a validation that's too high" do
22
+ setup { @dummy_class.validates_attachment_size :avatar, :in => 256..2048 }
23
+ should_reject_dummy_class
24
+ end
25
+
26
+ context "given a class with a validation that's too low" do
27
+ setup { @dummy_class.validates_attachment_size :avatar, :in => 0..1024 }
28
+ should_reject_dummy_class
29
+ end
30
+
31
+ context "given a class with a validation that matches" do
32
+ setup { @dummy_class.validates_attachment_size :avatar, :in => 256..1024 }
33
+ should_accept_dummy_class
34
+ end
35
+ end
36
+
37
+ context "validates_attachment_size with infinite range" do
38
+ setup{ @matcher = self.class.validate_attachment_size(:avatar) }
39
+
40
+ context "given a class with an upper limit" do
41
+ setup { @dummy_class.validates_attachment_size :avatar, :less_than => 1 }
42
+ should_accept_dummy_class
43
+ end
44
+
45
+ context "given a class with no upper limit" do
46
+ setup { @dummy_class.validates_attachment_size :avatar, :greater_than => 1 }
47
+ should_accept_dummy_class
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,301 @@
1
+ require './test/helper'
2
+
3
+ class PaperclipTest < Test::Unit::TestCase
4
+ context "Calling Paperclip.run" do
5
+ setup do
6
+ Paperclip.options[:image_magick_path] = nil
7
+ Paperclip.options[:command_path] = nil
8
+ Paperclip::CommandLine.stubs(:'`')
9
+ end
10
+
11
+ should "execute the right command with :image_magick_path" do
12
+ Paperclip.options[:image_magick_path] = "/usr/bin"
13
+ Paperclip.expects(:log).with(includes('[DEPRECATION]'))
14
+ Paperclip.expects(:log).with(regexp_matches(%r{/usr/bin/convert ['"]one.jpg['"] ['"]two.jpg['"]}))
15
+ Paperclip::CommandLine.expects(:"`").with(regexp_matches(%r{/usr/bin/convert ['"]one.jpg['"] ['"]two.jpg['"]}))
16
+ Paperclip.run("convert", ":one :two", :one => "one.jpg", :two => "two.jpg")
17
+ end
18
+
19
+ should "execute the right command with :command_path" do
20
+ Paperclip.options[:command_path] = "/usr/bin"
21
+ Paperclip::CommandLine.expects(:"`").with(regexp_matches(%r{/usr/bin/convert ['"]one.jpg['"] ['"]two.jpg['"]}))
22
+ Paperclip.run("convert", ":one :two", :one => "one.jpg", :two => "two.jpg")
23
+ end
24
+
25
+ should "execute the right command with no path" do
26
+ Paperclip::CommandLine.expects(:"`").with(regexp_matches(%r{convert ['"]one.jpg['"] ['"]two.jpg['"]}))
27
+ Paperclip.run("convert", ":one :two", :one => "one.jpg", :two => "two.jpg")
28
+ end
29
+
30
+ should "tell you the command isn't there if the shell returns 127" do
31
+ with_exitstatus_returning(127) do
32
+ assert_raises(Paperclip::CommandNotFoundError) do
33
+ Paperclip.run("command")
34
+ end
35
+ end
36
+ end
37
+
38
+ should "tell you the command isn't there if an ENOENT is raised" do
39
+ assert_raises(Paperclip::CommandNotFoundError) do
40
+ Paperclip::CommandLine.stubs(:"`").raises(Errno::ENOENT)
41
+ Paperclip.run("command")
42
+ end
43
+ end
44
+ end
45
+
46
+ context "Paperclip.each_instance_with_attachment" do
47
+ setup do
48
+ @file = File.new(File.join(FIXTURES_DIR, "5k.png"), 'rb')
49
+ d1 = Dummy.create(:avatar => @file)
50
+ d2 = Dummy.create
51
+ d3 = Dummy.create(:avatar => @file)
52
+ @expected = [d1, d3]
53
+ end
54
+ should "yield every instance of a model that has an attachment" do
55
+ actual = []
56
+ Paperclip.each_instance_with_attachment("Dummy", "avatar") do |instance|
57
+ actual << instance
58
+ end
59
+ assert_same_elements @expected, actual
60
+ end
61
+ end
62
+
63
+ should "raise when sent #processor and the name of a class that exists but isn't a subclass of Processor" do
64
+ assert_raises(Paperclip::PaperclipError){ Paperclip.processor(:attachment) }
65
+ end
66
+
67
+ should "raise when sent #processor and the name of a class that doesn't exist" do
68
+ assert_raises(NameError){ Paperclip.processor(:boogey_man) }
69
+ end
70
+
71
+ should "return a class when sent #processor and the name of a class under Paperclip" do
72
+ assert_equal ::Paperclip::Thumbnail, Paperclip.processor(:thumbnail)
73
+ end
74
+
75
+ context "An ActiveRecord model with an 'avatar' attachment" do
76
+ setup do
77
+ rebuild_model :path => "tmp/:class/omg/:style.:extension"
78
+ @file = File.new(File.join(FIXTURES_DIR, "5k.png"), 'rb')
79
+ end
80
+
81
+ teardown { @file.close }
82
+
83
+ should "not error when trying to also create a 'blah' attachment" do
84
+ assert_nothing_raised do
85
+ Dummy.class_eval do
86
+ has_attached_file :blah
87
+ end
88
+ end
89
+ end
90
+
91
+ context "that is attr_protected" do
92
+ setup do
93
+ Dummy.class_eval do
94
+ attr_protected :avatar
95
+ end
96
+ @dummy = Dummy.new
97
+ end
98
+
99
+ should "not assign the avatar on mass-set" do
100
+ @dummy.attributes = { :other => "I'm set!",
101
+ :avatar => @file }
102
+
103
+ assert_equal "I'm set!", @dummy.other
104
+ assert ! @dummy.avatar?
105
+ end
106
+
107
+ should "still allow assigment on normal set" do
108
+ @dummy.other = "I'm set!"
109
+ @dummy.avatar = @file
110
+
111
+ assert_equal "I'm set!", @dummy.other
112
+ assert @dummy.avatar?
113
+ end
114
+ end
115
+
116
+ context "with a subclass" do
117
+ setup do
118
+ class ::SubDummy < Dummy; end
119
+ end
120
+
121
+ should "be able to use the attachment from the subclass" do
122
+ assert_nothing_raised do
123
+ @subdummy = SubDummy.create(:avatar => @file)
124
+ end
125
+ end
126
+
127
+ should "be able to see the attachment definition from the subclass's class" do
128
+ assert_equal "tmp/:class/omg/:style.:extension",
129
+ SubDummy.attachment_definitions[:avatar][:path]
130
+ end
131
+
132
+ teardown do
133
+ Object.send(:remove_const, "SubDummy") rescue nil
134
+ end
135
+ end
136
+
137
+ should "have an #avatar method" do
138
+ assert Dummy.new.respond_to?(:avatar)
139
+ end
140
+
141
+ should "have an #avatar= method" do
142
+ assert Dummy.new.respond_to?(:avatar=)
143
+ end
144
+
145
+ context "that is valid" do
146
+ setup do
147
+ @dummy = Dummy.new
148
+ @dummy.avatar = @file
149
+ end
150
+
151
+ should "be valid" do
152
+ assert @dummy.valid?
153
+ end
154
+ end
155
+
156
+ context "a validation with an if guard clause" do
157
+ setup do
158
+ Dummy.send(:"validates_attachment_presence", :avatar, :if => lambda{|i| i.foo })
159
+ @dummy = Dummy.new
160
+ @dummy.stubs(:avatar_file_name).returns(nil)
161
+ end
162
+
163
+ should "attempt validation if the guard returns true" do
164
+ @dummy.expects(:foo).returns(true)
165
+ assert ! @dummy.valid?
166
+ end
167
+
168
+ should "not attempt validation if the guard returns false" do
169
+ @dummy.expects(:foo).returns(false)
170
+ assert @dummy.valid?
171
+ end
172
+ end
173
+
174
+ context "a validation with an unless guard clause" do
175
+ setup do
176
+ Dummy.send(:"validates_attachment_presence", :avatar, :unless => lambda{|i| i.foo })
177
+ @dummy = Dummy.new
178
+ @dummy.stubs(:avatar_file_name).returns(nil)
179
+ end
180
+
181
+ should "attempt validation if the guard returns true" do
182
+ @dummy.expects(:foo).returns(false)
183
+ assert ! @dummy.valid?
184
+ end
185
+
186
+ should "not attempt validation if the guard returns false" do
187
+ @dummy.expects(:foo).returns(true)
188
+ assert @dummy.valid?
189
+ end
190
+ end
191
+
192
+ should "not have Attachment in the ActiveRecord::Base namespace" do
193
+ assert_raises(NameError) do
194
+ ActiveRecord::Base::Attachment
195
+ end
196
+ end
197
+
198
+ def self.should_validate validation, options, valid_file, invalid_file
199
+ context "with #{validation} validation and #{options.inspect} options" do
200
+ setup do
201
+ rebuild_class
202
+ Dummy.send(:"validates_attachment_#{validation}", :avatar, options)
203
+ @dummy = Dummy.new
204
+ end
205
+ context "and assigning nil" do
206
+ setup do
207
+ @dummy.avatar = nil
208
+ @dummy.valid?
209
+ end
210
+ if validation == :presence
211
+ should "have an error on the attachment" do
212
+ assert @dummy.errors[:avatar_file_name]
213
+ end
214
+ else
215
+ should "not have an error on the attachment" do
216
+ assert @dummy.errors.blank?, @dummy.errors.full_messages.join(", ")
217
+ end
218
+ end
219
+ end
220
+ context "and assigned a valid file" do
221
+ setup do
222
+ @dummy.avatar = valid_file
223
+ @dummy.valid?
224
+ end
225
+ should "not have an error when assigned a valid file" do
226
+ assert_equal 0, @dummy.errors.length, @dummy.errors.full_messages.join(", ")
227
+ end
228
+ end
229
+ context "and assigned an invalid file" do
230
+ setup do
231
+ @dummy.avatar = invalid_file
232
+ @dummy.valid?
233
+ end
234
+ should "have an error when assigned a valid file" do
235
+ assert @dummy.errors.length > 0
236
+ end
237
+ end
238
+ end
239
+ end
240
+
241
+ [[:presence, {}, "5k.png", nil],
242
+ [:size, {:in => 1..10240}, "5k.png", "12k.png"],
243
+ [:size, {:less_than => 10240}, "5k.png", "12k.png"],
244
+ [:size, {:greater_than => 8096}, "12k.png", "5k.png"],
245
+ [:content_type, {:content_type => "image/png"}, "5k.png", "text.txt"],
246
+ [:content_type, {:content_type => "text/plain"}, "text.txt", "5k.png"],
247
+ [:content_type, {:content_type => %r{image/.*}}, "5k.png", "text.txt"]].each do |args|
248
+ validation, options, valid_file, invalid_file = args
249
+ valid_file &&= File.open(File.join(FIXTURES_DIR, valid_file), "rb")
250
+ invalid_file &&= File.open(File.join(FIXTURES_DIR, invalid_file), "rb")
251
+
252
+ should_validate validation, options, valid_file, invalid_file
253
+ end
254
+
255
+ context "with content_type validation and lambda message" do
256
+ context "and assigned an invalid file" do
257
+ setup do
258
+ Dummy.send(:"validates_attachment_content_type", :avatar, :content_type => %r{image/.*}, :message => lambda {'lambda content type message'})
259
+ @dummy = Dummy.new
260
+ @dummy.avatar &&= File.open(File.join(FIXTURES_DIR, "text.txt"), "rb")
261
+ @dummy.valid?
262
+ end
263
+
264
+ should "have a content type error message" do
265
+ assert [@dummy.errors[:avatar_content_type]].flatten.any?{|error| error =~ %r/lambda content type message/ }
266
+ end
267
+ end
268
+ end
269
+
270
+ context "with size validation and less_than 10240 option" do
271
+ context "and assigned an invalid file" do
272
+ setup do
273
+ Dummy.send(:"validates_attachment_size", :avatar, :less_than => 10240)
274
+ @dummy = Dummy.new
275
+ @dummy.avatar &&= File.open(File.join(FIXTURES_DIR, "12k.png"), "rb")
276
+ @dummy.valid?
277
+ end
278
+
279
+ should "have a file size min/max error message" do
280
+ assert [@dummy.errors[:avatar_file_size]].flatten.any?{|error| error =~ %r/between 0 and 10240 bytes/ }
281
+ end
282
+ end
283
+ end
284
+
285
+ context "with size validation and less_than 10240 option with lambda message" do
286
+ context "and assigned an invalid file" do
287
+ setup do
288
+ Dummy.send(:"validates_attachment_size", :avatar, :less_than => 10240, :message => lambda {'lambda between 0 and 10240 bytes'})
289
+ @dummy = Dummy.new
290
+ @dummy.avatar &&= File.open(File.join(FIXTURES_DIR, "12k.png"), "rb")
291
+ @dummy.valid?
292
+ end
293
+
294
+ should "have a file size min/max error message" do
295
+ assert [@dummy.errors[:avatar_file_size]].flatten.any?{|error| error =~ %r/lambda between 0 and 10240 bytes/ }
296
+ end
297
+ end
298
+ end
299
+
300
+ end
301
+ end