file_validators 2.1.0 → 2.2.0.beta1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 451e981eb130a49dc6c51834bd7ed4dd30652c9a
4
- data.tar.gz: e6b28941ccf9ced999b0e201ad17738efb8bc767
3
+ metadata.gz: 75fbf34dcce7be5b3770f09d4068c00f50f2cd9d
4
+ data.tar.gz: e81f181e641308492a13b1ef3ed5034724d2a7f6
5
5
  SHA512:
6
- metadata.gz: 8c40fa1dae6faf187cc4d3ba77db40691b9bfe58fe9fa99bc88b9fc36477b49ef06bd360ffa8a8af4e2d6f4d56421259b9d9623ab3732a06883b8e64c3f57eb4
7
- data.tar.gz: 4c6aed01f6c15c42c3f917dcdbbbb4c28907ed662a16f823e33d7416005122e159f2504d4991f5fd4b7b20405b332566a1d52137164f224ce5c1504df1c45407
6
+ metadata.gz: abb281ff04de1964a07f19d2ee5fa5ccc51f63827b0ae7bb2628c3ddc36379d16ad48e9aa037d5e16ed18a6ab5d0690b0cc866a263c48ce9a754006c53204d9f
7
+ data.tar.gz: 01417d071f54021f5c8ad73b6a9eb5d35c7b49b29c450037dd2b3b40cbaa13fb9250bf9cfc66931385caab5e2bd934b51987329a736a87645ce6cfa7063bee6c
data/.gitignore CHANGED
@@ -11,3 +11,5 @@ gemfiles/*.lock
11
11
  coverage/
12
12
  /.idea
13
13
  .ruby-version
14
+ .agignore
15
+ tags
data/.travis.yml CHANGED
@@ -7,12 +7,11 @@ rvm:
7
7
  - jruby-9.0.4.0
8
8
 
9
9
  gemfile:
10
+ - gemfiles/activemodel_5.0.gemfile
10
11
  - gemfiles/activemodel_4.2.gemfile
11
12
  - gemfiles/activemodel_4.1.gemfile
12
13
  - gemfiles/activemodel_4.0.gemfile
13
14
  - gemfiles/activemodel_3.2.gemfile
14
- - gemfiles/activemodel_3.1.gemfile
15
- - gemfiles/activemodel_3.0.gemfile
16
15
 
17
16
  matrix:
18
17
  allow_failures:
data/Appraisals CHANGED
@@ -1,17 +1,9 @@
1
- appraise 'activemodel-3.0' do
2
- gem 'activemodel', '3.0.20'
3
- end
4
-
5
- appraise 'activemodel-3.1' do
6
- gem 'activemodel', '3.1.12'
7
- end
8
-
9
1
  appraise 'activemodel-3.2' do
10
- gem 'activemodel', '3.2.18'
2
+ gem 'activemodel', '3.2.22.5'
11
3
  end
12
4
 
13
5
  appraise 'activemodel-4.0' do
14
- gem 'activemodel', '4.0.10'
6
+ gem 'activemodel', '4.0.13'
15
7
  end
16
8
 
17
9
  appraise 'activemodel-4.1' do
@@ -19,5 +11,9 @@ appraise 'activemodel-4.1' do
19
11
  end
20
12
 
21
13
  appraise 'activemodel-4.2' do
22
- gem 'activemodel', '4.2.3'
14
+ gem 'activemodel', '4.2.7.1'
15
+ end
16
+
17
+ appraise 'activemodel-5.0' do
18
+ gem 'activemodel', '5.0.1'
23
19
  end
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # 2.2.0-beta.1
2
+
3
+ * [#17](https://github.com/musaffa/file_validators/pull/17) Now Supports multiple file uploads
4
+ * As activemodel 3.0 and 3.1 doesn't support `added?` method on the Errors class, the support for both of them have been deprecated in this release.
5
+
6
+ # 2.1.0
7
+
8
+ * Use autoload for lazy loading of libraries.
9
+ * Media type spoof valiation is moved to content type detector.
10
+ * `spoofed_file_media_type` message isn't needed anymore.
11
+ * Logger info and warning is added.
data/README.md CHANGED
@@ -12,8 +12,11 @@ Any module that uses ActiveModel, for example ActiveRecord, can use these file v
12
12
 
13
13
  ## Support
14
14
 
15
- * ActiveModel versions: 3 and 4.
16
- * Rails versions: 3 and 4.
15
+ * ActiveModel versions: 3.2, 4 and 5.
16
+ * Rails versions: 3.2, 4 and 5.
17
+
18
+ As of version `2.2`, activemodel 3.0 and 3.1 will no longer be supported.
19
+ For activemodel 3.0 and 3.1, please use file_validators version `<= 2.1`.
17
20
 
18
21
  It has been tested to work with Carrierwave, Paperclip, Dragonfly, Refile etc file uploading solutions.
19
22
  Validations works both before and after uploads.
@@ -253,8 +256,8 @@ $ rake test:unit
253
256
  $ rake test:integration
254
257
 
255
258
  # test different active model versions
256
- $ appraisal install
257
- $ appraisal rake
259
+ $ bundle exec appraisal install
260
+ $ bundle exec appraisal rake
258
261
  ```
259
262
 
260
263
  ## Problems
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
17
17
  s.test_files = s.files.grep(%r{^spec/})
18
18
  s.require_paths = ['lib']
19
19
 
20
- s.add_dependency 'activemodel', '>= 3.0'
20
+ s.add_dependency 'activemodel', '>= 3.2'
21
21
  s.add_dependency 'mime-types', '>= 1.0'
22
22
 
23
23
  s.add_development_dependency 'cocaine', '~> 0.5.4'
@@ -3,6 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
- gem "activemodel", "3.2.18"
6
+ gem "activemodel", "3.2.22.5"
7
7
 
8
8
  gemspec :path => "../"
@@ -3,6 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
- gem "activemodel", "4.0.10"
6
+ gem "activemodel", "4.0.13"
7
7
 
8
8
  gemspec :path => "../"
@@ -3,6 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
- gem "activemodel", "4.2.3"
6
+ gem "activemodel", "4.2.7.1"
7
7
 
8
8
  gemspec :path => "../"
@@ -3,6 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
- gem "activemodel", "3.0.20"
6
+ gem "activemodel", "5.0.1"
7
7
 
8
8
  gemspec :path => "../"
@@ -22,20 +22,23 @@ module FileValidators
22
22
 
23
23
  # content type detection strategy:
24
24
  #
25
- # 1. empty file: returns 'inode/x-empty'
26
- # 2. nonempty file: if the file is not empty then returns the content type using file command
27
- # 3. invalid file: file command raises error and returns 'application/octet-stream'
25
+ # 1. invalid file_path: returns 'application/octet-stream'
26
+ # 2. empty file: returns 'inode/x-empty'
27
+ # 3. valid file: returns the content type using file command
28
+ # 4. valid file but file commoand raises error: returns 'application/octet-stream'
28
29
 
29
30
  def detect
30
- empty_file? ? EMPTY_CONTENT_TYPE : content_type_from_content
31
+ if !File.exist?(file_path)
32
+ DEFAULT_CONTENT_TYPE
33
+ elsif File.zero?(file_path)
34
+ EMPTY_CONTENT_TYPE
35
+ else
36
+ content_type_from_content
37
+ end
31
38
  end
32
39
 
33
40
  private
34
41
 
35
- def empty_file?
36
- File.exists?(file_path) && File.size(file_path) == 0
37
- end
38
-
39
42
  def content_type_from_content
40
43
  content_type = type_from_file_command
41
44
 
@@ -9,15 +9,17 @@ module ActiveModel
9
9
  end
10
10
 
11
11
  def validate_each(record, attribute, value)
12
- value = JSON.parse(value) if value.is_a?(String) && value.present?
13
- unless value.blank?
12
+ values = parse_values(value)
13
+ unless values.empty?
14
14
  mode = option_value(record, :mode)
15
- content_type = get_content_type(value, mode)
16
15
  allowed_types = option_content_types(record, :allow)
17
16
  forbidden_types = option_content_types(record, :exclude)
18
17
 
19
- validate_whitelist(record, attribute, content_type, allowed_types)
20
- validate_blacklist(record, attribute, content_type, forbidden_types)
18
+ values.each do |value|
19
+ content_type = get_content_type(value, mode)
20
+ validate_whitelist(record, attribute, content_type, allowed_types)
21
+ validate_blacklist(record, attribute, content_type, forbidden_types)
22
+ end
21
23
  end
22
24
  end
23
25
 
@@ -35,6 +37,14 @@ module ActiveModel
35
37
 
36
38
  private
37
39
 
40
+ def parse_values(value)
41
+ return [] unless value.present?
42
+
43
+ value = JSON.parse(value) if value.is_a?(String)
44
+
45
+ Array.wrap(value).reject { |value| value.blank? }
46
+ end
47
+
38
48
  def get_file_path(value)
39
49
  if value.try(:path)
40
50
  value.path
@@ -87,7 +97,10 @@ module ActiveModel
87
97
  end
88
98
 
89
99
  def mark_invalid(record, attribute, error, option_types)
90
- record.errors.add attribute, error, options.merge(types: option_types.join(', '))
100
+ error_options = options.merge(types: option_types.join(', '))
101
+ unless record.errors.added?(attribute, error, error_options)
102
+ record.errors.add attribute, error, error_options
103
+ end
91
104
  end
92
105
  end
93
106
 
@@ -13,15 +13,14 @@ module ActiveModel
13
13
  end
14
14
 
15
15
  def validate_each(record, attribute, value)
16
- value = JSON.parse(value) if value.is_a?(String) && value.present?
17
- unless value.blank?
16
+ values = parse_values(value)
17
+ unless values.empty?
18
18
  options.slice(*CHECKS.keys).each do |option, option_value|
19
- value = OpenStruct.new(value) if value.is_a?(Hash)
20
19
  option_value = option_value.call(record) if option_value.is_a?(Proc)
21
- unless valid_size?(value.size, option, option_value)
20
+ if values.any? { |v| not valid_size?(v.size, option, option_value) }
22
21
  record.errors.add(attribute,
23
22
  "file_size_is_#{option}".to_sym,
24
- filtered_options(value).merge!(detect_error_options(option_value)))
23
+ filtered_options(values).merge!(detect_error_options(option_value)))
25
24
  end
26
25
  end
27
26
  end
@@ -39,6 +38,17 @@ module ActiveModel
39
38
 
40
39
  private
41
40
 
41
+ def parse_values(value)
42
+ return [] unless value.present?
43
+
44
+ value = JSON.parse(value) if value.is_a?(String)
45
+ return [] unless value.present?
46
+
47
+ value = OpenStruct.new(value) if value.is_a?(Hash)
48
+
49
+ Array.wrap(value).reject { |value| value.blank? }
50
+ end
51
+
42
52
  def check_options(klass, options)
43
53
  options.each do |option, value|
44
54
  unless value.is_a?(klass) || value.is_a?(Proc)
@@ -1,3 +1,3 @@
1
1
  module FileValidators
2
- VERSION = '2.1.0'
2
+ VERSION = '2.2.0.beta1'
3
3
  end
@@ -379,4 +379,54 @@ describe 'File Content Type integration with ActiveModel' do
379
379
  it { is_expected.to be_valid }
380
380
  end
381
381
  end
382
+
383
+ context 'image data as array' do
384
+ before :all do
385
+ Person.class_eval do
386
+ Person.reset_callbacks(:validate)
387
+ validates :avatar, file_content_type: { allow: 'image/jpeg' }
388
+ end
389
+ end
390
+
391
+ subject { Person.new }
392
+
393
+ context 'for one invalid content type' do
394
+ before {
395
+ subject.avatar = [
396
+ Rack::Test::UploadedFile.new(@sample_text_path, 'text/plain'),
397
+ Rack::Test::UploadedFile.new(@cute_path, 'image/jpeg')
398
+ ]
399
+ }
400
+ it { is_expected.not_to be_valid }
401
+ end
402
+
403
+ context 'for two invalid content types' do
404
+ before {
405
+ subject.avatar = [
406
+ Rack::Test::UploadedFile.new(@sample_text_path, 'text/plain'),
407
+ Rack::Test::UploadedFile.new(@sample_text_path, 'text/plain')
408
+ ]
409
+ }
410
+
411
+ it 'is invalid and adds just one error' do
412
+ expect(subject).not_to be_valid
413
+ expect(subject.errors.count).to eq 1
414
+ end
415
+ end
416
+
417
+ context 'for valid content type' do
418
+ before {
419
+ subject.avatar = [
420
+ Rack::Test::UploadedFile.new(@cute_path, 'image/jpeg'),
421
+ Rack::Test::UploadedFile.new(@cute_path, 'image/jpeg')
422
+ ]
423
+ }
424
+ it { is_expected.to be_valid }
425
+ end
426
+
427
+ context 'empty array' do
428
+ before { subject.avatar = [] }
429
+ it { is_expected.to be_valid }
430
+ end
431
+ end
382
432
  end
@@ -263,4 +263,67 @@ describe 'File Size Validator integration with ActiveModel' do
263
263
  it { is_expected.to be_valid }
264
264
  end
265
265
  end
266
+
267
+ context 'image data as array' do
268
+ before :all do
269
+ Person.class_eval do
270
+ Person.reset_callbacks(:validate)
271
+ validates :avatar, file_size: { greater_than: 20.kilobytes }
272
+ end
273
+ end
274
+
275
+ subject { Person.new }
276
+
277
+ context 'when size of one file is less than the specified size' do
278
+ before {
279
+ subject.avatar = [
280
+ Rack::Test::UploadedFile.new(@cute_path),
281
+ Rack::Test::UploadedFile.new(@chubby_bubble_path)
282
+ ]
283
+ }
284
+ it { is_expected.not_to be_valid }
285
+ end
286
+
287
+ context 'when size of all files is within the specified size' do
288
+ before {
289
+ subject.avatar = [
290
+ Rack::Test::UploadedFile.new(@cute_path),
291
+ Rack::Test::UploadedFile.new(@cute_path)
292
+ ]
293
+ }
294
+
295
+ it 'is invalid and adds just one error' do
296
+ expect(subject).not_to be_valid
297
+ expect(subject.errors.count).to eq 1
298
+ end
299
+ end
300
+
301
+ context 'when size of all files is less than the specified size' do
302
+ before {
303
+ subject.avatar = [
304
+ Rack::Test::UploadedFile.new(@chubby_bubble_path),
305
+ Rack::Test::UploadedFile.new(@chubby_bubble_path)
306
+ ]
307
+ }
308
+
309
+ it { is_expected.to be_valid }
310
+ end
311
+
312
+ context 'one file' do
313
+ context 'when file size is out of range' do
314
+ before { subject.avatar = [Rack::Test::UploadedFile.new(@cute_path)] }
315
+ it { is_expected.not_to be_valid }
316
+ end
317
+
318
+ context 'when file size within range' do
319
+ before { subject.avatar = [Rack::Test::UploadedFile.new(@chubby_bubble_path)] }
320
+ it { is_expected.to be_valid }
321
+ end
322
+ end
323
+
324
+ context 'empty array' do
325
+ before { subject.avatar = [] }
326
+ it { is_expected.to be_valid }
327
+ end
328
+ end
266
329
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  ENV['RAILS_ENV'] ||= 'test'
2
2
 
3
3
  require 'active_support'
4
+ require 'active_support/deprecation'
4
5
  require 'active_support/core_ext'
5
6
  require 'file_validators'
6
7
  require 'rspec'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: file_validators
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ahmad Musaffa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-09 00:00:00.000000000 Z
11
+ date: 2017-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: '3.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '3.0'
26
+ version: '3.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: mime-types
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -119,19 +119,18 @@ files:
119
119
  - ".rspec"
120
120
  - ".travis.yml"
121
121
  - Appraisals
122
- - CHANGELOG.mod
122
+ - CHANGELOG.md
123
123
  - Gemfile
124
124
  - MIT-LICENSE
125
125
  - README.md
126
126
  - README.rdoc
127
127
  - Rakefile
128
128
  - file_validators.gemspec
129
- - gemfiles/activemodel_3.0.gemfile
130
- - gemfiles/activemodel_3.1.gemfile
131
129
  - gemfiles/activemodel_3.2.gemfile
132
130
  - gemfiles/activemodel_4.0.gemfile
133
131
  - gemfiles/activemodel_4.1.gemfile
134
132
  - gemfiles/activemodel_4.2.gemfile
133
+ - gemfiles/activemodel_5.0.gemfile
135
134
  - lib/file_validators.rb
136
135
  - lib/file_validators/locale/en.yml
137
136
  - lib/file_validators/utils/content_type_detector.rb
@@ -170,9 +169,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
170
169
  version: '0'
171
170
  required_rubygems_version: !ruby/object:Gem::Requirement
172
171
  requirements:
173
- - - ">="
172
+ - - ">"
174
173
  - !ruby/object:Gem::Version
175
- version: '0'
174
+ version: 1.3.1
176
175
  requirements: []
177
176
  rubyforge_project:
178
177
  rubygems_version: 2.5.1
data/CHANGELOG.mod DELETED
@@ -1,6 +0,0 @@
1
- # 2.1.0
2
-
3
- * Use autoload for lazy loading of libraries
4
- * Media type spoof valiation is moved to content type detector
5
- * spoofed_file_media_type message isn't needed anymore
6
- * Show logger info and warning
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "appraisal"
6
- gem "activemodel", "3.1.12"
7
-
8
- gemspec :path => "../"