cloudfuji_paperclip 2.4.6 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. data/.gitignore +2 -0
  2. data/.travis.yml +9 -6
  3. data/Appraisals +6 -6
  4. data/CONTRIBUTING.md +34 -2
  5. data/Gemfile +2 -0
  6. data/NEWS +90 -0
  7. data/README.md +62 -29
  8. data/RUNNING_TESTS.md +4 -0
  9. data/Rakefile +7 -2
  10. data/UPGRADING +14 -0
  11. data/features/basic_integration.feature +11 -7
  12. data/features/rake_tasks.feature +1 -1
  13. data/features/step_definitions/attachment_steps.rb +11 -2
  14. data/features/step_definitions/rails_steps.rb +17 -79
  15. data/features/support/env.rb +3 -0
  16. data/features/support/fakeweb.rb +7 -0
  17. data/features/support/file_helpers.rb +24 -0
  18. data/features/support/rails.rb +3 -3
  19. data/gemfiles/{rails3_1.gemfile → 3.0.gemfile} +3 -1
  20. data/gemfiles/{rails2.gemfile → 3.1.gemfile} +3 -1
  21. data/gemfiles/{rails3.gemfile → 3.2.gemfile} +3 -1
  22. data/images.rake +21 -0
  23. data/lib/cloudfuji_paperclip.rb +1 -0
  24. data/lib/generators/paperclip/paperclip_generator.rb +1 -2
  25. data/lib/paperclip.rb +54 -319
  26. data/lib/paperclip/attachment.rb +86 -107
  27. data/lib/paperclip/attachment_options.rb +9 -0
  28. data/lib/paperclip/callbacks.rb +30 -0
  29. data/lib/paperclip/errors.rb +27 -0
  30. data/lib/paperclip/geometry.rb +6 -4
  31. data/lib/paperclip/glue.rb +23 -0
  32. data/lib/paperclip/helpers.rb +71 -0
  33. data/lib/paperclip/instance_methods.rb +35 -0
  34. data/lib/paperclip/interpolations.rb +4 -4
  35. data/lib/paperclip/io_adapters/attachment_adapter.rb +69 -0
  36. data/lib/paperclip/io_adapters/file_adapter.rb +81 -0
  37. data/lib/paperclip/io_adapters/identity_adapter.rb +12 -0
  38. data/lib/paperclip/io_adapters/nil_adapter.rb +34 -0
  39. data/lib/paperclip/io_adapters/registry.rb +32 -0
  40. data/lib/paperclip/io_adapters/stringio_adapter.rb +64 -0
  41. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +63 -0
  42. data/lib/paperclip/locales/en.yml +17 -0
  43. data/lib/paperclip/logger.rb +21 -0
  44. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +5 -5
  45. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +7 -7
  46. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +11 -11
  47. data/lib/paperclip/missing_attachment_styles.rb +6 -9
  48. data/lib/paperclip/processor.rb +32 -17
  49. data/lib/paperclip/railtie.rb +13 -17
  50. data/lib/paperclip/storage/filesystem.rb +4 -13
  51. data/lib/paperclip/storage/fog.rb +33 -24
  52. data/lib/paperclip/storage/s3.rb +36 -28
  53. data/lib/paperclip/tempfile.rb +41 -0
  54. data/lib/paperclip/thumbnail.rb +2 -3
  55. data/lib/paperclip/validators.rb +45 -0
  56. data/lib/paperclip/validators/attachment_content_type_validator.rb +54 -0
  57. data/lib/paperclip/validators/attachment_presence_validator.rb +26 -0
  58. data/lib/paperclip/validators/attachment_size_validator.rb +102 -0
  59. data/lib/paperclip/version.rb +1 -1
  60. data/lib/tasks/paperclip.rake +4 -12
  61. data/paperclip.gemspec +15 -5
  62. data/test/adapter_registry_test.rb +32 -0
  63. data/test/attachment_adapter_test.rb +51 -0
  64. data/test/attachment_options_test.rb +27 -0
  65. data/test/attachment_test.rb +130 -46
  66. data/test/file_adapter_test.rb +88 -0
  67. data/test/generator_test.rb +78 -0
  68. data/test/geometry_test.rb +5 -5
  69. data/test/helper.rb +21 -22
  70. data/test/identity_adapter_test.rb +8 -0
  71. data/test/integration_test.rb +55 -102
  72. data/test/interpolations_test.rb +15 -5
  73. data/test/matchers/validate_attachment_content_type_matcher_test.rb +23 -0
  74. data/test/matchers/validate_attachment_presence_matcher_test.rb +21 -0
  75. data/test/matchers/validate_attachment_size_matcher_test.rb +37 -2
  76. data/test/nil_adapter_test.rb +25 -0
  77. data/test/paperclip_missing_attachment_styles_test.rb +16 -0
  78. data/test/paperclip_test.rb +34 -183
  79. data/test/storage/filesystem_test.rb +27 -27
  80. data/test/storage/fog_test.rb +68 -12
  81. data/test/storage/s3_live_test.rb +79 -38
  82. data/test/storage/s3_test.rb +204 -34
  83. data/test/stringio_adapter_test.rb +42 -0
  84. data/test/thumbnail_test.rb +29 -8
  85. data/test/uploaded_file_adapter_test.rb +98 -0
  86. data/test/url_generator_test.rb +8 -8
  87. data/test/validators/attachment_content_type_validator_test.rb +192 -0
  88. data/test/validators/attachment_presence_validator_test.rb +85 -0
  89. data/test/validators/attachment_size_validator_test.rb +207 -0
  90. data/test/validators_test.rb +25 -0
  91. metadata +166 -59
  92. data/generators/paperclip/USAGE +0 -5
  93. data/generators/paperclip/paperclip_generator.rb +0 -27
  94. data/generators/paperclip/templates/paperclip_migration.rb.erb +0 -19
  95. data/init.rb +0 -4
  96. data/lib/paperclip/callback_compatibility.rb +0 -61
  97. data/lib/paperclip/iostream.rb +0 -45
  98. data/lib/paperclip/upfile.rb +0 -62
  99. data/rails/init.rb +0 -2
  100. data/test/.gitignore +0 -1
  101. data/test/fixtures/question?mark.png +0 -0
  102. data/test/iostream_test.rb +0 -71
  103. data/test/upfile_test.rb +0 -53
@@ -0,0 +1,42 @@
1
+ require './test/helper'
2
+
3
+ class StringioFileProxyTest < Test::Unit::TestCase
4
+ context "a new instance" do
5
+ setup do
6
+ @contents = "abc123"
7
+ @stringio = StringIO.new(@contents)
8
+ @subject = Paperclip.io_adapters.for(@stringio)
9
+ end
10
+
11
+ should "return a file name" do
12
+ assert_equal "stringio.txt", @subject.original_filename
13
+ end
14
+
15
+ should "allow us to set a name" do
16
+ @subject.original_filename = "data.txt"
17
+ assert_equal "data.txt", @subject.original_filename
18
+ end
19
+
20
+ should "return a content type" do
21
+ assert_equal "text/plain", @subject.content_type
22
+ end
23
+
24
+ should "allow us to set a content type" do
25
+ @subject.content_type = "image/jpg"
26
+ assert_equal "image/jpg", @subject.content_type
27
+ end
28
+
29
+ should "return the size of the data" do
30
+ assert_equal 6, @subject.size
31
+ end
32
+
33
+ should "generate an MD5 hash of the contents" do
34
+ assert_equal Digest::MD5.hexdigest(@contents), @subject.fingerprint
35
+ end
36
+
37
+ should "return the data contained in the StringIO" do
38
+ assert_equal "abc123", @subject.read
39
+ end
40
+
41
+ end
42
+ end
@@ -7,6 +7,8 @@ class ThumbnailTest < Test::Unit::TestCase
7
7
  @tempfile = Paperclip::Tempfile.new(["file", ".jpg"])
8
8
  end
9
9
 
10
+ teardown { @tempfile.close }
11
+
10
12
  should "have its path contain a real extension" do
11
13
  assert_equal ".jpg", File.extname(@tempfile.path)
12
14
  end
@@ -21,6 +23,8 @@ class ThumbnailTest < Test::Unit::TestCase
21
23
  @tempfile = Paperclip::Tempfile.new("file")
22
24
  end
23
25
 
26
+ teardown { @tempfile.close }
27
+
24
28
  should "not have an extension if not given one" do
25
29
  assert_equal "", File.extname(@tempfile.path)
26
30
  end
@@ -77,8 +81,10 @@ class ThumbnailTest < Test::Unit::TestCase
77
81
  old_path = ENV['PATH']
78
82
  begin
79
83
  ENV['PATH'] = ''
80
- assert_raises(Paperclip::CommandNotFoundError) do
81
- @thumb.make
84
+ assert_raises(Paperclip::Errors::CommandNotFoundError) do
85
+ silence_stream(STDERR) do
86
+ @thumb.make
87
+ end
82
88
  end
83
89
  ensure
84
90
  ENV['PATH'] = old_path
@@ -154,8 +160,10 @@ class ThumbnailTest < Test::Unit::TestCase
154
160
  end
155
161
 
156
162
  should "error when trying to create the thumbnail" do
157
- assert_raises(Paperclip::PaperclipError) do
158
- @thumb.make
163
+ assert_raises(Paperclip::Error) do
164
+ silence_stream(STDERR) do
165
+ @thumb.make
166
+ end
159
167
  end
160
168
  end
161
169
  end
@@ -194,8 +202,10 @@ class ThumbnailTest < Test::Unit::TestCase
194
202
  end
195
203
 
196
204
  should "error when trying to create the thumbnail" do
197
- assert_raises(Paperclip::PaperclipError) do
198
- @thumb.make
205
+ assert_raises(Paperclip::Error) do
206
+ silence_stream(STDERR) do
207
+ @thumb.make
208
+ end
199
209
  end
200
210
  end
201
211
 
@@ -203,8 +213,10 @@ class ThumbnailTest < Test::Unit::TestCase
203
213
  old_path = ENV['PATH']
204
214
  begin
205
215
  ENV['PATH'] = ''
206
- assert_raises(Paperclip::CommandNotFoundError) do
207
- @thumb.make
216
+ assert_raises(Paperclip::Errors::CommandNotFoundError) do
217
+ silence_stream(STDERR) do
218
+ @thumb.make
219
+ end
208
220
  end
209
221
  ensure
210
222
  ENV['PATH'] = old_path
@@ -226,11 +238,16 @@ class ThumbnailTest < Test::Unit::TestCase
226
238
  end
227
239
 
228
240
  context "passing a custom file geometry parser" do
241
+ teardown do
242
+ self.class.send(:remove_const, :GeoParser)
243
+ end
244
+
229
245
  should "produce the appropriate transformation_command" do
230
246
  GeoParser = Class.new do
231
247
  def self.from_file(file)
232
248
  new
233
249
  end
250
+
234
251
  def transformation_to(target, should_crop)
235
252
  ["SCALE", "CROP"]
236
253
  end
@@ -252,6 +269,10 @@ class ThumbnailTest < Test::Unit::TestCase
252
269
  end
253
270
 
254
271
  context "passing a custom geometry string parser" do
272
+ teardown do
273
+ self.class.send(:remove_const, :GeoParser)
274
+ end
275
+
255
276
  should "produce the appropriate transformation_command" do
256
277
  GeoParser = Class.new do
257
278
  def self.parse(s)
@@ -0,0 +1,98 @@
1
+ require './test/helper'
2
+
3
+ class UploadedFileAdapterTest < Test::Unit::TestCase
4
+ context "a new instance" do
5
+ context "with UploadedFile responding to #tempfile" do
6
+ setup do
7
+ class UploadedFile < OpenStruct; end
8
+ tempfile = File.new(fixture_file("5k.png"))
9
+ tempfile.binmode
10
+
11
+ @file = UploadedFile.new(
12
+ :original_filename => "5k.png",
13
+ :content_type => "image/png",
14
+ :head => "",
15
+ :tempfile => tempfile
16
+ )
17
+ @subject = Paperclip.io_adapters.for(@file)
18
+ end
19
+
20
+ should "get the right filename" do
21
+ assert_equal "5k.png", @subject.original_filename
22
+ end
23
+
24
+ should "force binmode on tempfile" do
25
+ assert @subject.instance_variable_get("@tempfile").binmode?
26
+ end
27
+
28
+ should "get the content type" do
29
+ assert_equal "image/png", @subject.content_type
30
+ end
31
+
32
+ should "get the file's size" do
33
+ assert_equal 4456, @subject.size
34
+ end
35
+
36
+ should "return false for a call to nil?" do
37
+ assert ! @subject.nil?
38
+ end
39
+
40
+ should "generate a MD5 hash of the contents" do
41
+ expected = Digest::MD5.file(@file.tempfile.path).to_s
42
+ assert_equal expected, @subject.fingerprint
43
+ end
44
+
45
+ should "read the contents of the file" do
46
+ expected = @file.tempfile.read
47
+ assert expected.length > 0
48
+ assert_equal expected, @subject.read
49
+ end
50
+ end
51
+
52
+ context "with UploadFile responding to #path" do
53
+ setup do
54
+ class UploadedFile < OpenStruct; end
55
+ @file = UploadedFile.new(
56
+ :original_filename => "5k.png",
57
+ :content_type => "image/png",
58
+ :head => "",
59
+ :path => fixture_file("5k.png")
60
+ )
61
+ @subject = Paperclip.io_adapters.for(@file)
62
+ end
63
+
64
+ should "get the right filename" do
65
+ assert_equal "5k.png", @subject.original_filename
66
+ end
67
+
68
+ should "force binmode on tempfile" do
69
+ assert @subject.instance_variable_get("@tempfile").binmode?
70
+ end
71
+
72
+ should "get the content type" do
73
+ assert_equal "image/png", @subject.content_type
74
+ end
75
+
76
+ should "get the file's size" do
77
+ assert_equal 4456, @subject.size
78
+ end
79
+
80
+ should "return false for a call to nil?" do
81
+ assert ! @subject.nil?
82
+ end
83
+
84
+ should "generate a MD5 hash of the contents" do
85
+ expected = Digest::MD5.file(@file.path).to_s
86
+ assert_equal expected, @subject.fingerprint
87
+ end
88
+
89
+ should "read the contents of the file" do
90
+ expected_file = File.new(@file.path)
91
+ expected_file.binmode
92
+ expected = expected_file.read
93
+ assert expected.length > 0
94
+ assert_equal expected, @subject.read
95
+ end
96
+ end
97
+ end
98
+ end
@@ -77,7 +77,7 @@ class UrlGeneratorTest < Test::Unit::TestCase
77
77
  end.new
78
78
  mock_attachment = MockAttachment.new
79
79
  mock_interpolator = MockInterpolator.new(:result => expected)
80
- options = { :interpolator => mock_interpolator}
80
+ options = { :interpolator => mock_interpolator }
81
81
  url_generator = Paperclip::UrlGenerator.new(mock_attachment, options)
82
82
 
83
83
  result = url_generator.for(:style_name, {:escape => true})
@@ -89,7 +89,7 @@ class UrlGeneratorTest < Test::Unit::TestCase
89
89
  expected = "the expected result"
90
90
  mock_attachment = MockAttachment.new
91
91
  mock_interpolator = MockInterpolator.new(:result => expected)
92
- options = { :interpolator => mock_interpolator}
92
+ options = { :interpolator => mock_interpolator }
93
93
  url_generator = Paperclip::UrlGenerator.new(mock_attachment, options)
94
94
 
95
95
  result = url_generator.for(:style_name, {:escape => false})
@@ -101,7 +101,7 @@ class UrlGeneratorTest < Test::Unit::TestCase
101
101
  expected = "the expected result"
102
102
  mock_attachment = MockAttachment.new
103
103
  mock_interpolator = MockInterpolator.new(:result => expected)
104
- options = { :interpolator => mock_interpolator}
104
+ options = { :interpolator => mock_interpolator }
105
105
  url_generator = Paperclip::UrlGenerator.new(mock_attachment, options)
106
106
 
107
107
  result = url_generator.for(:style_name, {})
@@ -113,7 +113,7 @@ class UrlGeneratorTest < Test::Unit::TestCase
113
113
  expected = "the expected result"
114
114
  mock_interpolator = MockInterpolator.new(:result => expected)
115
115
  mock_attachment = MockAttachment.new(:responds_to_updated_at => false)
116
- options = { :interpolator => mock_interpolator}
116
+ options = { :interpolator => mock_interpolator }
117
117
  url_generator = Paperclip::UrlGenerator.new(mock_attachment, options)
118
118
 
119
119
  result = url_generator.for(:style_name, {:timestamp => true})
@@ -125,7 +125,7 @@ class UrlGeneratorTest < Test::Unit::TestCase
125
125
  expected = "the expected result"
126
126
  mock_interpolator = MockInterpolator.new(:result => expected)
127
127
  mock_attachment = MockAttachment.new(:responds_to_updated_at => true, :updated_at => nil)
128
- options = { :interpolator => mock_interpolator}
128
+ options = { :interpolator => mock_interpolator }
129
129
  url_generator = Paperclip::UrlGenerator.new(mock_attachment, options)
130
130
 
131
131
  result = url_generator.for(:style_name, {:timestamp => true})
@@ -138,7 +138,7 @@ class UrlGeneratorTest < Test::Unit::TestCase
138
138
  updated_at = 1231231234
139
139
  mock_interpolator = MockInterpolator.new(:result => expected)
140
140
  mock_attachment = MockAttachment.new(:updated_at => updated_at)
141
- options = { :interpolator => mock_interpolator}
141
+ options = { :interpolator => mock_interpolator }
142
142
  url_generator = Paperclip::UrlGenerator.new(mock_attachment, options)
143
143
 
144
144
  result = url_generator.for(:style_name, {:timestamp => true})
@@ -151,7 +151,7 @@ class UrlGeneratorTest < Test::Unit::TestCase
151
151
  updated_at = 1231231234
152
152
  mock_interpolator = MockInterpolator.new(:result => expected)
153
153
  mock_attachment = MockAttachment.new(:updated_at => updated_at)
154
- options = { :interpolator => mock_interpolator}
154
+ options = { :interpolator => mock_interpolator }
155
155
  url_generator = Paperclip::UrlGenerator.new(mock_attachment, options)
156
156
 
157
157
  result = url_generator.for(:style_name, {:timestamp => true})
@@ -164,7 +164,7 @@ class UrlGeneratorTest < Test::Unit::TestCase
164
164
  updated_at = 1231231234
165
165
  mock_interpolator = MockInterpolator.new(:result => expected)
166
166
  mock_attachment = MockAttachment.new(:updated_at => updated_at)
167
- options = { :interpolator => mock_interpolator}
167
+ options = { :interpolator => mock_interpolator }
168
168
  url_generator = Paperclip::UrlGenerator.new(mock_attachment, options)
169
169
 
170
170
  result = url_generator.for(:style_name, {:timestamp => false})
@@ -0,0 +1,192 @@
1
+ require './test/helper'
2
+
3
+ class AttachmentContentTypeValidatorTest < Test::Unit::TestCase
4
+ def setup
5
+ rebuild_model
6
+ @dummy = Dummy.new
7
+ end
8
+
9
+ def build_validator(options)
10
+ @validator = Paperclip::Validators::AttachmentContentTypeValidator.new(options.merge(
11
+ :attributes => :avatar
12
+ ))
13
+ end
14
+
15
+ context "with a nil content type" do
16
+ setup do
17
+ build_validator :content_type => "image/jpg"
18
+ @dummy.stubs(:avatar_content_type => nil)
19
+ @validator.validate(@dummy)
20
+ end
21
+
22
+ should "not set an error message" do
23
+ assert @dummy.errors[:avatar_content_type].blank?
24
+ end
25
+ end
26
+
27
+ context "with :allow_nil option" do
28
+ context "as true" do
29
+ setup do
30
+ build_validator :content_type => "image/png", :allow_nil => true
31
+ @dummy.stubs(:avatar_content_type => nil)
32
+ @validator.validate(@dummy)
33
+ end
34
+
35
+ should "allow avatar_content_type as nil" do
36
+ assert @dummy.errors[:avatar_content_type].blank?
37
+ end
38
+ end
39
+
40
+ context "as false" do
41
+ setup do
42
+ build_validator :content_type => "image/png", :allow_nil => false
43
+ @dummy.stubs(:avatar_content_type => nil)
44
+ @validator.validate(@dummy)
45
+ end
46
+
47
+ should "not allow avatar_content_type as nil" do
48
+ assert @dummy.errors[:avatar_content_type].present?
49
+ end
50
+ end
51
+ end
52
+
53
+ context "with :allow_blank option" do
54
+ context "as true" do
55
+ setup do
56
+ build_validator :content_type => "image/png", :allow_blank => true
57
+ @dummy.stubs(:avatar_content_type => "")
58
+ @validator.validate(@dummy)
59
+ end
60
+
61
+ should "allow avatar_content_type as blank" do
62
+ assert @dummy.errors[:avatar_content_type].blank?
63
+ end
64
+ end
65
+
66
+ context "as false" do
67
+ setup do
68
+ build_validator :content_type => "image/png", :allow_blank => false
69
+ @dummy.stubs(:avatar_content_type => "")
70
+ @validator.validate(@dummy)
71
+ end
72
+
73
+ should "not allow avatar_content_type as blank" do
74
+ assert @dummy.errors[:avatar_content_type].present?
75
+ end
76
+ end
77
+ end
78
+
79
+ context "with an allowed type" do
80
+ context "as a string" do
81
+ setup do
82
+ build_validator :content_type => "image/jpg"
83
+ @dummy.stubs(:avatar_content_type => "image/jpg")
84
+ @validator.validate(@dummy)
85
+ end
86
+
87
+ should "not set an error message" do
88
+ assert @dummy.errors[:avatar_content_type].blank?
89
+ end
90
+ end
91
+
92
+ context "as an regexp" do
93
+ setup do
94
+ build_validator :content_type => /^image\/.*/
95
+ @dummy.stubs(:avatar_content_type => "image/jpg")
96
+ @validator.validate(@dummy)
97
+ end
98
+
99
+ should "not set an error message" do
100
+ assert @dummy.errors[:avatar_content_type].blank?
101
+ end
102
+ end
103
+
104
+ context "as a list" do
105
+ setup do
106
+ build_validator :content_type => ["image/png", "image/jpg", "image/jpeg"]
107
+ @dummy.stubs(:avatar_content_type => "image/jpg")
108
+ @validator.validate(@dummy)
109
+ end
110
+
111
+ should "not set an error message" do
112
+ assert @dummy.errors[:avatar_content_type].blank?
113
+ end
114
+ end
115
+ end
116
+
117
+ context "with a disallowed type" do
118
+ context "as a string" do
119
+ setup do
120
+ build_validator :content_type => "image/png"
121
+ @dummy.stubs(:avatar_content_type => "image/jpg")
122
+ @validator.validate(@dummy)
123
+ end
124
+
125
+ should "set a correct default error message" do
126
+ assert @dummy.errors[:avatar_content_type].present?
127
+ assert_includes @dummy.errors[:avatar_content_type], "is invalid"
128
+ end
129
+ end
130
+
131
+ context "as a regexp" do
132
+ setup do
133
+ build_validator :content_type => /^text\/.*/
134
+ @dummy.stubs(:avatar_content_type => "image/jpg")
135
+ @validator.validate(@dummy)
136
+ end
137
+
138
+ should "set a correct default error message" do
139
+ assert @dummy.errors[:avatar_content_type].present?
140
+ assert_includes @dummy.errors[:avatar_content_type], "is invalid"
141
+ end
142
+ end
143
+
144
+ context "with :message option" do
145
+ context "without interpolation" do
146
+ setup do
147
+ build_validator :content_type => "image/png", :message => "should be a PNG image"
148
+ @dummy.stubs(:avatar_content_type => "image/jpg")
149
+ @validator.validate(@dummy)
150
+ end
151
+
152
+ should "set a correct error message" do
153
+ assert_includes @dummy.errors[:avatar_content_type], "should be a PNG image"
154
+ end
155
+ end
156
+
157
+ context "with interpolation" do
158
+ setup do
159
+ build_validator :content_type => "image/png", :message => "should have content type %{types}"
160
+ @dummy.stubs(:avatar_content_type => "image/jpg")
161
+ @validator.validate(@dummy)
162
+ end
163
+
164
+ should "set a correct error message" do
165
+ assert_includes @dummy.errors[:avatar_content_type], "should have content type image/png"
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ context "using the helper" do
172
+ setup do
173
+ Dummy.validates_attachment_content_type :avatar, :content_type => "image/jpg"
174
+ end
175
+
176
+ should "add the validator to the class" do
177
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_content_type }
178
+ end
179
+ end
180
+
181
+ context "given options" do
182
+ should "raise argument error if no required argument was given" do
183
+ assert_raises(ArgumentError) do
184
+ build_validator :message => "Some message"
185
+ end
186
+ end
187
+
188
+ should "not raise arguemnt error if :content_type was given" do
189
+ build_validator :content_type => "image/jpg"
190
+ end
191
+ end
192
+ end