Skip to content

Commit

Permalink
[Matcher] Bugfix when several validator are used on the same attribute (
Browse files Browse the repository at this point in the history
  • Loading branch information
Mth0158 committed Jan 2, 2024
1 parent 812d805 commit b9ac7bd
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 8 deletions.
10 changes: 7 additions & 3 deletions lib/active_storage_validations/matchers/concerns/validatable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def is_valid?
def available_errors
[
*validator_class::ERROR_TYPES,
*error_from_custom_message
*errors_from_custom_messages
].compact
end

Expand All @@ -40,8 +40,12 @@ def attribute_validator
end
end

def error_from_custom_message
attribute_validator.options[:message]
def errors_from_custom_messages
# TODO: Refacto attribute_validator with this logic and make sure it
# works for contextable
@subject.class.validators_on(@attribute_name).filter_map do |validator|
validator.options[:message] if validator.class == validator_class
end
end
end
end
Expand Down
6 changes: 6 additions & 0 deletions test/dummy/app/models/aspect_ratio/matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#

class AspectRatio::Matcher < ApplicationRecord
include Validatable

ActiveStorageValidations::AspectRatioValidator::NAMED_ASPECT_RATIOS.each do |aspect_ratio|
has_one_attached :"allowing_one_#{aspect_ratio}"
validates :"allowing_one_#{aspect_ratio}", aspect_ratio: aspect_ratio
Expand All @@ -32,6 +34,10 @@ class AspectRatio::Matcher < ApplicationRecord
has_one_attached :as_instance
validates :as_instance, aspect_ratio: :square

has_one_attached :validatable_different_error_messages
validates :validatable_different_error_messages, aspect_ratio: { with: :portrait, message: 'Custom message 1' }, if: :title_is_quo_vadis?
validates :validatable_different_error_messages, aspect_ratio: { with: :square, message: 'Custom message 2' }, if: :title_is_american_psycho?

has_one_attached :failure_message
validates :failure_message, aspect_ratio: :square
has_one_attached :failure_message_when_negated
Expand Down
6 changes: 6 additions & 0 deletions test/dummy/app/models/attached/matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#

class Attached::Matcher < ApplicationRecord
include Validatable

has_one_attached :required
validates :required, attached: true

Expand All @@ -25,6 +27,10 @@ class Attached::Matcher < ApplicationRecord
has_one_attached :as_instance
validates :as_instance, attached: true

has_one_attached :validatable_different_error_messages
validates :validatable_different_error_messages, attached: { message: 'Custom message 1' }, if: :title_is_quo_vadis?
validates :validatable_different_error_messages, attached: { message: 'Custom message 2' }, if: :title_is_american_psycho?

has_one_attached :failure_message
validates :failure_message, attached: true
has_one_attached :failure_message_when_negated
Expand Down
17 changes: 17 additions & 0 deletions test/dummy/app/models/concerns/validatable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module Validatable
extend ActiveSupport::Concern

private

def title_is_quo_vadis?
return false if self.title.blank?

self.title == "Quo vadis"
end

def title_is_american_psycho?
return false if self.title.blank?

self.title == "American Psycho"
end
end
6 changes: 6 additions & 0 deletions test/dummy/app/models/content_type/matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#

class ContentType::Matcher < ApplicationRecord
include Validatable

has_one_attached :allowing_one
validates :allowing_one, content_type: :png
has_one_attached :allowing_several
Expand All @@ -32,6 +34,10 @@ class ContentType::Matcher < ApplicationRecord
has_one_attached :as_instance
validates :as_instance, content_type: :png

has_one_attached :validatable_different_error_messages
validates :validatable_different_error_messages, content_type: { with: :pdf, message: 'Custom message 1' }, if: :title_is_quo_vadis?
validates :validatable_different_error_messages, content_type: { with: :png, message: 'Custom message 2' }, if: :title_is_american_psycho?

has_one_attached :failure_message
validates :failure_message, content_type: :png
has_one_attached :failure_message_when_negated
Expand Down
6 changes: 6 additions & 0 deletions test/dummy/app/models/dimension/matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#

class Dimension::Matcher < ApplicationRecord
include Validatable

%i(width height).each do |dimension|
has_one_attached :"#{dimension}_exact"
has_one_attached :"#{dimension}_in"
Expand Down Expand Up @@ -57,6 +59,10 @@ class Dimension::Matcher < ApplicationRecord
has_one_attached :as_instance
validates :as_instance, dimension: { width: 150, height: 150 }

has_one_attached :validatable_different_error_messages
validates :validatable_different_error_messages, dimension: { width: 150, message: 'Custom message 1' }, if: :title_is_quo_vadis?
validates :validatable_different_error_messages, dimension: { width: 150, message: 'Custom message 2' }, if: :title_is_american_psycho?

has_one_attached :failure_message
validates :failure_message, dimension: { width: 150, height: 150 }
has_one_attached :failure_message_when_negated
Expand Down
6 changes: 6 additions & 0 deletions test/dummy/app/models/size/matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#

class Size::Matcher < ApplicationRecord
include Validatable

has_one_attached :less_than
has_one_attached :less_than_or_equal_to
has_one_attached :greater_than
Expand Down Expand Up @@ -47,6 +49,10 @@ class Size::Matcher < ApplicationRecord
has_one_attached :as_instance
validates :as_instance, size: { less_than_or_equal_to: 5.megabytes }

has_one_attached :validatable_different_error_messages
validates :validatable_different_error_messages, size: { less_than: 20.megabytes, message: 'Custom message 1' }, if: :title_is_quo_vadis?
validates :validatable_different_error_messages, size: { less_than: 10.megabytes, message: 'Custom message 2' }, if: :title_is_american_psycho?

has_one_attached :failure_message
validates :failure_message, size: { less_than_or_equal_to: 5.megabytes }
has_one_attached :failure_message_when_negated
Expand Down
4 changes: 3 additions & 1 deletion test/matchers/aspect_ratio_validator_matcher_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require 'test_helper'
require 'matchers/shared_examples/checks_if_is_a_valid_active_storage_attribute'
require 'matchers/shared_examples/checks_if_is_valid'
require 'matchers/shared_examples/has_valid_rspec_message_methods'
require 'matchers/shared_examples/works_with_allow_blank'
require 'matchers/shared_examples/works_with_both_instance_and_class'
Expand All @@ -11,8 +12,9 @@
describe ActiveStorageValidations::Matchers::AspectRatioValidatorMatcher do
include MatcherHelpers

include HasValidRspecMessageMethods
include ChecksIfIsAValidActiveStorageAttribute
include ChecksIfIsValid
include HasValidRspecMessageMethods
include WorksWithBothInstanceAndClass

let(:matcher) { ActiveStorageValidations::Matchers::AspectRatioValidatorMatcher.new(model_attribute) }
Expand Down
4 changes: 3 additions & 1 deletion test/matchers/attached_validator_matcher_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require 'test_helper'
require 'matchers/shared_examples/checks_if_is_a_valid_active_storage_attribute'
require 'matchers/shared_examples/checks_if_is_valid'
require 'matchers/shared_examples/has_valid_rspec_message_methods'
require 'matchers/shared_examples/works_with_both_instance_and_class'
require 'matchers/shared_examples/works_with_context'
Expand All @@ -10,8 +11,9 @@
describe ActiveStorageValidations::Matchers::AttachedValidatorMatcher do
include MatcherHelpers

include HasValidRspecMessageMethods
include ChecksIfIsAValidActiveStorageAttribute
include ChecksIfIsValid
include HasValidRspecMessageMethods
include WorksWithBothInstanceAndClass

let(:matcher) { ActiveStorageValidations::Matchers::AttachedValidatorMatcher.new(model_attribute) }
Expand Down
4 changes: 3 additions & 1 deletion test/matchers/content_type_validator_matcher_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require 'test_helper'
require 'matchers/shared_examples/checks_if_is_a_valid_active_storage_attribute'
require 'matchers/shared_examples/checks_if_is_valid'
require 'matchers/shared_examples/has_valid_rspec_message_methods'
require 'matchers/shared_examples/works_with_allow_blank'
require 'matchers/shared_examples/works_with_both_instance_and_class'
Expand All @@ -11,8 +12,9 @@
describe ActiveStorageValidations::Matchers::ContentTypeValidatorMatcher do
include MatcherHelpers

include HasValidRspecMessageMethods
include ChecksIfIsAValidActiveStorageAttribute
include ChecksIfIsValid
include HasValidRspecMessageMethods
include WorksWithBothInstanceAndClass

let(:matcher) { ActiveStorageValidations::Matchers::ContentTypeValidatorMatcher.new(model_attribute) }
Expand Down
4 changes: 3 additions & 1 deletion test/matchers/dimension_validator_matcher_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require 'test_helper'
require 'matchers/shared_examples/checks_if_is_a_valid_active_storage_attribute'
require 'matchers/shared_examples/checks_if_is_valid'
require 'matchers/shared_examples/has_valid_rspec_message_methods'
require 'matchers/shared_examples/works_with_allow_blank'
require 'matchers/shared_examples/works_with_both_instance_and_class'
Expand Down Expand Up @@ -141,8 +142,9 @@ module OnlyMatchWhenExactValues
describe ActiveStorageValidations::Matchers::DimensionValidatorMatcher do
include MatcherHelpers

include HasValidRspecMessageMethods
include ChecksIfIsAValidActiveStorageAttribute
include ChecksIfIsValid
include HasValidRspecMessageMethods
include WorksWithBothInstanceAndClass

let(:matcher) { ActiveStorageValidations::Matchers::DimensionValidatorMatcher.new(model_attribute) }
Expand Down
28 changes: 28 additions & 0 deletions test/matchers/shared_examples/checks_if_is_valid.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module ChecksIfIsValid
extend ActiveSupport::Concern

included do
describe 'Edge cases' do
describe 'when the validator is used several times on the same attributes' do
describe 'and is provided with different error messages' do
before do
case validator_sym
when :aspect_ratio then matcher.allowing(:square)
when :attached then matcher
when :content_type then matcher.rejecting('image/jpg')
when :dimension then matcher.width(150)
when :size then matcher.less_than(10.megabytes)
end
end

subject { matcher }

let(:model_attribute) { :validatable_different_error_messages }
let(:instance) { klass.new(title: "American Psycho") }

it { is_expected_to_match_for(instance) }
end
end
end
end
end
4 changes: 3 additions & 1 deletion test/matchers/size_validator_matcher_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require 'test_helper'
require 'matchers/shared_examples/checks_if_is_a_valid_active_storage_attribute'
require 'matchers/shared_examples/checks_if_is_valid'
require 'matchers/shared_examples/has_valid_rspec_message_methods'
require 'matchers/shared_examples/works_with_allow_blank'
require 'matchers/shared_examples/works_with_both_instance_and_class'
Expand Down Expand Up @@ -61,8 +62,9 @@ module OnlyMatchWhenExactValue
describe ActiveStorageValidations::Matchers::SizeValidatorMatcher do
include MatcherHelpers

include HasValidRspecMessageMethods
include ChecksIfIsAValidActiveStorageAttribute
include ChecksIfIsValid
include HasValidRspecMessageMethods
include WorksWithBothInstanceAndClass

let(:matcher) { ActiveStorageValidations::Matchers::SizeValidatorMatcher.new(model_attribute) }
Expand Down

0 comments on commit b9ac7bd

Please sign in to comment.