From ddfa3dc41479ac7b96d67f199ec3c0ad54e501ff Mon Sep 17 00:00:00 2001 From: Robin Gustafsson <robin@rgson.se> Date: Tue, 22 Apr 2025 23:01:59 +0200 Subject: [PATCH] New upstream version 11.44.2+dfsg --- CHANGELOG.md | 20 ++++++- composer.json | 2 +- .../Collections/Traits/EnumeratesValues.php | 2 +- src/Illuminate/Database/Eloquent/Builder.php | 2 +- .../Concerns/QueriesRelationships.php | 2 +- .../Eloquent/Relations/BelongsToMany.php | 2 +- .../Relations/HasOneOrManyThrough.php | 2 +- src/Illuminate/Database/Query/Builder.php | 2 +- src/Illuminate/Database/Seeder.php | 12 +++-- src/Illuminate/Foundation/Application.php | 4 +- .../Redis/Connections/PacksPhpRedisValues.php | 12 ++--- src/Illuminate/Validation/Validator.php | 45 ++++++++++------ .../Database/DatabaseEloquentBuilderTest.php | 12 ++--- tests/Integration/Cache/DynamoDbStoreTest.php | 2 +- tests/Integration/Cookie/CookieTest.php | 2 +- ...terCommitUsingDatabaseTransactionsTest.php | 2 +- ...seEmulatePreparesMariaDbConnectionTest.php | 4 +- ...baseEmulatePreparesMySqlConnectionTest.php | 4 +- .../Postgres/PostgresSchemaBuilderTest.php | 4 +- .../Mail/SendingMarkdownMailTest.php | 2 +- .../Mail/SendingQueuedMailTest.php | 2 +- tests/Integration/Queue/JobEncryptionTest.php | 4 +- .../Queue/ModelSerializationTest.php | 2 +- .../Integration/Queue/QueueConnectionTest.php | 9 ++-- .../Validation/Rules/EmailValidationTest.php | 49 +++++++++++++++++ .../Validation/Rules/FileValidationTest.php | 54 +++++++++++++++++++ .../Rules/PasswordValidationTest.php | 49 +++++++++++++++++ .../View/BladeAnonymousComponentTest.php | 2 +- tests/Integration/View/BladeTest.php | 2 +- .../View/RenderableViewExceptionTest.php | 2 +- tests/Validation/ValidationEmailRuleTest.php | 3 ++ 31 files changed, 253 insertions(+), 64 deletions(-) create mode 100644 tests/Integration/Validation/Rules/EmailValidationTest.php create mode 100644 tests/Integration/Validation/Rules/FileValidationTest.php create mode 100644 tests/Integration/Validation/Rules/PasswordValidationTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b6df29a5b..8a4c7a4c7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,24 @@ # Release Notes for 11.x -## [Unreleased](https://github.com/laravel/framework/compare/v11.43.2...11.x) +## [Unreleased](https://github.com/laravel/framework/compare/v11.44.1...11.x) + +## [v11.44.1](https://github.com/laravel/framework/compare/v11.44.0...v11.44.1) - 2025-03-05 + +* [11.x] Add valid values to ensure method by [@lancepioch](https://github.com/lancepioch) in https://github.com/laravel/framework/pull/54840 +* Fix attribute name used on `Validator` instance within certain rule classes by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54845 +* [11.x] Fix `Application::interBasePath()` fails to resolve application when project name is "vendor" by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54871 +* [11.x] Test improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54879 + +## [v11.44.0](https://github.com/laravel/framework/compare/v11.43.2...v11.44.0) - 2025-02-24 + +* [11.x] Fix parsing `PHP_CLI_SERVER_WORKERS` as `string` instead of `int` by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/54724 +* [11.x] Rename Redis parse connection for cluster test method to follow naming conventions by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/54721 +* [11.x] Allow `readAt` method to use in database channel by [@utsavsomaiya](https://github.com/utsavsomaiya) in https://github.com/laravel/framework/pull/54729 +* [11.x] Fix: Custom Exceptions with Multiple Arguments does not properly rein… by [@pandiselvamm](https://github.com/pandiselvamm) in https://github.com/laravel/framework/pull/54705 +* [11.x] Update ConcurrencyTest exception reference to use namespace by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/54732 +* [11.x] Deprecate `Factory::$modelNameResolver` by [@samlev](https://github.com/samlev) in https://github.com/laravel/framework/pull/54736 +* [11x.] Improved typehints for `InteractsWithDatabase` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/54748 +* [11.x] Improved typehints for `InteractsWithExceptionHandling` && `ExceptionHandlerFake` by [@cosmastech](https://github.com/cosmastech) in https://github.com/laravel/framework/pull/54747 ## [v11.43.2](https://github.com/laravel/framework/compare/v11.43.1...v11.43.2) - 2025-02-19 diff --git a/composer.json b/composer.json index cf2c2589ce..282d9ff0aa 100644 --- a/composer.json +++ b/composer.json @@ -111,7 +111,7 @@ "league/flysystem-read-only": "^3.25.1", "league/flysystem-sftp-v3": "^3.25.1", "mockery/mockery": "^1.6.10", - "orchestra/testbench-core": "^9.9.4", + "orchestra/testbench-core": "^9.11.2", "pda/pheanstalk": "^5.0.6", "php-http/discovery": "^1.15", "phpstan/phpstan": "^2.0", diff --git a/src/Illuminate/Collections/Traits/EnumeratesValues.php b/src/Illuminate/Collections/Traits/EnumeratesValues.php index ce3c302038..55c7110942 100644 --- a/src/Illuminate/Collections/Traits/EnumeratesValues.php +++ b/src/Illuminate/Collections/Traits/EnumeratesValues.php @@ -342,7 +342,7 @@ trait EnumeratesValues * * @template TEnsureOfType * - * @param class-string<TEnsureOfType>|array<array-key, class-string<TEnsureOfType>> $type + * @param class-string<TEnsureOfType>|array<array-key, class-string<TEnsureOfType>>|'string'|'int'|'float'|'bool'|'array'|'null' $type * @return static<TKey, TEnsureOfType> * * @throws \UnexpectedValueException diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index 1c27bb2ff7..57baa3a680 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -1018,7 +1018,7 @@ class Builder implements BuilderContract * @param string $pageName * @param int|null $page * @param \Closure|int|null $total - * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator + * @return \Illuminate\Pagination\LengthAwarePaginator * * @throws \InvalidArgumentException */ diff --git a/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php b/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php index c6162d7656..a9acf90fb6 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php +++ b/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php @@ -674,7 +674,7 @@ trait QueriesRelationships $models->groupBy(fn ($model) => $model->getMorphClass())->each(function ($models) use ($query, $relation) { $query->orWhere(function ($query) use ($relation, $models) { $query->where($relation->qualifyColumn($relation->getMorphType()), '<=>', $models->first()->getMorphClass()) - ->whereNotIn($relation->qualifyColumn($relation->getForeignKeyName()), $models->map->getKey()); + ->whereIn($relation->qualifyColumn($relation->getForeignKeyName()), $models->map->getKey()); }); }); }, null, null, $boolean); diff --git a/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php b/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php index 7019cf49c0..5618f0190f 100755 --- a/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php +++ b/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php @@ -938,7 +938,7 @@ class BelongsToMany extends Relation * @param array $columns * @param string $pageName * @param int|null $page - * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator + * @return \Illuminate\Pagination\LengthAwarePaginator */ public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null) { diff --git a/src/Illuminate/Database/Eloquent/Relations/HasOneOrManyThrough.php b/src/Illuminate/Database/Eloquent/Relations/HasOneOrManyThrough.php index 6e74acf746..72a65b0c1f 100644 --- a/src/Illuminate/Database/Eloquent/Relations/HasOneOrManyThrough.php +++ b/src/Illuminate/Database/Eloquent/Relations/HasOneOrManyThrough.php @@ -468,7 +468,7 @@ abstract class HasOneOrManyThrough extends Relation * @param array $columns * @param string $pageName * @param int $page - * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator + * @return \Illuminate\Pagination\LengthAwarePaginator */ public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null) { diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 538994fe4b..d6d9fd07b4 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -3142,7 +3142,7 @@ class Builder implements BuilderContract * @param string $pageName * @param int|null $page * @param \Closure|int|null $total - * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator + * @return \Illuminate\Pagination\LengthAwarePaginator */ public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null, $total = null) { diff --git a/src/Illuminate/Database/Seeder.php b/src/Illuminate/Database/Seeder.php index bfb48aedf3..08e57b2d78 100755 --- a/src/Illuminate/Database/Seeder.php +++ b/src/Illuminate/Database/Seeder.php @@ -110,11 +110,15 @@ abstract class Seeder */ public function callOnce($class, $silent = false, array $parameters = []) { - if (in_array($class, static::$called)) { - return; - } + $classes = Arr::wrap($class); + + foreach ($classes as $class) { + if (in_array($class, static::$called)) { + continue; + } - $this->call($class, $silent, $parameters); + $this->call($class, $silent, $parameters); + } } /** diff --git a/src/Illuminate/Foundation/Application.php b/src/Illuminate/Foundation/Application.php index cc9783289b..be7345c8ef 100755 --- a/src/Illuminate/Foundation/Application.php +++ b/src/Illuminate/Foundation/Application.php @@ -45,7 +45,7 @@ class Application extends Container implements ApplicationContract, CachesConfig * * @var string */ - const VERSION = '11.44.0'; + const VERSION = '11.44.2'; /** * The base path for the Laravel installation. @@ -257,7 +257,7 @@ class Application extends Container implements ApplicationContract, CachesConfig isset($_ENV['APP_BASE_PATH']) => $_ENV['APP_BASE_PATH'], default => dirname(array_values(array_filter( array_keys(ClassLoader::getRegisteredLoaders()), - fn ($path) => ! str_contains($path, '/vendor/'), + fn ($path) => ! str_starts_with($path, 'phar://'), ))[0]), }; } diff --git a/src/Illuminate/Redis/Connections/PacksPhpRedisValues.php b/src/Illuminate/Redis/Connections/PacksPhpRedisValues.php index 526a764ede..1a81720b07 100644 --- a/src/Illuminate/Redis/Connections/PacksPhpRedisValues.php +++ b/src/Illuminate/Redis/Connections/PacksPhpRedisValues.php @@ -95,26 +95,26 @@ trait PacksPhpRedisValues $oldSerializer = null; if ($this->serialized()) { - $oldSerializer = $client->getOption($client::OPT_SERIALIZER); - $client->setOption($client::OPT_SERIALIZER, $client::SERIALIZER_NONE); + $oldSerializer = $client->getOption(Redis::OPT_SERIALIZER); + $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE); } $oldCompressor = null; if ($this->compressed()) { - $oldCompressor = $client->getOption($client::OPT_COMPRESSION); - $client->setOption($client::OPT_COMPRESSION, $client::COMPRESSION_NONE); + $oldCompressor = $client->getOption(Redis::OPT_COMPRESSION); + $client->setOption(Redis::OPT_COMPRESSION, Redis::COMPRESSION_NONE); } try { return $callback(); } finally { if ($oldSerializer !== null) { - $client->setOption($client::OPT_SERIALIZER, $oldSerializer); + $client->setOption(Redis::OPT_SERIALIZER, $oldSerializer); } if ($oldCompressor !== null) { - $client->setOption($client::OPT_COMPRESSION, $oldCompressor); + $client->setOption(Redis::OPT_COMPRESSION, $oldCompressor); } } } diff --git a/src/Illuminate/Validation/Validator.php b/src/Illuminate/Validation/Validator.php index 557ab19f57..21cb2e7273 100755 --- a/src/Illuminate/Validation/Validator.php +++ b/src/Illuminate/Validation/Validator.php @@ -307,11 +307,11 @@ class Validator implements ValidatorContract protected $defaultNumericRules = ['Numeric', 'Integer', 'Decimal']; /** - * The current placeholder for dots in rule keys. + * The current random hash for the validator. * * @var string */ - protected $dotPlaceholder; + protected static $placeholderHash; /** * The exception to throw upon failure. @@ -344,7 +344,9 @@ class Validator implements ValidatorContract array $messages = [], array $attributes = [], ) { - $this->dotPlaceholder = Str::random(); + if (! isset(static::$placeholderHash)) { + static::$placeholderHash = Str::random(); + } $this->initialRules = $rules; $this->translator = $translator; @@ -372,7 +374,7 @@ class Validator implements ValidatorContract $key = str_replace( ['.', '*'], - [$this->dotPlaceholder, '__asterisk__'], + ['__dot__'.static::$placeholderHash, '__asterisk__'.static::$placeholderHash], $key ); @@ -410,7 +412,7 @@ class Validator implements ValidatorContract protected function replacePlaceholderInString(string $value) { return str_replace( - [$this->dotPlaceholder, '__asterisk__'], + ['__dot__'.static::$placeholderHash, '__asterisk__'.static::$placeholderHash], ['.', '*'], $value ); @@ -419,13 +421,13 @@ class Validator implements ValidatorContract /** * Replace each field parameter dot placeholder with dot. * - * @param string $value - * @return string + * @param array $parameters + * @return array */ protected function replaceDotPlaceholderInParameters(array $parameters) { return array_map(function ($field) { - return str_replace($this->dotPlaceholder, '.', $field); + return str_replace('__dot__'.static::$placeholderHash, '.', $field); }, $parameters); } @@ -746,7 +748,7 @@ class Validator implements ValidatorContract protected function replaceDotInParameters(array $parameters) { return array_map(function ($field) { - return str_replace('\.', $this->dotPlaceholder, $field); + return str_replace('\.', '__dot__'.static::$placeholderHash, $field); }, $parameters); } @@ -872,11 +874,24 @@ class Validator implements ValidatorContract */ protected function validateUsingCustomRule($attribute, $value, $rule) { - $attribute = $this->replacePlaceholderInString($attribute); + $originalAttribute = $this->replacePlaceholderInString($attribute); + + $attribute = match (true) { + $rule instanceof Rules\Email => $attribute, + $rule instanceof Rules\File => $attribute, + $rule instanceof Rules\Password => $attribute, + default => $originalAttribute, + }; $value = is_array($value) ? $this->replacePlaceholders($value) : $value; if ($rule instanceof ValidatorAwareRule) { + if ($attribute !== $originalAttribute) { + $this->addCustomAttributes([ + $attribute => $this->customAttributes[$originalAttribute] ?? $originalAttribute, + ]); + } + $rule->setValidator($this); } @@ -889,14 +904,14 @@ class Validator implements ValidatorContract get_class($rule->invokable()) : get_class($rule); - $this->failedRules[$attribute][$ruleClass] = []; + $this->failedRules[$originalAttribute][$ruleClass] = []; - $messages = $this->getFromLocalArray($attribute, $ruleClass) ?? $rule->message(); + $messages = $this->getFromLocalArray($originalAttribute, $ruleClass) ?? $rule->message(); $messages = $messages ? (array) $messages : [$ruleClass]; foreach ($messages as $key => $message) { - $key = is_string($key) ? $key : $attribute; + $key = is_string($key) ? $key : $originalAttribute; $this->messages->add($key, $this->makeReplacements( $message, $key, $ruleClass, [] @@ -1189,7 +1204,7 @@ class Validator implements ValidatorContract { return (new Collection($this->rules)) ->mapWithKeys(fn ($value, $key) => [ - str_replace($this->dotPlaceholder, '\\.', $key) => $value, + str_replace('__dot__'.static::$placeholderHash, '\\.', $key) => $value, ]) ->all(); } @@ -1203,7 +1218,7 @@ class Validator implements ValidatorContract public function setRules(array $rules) { $rules = (new Collection($rules))->mapWithKeys(function ($value, $key) { - return [str_replace('\.', $this->dotPlaceholder, $key) => $value]; + return [str_replace('\.', '__dot__'.static::$placeholderHash, $key) => $value]; })->toArray(); $this->initialRules = $rules; diff --git a/tests/Database/DatabaseEloquentBuilderTest.php b/tests/Database/DatabaseEloquentBuilderTest.php index 60daa61f0b..ad0c86122a 100755 --- a/tests/Database/DatabaseEloquentBuilderTest.php +++ b/tests/Database/DatabaseEloquentBuilderTest.php @@ -1837,7 +1837,7 @@ class DatabaseEloquentBuilderTest extends TestCase $builder = $model->whereNotMorphedTo('morph', $relatedModel); - $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?)))', $builder->toSql()); + $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?)))', $builder->toSql()); $this->assertEquals([$relatedModel->getMorphClass(), $relatedModel->getKey()], $builder->getBindings()); } @@ -1854,7 +1854,7 @@ class DatabaseEloquentBuilderTest extends TestCase $builder = $model->whereNotMorphedTo('morph', new Collection([$firstRelatedModel, $secondRelatedModel])); - $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?, ?)))', $builder->toSql()); + $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?, ?)))', $builder->toSql()); $this->assertEquals([$firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $secondRelatedModel->getKey()], $builder->getBindings()); } @@ -1874,7 +1874,7 @@ class DatabaseEloquentBuilderTest extends TestCase $builder = $model->whereNotMorphedTo('morph', [$firstRelatedModel, $secondRelatedModel, $thirdRelatedModel]); - $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?, ?)) or ("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?)))', $builder->toSql()); + $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?, ?)) or ("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?)))', $builder->toSql()); $this->assertEquals([$firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $thirdRelatedModel->getKey(), $secondRelatedModel->getMorphClass(), $secondRelatedModel->id], $builder->getBindings()); } @@ -1950,7 +1950,7 @@ class DatabaseEloquentBuilderTest extends TestCase $builder = $model->where('bar', 'baz')->orWhereNotMorphedTo('morph', $relatedModel); - $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where "bar" = ? or not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?)))', $builder->toSql()); + $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where "bar" = ? or not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?)))', $builder->toSql()); $this->assertEquals(['baz', $relatedModel->getMorphClass(), $relatedModel->getKey()], $builder->getBindings()); } @@ -1967,7 +1967,7 @@ class DatabaseEloquentBuilderTest extends TestCase $builder = $model->where('bar', 'baz')->orWhereNotMorphedTo('morph', new Collection([$firstRelatedModel, $secondRelatedModel])); - $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where "bar" = ? or not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?, ?)))', $builder->toSql()); + $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where "bar" = ? or not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?, ?)))', $builder->toSql()); $this->assertEquals(['baz', $firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $secondRelatedModel->getKey()], $builder->getBindings()); } @@ -1987,7 +1987,7 @@ class DatabaseEloquentBuilderTest extends TestCase $builder = $model->where('bar', 'baz')->orWhereNotMorphedTo('morph', [$firstRelatedModel, $secondRelatedModel, $thirdRelatedModel]); - $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where "bar" = ? or not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?, ?)) or ("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" not in (?)))', $builder->toSql()); + $this->assertSame('select * from "eloquent_builder_test_model_parent_stubs" where "bar" = ? or not (("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?, ?)) or ("eloquent_builder_test_model_parent_stubs"."morph_type" <=> ? and "eloquent_builder_test_model_parent_stubs"."morph_id" in (?)))', $builder->toSql()); $this->assertEquals(['baz', $firstRelatedModel->getMorphClass(), $firstRelatedModel->getKey(), $thirdRelatedModel->getKey(), $secondRelatedModel->getMorphClass(), $secondRelatedModel->id], $builder->getBindings()); } diff --git a/tests/Integration/Cache/DynamoDbStoreTest.php b/tests/Integration/Cache/DynamoDbStoreTest.php index b465cc61ea..7abe70d278 100644 --- a/tests/Integration/Cache/DynamoDbStoreTest.php +++ b/tests/Integration/Cache/DynamoDbStoreTest.php @@ -65,7 +65,7 @@ class DynamoDbStoreTest extends TestCase * @param \Illuminate\Foundation\Application $app * @return void */ - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { if (! env('DYNAMODB_CACHE_TABLE')) { $this->markTestSkipped('DynamoDB not configured.'); diff --git a/tests/Integration/Cookie/CookieTest.php b/tests/Integration/Cookie/CookieTest.php index bc52526303..ed5223022a 100644 --- a/tests/Integration/Cookie/CookieTest.php +++ b/tests/Integration/Cookie/CookieTest.php @@ -42,7 +42,7 @@ class CookieTest extends TestCase $this->assertEquals(Carbon::now()->getTimestamp() + 60, $response->headers->getCookies()[1]->getExpiresTime()); } - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { $app->instance( ExceptionHandler::class, diff --git a/tests/Integration/Database/EloquentTransactionWithAfterCommitUsingDatabaseTransactionsTest.php b/tests/Integration/Database/EloquentTransactionWithAfterCommitUsingDatabaseTransactionsTest.php index 25a8b27a72..620df3d0b9 100644 --- a/tests/Integration/Database/EloquentTransactionWithAfterCommitUsingDatabaseTransactionsTest.php +++ b/tests/Integration/Database/EloquentTransactionWithAfterCommitUsingDatabaseTransactionsTest.php @@ -32,7 +32,7 @@ class EloquentTransactionWithAfterCommitUsingDatabaseTransactionsTest extends Te } } - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { $connection = $app->make('config')->get('database.default'); diff --git a/tests/Integration/Database/MariaDb/DatabaseEmulatePreparesMariaDbConnectionTest.php b/tests/Integration/Database/MariaDb/DatabaseEmulatePreparesMariaDbConnectionTest.php index 8c155518dc..451fd3a1bd 100755 --- a/tests/Integration/Database/MariaDb/DatabaseEmulatePreparesMariaDbConnectionTest.php +++ b/tests/Integration/Database/MariaDb/DatabaseEmulatePreparesMariaDbConnectionTest.php @@ -10,9 +10,9 @@ use PHPUnit\Framework\Attributes\RequiresPhpExtension; #[RequiresPhpExtension('pdo_mysql')] class DatabaseEmulatePreparesMariaDbConnectionTest extends DatabaseMariaDbConnectionTest { - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { - parent::getEnvironmentSetUp($app); + parent::defineEnvironment($app); $app['config']->set('database.connections.mariadb.options', [ PDO::ATTR_EMULATE_PREPARES => true, diff --git a/tests/Integration/Database/MySql/DatabaseEmulatePreparesMySqlConnectionTest.php b/tests/Integration/Database/MySql/DatabaseEmulatePreparesMySqlConnectionTest.php index 62592a4048..a67d747945 100755 --- a/tests/Integration/Database/MySql/DatabaseEmulatePreparesMySqlConnectionTest.php +++ b/tests/Integration/Database/MySql/DatabaseEmulatePreparesMySqlConnectionTest.php @@ -10,9 +10,9 @@ use PHPUnit\Framework\Attributes\RequiresPhpExtension; #[RequiresPhpExtension('pdo_mysql')] class DatabaseEmulatePreparesMySqlConnectionTest extends DatabaseMySqlConnectionTest { - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { - parent::getEnvironmentSetUp($app); + parent::defineEnvironment($app); $app['config']->set('database.connections.mysql.options', [ PDO::ATTR_EMULATE_PREPARES => true, diff --git a/tests/Integration/Database/Postgres/PostgresSchemaBuilderTest.php b/tests/Integration/Database/Postgres/PostgresSchemaBuilderTest.php index 4f64c21fbc..bfcf439d74 100644 --- a/tests/Integration/Database/Postgres/PostgresSchemaBuilderTest.php +++ b/tests/Integration/Database/Postgres/PostgresSchemaBuilderTest.php @@ -13,9 +13,9 @@ use PHPUnit\Framework\Attributes\RequiresPhpExtension; #[RequiresPhpExtension('pdo_pgsql')] class PostgresSchemaBuilderTest extends PostgresTestCase { - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { - parent::getEnvironmentSetUp($app); + parent::defineEnvironment($app); $app['config']->set('database.connections.pgsql.search_path', 'public,private'); } diff --git a/tests/Integration/Mail/SendingMarkdownMailTest.php b/tests/Integration/Mail/SendingMarkdownMailTest.php index 591b7264f6..43ecd15664 100644 --- a/tests/Integration/Mail/SendingMarkdownMailTest.php +++ b/tests/Integration/Mail/SendingMarkdownMailTest.php @@ -12,7 +12,7 @@ use Orchestra\Testbench\TestCase; class SendingMarkdownMailTest extends TestCase { - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { $app['config']->set('mail.driver', 'array'); diff --git a/tests/Integration/Mail/SendingQueuedMailTest.php b/tests/Integration/Mail/SendingQueuedMailTest.php index 6f982043ce..e20a44659c 100644 --- a/tests/Integration/Mail/SendingQueuedMailTest.php +++ b/tests/Integration/Mail/SendingQueuedMailTest.php @@ -11,7 +11,7 @@ use Orchestra\Testbench\TestCase; class SendingQueuedMailTest extends TestCase { - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { $app['config']->set('mail.driver', 'array'); diff --git a/tests/Integration/Queue/JobEncryptionTest.php b/tests/Integration/Queue/JobEncryptionTest.php index 704c080010..85701d5187 100644 --- a/tests/Integration/Queue/JobEncryptionTest.php +++ b/tests/Integration/Queue/JobEncryptionTest.php @@ -21,9 +21,9 @@ class JobEncryptionTest extends DatabaseTestCase { use DatabaseMigrations; - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { - parent::getEnvironmentSetUp($app); + parent::defineEnvironment($app); $app['config']->set('app.key', Str::random(32)); $app['config']->set('queue.default', 'database'); diff --git a/tests/Integration/Queue/ModelSerializationTest.php b/tests/Integration/Queue/ModelSerializationTest.php index 359bbff8fa..bd3b401c65 100644 --- a/tests/Integration/Queue/ModelSerializationTest.php +++ b/tests/Integration/Queue/ModelSerializationTest.php @@ -18,7 +18,7 @@ class ModelSerializationTest extends TestCase { use RefreshDatabase; - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { $app['config']->set('database.connections.custom', [ 'driver' => 'sqlite', diff --git a/tests/Integration/Queue/QueueConnectionTest.php b/tests/Integration/Queue/QueueConnectionTest.php index 1ae5f1ef90..7ad7722499 100644 --- a/tests/Integration/Queue/QueueConnectionTest.php +++ b/tests/Integration/Queue/QueueConnectionTest.php @@ -8,17 +8,14 @@ use Illuminate\Database\DatabaseTransactionsManager; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Support\Facades\Bus; use Mockery as m; +use Orchestra\Testbench\Attributes\WithConfig; use Orchestra\Testbench\TestCase; use Throwable; +#[WithConfig('queue.default', 'sqs')] +#[WithConfig('queue.connections.sqs.after_commit', true)] class QueueConnectionTest extends TestCase { - protected function getEnvironmentSetUp($app) - { - $app['config']->set('queue.default', 'sqs'); - $app['config']->set('queue.connections.sqs.after_commit', true); - } - protected function tearDown(): void { QueueConnectionTestJob::$ran = false; diff --git a/tests/Integration/Validation/Rules/EmailValidationTest.php b/tests/Integration/Validation/Rules/EmailValidationTest.php new file mode 100644 index 0000000000..558bef77a9 --- /dev/null +++ b/tests/Integration/Validation/Rules/EmailValidationTest.php @@ -0,0 +1,49 @@ +<?php + +namespace Illuminate\Tests\Integration\Validation\Rules; + +use Illuminate\Support\Facades\Validator; +use Illuminate\Validation\Rules\Email; +use Orchestra\Testbench\TestCase; +use PHPUnit\Framework\Attributes\TestWith; + +class EmailValidationTest extends TestCase +{ + #[TestWith(['0'])] + #[TestWith(['.'])] + #[TestWith(['*'])] + #[TestWith(['__asterisk__'])] + public function test_it_can_validate_attribute_as_array(string $attribute) + { + $validator = Validator::make([ + 'emails' => [ + $attribute => 'taylor@laravel.com', + ], + ], [ + 'emails.*' => ['required', Email::default()->rfcCompliant()], + ]); + + $this->assertTrue($validator->passes()); + } + + #[TestWith(['0'])] + #[TestWith(['.'])] + #[TestWith(['*'])] + #[TestWith(['__asterisk__'])] + public function test_it_can_validate_attribute_as_array_when_validation_should_fails(string $attribute) + { + $validator = Validator::make([ + 'emails' => [ + $attribute => 'taylor[at]laravel.com', + ], + ], [ + 'emails.*' => ['required', Email::default()->rfcCompliant()], + ]); + + $this->assertFalse($validator->passes()); + + $this->assertSame([ + 0 => __('validation.email', ['attribute' => sprintf('emails.%s', str_replace('_', ' ', $attribute))]), + ], $validator->messages()->all()); + } +} diff --git a/tests/Integration/Validation/Rules/FileValidationTest.php b/tests/Integration/Validation/Rules/FileValidationTest.php new file mode 100644 index 0000000000..ba0d54920e --- /dev/null +++ b/tests/Integration/Validation/Rules/FileValidationTest.php @@ -0,0 +1,54 @@ +<?php + +namespace Illuminate\Tests\Integration\Validation\Rules; + +use Illuminate\Http\UploadedFile; +use Illuminate\Support\Facades\Validator; +use Illuminate\Validation\Rules\File; +use Orchestra\Testbench\TestCase; +use PHPUnit\Framework\Attributes\TestWith; + +class FileValidationTest extends TestCase +{ + #[TestWith(['0'])] + #[TestWith(['.'])] + #[TestWith(['*'])] + #[TestWith(['__asterisk__'])] + public function test_it_can_validate_attribute_as_array(string $attribute) + { + $file = UploadedFile::fake()->create('laravel.png', 1, 'image/png'); + + $validator = Validator::make([ + 'files' => [ + $attribute => $file, + ], + ], [ + 'files.*' => ['required', File::types(['image/png', 'image/jpeg'])], + ]); + + $this->assertTrue($validator->passes()); + } + + #[TestWith(['0'])] + #[TestWith(['.'])] + #[TestWith(['*'])] + #[TestWith(['__asterisk__'])] + public function test_it_can_validate_attribute_as_array_when_validation_should_fails(string $attribute) + { + $file = UploadedFile::fake()->create('laravel.php', 1, 'image/php'); + + $validator = Validator::make([ + 'files' => [ + $attribute => $file, + ], + ], [ + 'files.*' => ['required', File::types($mimes = ['image/png', 'image/jpeg'])], + ]); + + $this->assertFalse($validator->passes()); + + $this->assertSame([ + 0 => __('validation.mimetypes', ['attribute' => sprintf('files.%s', str_replace('_', ' ', $attribute)), 'values' => implode(', ', $mimes)]), + ], $validator->messages()->all()); + } +} diff --git a/tests/Integration/Validation/Rules/PasswordValidationTest.php b/tests/Integration/Validation/Rules/PasswordValidationTest.php new file mode 100644 index 0000000000..e1f7672ac8 --- /dev/null +++ b/tests/Integration/Validation/Rules/PasswordValidationTest.php @@ -0,0 +1,49 @@ +<?php + +namespace Illuminate\Tests\Integration\Validation\Rules; + +use Illuminate\Support\Facades\Validator; +use Illuminate\Validation\Rules\Password; +use Orchestra\Testbench\TestCase; +use PHPUnit\Framework\Attributes\TestWith; + +class PasswordValidationTest extends TestCase +{ + #[TestWith(['0'])] + #[TestWith(['.'])] + #[TestWith(['*'])] + #[TestWith(['__asterisk__'])] + public function test_it_can_validate_attribute_as_array(string $attribute) + { + $validator = Validator::make([ + 'passwords' => [ + $attribute => 'secret', + ], + ], [ + 'passwords.*' => ['required', Password::default()->min(6)], + ]); + + $this->assertTrue($validator->passes()); + } + + #[TestWith(['0'])] + #[TestWith(['.'])] + #[TestWith(['*'])] + #[TestWith(['__asterisk__'])] + public function test_it_can_validate_attribute_as_array_when_validation_should_fails(string $attribute) + { + $validator = Validator::make([ + 'passwords' => [ + $attribute => 'secret', + ], + ], [ + 'passwords.*' => ['required', Password::default()->min(8)], + ]); + + $this->assertFalse($validator->passes()); + + $this->assertSame([ + 0 => sprintf('The passwords.%s field must be at least 8 characters.', str_replace('_', ' ', $attribute)), + ], $validator->messages()->all()); + } +} diff --git a/tests/Integration/View/BladeAnonymousComponentTest.php b/tests/Integration/View/BladeAnonymousComponentTest.php index eb29765dae..0281de48d8 100644 --- a/tests/Integration/View/BladeAnonymousComponentTest.php +++ b/tests/Integration/View/BladeAnonymousComponentTest.php @@ -41,7 +41,7 @@ class BladeAnonymousComponentTest extends TestCase $view = View::make('panel')->render(); } - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { $app['config']->set('view.paths', [__DIR__.'/anonymous-components-templates']); } diff --git a/tests/Integration/View/BladeTest.php b/tests/Integration/View/BladeTest.php index 7a08d43fd0..6495175337 100644 --- a/tests/Integration/View/BladeTest.php +++ b/tests/Integration/View/BladeTest.php @@ -210,7 +210,7 @@ class BladeTest extends TestCase $this->artisan('view:clear'); } - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { $app['config']->set('view.paths', [__DIR__.'/templates']); } diff --git a/tests/Integration/View/RenderableViewExceptionTest.php b/tests/Integration/View/RenderableViewExceptionTest.php index 93c91cb313..f5ed176e26 100644 --- a/tests/Integration/View/RenderableViewExceptionTest.php +++ b/tests/Integration/View/RenderableViewExceptionTest.php @@ -21,7 +21,7 @@ class RenderableViewExceptionTest extends TestCase $response->assertSee('This is a renderable exception.'); } - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app) { $app['config']->set('view.paths', [__DIR__.'/templates']); } diff --git a/tests/Validation/ValidationEmailRuleTest.php b/tests/Validation/ValidationEmailRuleTest.php index b6382f508b..c48451db9b 100644 --- a/tests/Validation/ValidationEmailRuleTest.php +++ b/tests/Validation/ValidationEmailRuleTest.php @@ -11,6 +11,7 @@ use Illuminate\Validation\Rule; use Illuminate\Validation\Rules\Email; use Illuminate\Validation\ValidationServiceProvider; use Illuminate\Validation\Validator; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; @@ -143,6 +144,7 @@ class ValidationEmailRuleTest extends TestCase ); } + #[RequiresPhpExtension('intl')] public function testValidateMxRecord() { $this->fails( @@ -674,6 +676,7 @@ class ValidationEmailRuleTest extends TestCase ); } + #[RequiresPhpExtension('intl')] public function testCombiningRules() { $this->passes( -- GitLab