paperclip 2.8.0 → 3.0.2

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.

Files changed (94) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +9 -7
  3. data/Appraisals +6 -12
  4. data/Gemfile +2 -0
  5. data/NEWS +24 -0
  6. data/README.md +53 -21
  7. data/Rakefile +7 -2
  8. data/UPGRADING +14 -0
  9. data/features/basic_integration.feature +8 -8
  10. data/features/rake_tasks.feature +1 -1
  11. data/features/step_definitions/attachment_steps.rb +11 -2
  12. data/features/step_definitions/rails_steps.rb +17 -79
  13. data/features/support/env.rb +3 -0
  14. data/features/support/file_helpers.rb +24 -0
  15. data/features/support/rails.rb +3 -3
  16. data/gemfiles/{rails3_1.gemfile → 3.0.gemfile} +3 -1
  17. data/gemfiles/{rails2.gemfile → 3.1.gemfile} +3 -1
  18. data/gemfiles/{rails3.gemfile → 3.2.gemfile} +3 -1
  19. data/images.rake +21 -0
  20. data/lib/generators/paperclip/paperclip_generator.rb +1 -2
  21. data/lib/paperclip.rb +48 -319
  22. data/lib/paperclip/attachment.rb +33 -81
  23. data/lib/paperclip/attachment_options.rb +0 -1
  24. data/lib/paperclip/callbacks.rb +30 -0
  25. data/lib/paperclip/errors.rb +27 -0
  26. data/lib/paperclip/geometry.rb +6 -4
  27. data/lib/paperclip/glue.rb +15 -0
  28. data/lib/paperclip/helpers.rb +71 -0
  29. data/lib/paperclip/instance_methods.rb +35 -0
  30. data/lib/paperclip/interpolations.rb +2 -2
  31. data/lib/paperclip/io_adapters/attachment_adapter.rb +62 -0
  32. data/lib/paperclip/io_adapters/file_adapter.rb +81 -0
  33. data/lib/paperclip/io_adapters/identity_adapter.rb +12 -0
  34. data/lib/paperclip/io_adapters/nil_adapter.rb +34 -0
  35. data/lib/paperclip/io_adapters/registry.rb +32 -0
  36. data/lib/paperclip/io_adapters/stringio_adapter.rb +64 -0
  37. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +63 -0
  38. data/lib/paperclip/locales/en.yml +17 -0
  39. data/lib/paperclip/logger.rb +21 -0
  40. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +1 -1
  41. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +2 -2
  42. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +7 -7
  43. data/lib/paperclip/processor.rb +32 -17
  44. data/lib/paperclip/railtie.rb +10 -15
  45. data/lib/paperclip/storage/filesystem.rb +5 -14
  46. data/lib/paperclip/storage/fog.rb +2 -21
  47. data/lib/paperclip/storage/s3.rb +12 -29
  48. data/lib/paperclip/tempfile.rb +41 -0
  49. data/lib/paperclip/thumbnail.rb +2 -3
  50. data/lib/paperclip/validators.rb +45 -0
  51. data/lib/paperclip/validators/attachment_content_type_validator.rb +47 -0
  52. data/lib/paperclip/validators/attachment_presence_validator.rb +26 -0
  53. data/lib/paperclip/validators/attachment_size_validator.rb +102 -0
  54. data/lib/paperclip/version.rb +1 -1
  55. data/lib/tasks/paperclip.rake +3 -11
  56. data/paperclip.gemspec +15 -5
  57. data/test/adapter_registry_test.rb +32 -0
  58. data/test/attachment_adapter_test.rb +48 -0
  59. data/test/attachment_options_test.rb +0 -13
  60. data/test/attachment_test.rb +27 -55
  61. data/test/file_adapter_test.rb +43 -0
  62. data/test/generator_test.rb +78 -0
  63. data/test/geometry_test.rb +5 -5
  64. data/test/helper.rb +9 -11
  65. data/test/identity_adapter_test.rb +8 -0
  66. data/test/integration_test.rb +39 -94
  67. data/test/interpolations_test.rb +8 -1
  68. data/test/matchers/validate_attachment_size_matcher_test.rb +16 -2
  69. data/test/nil_adapter_test.rb +25 -0
  70. data/test/paperclip_test.rb +30 -189
  71. data/test/storage/filesystem_test.rb +0 -14
  72. data/test/storage/fog_test.rb +0 -14
  73. data/test/storage/s3_live_test.rb +22 -9
  74. data/test/storage/s3_test.rb +70 -34
  75. data/test/stringio_adapter_test.rb +42 -0
  76. data/test/style_test.rb +10 -16
  77. data/test/thumbnail_test.rb +16 -10
  78. data/test/uploaded_file_adapter_test.rb +98 -0
  79. data/test/validators/attachment_content_type_validator_test.rb +140 -0
  80. data/test/validators/attachment_presence_validator_test.rb +85 -0
  81. data/test/validators/attachment_size_validator_test.rb +207 -0
  82. data/test/validators_test.rb +25 -0
  83. metadata +152 -30
  84. data/gemfiles/rails3_2.gemfile +0 -9
  85. data/generators/paperclip/USAGE +0 -5
  86. data/generators/paperclip/paperclip_generator.rb +0 -27
  87. data/generators/paperclip/templates/paperclip_migration.rb.erb +0 -19
  88. data/init.rb +0 -4
  89. data/lib/paperclip/callback_compatibility.rb +0 -61
  90. data/lib/paperclip/iostream.rb +0 -45
  91. data/lib/paperclip/upfile.rb +0 -64
  92. data/rails/init.rb +0 -2
  93. data/test/iostream_test.rb +0 -71
  94. data/test/upfile_test.rb +0 -53
@@ -0,0 +1,140 @@
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 an allowed type" do
28
+ context "as a string" do
29
+ setup do
30
+ build_validator :content_type => "image/jpg"
31
+ @dummy.stubs(:avatar_content_type => "image/jpg")
32
+ @validator.validate(@dummy)
33
+ end
34
+
35
+ should "not set an error message" do
36
+ assert @dummy.errors[:avatar_content_type].blank?
37
+ end
38
+ end
39
+
40
+ context "as an regexp" do
41
+ setup do
42
+ build_validator :content_type => /^image\/.*/
43
+ @dummy.stubs(:avatar_content_type => "image/jpg")
44
+ @validator.validate(@dummy)
45
+ end
46
+
47
+ should "not set an error message" do
48
+ assert @dummy.errors[:avatar_content_type].blank?
49
+ end
50
+ end
51
+
52
+ context "as a list" do
53
+ setup do
54
+ build_validator :content_type => ["image/png", "image/jpg", "image/jpeg"]
55
+ @dummy.stubs(:avatar_content_type => "image/jpg")
56
+ @validator.validate(@dummy)
57
+ end
58
+
59
+ should "not set an error message" do
60
+ assert @dummy.errors[:avatar_content_type].blank?
61
+ end
62
+ end
63
+ end
64
+
65
+ context "with a disallowed type" do
66
+ context "as a string" do
67
+ setup do
68
+ build_validator :content_type => "image/png"
69
+ @dummy.stubs(:avatar_content_type => "image/jpg")
70
+ @validator.validate(@dummy)
71
+ end
72
+
73
+ should "set a correct default error message" do
74
+ assert @dummy.errors[:avatar_content_type].present?
75
+ assert_includes @dummy.errors[:avatar_content_type], "is invalid"
76
+ end
77
+ end
78
+
79
+ context "as a regexp" do
80
+ setup do
81
+ build_validator :content_type => /^text\/.*/
82
+ @dummy.stubs(:avatar_content_type => "image/jpg")
83
+ @validator.validate(@dummy)
84
+ end
85
+
86
+ should "set a correct default error message" do
87
+ assert @dummy.errors[:avatar_content_type].present?
88
+ assert_includes @dummy.errors[:avatar_content_type], "is invalid"
89
+ end
90
+ end
91
+
92
+ context "with :message option" do
93
+ context "without interpolation" do
94
+ setup do
95
+ build_validator :content_type => "image/png", :message => "should be a PNG image"
96
+ @dummy.stubs(:avatar_content_type => "image/jpg")
97
+ @validator.validate(@dummy)
98
+ end
99
+
100
+ should "set a correct error message" do
101
+ assert_includes @dummy.errors[:avatar_content_type], "should be a PNG image"
102
+ end
103
+ end
104
+
105
+ context "with interpolation" do
106
+ setup do
107
+ build_validator :content_type => "image/png", :message => "should have content type %{types}"
108
+ @dummy.stubs(:avatar_content_type => "image/jpg")
109
+ @validator.validate(@dummy)
110
+ end
111
+
112
+ should "set a correct error message" do
113
+ assert_includes @dummy.errors[:avatar_content_type], "should have content type image/png"
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ context "using the helper" do
120
+ setup do
121
+ Dummy.validates_attachment_content_type :avatar, :content_type => "image/jpg"
122
+ end
123
+
124
+ should "add the validator to the class" do
125
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_content_type }
126
+ end
127
+ end
128
+
129
+ context "given options" do
130
+ should "raise argument error if no required argument was given" do
131
+ assert_raises(ArgumentError) do
132
+ build_validator :message => "Some message"
133
+ end
134
+ end
135
+
136
+ should "not raise arguemnt error if :content_type was given" do
137
+ build_validator :content_type => "image/jpg"
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,85 @@
1
+ require './test/helper'
2
+
3
+ class AttachmentPresenceValidatorTest < 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::AttachmentPresenceValidator.new(options.merge(
11
+ :attributes => :avatar
12
+ ))
13
+ end
14
+
15
+ context "nil attachment" do
16
+ setup do
17
+ @dummy.avatar = nil
18
+ end
19
+
20
+ context "with default options" do
21
+ setup do
22
+ build_validator
23
+ @validator.validate(@dummy)
24
+ end
25
+
26
+ should "add error on the attachment" do
27
+ assert @dummy.errors[:avatar].present?
28
+ end
29
+
30
+ should "not add an error on the file_name attribute" do
31
+ assert @dummy.errors[:avatar_file_name].blank?
32
+ end
33
+ end
34
+
35
+ context "with :if option" do
36
+ context "returning true" do
37
+ setup do
38
+ build_validator :if => true
39
+ @validator.validate(@dummy)
40
+ end
41
+
42
+ should "perform a validation" do
43
+ assert @dummy.errors[:avatar].present?
44
+ end
45
+ end
46
+
47
+ context "returning false" do
48
+ setup do
49
+ build_validator :if => false
50
+ @validator.validate(@dummy)
51
+ end
52
+
53
+ should "perform a validation" do
54
+ assert @dummy.errors[:avatar].present?
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ context "with attachment" do
61
+ setup do
62
+ build_validator
63
+ @dummy.avatar = StringIO.new('.')
64
+ @validator.validate(@dummy)
65
+ end
66
+
67
+ should "not add error on the attachment" do
68
+ assert @dummy.errors[:avatar].blank?
69
+ end
70
+
71
+ should "not add an error on the file_name attribute" do
72
+ assert @dummy.errors[:avatar_file_name].blank?
73
+ end
74
+ end
75
+
76
+ context "using the helper" do
77
+ setup do
78
+ Dummy.validates_attachment_presence :avatar
79
+ end
80
+
81
+ should "add the validator to the class" do
82
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_presence }
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,207 @@
1
+ require './test/helper'
2
+
3
+ class AttachmentSizeValidatorTest < 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::AttachmentSizeValidator.new(options.merge(
11
+ :attributes => :avatar
12
+ ))
13
+ end
14
+
15
+ def self.should_allow_attachment_file_size(size)
16
+ context "when the attachment size is #{size}" do
17
+ should "add error to dummy object" do
18
+ @dummy.stubs(:avatar_file_size).returns(size)
19
+ @validator.validate(@dummy)
20
+ assert @dummy.errors[:avatar_file_size].blank?,
21
+ "Expect an error message on :avatar_file_size, got none."
22
+ end
23
+ end
24
+ end
25
+
26
+ def self.should_not_allow_attachment_file_size(size, options = {})
27
+ context "when the attachment size is #{size}" do
28
+ setup do
29
+ @dummy.stubs(:avatar_file_size).returns(size)
30
+ @validator.validate(@dummy)
31
+ end
32
+
33
+ should "add error to dummy object" do
34
+ assert @dummy.errors[:avatar_file_size].present?,
35
+ "Unexpected error message on :avatar_file_size"
36
+ end
37
+
38
+ if options[:message]
39
+ should "return a correct error message" do
40
+ assert_includes @dummy.errors[:avatar_file_size], options[:message]
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ context "with :in option" do
47
+ context "as a range" do
48
+ setup do
49
+ build_validator :in => (5.kilobytes..10.kilobytes)
50
+ end
51
+
52
+ should_allow_attachment_file_size(7.kilobytes)
53
+ should_not_allow_attachment_file_size(4.kilobytes)
54
+ should_not_allow_attachment_file_size(11.kilobytes)
55
+ end
56
+
57
+ context "as a proc" do
58
+ setup do
59
+ build_validator :in => lambda { |avatar| (5.kilobytes..10.kilobytes) }
60
+ end
61
+
62
+ should_allow_attachment_file_size(7.kilobytes)
63
+ should_not_allow_attachment_file_size(4.kilobytes)
64
+ should_not_allow_attachment_file_size(11.kilobytes)
65
+ end
66
+ end
67
+
68
+ context "with :greater_than option" do
69
+ context "as number" do
70
+ setup do
71
+ build_validator :greater_than => 10.kilobytes
72
+ end
73
+
74
+ should_allow_attachment_file_size 11.kilobytes
75
+ should_not_allow_attachment_file_size 10.kilobytes
76
+ end
77
+
78
+ context "as a proc" do
79
+ setup do
80
+ build_validator :greater_than => lambda { |avatar| 10.kilobytes }
81
+ end
82
+
83
+ should_allow_attachment_file_size 11.kilobytes
84
+ should_not_allow_attachment_file_size 10.kilobytes
85
+ end
86
+ end
87
+
88
+ context "with :less_than option" do
89
+ context "as number" do
90
+ setup do
91
+ build_validator :less_than => 10.kilobytes
92
+ end
93
+
94
+ should_allow_attachment_file_size 9.kilobytes
95
+ should_not_allow_attachment_file_size 10.kilobytes
96
+ end
97
+
98
+ context "as a proc" do
99
+ setup do
100
+ build_validator :less_than => lambda { |avatar| 10.kilobytes }
101
+ end
102
+
103
+ should_allow_attachment_file_size 9.kilobytes
104
+ should_not_allow_attachment_file_size 10.kilobytes
105
+ end
106
+ end
107
+
108
+ context "with :greater_than and :less_than option" do
109
+ context "as numbers" do
110
+ setup do
111
+ build_validator :greater_than => 5.kilobytes,
112
+ :less_than => 10.kilobytes
113
+ end
114
+
115
+ should_allow_attachment_file_size 7.kilobytes
116
+ should_not_allow_attachment_file_size 5.kilobytes
117
+ should_not_allow_attachment_file_size 10.kilobytes
118
+ end
119
+
120
+ context "as a proc" do
121
+ setup do
122
+ build_validator :greater_than => lambda { |avatar| 5.kilobytes },
123
+ :less_than => lambda { |avatar| 10.kilobytes }
124
+ end
125
+
126
+ should_allow_attachment_file_size 7.kilobytes
127
+ should_not_allow_attachment_file_size 5.kilobytes
128
+ should_not_allow_attachment_file_size 10.kilobytes
129
+ end
130
+ end
131
+
132
+ context "with :message option" do
133
+ context "given a range" do
134
+ setup do
135
+ build_validator :in => (5.kilobytes..10.kilobytes),
136
+ :message => "is invalid. (Between %{min} and %{max} please.)"
137
+ end
138
+
139
+ should_not_allow_attachment_file_size 11.kilobytes,
140
+ :message => "is invalid. (Between 5120 Bytes and 10240 Bytes please.)"
141
+ end
142
+
143
+ context "given :less_than and :greater_than" do
144
+ setup do
145
+ build_validator :less_than => 10.kilobytes,
146
+ :greater_than => 5.kilobytes,
147
+ :message => "is invalid. (Between %{min} and %{max} please.)"
148
+ end
149
+
150
+ should_not_allow_attachment_file_size 11.kilobytes,
151
+ :message => "is invalid. (Between 5120 Bytes and 10240 Bytes please.)"
152
+ end
153
+ end
154
+
155
+ context "default error messages" do
156
+ context "given :less_than and :greater_than" do
157
+ setup do
158
+ build_validator :greater_than => 5.kilobytes,
159
+ :less_than => 10.kilobytes
160
+ end
161
+
162
+ should_not_allow_attachment_file_size 11.kilobytes,
163
+ :message => "must be less than 10240 Bytes"
164
+ should_not_allow_attachment_file_size 4.kilobytes,
165
+ :message => "must be greater than 5120 Bytes"
166
+ end
167
+
168
+ context "given a size range" do
169
+ setup do
170
+ build_validator :in => (5.kilobytes..10.kilobytes)
171
+ end
172
+
173
+ should_not_allow_attachment_file_size 11.kilobytes,
174
+ :message => "must be in between 5120 Bytes and 10240 Bytes"
175
+ should_not_allow_attachment_file_size 4.kilobytes,
176
+ :message => "must be in between 5120 Bytes and 10240 Bytes"
177
+ end
178
+ end
179
+
180
+ context "using the helper" do
181
+ setup do
182
+ Dummy.validates_attachment_size :avatar, :in => (5.kilobytes..10.kilobytes)
183
+ end
184
+
185
+ should "add the validator to the class" do
186
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_size }
187
+ end
188
+ end
189
+
190
+ context "given options" do
191
+ should "raise argument error if no required argument was given" do
192
+ assert_raises(ArgumentError) do
193
+ build_validator :message => "Some message"
194
+ end
195
+ end
196
+
197
+ (Paperclip::Validators::AttachmentSizeValidator::AVAILABLE_CHECKS).each do |argument|
198
+ should "not raise arguemnt error if #{argument} was given" do
199
+ build_validator argument => 5.kilobytes
200
+ end
201
+ end
202
+
203
+ should "not raise argument error if :in was given" do
204
+ build_validator :in => (5.kilobytes..10.kilobytes)
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,25 @@
1
+ require './test/helper'
2
+
3
+ class ValidatorsTest < Test::Unit::TestCase
4
+ def setup
5
+ rebuild_model
6
+ end
7
+
8
+ context "using the helper" do
9
+ setup do
10
+ Dummy.validates_attachment :avatar, :presence => true, :content_type => { :content_type => "image/jpg" }, :size => { :in => 0..10.kilobytes }
11
+ end
12
+
13
+ should "add the attachment_presence validator to the class" do
14
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_presence }
15
+ end
16
+
17
+ should "add the attachment_content_type validator to the class" do
18
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_content_type }
19
+ end
20
+
21
+ should "add the attachment_size validator to the class" do
22
+ assert Dummy.validators_on(:avatar).any?{ |validator| validator.kind == :attachment_size }
23
+ end
24
+ end
25
+ end