From 9b7b29a217c8a937a673d77c9e7a5822b3323486 Mon Sep 17 00:00:00 2001 From: Mathieu EUSTACHY Date: Mon, 30 Dec 2024 18:15:58 +0100 Subject: [PATCH] [Matcher] Add support for symbol content_types for content_type matcher options (#315) --- .../matchers/content_type_validator_matcher.rb | 8 ++++++-- test/dummy/app/models/content_type/matcher.rb | 2 ++ test/matchers/content_type_validator_matcher_test.rb | 11 +++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/active_storage_validations/matchers/content_type_validator_matcher.rb b/lib/active_storage_validations/matchers/content_type_validator_matcher.rb index ff416cbd..e012a95b 100644 --- a/lib/active_storage_validations/matchers/content_type_validator_matcher.rb +++ b/lib/active_storage_validations/matchers/content_type_validator_matcher.rb @@ -46,12 +46,12 @@ def failure_message end def allowing(*content_types) - @allowed_content_types = content_types.flatten + @allowed_content_types = content_types.map { |content_type| normalize_content_type(content_type) }.flatten self end def rejecting(*content_types) - @rejected_content_types = content_types.flatten + @rejected_content_types = content_types.map { |content_type| normalize_content_type(content_type) }.flatten self end @@ -88,6 +88,10 @@ def pluralize(types) end end + def normalize_content_type(content_type) + Marcel::MimeType.for(declared_type: content_type.to_s, extension: content_type.to_s) + end + def all_allowed_content_types_allowed? @allowed_content_types_not_allowed ||= @allowed_content_types.reject { |type| type_allowed?(type) } @allowed_content_types_not_allowed.empty? diff --git a/test/dummy/app/models/content_type/matcher.rb b/test/dummy/app/models/content_type/matcher.rb index 9fc75cd0..afaec527 100644 --- a/test/dummy/app/models/content_type/matcher.rb +++ b/test/dummy/app/models/content_type/matcher.rb @@ -23,6 +23,8 @@ class ContentType::Matcher < ApplicationRecord has_one_attached :allowing_several_through_regex validates :allowing_several_through_regex, content_type: [/\Aimage\/.*\z/] + has_one_attached :allowing_symbol + validates :allowing_symbol, content_type: :png has_one_attached :allowing_sneaky_edge_cases validates :allowing_sneaky_edge_cases, content_type: ["image/svg+xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"] diff --git a/test/matchers/content_type_validator_matcher_test.rb b/test/matchers/content_type_validator_matcher_test.rb index dee0d222..6b44fc4b 100644 --- a/test/matchers/content_type_validator_matcher_test.rb +++ b/test/matchers/content_type_validator_matcher_test.rb @@ -117,6 +117,17 @@ end describe 'Edge cases' do + describe "when the passed content_type is a symbol (e.g. :png)" do + let(:model_attribute) { :allowing_symbol } + let(:allowed_type) { :png } + + describe 'when provided with the exact allowed type' do + subject { matcher.allowing(allowed_type) } + + it { is_expected_to_match_for(klass) } + end + end + describe "when the content_type specifier (e.g. 'svg+xml') is not strictly equal to the file extension (e.g. '.svg')" do let(:model_attribute) { :allowing_sneaky_edge_cases } let(:allowed_types) { ["image/svg+xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"] }