From eb2490b5d29be326411669f65a2d7ed9e58824e1 Mon Sep 17 00:00:00 2001 From: Franck DAKIA Date: Thu, 12 Dec 2024 09:22:41 +0000 Subject: [PATCH] fix: match should return Route class instance --- .github/workflows/tests.yml | 8 +-- src/Router/Route.php | 16 ++---- src/Router/Router.php | 60 +++++++++++---------- tests/Auth/AuthenticationTest.php | 4 +- tests/Config/stubs/storage.php | 2 +- tests/Console/GeneratorBasicTest.php | 8 +-- tests/Console/GeneratorDeepTest.php | 80 ++++++++++++++-------------- tests/Filesystem/FTPServiceTest.php | 4 +- tests/Mail/MailServiceTest.php | 7 ++- 9 files changed, 93 insertions(+), 96 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4b853d99..a42cde0d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,7 +41,7 @@ jobs: extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, mysql, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, redis coverage: none - - run: docker run --net=host -p 21:21 -e FTP_USER=$FTP_USER -e FTP_PASS=$FTP_PASSWORD -e PASV_ADDRESS=127.0.0.1 -e PASV_MIN_PORT=21100 -e PASV_MAX_PORT=21110 -d --name ftp -v $(pwd)/:/ftp/$FTP_USER --restart=always fauria/vsftpd + - run: docker run --net=host -p 21:21 -e FTP_USER=$FTP_USER -e FTP_PASS=$FTP_PASSWORD -e PASV_ADDRESS=127.0.0.1 -e PASV_MIN_PORT=21100 -e PASV_MAX_PORT=21110 -d --name ftp -v $(pwd)/:/home/vsftpd fauria/vsftpd - run: docker run -p 1080:1080 -p 1025:1025 -d --name maildev soulteary/maildev - run: docker run -p 6379:6379 -d --name redis redis - run: docker run -p 5432:5432 --name postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=postgres -e POSTGRES_PASSWORD=postgres -d postgis/postgis @@ -57,13 +57,13 @@ jobs: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} - name: Copy the php ini config - run: cp php.dist.ini php.ini + run: sudo cp php.dist.ini php.ini - name: Install dependencies - run: composer update --prefer-dist --no-interaction + run: sudo composer update --prefer-dist --no-interaction - name: Create test cache directory run: if [ ! -d /tmp/bowphp_testing ]; then mkdir -p /tmp/bowphp_testing; fi; - name: Run test suite - run: composer run-script test + run: sudo composer run-script test diff --git a/src/Router/Route.php b/src/Router/Route.php index 5313b119..850459c3 100644 --- a/src/Router/Route.php +++ b/src/Router/Route.php @@ -13,7 +13,7 @@ class Route /** * The callback has launched if the url of the query has matched. * - * @var callable + * @var mixed */ private mixed $cb; @@ -70,7 +70,7 @@ class Route * Route constructor * * @param string $path - * @param callable $cb + * @param mixed $cb * * @throws */ @@ -124,11 +124,7 @@ public function middleware(array|string $middleware): Route return $this; } - if (!isset($this->cb['middleware'])) { - $this->cb['middleware'] = $middleware; - } else { - $this->cb['middleware'] = array_merge((array) $this->cb['middleware'], $middleware); - } + $this->cb['middleware'] = !isset($this->cb['middleware']) ? $middleware : array_merge((array) $this->cb['middleware'], $middleware); return $this; } @@ -142,11 +138,7 @@ public function middleware(array|string $middleware): Route */ public function where(array|string $where, $regex_constraint = null): Route { - if (is_array($where)) { - $other_rule = $where; - } else { - $other_rule = [$where => $regex_constraint]; - } + $other_rule = is_array($where) ? $where : [$where => $regex_constraint]; $this->with = array_merge($this->with, $other_rule); diff --git a/src/Router/Router.php b/src/Router/Router.php index e8f2f399..f2fb09d7 100644 --- a/src/Router/Router.php +++ b/src/Router/Router.php @@ -162,11 +162,7 @@ public function middleware(array|string $middlewares): Router $collection = []; foreach ($middlewares as $middleware) { - if (class_exists($middleware, true)) { - $collection[] = [new $middleware(), 'process']; - } else { - $collection[] = $middleware; - } + $collection[] = class_exists($middleware, true) ? [new $middleware(), 'process'] : $middleware; } return new Router($this->method, $this->magic_method, $this->base_route, $collection); @@ -341,66 +337,72 @@ public function code(int $code, callable|array|string $cb): Router * @param callable|string|array $cb * @return Router */ - public function match(array $methods, string $path, callable|string|array $cb): Router + public function match(array $methods, string $path, callable|string|array $cb): Route { - foreach ($methods as $method) { - if ($this->method == strtoupper($method)) { - $this->pushHttpVerb(strtoupper($method), $path, $cb); - } - } + $methods = array_map('strtoupper', $methods); - return $this; + return $this->pushHttpVerb($methods, $path, $cb); } /** * Add other HTTP verbs [PUT, DELETE, UPDATE, HEAD, PATCH] * - * @param string $method + * @param string|array $methods * @param string $path * @param callable|array|string $cb * @return Route */ - private function pushHttpVerb(string $method, string $path, callable|string|array $cb): Route + private function pushHttpVerb(string|array $methods, string $path, callable|string|array $cb): Route { - if ($this->magic_method) { + $methods = (array) $methods; + + if (!$this->magic_method) { + return $this->routeLoader($methods, $path, $cb); + } + + foreach ($methods as $key => $method) { if ($this->magic_method === $method) { - $method = $this->magic_method; + $methods[$key] = $this->magic_method; } } - return $this->routeLoader($method, $path, $cb); + return $this->routeLoader($methods, $path, $cb); } /** * Start loading a route. * - * @param string $method + * @param string|array $method * @param string $path - * @param Callable|string|array $cb + * @param callable|string|array $cb * @return Route */ - private function routeLoader(string $method, string $path, callable|string|array $cb): Route + private function routeLoader(string|array $methods, string $path, callable|string|array $cb): Route { + $methods = (array) $methods; + $path = '/' . trim($path, '/'); // We build the original path based on the Router loader $path = $this->base_route . $this->prefix . $path; - // We define the current route and current method - $this->current = ['path' => $path, 'method' => $method]; - // We add the new route $route = new Route($path, $cb); $route->middleware($this->middlewares); - static::$routes[$method][] = $route; + foreach ($methods as $method) { + static::$routes[$method][] = $route; + + // We define the current route and current method + $this->current = ['path' => $path, 'method' => $method]; - if ( - $this->auto_csrf === true - && in_array($method, ['POST', 'DELETE', 'PUT']) - ) { - $route->middleware('csrf'); + if ( + $this->auto_csrf === true + && in_array($method, ['POST', 'DELETE', 'PUT']) + ) { + $route->middleware('csrf'); + } } return $route; diff --git a/tests/Auth/AuthenticationTest.php b/tests/Auth/AuthenticationTest.php index 9a957317..e233abaa 100644 --- a/tests/Auth/AuthenticationTest.php +++ b/tests/Auth/AuthenticationTest.php @@ -105,7 +105,7 @@ public function test_attempt_login_with_jwt_provider() $this->assertInstanceOf(Authentication::class, $user); $this->assertTrue($auth->check()); $this->assertEquals($auth->id(), $user->id); - $this->assertRegExp("/^([a-zA-Z0-9_-]+\.){2}[a-zA-Z0-9_-]+$/", $token); + $this->assertMatchesRegularExpression("/^([a-zA-Z0-9_-]+\.){2}[a-zA-Z0-9_-]+$/", $token); } public function test_direct_login_with_jwt_provider() @@ -119,7 +119,7 @@ public function test_direct_login_with_jwt_provider() $this->assertTrue($auth->check()); $this->assertInstanceOf(Authentication::class, $user); $this->assertEquals($auth->id(), $user->id); - $this->assertRegExp("/^([a-zA-Z0-9_-]+\.){2}[a-zA-Z0-9_-]+$/", $token); + $this->assertMatchesRegularExpression("/^([a-zA-Z0-9_-]+\.){2}[a-zA-Z0-9_-]+$/", $token); } public function test_attempt_login_with_jwt_provider_fail() diff --git a/tests/Config/stubs/storage.php b/tests/Config/stubs/storage.php index 4fcc382a..1cbeed83 100644 --- a/tests/Config/stubs/storage.php +++ b/tests/Config/stubs/storage.php @@ -23,7 +23,7 @@ */ 'ftp' => [ "driver" => "ftp", - 'hostname' => app_env('FTP_HOST', 'localhost'), + 'hostname' => app_env('FTP_HOST', '127.0.0.1'), 'password' => app_env('FTP_PASSWORD', 'password'), 'username' => app_env('FTP_USERNAME', 'username'), 'port' => app_env('FTP_PORT', 21), diff --git a/tests/Console/GeneratorBasicTest.php b/tests/Console/GeneratorBasicTest.php index d8597e86..78640aff 100644 --- a/tests/Console/GeneratorBasicTest.php +++ b/tests/Console/GeneratorBasicTest.php @@ -16,8 +16,8 @@ public function test_generate_stubs() ]); $this->assertNotNull($content); - $this->assertRegExp("@\nnamespace\sGenerator\\\Testing;\n@", $content); - $this->assertRegExp("@\nclass\sCreateUserCommand\sextends\sConsoleCommand\n@", $content); + $this->assertMatchesRegularExpression("@\nnamespace\sGenerator\\\Testing;\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sCreateUserCommand\sextends\sConsoleCommand\n@", $content); } public function test_generate_stub_without_data() @@ -26,8 +26,8 @@ public function test_generate_stub_without_data() $content = $generator->makeStubContent('command', []); $this->assertNotNull($content); - $this->assertRegExp("@\nnamespace\s\{baseNamespace\}\{namespace\};\n@", $content); - $this->assertRegExp("@\nclass\s\{className\}\sextends\sConsoleCommand\n@", $content); + $this->assertMatchesRegularExpression("@\nnamespace\s\{baseNamespace\}\{namespace\};\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\s\{className\}\sextends\sConsoleCommand\n@", $content); } public function test_generate_by_writing_file() diff --git a/tests/Console/GeneratorDeepTest.php b/tests/Console/GeneratorDeepTest.php index b6fbd8c9..a497ec2e 100644 --- a/tests/Console/GeneratorDeepTest.php +++ b/tests/Console/GeneratorDeepTest.php @@ -20,8 +20,8 @@ public function test_generate_command_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nnamespace\sApp\\\Commands;\n@", $content); - $this->assertRegExp("@\nclass\sFakeCommand\sextends\sConsoleCommand\n@", $content); + $this->assertMatchesRegularExpression("@\nnamespace\sApp\\\Commands;\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sFakeCommand\sextends\sConsoleCommand\n@", $content); } public function test_generate_configuration_stubs() @@ -35,8 +35,8 @@ public function test_generate_configuration_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nnamespace\sApp\\\Configurations;\n@", $content); - $this->assertRegExp("@\nclass\sFakeConfiguration\sextends\sConfiguration\n@", $content); + $this->assertMatchesRegularExpression("@\nnamespace\sApp\\\Configurations;\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sFakeConfiguration\sextends\sConfiguration\n@", $content); } public function test_generate_event_stubs() @@ -50,8 +50,8 @@ public function test_generate_event_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nnamespace\sApp\\\Events;\n@", $content); - $this->assertRegExp("@\nclass\sFakeEvent\simplements\sAppEvent\n@", $content); + $this->assertMatchesRegularExpression("@\nnamespace\sApp\\\Events;\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sFakeEvent\simplements\sAppEvent\n@", $content); } public function test_generate_exception_stubs() @@ -65,8 +65,8 @@ public function test_generate_exception_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nnamespace\sApp\\\Exceptions;\n@", $content); - $this->assertRegExp("@\nclass\sFakeException\sextends\sException\n@", $content); + $this->assertMatchesRegularExpression("@\nnamespace\sApp\\\Exceptions;\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sFakeException\sextends\sException\n@", $content); } public function test_generate_listener_stubs() @@ -80,8 +80,8 @@ public function test_generate_listener_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nnamespace\sApp\\\Listeners;\n@", $content); - $this->assertRegExp("@\nclass\sFakeListener\simplements\sEventListener\n@", $content); + $this->assertMatchesRegularExpression("@\nnamespace\sApp\\\Listeners;\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sFakeListener\simplements\sEventListener\n@", $content); } public function test_generate_middleware_stubs() @@ -95,8 +95,8 @@ public function test_generate_middleware_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nnamespace\sApp\\\Middlewares;\n@", $content); - $this->assertRegExp("@\nclass\sFakeMiddleware\simplements\sBaseMiddleware\n@", $content); + $this->assertMatchesRegularExpression("@\nnamespace\sApp\\\Middlewares;\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sFakeMiddleware\simplements\sBaseMiddleware\n@", $content); } public function test_generate_producer_stubs() @@ -110,8 +110,8 @@ public function test_generate_producer_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nnamespace\sApp\\\Producers;\n@", $content); - $this->assertRegExp("@\nclass\sFakeProducer\sextends\sProducerService\n@", $content); + $this->assertMatchesRegularExpression("@\nnamespace\sApp\\\Producers;\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sFakeProducer\sextends\sProducerService\n@", $content); } public function test_generate_seeder_stubs() @@ -137,8 +137,8 @@ public function test_generate_service_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nnamespace\sApp\\\Services;\n@", $content); - $this->assertRegExp("@\nclass\sFakeService\n@", $content); + $this->assertMatchesRegularExpression("@\nnamespace\sApp\\\Services;\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sFakeService\n@", $content); } public function test_generate_validation_stubs() @@ -152,8 +152,8 @@ public function test_generate_validation_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nnamespace\sApp\\\Validations;\n@", $content); - $this->assertRegExp("@\nclass\sFakeValidationRequest\sextends\sRequestValidation\n@", $content); + $this->assertMatchesRegularExpression("@\nnamespace\sApp\\\Validations;\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sFakeValidationRequest\sextends\sRequestValidation\n@", $content); } public function test_generate_cache_migration_stubs() @@ -165,7 +165,7 @@ public function test_generate_cache_migration_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nclass\sFakeCacheMigration\sextends\sMigration\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sFakeCacheMigration\sextends\sMigration\n@", $content); } public function test_generate_session_migration_stubs() @@ -177,7 +177,7 @@ public function test_generate_session_migration_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nclass\sFakeSessionMigration\sextends\sMigration\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sFakeSessionMigration\sextends\sMigration\n@", $content); } public function test_generate_queue_migration_stubs() @@ -189,7 +189,7 @@ public function test_generate_queue_migration_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nclass\sQueueTableMigration\sextends\sMigration\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sQueueTableMigration\sextends\sMigration\n@", $content); $this->assertStringContainsString("\$this->create(\"queues\", function (SQLGenerator \$table) {", $content); $this->assertStringContainsString("\$table->addInteger('attempts', [\"default\" => 3]);\n", $content); } @@ -204,7 +204,7 @@ public function test_generate_table_migration_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nclass\sFakeTableMigration\sextends\sMigration\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sFakeTableMigration\sextends\sMigration\n@", $content); } public function test_generate_create_migration_stubs() @@ -217,7 +217,7 @@ public function test_generate_create_migration_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nclass\sFakeCreateTableMigration\sextends\sMigration\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sFakeCreateTableMigration\sextends\sMigration\n@", $content); } public function test_generate_standard_migration_stubs() @@ -230,7 +230,7 @@ public function test_generate_standard_migration_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nclass\sFakeStandardTableMigration\sextends\sMigration\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sFakeStandardTableMigration\sextends\sMigration\n@", $content); } public function test_generate_model_stubs() @@ -245,7 +245,7 @@ public function test_generate_model_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nclass\sExample\sextends\sModel\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sExample\sextends\sModel\n@", $content); } public function test_generate_controller_stubs() @@ -259,7 +259,7 @@ public function test_generate_controller_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp("@\nclass\sExampleController\sextends\sController\n@", $content); + $this->assertMatchesRegularExpression("@\nclass\sExampleController\sextends\sController\n@", $content); } public function test_generate_controller_no_plain_stubs() @@ -273,14 +273,14 @@ public function test_generate_controller_no_plain_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp('@\nclass\sExampleController\sextends\sController\n@', $content); - $this->assertRegExp('@public\sfunction\sindex()@', $content); - $this->assertRegExp('@public\sfunction\screate()@', $content); - $this->assertRegExp('@public\sfunction\supdate\(Request\s\$request,\smixed\s\$id\)@', $content); - $this->assertRegExp('@public\sfunction\sshow\(mixed\s\$id\)@', $content); - $this->assertRegExp('@public\sfunction\sedit\(mixed\s\$id\)@', $content); - $this->assertRegExp('@public\sfunction\sstore\(Request\s\$request\)@', $content); - $this->assertRegExp('@public\sfunction\sdestroy\(mixed\s\$id\)@', $content); + $this->assertMatchesRegularExpression('@\nclass\sExampleController\sextends\sController\n@', $content); + $this->assertMatchesRegularExpression('@public\sfunction\sindex()@', $content); + $this->assertMatchesRegularExpression('@public\sfunction\screate()@', $content); + $this->assertMatchesRegularExpression('@public\sfunction\supdate\(Request\s\$request,\smixed\s\$id\)@', $content); + $this->assertMatchesRegularExpression('@public\sfunction\sshow\(mixed\s\$id\)@', $content); + $this->assertMatchesRegularExpression('@public\sfunction\sedit\(mixed\s\$id\)@', $content); + $this->assertMatchesRegularExpression('@public\sfunction\sstore\(Request\s\$request\)@', $content); + $this->assertMatchesRegularExpression('@public\sfunction\sdestroy\(mixed\s\$id\)@', $content); } public function test_generate_controller_rest_stubs() @@ -294,11 +294,11 @@ public function test_generate_controller_rest_stubs() $this->assertNotNull($content); $this->assertMatchesSnapshot($content); - $this->assertRegExp('@\nclass\sExampleController\sextends\sController\n@', $content); - $this->assertRegExp('@public\sfunction\sindex()@', $content); - $this->assertRegExp('@public\sfunction\supdate\(Request\s\$request,\smixed\s\$id\)@', $content); - $this->assertRegExp('@public\sfunction\sshow\(Request\s\$request,\smixed\s\$id\)@', $content); - $this->assertRegExp('@public\sfunction\sstore\(Request\s\$request\)@', $content); - $this->assertRegExp('@public\sfunction\sdestroy\(Request\s\$request,\smixed\s\$id\)@', $content); + $this->assertMatchesRegularExpression('@\nclass\sExampleController\sextends\sController\n@', $content); + $this->assertMatchesRegularExpression('@public\sfunction\sindex()@', $content); + $this->assertMatchesRegularExpression('@public\sfunction\supdate\(Request\s\$request,\smixed\s\$id\)@', $content); + $this->assertMatchesRegularExpression('@public\sfunction\sshow\(Request\s\$request,\smixed\s\$id\)@', $content); + $this->assertMatchesRegularExpression('@public\sfunction\sstore\(Request\s\$request\)@', $content); + $this->assertMatchesRegularExpression('@public\sfunction\sdestroy\(Request\s\$request,\smixed\s\$id\)@', $content); } } diff --git a/tests/Filesystem/FTPServiceTest.php b/tests/Filesystem/FTPServiceTest.php index 2014cc70..c12b74fe 100644 --- a/tests/Filesystem/FTPServiceTest.php +++ b/tests/Filesystem/FTPServiceTest.php @@ -159,7 +159,7 @@ public function test_append_content_into_file() $this->createFile($this->ftp_service, 'append.txt', 'something'); $this->ftp_service->append('append.txt', ' else'); - $this->assertRegExp('/something else/', $this->ftp_service->get('append.txt')); + $this->assertMatchesRegularExpression('/something else/', $this->ftp_service->get('append.txt')); } public function test_prepend_content_into_file() @@ -167,7 +167,7 @@ public function test_prepend_content_into_file() $this->createFile($this->ftp_service, 'prepend.txt', 'else'); $this->ftp_service->prepend('prepend.txt', 'something '); - $this->assertRegExp('/something else/', $this->ftp_service->get('prepend.txt')); + $this->assertMatchesRegularExpression('/something else/', $this->ftp_service->get('prepend.txt')); } public function test_put_content_into_file() diff --git a/tests/Mail/MailServiceTest.php b/tests/Mail/MailServiceTest.php index dddf1f79..2fe9daf3 100644 --- a/tests/Mail/MailServiceTest.php +++ b/tests/Mail/MailServiceTest.php @@ -110,8 +110,9 @@ public function test_send_mail_with_view_for_notive_driver() return $this->markTestSkipped('Test have been skip because /usr/sbin/sendmail not found'); } + $config = (array) $this->config["mail"]; View::configure($this->config["view"]); - Mail::configure([...$this->config["mail"], "driver" => "mail"]); + Mail::configure([...$config, "driver" => "mail"]); $response = Mail::send('mail', ['name' => "papac"], function (Message $message) { $message->to('bow@bowphp.com'); @@ -123,8 +124,10 @@ public function test_send_mail_with_view_for_notive_driver() public function test_send_mail_with_view_not_found_for_notive_driver() { + $config = (array) $this->config["mail"]; + View::configure($this->config["view"]); - Mail::configure([...$this->config["mail"], "driver" => "mail"]); + Mail::configure([...$config, "driver" => "mail"]); $this->expectException(ViewException::class); $this->expectExceptionMessage('The view [mail_view_not_found.twig] does not exists.');