diff --git a/resources/js/components/fieldtypes/assets/Asset.js b/resources/js/components/fieldtypes/assets/Asset.js index ab72d882c9..60bc3a287f 100644 --- a/resources/js/components/fieldtypes/assets/Asset.js +++ b/resources/js/components/fieldtypes/assets/Asset.js @@ -9,6 +9,7 @@ export default { props: { asset: Object, readOnly: Boolean, + errors: Array, showFilename: { type: Boolean, default: true diff --git a/resources/js/components/fieldtypes/assets/AssetRow.vue b/resources/js/components/fieldtypes/assets/AssetRow.vue index 664a1593b2..b19e17fa40 100644 --- a/resources/js/components/fieldtypes/assets/AssetRow.vue +++ b/resources/js/components/fieldtypes/assets/AssetRow.vue @@ -23,11 +23,14 @@ <button v-if="showFilename" @click="editOrOpen" - class="flex items-center flex-1 rtl:mr-3 ltr:ml-3 text-xs rtl:text-right ltr:text-left truncate w-full" + class="flex flex-col justify-center gap-2 flex-1 rtl:mr-3 ltr:ml-3 text-xs rtl:text-right ltr:text-left truncate w-full" :title="__('Edit')" :aria-label="__('Edit Asset')" > - {{ asset.basename }} + <div>{{ asset.basename }}</div> + <template v-if="errors.length"> + <small class="help-block text-red-500 mb-0" v-for="(error, i) in errors" :key="i" v-text="error" /> + </template> </button> <button diff --git a/resources/js/components/fieldtypes/assets/AssetTile.vue b/resources/js/components/fieldtypes/assets/AssetTile.vue index f4b7cb788a..74f244d09a 100644 --- a/resources/js/components/fieldtypes/assets/AssetTile.vue +++ b/resources/js/components/fieldtypes/assets/AssetTile.vue @@ -20,6 +20,15 @@ <div class="asset-thumb-container"> <div class="asset-thumb" :class="{ 'bg-checkerboard': canBeTransparent }"> + <template v-if="errors.length"> + <div class="absolute z-10 inset-0 bg-white/75 dark:bg-dark-800/90 flex flex-col gap-2 items-center justify-center px-1 py-2"> + <small + class="help-block text-red-500 text-center mb-0" + v-text="errors[0]" + /> + </div> + </template> + <!-- Solo Bard --> <template v-if="isImage && isInBardField && !isInAssetBrowser"> <img :src="asset.url" /> @@ -38,7 +47,7 @@ </template> </template> - <div class="asset-controls"> + <div class="asset-controls z-10"> <div class="flex items-center justify-center space-x-1 rtl:space-x-reverse"> <template v-if="!readOnly"> <button @click="edit" class="btn btn-icon" :title="__('Edit')"> diff --git a/resources/js/components/fieldtypes/assets/AssetsFieldtype.vue b/resources/js/components/fieldtypes/assets/AssetsFieldtype.vue index 8f1418dd4c..8f53e77c52 100644 --- a/resources/js/components/fieldtypes/assets/AssetsFieldtype.vue +++ b/resources/js/components/fieldtypes/assets/AssetsFieldtype.vue @@ -83,9 +83,10 @@ > <div class="asset-grid-listing border dark:border-dark-900 rounded overflow-hidden" :class="{ 'rounded-t-none': !isReadOnly && (showPicker || uploads.length) }" ref="assets"> <asset-tile - v-for="asset in assets" + v-for="(asset, index) in assets" :key="asset.id" :asset="asset" + :errors="errors[index] ?? []" :read-only="isReadOnly" :show-filename="config.show_filename" :show-set-alt="showSetAlt" @@ -110,9 +111,10 @@ <tbody ref="assets"> <tr is="assetRow" class="asset-row" - v-for="asset in assets" + v-for="(asset, index) in assets" :key="asset.id" :asset="asset" + :errors="errors[index] ?? []" :read-only="isReadOnly" :show-filename="config.show_filename" :show-set-alt="showSetAlt" @@ -191,6 +193,7 @@ export default { mixins: [Fieldtype], + inject: ['storeName'], data() { return { @@ -455,6 +458,27 @@ export default { ]; }, + errors() { + const state = this.$store.state.publish[this.storeName]; + + console.log({ state }); + if (! state) { + return {}; + } + + let errors = {} + + // Filter errors to only include those for this field, and remove the field path prefix + // if there is one, then append it to the errors object. + Object.entries(state.errors) + .filter(([key, value]) => key.startsWith(this.fieldPathPrefix || this.handle)) + .forEach(([key, value]) => { + errors[key.split('.').pop()] = value + }) + + return errors + }, + }, events: { diff --git a/resources/lang/en/validation.php b/resources/lang/en/validation.php index bd70f18372..db20e7a923 100644 --- a/resources/lang/en/validation.php +++ b/resources/lang/en/validation.php @@ -44,7 +44,17 @@ 'different' => 'This field and :other must be different.', 'digits' => 'Must be :digits digits.', 'digits_between' => 'Must be between :min and :max digits.', - 'dimensions' => 'Invalid image dimensions.', + 'dimensions' => [ + 'unknown' => 'Image dimensions are unknown.', + 'ratio' => 'Must have a ratio of :ratio.', + 'same' => 'Must be :comparison :width×:height pixels.', + 'different' => 'Must be :comparison_width :width pixels wide and :comparison_height :height pixels tall.', + 'width' => 'Must be :comparison_width :width pixels wide.', + 'height' => 'Must be :comparison_height :height pixels tall.', + 'min' => 'at least', + 'max' => 'at most', + 'exact' => 'exactly', + ], 'distinct' => 'This field has a duplicate value.', 'doesnt_end_with' => 'Must not end with one of the following: :values.', 'doesnt_start_with' => 'Must not start with one of the following: :values.', @@ -66,7 +76,7 @@ 'numeric' => 'Must be greater than or equal :value.', 'string' => 'Must be greater than or equal :value characters.', ], - 'image' => 'Must be an image.', + 'image' => 'Must be an image of type: :extensions.', 'in' => 'This is invalid.', 'in_array' => 'This field does not exist in :other.', 'integer' => 'Must be an integer.', diff --git a/src/Fields/Field.php b/src/Fields/Field.php index ef9c1c9a36..8ccb33e038 100644 --- a/src/Fields/Field.php +++ b/src/Fields/Field.php @@ -137,11 +137,21 @@ public function alwaysSave() public function rules() { - $rules = [$this->handle => $this->addNullableRule(array_merge( + $temp_rules = collect($this->addNullableRule(array_merge( $this->get('required') ? ['required'] : [], Validator::explodeRules($this->fieldtype()->fieldRules()), Validator::explodeRules($this->fieldtype()->rules()) - ))]; + ))); + + $rules = []; + if ($this->type() === 'assets') { + $rules = [ + $this->handle.'.*' => $temp_rules->reject(fn ($rule) => in_array($rule, ['array', 'required']))->all(), + $this->handle => $temp_rules->filter(fn ($rule) => in_array($rule, ['array', 'required']))->all(), + ]; + } else { + $rules = [$this->handle => $temp_rules->all()]; + } $extra = collect($this->fieldtype()->extraRules())->map(function ($rules) { return $this->addNullableRule(Validator::explodeRules($rules)); diff --git a/src/Fieldtypes/Assets/DimensionsRule.php b/src/Fieldtypes/Assets/DimensionsRule.php index d1864601fe..aaba14ac69 100644 --- a/src/Fieldtypes/Assets/DimensionsRule.php +++ b/src/Fieldtypes/Assets/DimensionsRule.php @@ -2,122 +2,114 @@ namespace Statamic\Fieldtypes\Assets; -use Illuminate\Contracts\Validation\Rule; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; use Statamic\Facades\Asset; use Statamic\Statamic; use Symfony\Component\HttpFoundation\File\UploadedFile; -class DimensionsRule implements Rule +class DimensionsRule implements ValidationRule { - protected $parameters; - - public function __construct($parameters = null) + public function __construct(protected $parameters) { - $this->parameters = $parameters; + $this->parameters = array_reduce($parameters, function ($result, $item) { + [$key, $value] = array_pad(explode('=', $item, 2), 2, null); + + $result[$key] = $value; + + return $result; + }); } - /** - * Determine if the validation rule passes. - * - * @param string $attribute - * @param mixed $value - * @return bool - */ - public function passes($attribute, $value) + public function validate(string $attribute, mixed $value, Closure $fail): void { - return collect($value)->every(function ($id) { - if ($id instanceof UploadedFile) { - if (in_array($id->getMimeType(), ['image/svg+xml', 'image/svg'])) { - return true; - } - - $size = getimagesize($id->getPathname()); - } else { - if (! $asset = Asset::find($id)) { - return false; - } - - if ($asset->isSvg()) { - return true; - } - - $size = $asset->dimensions(); - } - - [$width, $height] = $size; + $size = [0, 0]; - $parameters = $this->parseNamedParameters($this->parameters); + if ($value instanceof UploadedFile) { + if (in_array($value->getMimeType(), ['image/svg+xml', 'image/svg'])) { + return; + } - if ($this->failsBasicDimensionChecks($parameters, $width, $height) || - $this->failsRatioCheck($parameters, $width, $height)) { - return false; + $size = getimagesize($value->getPathname()); + } elseif ($asset = Asset::find($value)) { + if ($asset->isSvg()) { + return; } - return true; - }); - } + $size = $asset->dimensions(); + } - /** - * Get the validation error message. - * - * @return string - */ - public function message() - { - return __((Statamic::isCpRoute() ? 'statamic::' : '').'validation.dimensions'); + [$width, $height] = $size; + if ($message = $this->message($width, $height)) { + $fail($message); + } } - /** - * Parse named parameters to $key => $value items. - * - * @param array $parameters - * @return array - */ - protected function parseNamedParameters($parameters) + public function message(int $width, int $height): ?string { - return array_reduce($parameters, function ($result, $item) { - [$key, $value] = array_pad(explode('=', $item, 2), 2, null); + $invalid_ratio = $this->validateRatio($width, $height); + $invalid_width = $this->validateWidth($width); + $invalid_height = $this->validateHeight($height); + $key = match (true) { + $invalid_ratio => 'ratio', + $invalid_width && $invalid_height && $invalid_width === $invalid_height => 'same', + $invalid_width && $invalid_height && $invalid_width !== $invalid_height => 'different', + (bool) $invalid_width => 'width', + (bool) $invalid_height => 'height', + default => null, + }; + + if (! $key) { + return null; + } - $result[$key] = $value; + $prefix = Statamic::isCpRoute() ? 'statamic::' : ''; + + $comparisons = [ + 'min' => __("{$prefix}validation.dimensions.min"), + 'max' => __("{$prefix}validation.dimensions.max"), + 'exact' => __("{$prefix}validation.dimensions.exact"), + ]; + + return __("{$prefix}validation.dimensions.{$key}", [ + 'width' => $this->parameters['width'] ?? $this->parameters['min_width'] ?? $this->parameters['max_width'] ?? null, + 'height' => $this->parameters['height'] ?? $this->parameters['min_height'] ?? $this->parameters['max_height'] ?? null, + 'ratio' => $this->parameters['ratio'] ?? null, + 'comparison' => $comparisons[$invalid_width] ?? '', + 'comparison_width' => $comparisons[$invalid_width] ?? '', + 'comparison_height' => $comparisons[$invalid_height] ?? '', + ]); + } - return $result; - }); + public function validateWidth(int $width): ?string + { + return match (true) { + isset($this->parameters['width']) && $this->parameters['width'] != $width => 'exact', + isset($this->parameters['min_width']) && $this->parameters['min_width'] > $width => 'min', + isset($this->parameters['max_width']) && $this->parameters['max_width'] < $width => 'max', + default => null, + }; } - /** - * Test if the given width and height fail any conditions. - * - * @param array $parameters - * @param int $width - * @param int $height - * @return bool - */ - protected function failsBasicDimensionChecks($parameters, $width, $height) + public function validateHeight(int $height): ?string { - return (isset($parameters['width']) && $parameters['width'] != $width) || - (isset($parameters['min_width']) && $parameters['min_width'] > $width) || - (isset($parameters['max_width']) && $parameters['max_width'] < $width) || - (isset($parameters['height']) && $parameters['height'] != $height) || - (isset($parameters['min_height']) && $parameters['min_height'] > $height) || - (isset($parameters['max_height']) && $parameters['max_height'] < $height); + return match (true) { + isset($this->parameters['height']) && $this->parameters['height'] != $height => 'exact', + isset($this->parameters['min_height']) && $this->parameters['min_height'] > $height => 'min', + isset($this->parameters['max_height']) && $this->parameters['max_height'] < $height => 'max', + default => null, + }; } - /** - * Determine if the given parameters fail a dimension ratio check. - * - * @param array $parameters - * @param int $width - * @param int $height - * @return bool - */ - protected function failsRatioCheck($parameters, $width, $height) + public function validateRatio(int $width, int $height): bool { - if (! isset($parameters['ratio'])) { + if (! isset($this->parameters['ratio'])) { return false; } [$numerator, $denominator] = array_replace( - [1, 1], array_filter(sscanf($parameters['ratio'], '%f/%d')) + [1, 1], + array_filter(sscanf($this->parameters['ratio'], '%f/%d')) ); $precision = 1 / (max($width, $height) + 1); diff --git a/src/Fieldtypes/Assets/ImageRule.php b/src/Fieldtypes/Assets/ImageRule.php index eb9955d158..c86f351008 100644 --- a/src/Fieldtypes/Assets/ImageRule.php +++ b/src/Fieldtypes/Assets/ImageRule.php @@ -2,51 +2,37 @@ namespace Statamic\Fieldtypes\Assets; -use Illuminate\Contracts\Validation\Rule; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; use Statamic\Facades\Asset; use Statamic\Statamic; use Symfony\Component\HttpFoundation\File\UploadedFile; -class ImageRule implements Rule +class ImageRule implements ValidationRule { - protected $parameters; + public $extensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp', 'avif']; - public function __construct($parameters = null) + public function __construct(protected $parameters) { - $this->parameters = $parameters; } - /** - * Determine if the validation rule passes. - * - * @param string $attribute - * @param mixed $value - * @return bool - */ - public function passes($attribute, $value) + public function validate(string $attribute, mixed $value, Closure $fail): void { - $extensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp', 'avif']; + $extension = ''; - return collect($value)->every(function ($id) use ($extensions) { - if ($id instanceof UploadedFile) { - return in_array($id->guessExtension(), $extensions); - } + if ($value instanceof UploadedFile) { + $extension = $value->guessExtension(); + } elseif ($asset = Asset::find($value)) { + $extension = $asset->extension(); + } - if (! $asset = Asset::find($id)) { - return false; - } - - return $asset->guessedExtensionIsOneOf($extensions); - }); + if (! in_array($extension, $this->extensions)) { + $fail($this->message()); + } } - /** - * Get the validation error message. - * - * @return string - */ - public function message() + public function message(): string { - return __((Statamic::isCpRoute() ? 'statamic::' : '').'validation.image'); + return __((Statamic::isCpRoute() ? 'statamic::' : '').'validation.image', ['extensions' => implode(', ', $this->extensions)]); } } diff --git a/src/Fieldtypes/Assets/MaxRule.php b/src/Fieldtypes/Assets/MaxRule.php index 8a5f04e86f..3d41b7fa2c 100644 --- a/src/Fieldtypes/Assets/MaxRule.php +++ b/src/Fieldtypes/Assets/MaxRule.php @@ -2,28 +2,35 @@ namespace Statamic\Fieldtypes\Assets; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; +use Statamic\Facades\Asset; use Statamic\Statamic; +use Symfony\Component\HttpFoundation\File\UploadedFile; -class MaxRule extends SizeBasedRule +class MaxRule implements ValidationRule { - /** - * Determine if the the rule passes for the given size. - * - * @param int $size - * @return bool - */ - public function sizePasses($size) + public function __construct(protected $parameters) { - return $size <= $this->parameters[0]; } - /** - * Get the validation error message. - * - * @return string - */ - public function message() + public function validate(string $attribute, mixed $value, Closure $fail): void { - return str_replace(':max', $this->parameters[0], __((Statamic::isCpRoute() ? 'statamic::' : '').'validation.max.file')); + $size = 0; + + if ($value instanceof UploadedFile) { + $size = $value->getSize() / 1024; + } elseif ($asset = Asset::find($value)) { + $size = $asset->size() / 1024; + } + + if ($size > $this->parameters[0]) { + $fail($this->message()); + } + } + + public function message(): string + { + return __((Statamic::isCpRoute() ? 'statamic::' : '').'validation.max.file', ['max' => $this->parameters[0]]); } } diff --git a/src/Fieldtypes/Assets/MimesRule.php b/src/Fieldtypes/Assets/MimesRule.php index 485ac393cf..660554345b 100644 --- a/src/Fieldtypes/Assets/MimesRule.php +++ b/src/Fieldtypes/Assets/MimesRule.php @@ -2,12 +2,13 @@ namespace Statamic\Fieldtypes\Assets; -use Illuminate\Contracts\Validation\Rule; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; use Statamic\Facades\Asset; use Statamic\Statamic; use Symfony\Component\HttpFoundation\File\UploadedFile; -class MimesRule implements Rule +class MimesRule implements ValidationRule { protected $parameters; @@ -17,38 +18,26 @@ public function __construct($parameters) $parameters = array_unique(array_merge($parameters, ['jpg', 'jpeg'])); } - $this->parameters = $parameters; + $this->parameters = array_map(strtolower(...), $parameters); } - /** - * Determine if the validation rule passes. - * - * @param string $attribute - * @param mixed $value - * @return bool - */ - public function passes($attribute, $value) + public function validate(string $attribute, mixed $value, Closure $fail): void { - return collect($value)->every(function ($id) { - if ($id instanceof UploadedFile) { - return in_array($id->guessExtension(), $this->parameters); - } + $mime = ''; - if (! $asset = Asset::find($id)) { - return false; - } + if ($value instanceof UploadedFile) { + $mime = $value->guessExtension(); + } elseif ($asset = Asset::find($value)) { + $mime = $asset->extension(); + } - return $asset->guessedExtensionIsOneOf($this->parameters); - }); + if (! in_array($mime, $this->parameters)) { + $fail($this->message()); + } } - /** - * Get the validation error message. - * - * @return string - */ - public function message() + public function message(): string { - return str_replace(':values', implode(', ', $this->parameters), __((Statamic::isCpRoute() ? 'statamic::' : '').'validation.mimes')); + return __((Statamic::isCpRoute() ? 'statamic::' : '').'validation.mimes', ['values' => implode(', ', $this->parameters)]); } } diff --git a/src/Fieldtypes/Assets/MimetypesRule.php b/src/Fieldtypes/Assets/MimetypesRule.php index ad1c82acaa..f4dc92afc3 100644 --- a/src/Fieldtypes/Assets/MimetypesRule.php +++ b/src/Fieldtypes/Assets/MimetypesRule.php @@ -2,48 +2,35 @@ namespace Statamic\Fieldtypes\Assets; -use Illuminate\Contracts\Validation\Rule; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; use Statamic\Facades\Asset; use Statamic\Statamic; use Symfony\Component\HttpFoundation\File\UploadedFile; -class MimetypesRule implements Rule +class MimetypesRule implements ValidationRule { - protected $parameters; - - public function __construct($parameters) + public function __construct(protected $parameters) { - $this->parameters = $parameters; } - /** - * Determine if the validation rule passes. - * - * @param string $attribute - * @param mixed $value - * @return bool - */ - public function passes($attribute, $value) + public function validate(string $attribute, mixed $value, Closure $fail): void { - return collect($value)->every(function ($id) { - if ($id instanceof UploadedFile) { - $mimeType = $id->getMimeType(); - } elseif (! ($mimeType = optional(Asset::find($id))->mimeType())) { - return false; - } + $mime_type = ''; + + if ($value instanceof UploadedFile) { + $mime_type = $value->getMimeType(); + } elseif ($asset = Asset::find($value)) { + $mime_type = $asset->mimeType(); + } - return in_array($mimeType, $this->parameters) || - in_array(explode('/', $mimeType)[0].'/*', $this->parameters); - }); + if (! in_array($mime_type, $this->parameters) && ! in_array(explode('/', $mime_type)[0].'/*', $this->parameters)) { + $fail($this->message()); + } } - /** - * Get the validation error message. - * - * @return string - */ public function message() { - return str_replace(':values', implode(', ', $this->parameters), __((Statamic::isCpRoute() ? 'statamic::' : '').'validation.mimetypes')); + return __((Statamic::isCpRoute() ? 'statamic::' : '').'validation.mimetypes', ['values' => implode(', ', $this->parameters)]); } } diff --git a/src/Fieldtypes/Assets/MinRule.php b/src/Fieldtypes/Assets/MinRule.php index b37bfaa587..64fb897768 100644 --- a/src/Fieldtypes/Assets/MinRule.php +++ b/src/Fieldtypes/Assets/MinRule.php @@ -2,28 +2,35 @@ namespace Statamic\Fieldtypes\Assets; +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; +use Statamic\Facades\Asset; use Statamic\Statamic; +use Symfony\Component\HttpFoundation\File\UploadedFile; -class MinRule extends SizeBasedRule +class MinRule implements ValidationRule { - /** - * Determine if the the rule passes for the given size. - * - * @param int $size - * @return bool - */ - public function sizePasses($size) + public function __construct(protected $parameters) { - return $size >= $this->parameters[0]; } - /** - * Get the validation error message. - * - * @return string - */ - public function message() + public function validate(string $attribute, mixed $value, Closure $fail): void { - return str_replace(':min', $this->parameters[0], __((Statamic::isCpRoute() ? 'statamic::' : '').'validation.min.file')); + $size = 0; + + if ($value instanceof UploadedFile) { + $size = $value->getSize() / 1024; + } elseif ($asset = Asset::find($value)) { + $size = $asset->size() / 1024; + } + + if ($size < $this->parameters[0]) { + $fail($this->message()); + } + } + + public function message(): string + { + return __((Statamic::isCpRoute() ? 'statamic::' : '').'validation.min.file', ['min' => $this->parameters[0]]); } } diff --git a/src/Fieldtypes/Assets/SizeBasedRule.php b/src/Fieldtypes/Assets/SizeBasedRule.php deleted file mode 100644 index 35338e010c..0000000000 --- a/src/Fieldtypes/Assets/SizeBasedRule.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php - -namespace Statamic\Fieldtypes\Assets; - -use Illuminate\Contracts\Validation\Rule; -use Statamic\Facades\Asset; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -abstract class SizeBasedRule implements Rule -{ - protected $parameters; - - public function __construct($parameters = null) - { - $this->parameters = $parameters; - } - - /** - * Determine if the validation rule passes. - * - * @param string $attribute - * @param mixed $value - * @return bool - */ - public function passes($attribute, $value) - { - return collect($value)->every(function ($id) { - if (($size = $this->getFileSize($id)) === false) { - return false; - } - - return $this->sizePasses($size); - }); - } - - /** - * Determine if the the rule passes for the given size. - * - * @param int $size - * @return bool - */ - abstract public function sizePasses($size); - - /** - * Get the validation error message. - * - * @return string - */ - abstract public function message(); - - /** - * Get the file size. - * - * @param string|UploadedFile $id - * @return int|false - */ - protected function getFileSize($id) - { - if ($id instanceof UploadedFile) { - return $id->getSize() / 1024; - } - - if ($asset = Asset::find($id)) { - return $asset->size() / 1024; - } - - return false; - } -} diff --git a/tests/Assets/AssetTest.php b/tests/Assets/AssetTest.php index ccfa5ed047..67d336f7bd 100644 --- a/tests/Assets/AssetTest.php +++ b/tests/Assets/AssetTest.php @@ -11,6 +11,7 @@ use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Storage; +use Illuminate\Support\Facades\Validator; use League\Flysystem\PathTraversalDetected; use Mockery; use PHPUnit\Framework\Attributes\DataProvider; @@ -48,8 +49,9 @@ class AssetTest extends TestCase use PreventSavingStacheItemsToDisk; private $container; + private $validator; - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -938,7 +940,7 @@ public function it_saves_quietly() } #[Test] - public function when_saving_quietly_the_cached_assets_withEvents_flag_will_be_set_back_to_true() + public function when_saving_quietly_the_cached_assets_with_events_flag_will_be_set_back_to_true() { Event::fake(); Storage::fake('test'); @@ -1504,7 +1506,10 @@ public function it_gets_dimensions() public function it_passes_the_dimensions_validation() { $file = UploadedFile::fake()->image('image.jpg', 30, 60); - $validDimensions = (new DimensionsRule(['max_width=10']))->passes('Image', [$file]); + $validDimensions = Validator::make( + ['Image' => $file], + ['Image' => [new DimensionsRule(['max_width=10'])]], + )->passes(); $this->assertFalse($validDimensions); } diff --git a/tests/Fieldtypes/AssetsTest.php b/tests/Fieldtypes/AssetsTest.php index 19ae89d96d..72be3f6290 100644 --- a/tests/Fieldtypes/AssetsTest.php +++ b/tests/Fieldtypes/AssetsTest.php @@ -26,7 +26,7 @@ class AssetsTest extends TestCase use PreventSavingStacheItemsToDisk; use TestsQueryableValueWithMaxItems; - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -138,7 +138,7 @@ public function it_replaces_dimensions_rule() $this->assertIsArray($replaced); $this->assertCount(1, $replaced); $this->assertInstanceOf(DimensionsRule::class, $replaced[0]); - $this->assertEquals(__('statamic::validation.dimensions'), $replaced[0]->message()); + $this->assertEquals(__('statamic::validation.dimensions.same', ['width' => '180', 'height' => '180', 'comparison' => 'exactly']), $replaced[0]->message(100, 100)); } #[Test] @@ -151,7 +151,7 @@ public function it_replaces_image_rule() $this->assertIsArray($replaced); $this->assertCount(1, $replaced); $this->assertInstanceOf(ImageRule::class, $replaced[0]); - $this->assertEquals(__('statamic::validation.image'), $replaced[0]->message()); + $this->assertEquals(__('statamic::validation.image', ['extensions' => implode(', ', $replaced[0]->extensions)]), $replaced[0]->message()); } #[Test]