active_storage_validations 0.8.6 → 0.8.7
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 +4 -4
- data/README.md +87 -0
- data/lib/active_storage_validations/matchers.rb +43 -0
- data/lib/active_storage_validations/matchers/attached_validator_matcher.rb +52 -0
- data/lib/active_storage_validations/matchers/content_type_validator_matcher.rb +95 -0
- data/lib/active_storage_validations/matchers/dimension_validator_matcher.rb +138 -0
- data/lib/active_storage_validations/matchers/size_validator_matcher.rb +87 -0
- data/lib/active_storage_validations/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ee7d6623af014086158c960b7ef7408f4cf7527536f57539765351357160189
|
4
|
+
data.tar.gz: 6819ee596bd09560ca801fade1006bfbe4bf03b820b7ca1b0f84eafe0bb47ac1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1a79fa7e8825320b308f8a689b3b09763072ec8093c5fc1f43e4686dad3dd05b4d345ce8d62149b23865b5c215b90dcdd68b292ea4ccef26456e752a35aad5a
|
7
|
+
data.tar.gz: 69517cf6f0d5a5c64c39416945f06bb31ccb6c5b1c0288d883005184c96e353d44a3f9479767783bd9aae856ee2157a6ffdde48ebdb6abbf23a5f4972fd8f3b0
|
data/README.md
CHANGED
@@ -189,6 +189,92 @@ Very simple example of validation with file attached, content type check and cus
|
|
189
189
|
|
190
190
|
[](https://raw.githubusercontent.com/igorkasyanchuk/active_storage_validations/master/docs/preview.png)
|
191
191
|
|
192
|
+
## Test matchers
|
193
|
+
Provides RSpec-compatible and Minitest-compatible matchers for testing the validators.
|
194
|
+
|
195
|
+
### RSpec
|
196
|
+
|
197
|
+
In spec_helper.rb, you'll need to require the matchers:
|
198
|
+
|
199
|
+
```ruby
|
200
|
+
require 'active_storage_validations/matchers'
|
201
|
+
```
|
202
|
+
|
203
|
+
And _include_ the module:
|
204
|
+
|
205
|
+
```ruby
|
206
|
+
RSpec.configure do |config|
|
207
|
+
config.include ActiveStorageValidations::Matchers
|
208
|
+
end
|
209
|
+
```
|
210
|
+
|
211
|
+
Example (Note that the options are chainable):
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
describe User do
|
215
|
+
it { is_expected.to validate_attached_of(:avatar) }
|
216
|
+
|
217
|
+
it { is_expected.to validate_content_type_of(:avatar).allowing('image/png', 'image/gif') }
|
218
|
+
it { is_expected.to validate_content_type_of(:avatar).rejecting('text/plain', 'text/xml') }
|
219
|
+
|
220
|
+
it { is_expected.to validate_dimensions_of(:avatar).width(250) }
|
221
|
+
it { is_expected.to validate_dimensions_of(:avatar).height(200) }
|
222
|
+
it { is_expected.to validate_dimensions_of(:avatar).width_min(200) }
|
223
|
+
it { is_expected.to validate_dimensions_of(:avatar).width_max(500) }
|
224
|
+
it { is_expected.to validate_dimensions_of(:avatar).height_min(100) }
|
225
|
+
it { is_expected.to validate_dimensions_of(:avatar).height_max(300) }
|
226
|
+
it { is_expected.to validate_dimensions_of(:avatar).width_between(200..500) }
|
227
|
+
it { is_expected.to validate_dimensions_of(:avatar).height_between(100..300) }
|
228
|
+
|
229
|
+
it { is_expected.to validate_size_of(:avatar).less_than(50.kilobytes) }
|
230
|
+
it { is_expected.to validate_size_of(:avatar).less_than_or_equal_to(50.kilobytes) }
|
231
|
+
it { is_expected.to validate_size_of(:avatar).greater_than(1.kilobyte) }
|
232
|
+
it { is_expected.to validate_size_of(:avatar).greater_than_or_equal_to(1.kilobyte) }
|
233
|
+
it { is_expected.to validate_size_of(:avatar).between(100..500.kilobytes) }
|
234
|
+
end
|
235
|
+
```
|
236
|
+
|
237
|
+
### Minitest
|
238
|
+
To use the following syntax, make sure you have the [shoulda-context](https://github.com/thoughtbot/shoulda-context) gem up and running. To make use of the matchers you need to require the matchers:
|
239
|
+
|
240
|
+
```ruby
|
241
|
+
require 'active_storage_validations/matchers'
|
242
|
+
```
|
243
|
+
|
244
|
+
And _extend_ the module:
|
245
|
+
|
246
|
+
```bash
|
247
|
+
class ActiveSupport::TestCase
|
248
|
+
extend ActiveStorageValidations::Matchers
|
249
|
+
end
|
250
|
+
```
|
251
|
+
|
252
|
+
Example (Note that the options are chainable):
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
class UserTest < ActiveSupport::TestCase
|
256
|
+
should validate_attached_of(:avatar)
|
257
|
+
|
258
|
+
should validate_content_type_of(:avatar).allowing('image/png', 'image/gif')
|
259
|
+
should validate_content_type_of(:avatar).rejecting('text/plain', 'text/xml')
|
260
|
+
|
261
|
+
should validate_dimensions_of(:avatar).width(250)
|
262
|
+
should validate_dimensions_of(:avatar).height(200)
|
263
|
+
should validate_dimensions_of(:avatar).width_min(200)
|
264
|
+
should validate_dimensions_of(:avatar).width_max(500)
|
265
|
+
should validate_dimensions_of(:avatar).height_min(100)
|
266
|
+
should validate_dimensions_of(:avatar).height_max(300)
|
267
|
+
should validate_dimensions_of(:avatar).width_between(200..500)
|
268
|
+
should validate_dimensions_of(:avatar).height_between(100..300)
|
269
|
+
|
270
|
+
should validate_size_of(:avatar).less_than(50.kilobytes)
|
271
|
+
should validate_size_of(:avatar).less_than_or_equal_to(50.kilobytes)
|
272
|
+
should validate_size_of(:avatar).greater_than(1.kilobyte)
|
273
|
+
should validate_size_of(:avatar).greater_than_or_equal_to(1.kilobyte)
|
274
|
+
should validate_size_of(:avatar).between(100..500.kilobytes)
|
275
|
+
end
|
276
|
+
```
|
277
|
+
|
192
278
|
## Todo
|
193
279
|
|
194
280
|
* verify with remote storages (s3, etc)
|
@@ -240,6 +326,7 @@ You are welcome to contribute.
|
|
240
326
|
- https://github.com/UICJohn
|
241
327
|
- https://github.com/giovannibonetti
|
242
328
|
- https://github.com/dlepage
|
329
|
+
- https://github.com/StefSchenkelaars
|
243
330
|
|
244
331
|
## License
|
245
332
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_storage_validations/matchers/attached_validator_matcher'
|
4
|
+
require 'active_storage_validations/matchers/content_type_validator_matcher'
|
5
|
+
require 'active_storage_validations/matchers/dimension_validator_matcher'
|
6
|
+
require 'active_storage_validations/matchers/size_validator_matcher'
|
7
|
+
|
8
|
+
module ActiveStorageValidations
|
9
|
+
module Matchers
|
10
|
+
# Helper to stub a method with either RSpec or Minitest (whatever is available)
|
11
|
+
def self.stub_method(object, method, result)
|
12
|
+
if defined?(Minitest::Mock)
|
13
|
+
object.stub(method, result) do
|
14
|
+
yield
|
15
|
+
end
|
16
|
+
elsif defined?(RSpec::Mocks)
|
17
|
+
RSpec::Mocks.allow_message(object, method) { result }
|
18
|
+
yield
|
19
|
+
else
|
20
|
+
raise 'Need either Minitest::Mock or RSpec::Mocks to run this validator matcher'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.mock_metadata(attachment, width, height)
|
25
|
+
if Rails::VERSION::MAJOR >= 6
|
26
|
+
# Mock the Metadata class for rails 6
|
27
|
+
mock = OpenStruct.new(metadata: { width: width, height: height })
|
28
|
+
stub_method(ActiveStorageValidations::Metadata, :new, mock) do
|
29
|
+
yield
|
30
|
+
end
|
31
|
+
else
|
32
|
+
# Stub the metadata analysis for rails 5
|
33
|
+
stub_method(attachment, :analyze, true) do
|
34
|
+
stub_method(attachment, :analyzed?, true) do
|
35
|
+
stub_method(attachment, :metadata, { width: width, height: height }) do
|
36
|
+
yield
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveStorageValidations
|
4
|
+
module Matchers
|
5
|
+
def validate_attached_of(name)
|
6
|
+
AttachedValidatorMatcher.new(name)
|
7
|
+
end
|
8
|
+
|
9
|
+
class AttachedValidatorMatcher
|
10
|
+
def initialize(attribute_name)
|
11
|
+
@attribute_name = attribute_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
"validate #{@attribute_name} must be attached"
|
16
|
+
end
|
17
|
+
|
18
|
+
def matches?(subject)
|
19
|
+
@subject = subject.is_a?(Class) ? subject : subject.class
|
20
|
+
|
21
|
+
invalid_when_not_attached && valid_when_attached
|
22
|
+
end
|
23
|
+
|
24
|
+
def failure_message
|
25
|
+
"is expected to validate attached of #{@attribute_name}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def failure_message_when_negated
|
29
|
+
"is expected to not validate attached of #{@attribute_name}"
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def valid_when_attached
|
35
|
+
instance = @subject.new
|
36
|
+
instance.public_send(@attribute_name).attach(attachable)
|
37
|
+
instance.validate
|
38
|
+
instance.errors.details[@attribute_name].exclude?(error: :blank)
|
39
|
+
end
|
40
|
+
|
41
|
+
def invalid_when_not_attached
|
42
|
+
instance = @subject.new
|
43
|
+
instance.validate
|
44
|
+
instance.errors.details[@attribute_name].include?(error: :blank)
|
45
|
+
end
|
46
|
+
|
47
|
+
def attachable
|
48
|
+
{ io: Tempfile.new('.'), filename: 'dummy.txt', content_type: 'text/plain' }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Big thank you to the paperclip validation matchers:
|
4
|
+
# https://github.com/thoughtbot/paperclip/blob/v6.1.0/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb
|
5
|
+
module ActiveStorageValidations
|
6
|
+
module Matchers
|
7
|
+
def validate_content_type_of(name)
|
8
|
+
ContentTypeValidatorMatcher.new(name)
|
9
|
+
end
|
10
|
+
|
11
|
+
class ContentTypeValidatorMatcher
|
12
|
+
def initialize(attribute_name)
|
13
|
+
@attribute_name = attribute_name
|
14
|
+
end
|
15
|
+
|
16
|
+
def description
|
17
|
+
"validate the content types allowed on attachment #{@attribute_name}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def allowing(*types)
|
21
|
+
@allowed_types = types.flatten
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def rejecting(*types)
|
26
|
+
@rejected_types = types.flatten
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def matches?(subject)
|
31
|
+
@subject = subject.is_a?(Class) ? subject.new : subject
|
32
|
+
allowed_types_allowed? && rejected_types_rejected?
|
33
|
+
end
|
34
|
+
|
35
|
+
def failure_message
|
36
|
+
<<~MESSAGE
|
37
|
+
Expected #{@attribute_name}
|
38
|
+
|
39
|
+
Accept content types: #{allowed_types.join(", ")}
|
40
|
+
#{accepted_types_and_failures}
|
41
|
+
|
42
|
+
Reject content types: #{rejected_types.join(", ")}
|
43
|
+
#{rejected_types_and_failures}
|
44
|
+
MESSAGE
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
def allowed_types
|
50
|
+
@allowed_types || []
|
51
|
+
end
|
52
|
+
|
53
|
+
def rejected_types
|
54
|
+
@rejected_types || (Mime::LOOKUP.keys - allowed_types)
|
55
|
+
end
|
56
|
+
|
57
|
+
def allowed_types_allowed?
|
58
|
+
@missing_allowed_types ||= allowed_types.reject { |type| type_allowed?(type) }
|
59
|
+
@missing_allowed_types.none?
|
60
|
+
end
|
61
|
+
|
62
|
+
def rejected_types_rejected?
|
63
|
+
@missing_rejected_types ||= rejected_types.select { |type| type_allowed?(type) }
|
64
|
+
@missing_rejected_types.none?
|
65
|
+
end
|
66
|
+
|
67
|
+
def accepted_types_and_failures
|
68
|
+
if @missing_allowed_types.present?
|
69
|
+
"#{@missing_allowed_types.join(", ")} were rejected."
|
70
|
+
else
|
71
|
+
"All were accepted successfully."
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def rejected_types_and_failures
|
76
|
+
if @missing_rejected_types.present?
|
77
|
+
"#{@missing_rejected_types.join(", ")} were accepted."
|
78
|
+
else
|
79
|
+
"All were rejected successfully."
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def type_allowed?(type)
|
84
|
+
@subject.public_send(@attribute_name).attach(attachment_for(type))
|
85
|
+
@subject.validate
|
86
|
+
@subject.errors.details[@attribute_name].all? { |error| error[:error] != :content_type_invalid }
|
87
|
+
end
|
88
|
+
|
89
|
+
def attachment_for(type)
|
90
|
+
suffix = type.to_s.split('/').last
|
91
|
+
{ io: Tempfile.new('.'), filename: "test.#{suffix}", content_type: type }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveStorageValidations
|
4
|
+
module Matchers
|
5
|
+
def validate_dimensions_of(name)
|
6
|
+
DimensionValidatorMatcher.new(name)
|
7
|
+
end
|
8
|
+
|
9
|
+
class DimensionValidatorMatcher
|
10
|
+
def initialize(attribute_name)
|
11
|
+
@attribute_name = attribute_name
|
12
|
+
@width_min = @width_max = @height_min = @height_max = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def description
|
16
|
+
"validate image dimensions of #{@attribute_name}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def width_min(width)
|
20
|
+
@width_min = width
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def width_max(width)
|
25
|
+
@width_max = width
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def width(width)
|
30
|
+
@width_min = @width_max = width
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def height_min(height)
|
35
|
+
@height_min = height
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def height_max(height)
|
40
|
+
@height_max = height
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def width_between(range)
|
45
|
+
@width_min, @width_max = range.first, range.last
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
def height_between(range)
|
50
|
+
@height_min, @height_max = range.first, range.last
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def height(height)
|
55
|
+
@height_min = @height_max = height
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
def matches?(subject)
|
60
|
+
@subject = subject.is_a?(Class) ? subject.new : subject
|
61
|
+
width_smaller_than_min? && width_larger_than_min? && width_smaller_than_max? && width_larger_than_max? && width_equals? &&
|
62
|
+
height_smaller_than_min? && height_larger_than_min? && height_smaller_than_max? && height_larger_than_max? && height_equals?
|
63
|
+
end
|
64
|
+
|
65
|
+
def failure_message
|
66
|
+
<<~MESSAGE
|
67
|
+
is expected to validate dimensions of #{@attribute_name}
|
68
|
+
width between #{@width_min} and #{@width_max}
|
69
|
+
height between #{@height_min} and #{@height_max}
|
70
|
+
MESSAGE
|
71
|
+
end
|
72
|
+
|
73
|
+
protected
|
74
|
+
|
75
|
+
def valid_width
|
76
|
+
((@width_min || 0) + (@width_max || 2000)) / 2
|
77
|
+
end
|
78
|
+
|
79
|
+
def valid_height
|
80
|
+
((@height_min || 0) + (@height_max || 2000)) / 2
|
81
|
+
end
|
82
|
+
|
83
|
+
def width_smaller_than_min?
|
84
|
+
@width_min.nil? || !passes_validation_with_dimensions(@width_min - 1, valid_height, 'width')
|
85
|
+
end
|
86
|
+
|
87
|
+
def width_larger_than_min?
|
88
|
+
@width_min.nil? || @width_min == @width_max || passes_validation_with_dimensions(@width_min + 1, valid_height, 'width')
|
89
|
+
end
|
90
|
+
|
91
|
+
def width_smaller_than_max?
|
92
|
+
@width_max.nil? || @width_min == @width_max || passes_validation_with_dimensions(@width_max - 1, valid_height, 'width')
|
93
|
+
end
|
94
|
+
|
95
|
+
def width_larger_than_max?
|
96
|
+
@width_max.nil? || !passes_validation_with_dimensions(@width_max + 1, valid_height, 'width')
|
97
|
+
end
|
98
|
+
|
99
|
+
def width_equals?
|
100
|
+
@width_min.nil? || @width_min != @width_max || passes_validation_with_dimensions(@width_min, valid_height, 'width')
|
101
|
+
end
|
102
|
+
|
103
|
+
def height_smaller_than_min?
|
104
|
+
@height_min.nil? || !passes_validation_with_dimensions(valid_width, @height_min - 1, 'height')
|
105
|
+
end
|
106
|
+
|
107
|
+
def height_larger_than_min?
|
108
|
+
@height_min.nil? || @height_min == @height_max || passes_validation_with_dimensions(valid_width, @height_min + 1, 'height')
|
109
|
+
end
|
110
|
+
|
111
|
+
def height_smaller_than_max?
|
112
|
+
@height_max.nil? || @height_min == @height_max || passes_validation_with_dimensions(valid_width, @height_max - 1, 'height')
|
113
|
+
end
|
114
|
+
|
115
|
+
def height_larger_than_max?
|
116
|
+
@height_max.nil? || !passes_validation_with_dimensions(valid_width, @height_max + 1, 'height')
|
117
|
+
end
|
118
|
+
|
119
|
+
def height_equals?
|
120
|
+
@height_min.nil? || @height_min != @height_max || passes_validation_with_dimensions(valid_width, @height_min, 'height')
|
121
|
+
end
|
122
|
+
|
123
|
+
def passes_validation_with_dimensions(width, height, check)
|
124
|
+
@subject.public_send(@attribute_name).attach attachment_for(width, height)
|
125
|
+
|
126
|
+
attachment = @subject.public_send(@attribute_name)
|
127
|
+
Matchers.mock_metadata(attachment, width, height) do
|
128
|
+
@subject.validate
|
129
|
+
@subject.errors.details[@attribute_name].all? { |error| error[:error].to_s.exclude?("dimension_#{check}") }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def attachment_for(width, height)
|
134
|
+
{ io: Tempfile.new('Hello world!'), filename: 'test.png', content_type: 'image/png' }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Big thank you to the paperclip validation matchers:
|
4
|
+
# https://github.com/thoughtbot/paperclip/blob/v6.1.0/lib/paperclip/matchers/validate_attachment_size_matcher.rb
|
5
|
+
module ActiveStorageValidations
|
6
|
+
module Matchers
|
7
|
+
def validate_size_of(name)
|
8
|
+
SizeValidatorMatcher.new(name)
|
9
|
+
end
|
10
|
+
|
11
|
+
class SizeValidatorMatcher
|
12
|
+
def initialize(attribute_name)
|
13
|
+
@attribute_name = attribute_name
|
14
|
+
@low = @high = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def description
|
18
|
+
"validate file size of #{@attribute_name}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def less_than(size)
|
22
|
+
@high = size - 1.byte
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def less_than_or_equal_to(size)
|
27
|
+
@high = size
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def greater_than(size)
|
32
|
+
@low = size + 1.byte
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def greater_than_or_equal_to(size)
|
37
|
+
@low = size
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def between(range)
|
42
|
+
@low, @high = range.first, range.last
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def matches?(subject)
|
47
|
+
@subject = subject.is_a?(Class) ? subject.new : subject
|
48
|
+
lower_than_low? && higher_than_low? && lower_than_high? && higher_than_high?
|
49
|
+
end
|
50
|
+
|
51
|
+
def failure_message
|
52
|
+
"is expected to validate file size of #{@attribute_name} to be between #{@low} and #{@high} bytes"
|
53
|
+
end
|
54
|
+
|
55
|
+
def failure_message_when_negated
|
56
|
+
"is expected to not validate file size of #{@attribute_name} to be between #{@low} and #{@high} bytes"
|
57
|
+
end
|
58
|
+
|
59
|
+
protected
|
60
|
+
|
61
|
+
def lower_than_low?
|
62
|
+
@low.nil? || !passes_validation_with_size(@low - 1)
|
63
|
+
end
|
64
|
+
|
65
|
+
def higher_than_low?
|
66
|
+
@low.nil? || passes_validation_with_size(@low + 1)
|
67
|
+
end
|
68
|
+
|
69
|
+
def lower_than_high?
|
70
|
+
@high.nil? || @high == Float::INFINITY || passes_validation_with_size(@high - 1)
|
71
|
+
end
|
72
|
+
|
73
|
+
def higher_than_high?
|
74
|
+
@high.nil? || @high == Float::INFINITY || !passes_validation_with_size(@high + 1)
|
75
|
+
end
|
76
|
+
|
77
|
+
def passes_validation_with_size(new_size)
|
78
|
+
io = Tempfile.new('Hello world!')
|
79
|
+
Matchers.stub_method(io, :size, new_size) do
|
80
|
+
@subject.public_send(@attribute_name).attach(io: io, filename: 'test.png', content_type: 'image/pg')
|
81
|
+
@subject.validate
|
82
|
+
@subject.errors.details[@attribute_name].all? { |error| error[:error] != :file_size_out_of_range }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_storage_validations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Kasyanchuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-01-
|
11
|
+
date: 2020-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -117,6 +117,11 @@ files:
|
|
117
117
|
- lib/active_storage_validations/dimension_validator.rb
|
118
118
|
- lib/active_storage_validations/engine.rb
|
119
119
|
- lib/active_storage_validations/limit_validator.rb
|
120
|
+
- lib/active_storage_validations/matchers.rb
|
121
|
+
- lib/active_storage_validations/matchers/attached_validator_matcher.rb
|
122
|
+
- lib/active_storage_validations/matchers/content_type_validator_matcher.rb
|
123
|
+
- lib/active_storage_validations/matchers/dimension_validator_matcher.rb
|
124
|
+
- lib/active_storage_validations/matchers/size_validator_matcher.rb
|
120
125
|
- lib/active_storage_validations/metadata.rb
|
121
126
|
- lib/active_storage_validations/railtie.rb
|
122
127
|
- lib/active_storage_validations/size_validator.rb
|