From ef50a690739d39d94e573ad4a4f7826e29126422 Mon Sep 17 00:00:00 2001 From: Mathieu EUSTACHY Date: Mon, 3 Feb 2025 15:57:50 +0100 Subject: [PATCH] [Validator] Add extra tests for dimension validator and update matcher --- .../app/models/dimension/validator/check.rb | 7 + test/dummy/public/image_500x700.png | Bin 0 -> 22232 bytes test/dummy/public/image_600x600.png | Bin 0 -> 18505 bytes test/support/files.rb | 16 ++ .../validators/aspect_ratio_validator_test.rb | 8 +- test/validators/attached_validator_test.rb | 4 +- .../validators/content_type_validator_test.rb | 18 +-- test/validators/dimension_validator_test.rb | 151 ++++++++++++++++-- test/validators/duration_validator_test.rb | 16 +- .../integration/integration_test.rb | 6 +- test/validators/limit_validator_test.rb | 8 +- .../processable_file_validator_test.rb | 2 +- .../works_with_message_option.rb | 2 +- test/validators/size_validator_test.rb | 16 +- test/validators/support/validator_helpers.rb | 14 +- test/validators/total_size_validator_test.rb | 16 +- 16 files changed, 218 insertions(+), 66 deletions(-) create mode 100644 test/dummy/public/image_500x700.png create mode 100644 test/dummy/public/image_600x600.png diff --git a/test/dummy/app/models/dimension/validator/check.rb b/test/dummy/app/models/dimension/validator/check.rb index 00217e07..9862bdae 100644 --- a/test/dummy/app/models/dimension/validator/check.rb +++ b/test/dummy/app/models/dimension/validator/check.rb @@ -42,6 +42,13 @@ class Dimension::Validator::Check < ApplicationRecord validates :"#{bound}_proc", dimension: { "#{bound}": -> (record) { 500..500 } } end + # Integration tests + has_one_attached :width_height_exact + validates :width_height_exact, dimension: { width: 600, height: 600 } + has_one_attached :width_height_in + validates :width_height_in, dimension: { width: { in: 550..750 }, height: { in: 550..750 } } + + # Edge cases has_one_attached :with_invalid_media_file validates :with_invalid_media_file, dimension: { width: 150, height: 150 } end diff --git a/test/dummy/public/image_500x700.png b/test/dummy/public/image_500x700.png new file mode 100644 index 0000000000000000000000000000000000000000..262b962333d1a87b2bad2d5a8926262d149b1f05 GIT binary patch literal 22232 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