diff --git a/CHANGELOG-6.x.md b/CHANGELOG-6.x.md index 8ec4a08e9afe..078fe3776c23 100644 --- a/CHANGELOG-6.x.md +++ b/CHANGELOG-6.x.md @@ -1,6 +1,13 @@ # Release Notes for 6.x -## [Unreleased](https://github.com/laravel/framework/compare/v6.20.7...6.x) +## [Unreleased](https://github.com/laravel/framework/compare/v6.20.8...6.x) + + +## [v6.20.8 (2020-12-22)](https://github.com/laravel/framework/compare/v6.20.7...v6.20.8) + +### Fixed +- Fixed `Illuminate\Validation\Concerns\ValidatesAttributes::validateJson()` for PHP8 ([#35646](https://github.com/laravel/framework/pull/35646)) +- Catch DecryptException with invalid X-XSRF-TOKEN in `Illuminate\Foundation\Http\Middleware\VerifyCsrfToken` ([#35671](https://github.com/laravel/framework/pull/35671)) ## [v6.20.7 (2020-12-08)](https://github.com/laravel/framework/compare/v6.20.6...v6.20.7) diff --git a/CHANGELOG-8.x.md b/CHANGELOG-8.x.md index 12793d5c2139..c0499d7f01e5 100644 --- a/CHANGELOG-8.x.md +++ b/CHANGELOG-8.x.md @@ -1,6 +1,31 @@ # Release Notes for 8.x -## [Unreleased](https://github.com/laravel/framework/compare/v8.19.0...8.x) +## [Unreleased](https://github.com/laravel/framework/compare/v8.20.1...8.x) + + +## [v8.20.1 (2020-12-22)](https://github.com/laravel/framework/compare/v8.20.0...v8.20.1) + +### Revert +- Revert [Clear a cached user in RequestGuard if a request is changed](https://github.com/laravel/framework/pull/35692) ([ca8ccd6](https://github.com/laravel/framework/commit/ca8ccd6757d5639f0e5fb241b3df6878da6ce34e)) + + +## [v8.20.0 (2020-12-22)](https://github.com/laravel/framework/compare/v8.19.0...v8.20.0) + +### Added +- Added `Illuminate\Database\DBAL\TimestampType` ([a5761d4](https://github.com/laravel/framework/commit/a5761d4187abea654cb422c2f70054a880ffd2e0), [cff3705](https://github.com/laravel/framework/commit/cff37055cbf031109ae769e8fd6ad1951be47aa6) [382445f](https://github.com/laravel/framework/commit/382445f8487de45a05ebe121837f917b92560a97), [810047e](https://github.com/laravel/framework/commit/810047e1f184f8a4def372885591e4fbb6996b51)) +- Added ability to specify a separate lock connection ([#35621](https://github.com/laravel/framework/pull/35621), [3d95235](https://github.com/laravel/framework/commit/3d95235a6ad8525886071ad68e818a225786064f)) +- Added `Illuminate\Database\Eloquent\Relations\Concerns\InteractsWithPivotTable::syncWithPivotValues()` ([#35644](https://github.com/laravel/framework/pull/35644), [49b3ce0](https://github.com/laravel/framework/commit/49b3ce098d8a612797b195c4e3774b1e00c604c8)) + +### Fixed +- Fixed `Illuminate\Validation\Concerns\ValidatesAttributes::validateJson()` for PHP8 ([#35646](https://github.com/laravel/framework/pull/35646)) +- Fixed `assertCookieExpired()` and `assertCookieNotExpired()` methods in `Illuminate\Testing\TestResponse` ([#35637](https://github.com/laravel/framework/pull/35637)) +- Fixed: Account for a numerical array of views in Mailable::renderForAssertions() ([#35662](https://github.com/laravel/framework/pull/35662)) +- Catch DecryptException with invalid X-XSRF-TOKEN in `Illuminate\Foundation\Http\Middleware\VerifyCsrfToken` ([#35671](https://github.com/laravel/framework/pull/35671)) + +### Changed +- Check configuration in `Illuminate\Foundation\Console\Kernel::scheduleCache()` ([a253d0e](https://github.com/laravel/framework/commit/a253d0e40d3deb293d54df9f4455879af5365aab)) +- Modify `Model::mergeCasts` to return `$this` ([#35683](https://github.com/laravel/framework/pull/35683)) +- Clear a cached user in RequestGuard if a request is changed ([#35692](https://github.com/laravel/framework/pull/35692)) ## [v8.19.0 (2020-12-15)](https://github.com/laravel/framework/compare/v8.18.1...v8.19.0) diff --git a/src/Illuminate/Bus/Batch.php b/src/Illuminate/Bus/Batch.php index 1073ecd46d37..cac16e1e9f51 100644 --- a/src/Illuminate/Bus/Batch.php +++ b/src/Illuminate/Bus/Batch.php @@ -170,7 +170,10 @@ public function add($jobs) $count += count($job); return with($this->prepareBatchedChain($job), function ($chain) { - return $chain->first()->chain($chain->slice(1)->values()->all()); + return $chain->first() + ->allOnQueue($this->options['queue'] ?? null) + ->allOnConnection($this->options['connection'] ?? null) + ->chain($chain->slice(1)->values()->all()); }); } else { $job->withBatchId($this->id); diff --git a/src/Illuminate/Bus/DatabaseBatchRepository.php b/src/Illuminate/Bus/DatabaseBatchRepository.php index d911c380d551..ece6301c126f 100644 --- a/src/Illuminate/Bus/DatabaseBatchRepository.php +++ b/src/Illuminate/Bus/DatabaseBatchRepository.php @@ -4,11 +4,12 @@ use Carbon\CarbonImmutable; use Closure; +use DateTimeInterface; use Illuminate\Database\Connection; use Illuminate\Database\Query\Expression; use Illuminate\Support\Str; -class DatabaseBatchRepository implements BatchRepository +class DatabaseBatchRepository implements PrunableBatchRepository { /** * The batch factory instance. @@ -230,6 +231,29 @@ public function delete(string $batchId) $this->connection->table($this->table)->where('id', $batchId)->delete(); } + /** + * Prune all of the entries older than the given date. + * + * @param \DateTimeInterface $before + * @return int + */ + public function prune(DateTimeInterface $before) + { + $query = $this->connection->table($this->table) + ->whereNotNull('finished_at') + ->where('finished_at', '<', $before->getTimestamp()); + + $totalDeleted = 0; + + do { + $deleted = $query->take(1000)->delete(); + + $totalDeleted += $deleted; + } while ($deleted !== 0); + + return $totalDeleted; + } + /** * Execute the given Closure within a storage specific transaction. * diff --git a/src/Illuminate/Bus/PrunableBatchRepository.php b/src/Illuminate/Bus/PrunableBatchRepository.php new file mode 100644 index 000000000000..3f972553b597 --- /dev/null +++ b/src/Illuminate/Bus/PrunableBatchRepository.php @@ -0,0 +1,16 @@ +getSeconds($ttl) <= 0) { + $seconds = $this->getSeconds($ttl); + + if ($seconds <= 0) { return false; } @@ -301,8 +305,6 @@ public function add($key, $value, $ttl = null) // has a chance to override this logic. Some drivers better support the way // this operation should work with a total "atomic" implementation of it. if (method_exists($this->store, 'add')) { - $seconds = $this->getSeconds($ttl); - return $this->store->add( $this->itemKey($key), $value, $seconds ); @@ -313,7 +315,7 @@ public function add($key, $value, $ttl = null) // so it exists for subsequent requests. Then, we will return true so it is // easy to know if the value gets added. Otherwise, we will return false. if (is_null($this->get($key))) { - return $this->put($key, $value, $ttl); + return $this->put($key, $value, $seconds); } return false; diff --git a/src/Illuminate/Database/Console/DbCommand.php b/src/Illuminate/Database/Console/DbCommand.php index ee6633557017..9152d1dc844c 100644 --- a/src/Illuminate/Database/Console/DbCommand.php +++ b/src/Illuminate/Database/Console/DbCommand.php @@ -83,7 +83,7 @@ public function commandEnvironment(array $connection) { $driver = ucfirst($connection['driver']); - if (method_exists($this, "get{$driver}Env")) { + if (method_exists($this, "get{$driver}Environment")) { return $this->{"get{$driver}Environment"}($connection); } diff --git a/src/Illuminate/Database/Console/DumpCommand.php b/src/Illuminate/Database/Console/DumpCommand.php index e7b60c7efa7c..fe73fb2af033 100644 --- a/src/Illuminate/Database/Console/DumpCommand.php +++ b/src/Illuminate/Database/Console/DumpCommand.php @@ -66,7 +66,7 @@ public function handle(ConnectionResolverInterface $connections, Dispatcher $dis protected function schemaState(Connection $connection) { return $connection->getSchemaState() - ->withMigrationTable(Config::get('database.migrations', 'migrations')) + ->withMigrationTable($connection->getTablePrefix().Config::get('database.migrations', 'migrations')) ->handleOutputUsing(function ($type, $buffer) { $this->output->write($buffer); }); diff --git a/src/Illuminate/Database/DatabaseServiceProvider.php b/src/Illuminate/Database/DatabaseServiceProvider.php index 72f131d0db49..9f2ab18503e1 100755 --- a/src/Illuminate/Database/DatabaseServiceProvider.php +++ b/src/Illuminate/Database/DatabaseServiceProvider.php @@ -123,7 +123,9 @@ protected function registerDoctrineTypes() $types = $this->app['config']->get('database.dbal.types', []); foreach ($types as $name => $class) { - Type::addType($name, $class); + if (! Type::hasType($name)) { + Type::addType($name, $class); + } } } } diff --git a/src/Illuminate/Database/DetectsLostConnections.php b/src/Illuminate/Database/DetectsLostConnections.php index c214c0396c84..6ba3c4939faa 100644 --- a/src/Illuminate/Database/DetectsLostConnections.php +++ b/src/Illuminate/Database/DetectsLostConnections.php @@ -47,6 +47,7 @@ protected function causedByLostConnection(Throwable $e) 'SQLSTATE[HY000]: General error: 7 SSL SYSCALL error: EOF detected', 'SQLSTATE[HY000] [2002] Connection timed out', 'SSL: Connection timed out', + 'SQLSTATE[HY000]: General error: 1105 The last transaction was aborted due to Seamless Scaling. Please retry.', ]); } } diff --git a/src/Illuminate/Foundation/Application.php b/src/Illuminate/Foundation/Application.php index c7049c14096c..3dfa37ef701c 100755 --- a/src/Illuminate/Foundation/Application.php +++ b/src/Illuminate/Foundation/Application.php @@ -33,7 +33,7 @@ class Application extends Container implements ApplicationContract, CachesConfig * * @var string */ - const VERSION = '8.20.1'; + const VERSION = '8.21.0'; /** * The base path for the Laravel installation. diff --git a/src/Illuminate/Foundation/Console/stubs/test.stub b/src/Illuminate/Foundation/Console/stubs/test.stub index c5b50ad3cb6b..84c75cbfe98d 100644 --- a/src/Illuminate/Foundation/Console/stubs/test.stub +++ b/src/Illuminate/Foundation/Console/stubs/test.stub @@ -13,7 +13,7 @@ class {{ class }} extends TestCase * * @return void */ - public function testExample() + public function test_example() { $response = $this->get('/'); diff --git a/src/Illuminate/Foundation/Console/stubs/test.unit.stub b/src/Illuminate/Foundation/Console/stubs/test.unit.stub index 98af6529355c..b6816aa72f29 100644 --- a/src/Illuminate/Foundation/Console/stubs/test.unit.stub +++ b/src/Illuminate/Foundation/Console/stubs/test.unit.stub @@ -11,7 +11,7 @@ class {{ class }} extends TestCase * * @return void */ - public function testExample() + public function test_example() { $this->assertTrue(true); } diff --git a/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php b/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php index 99953bfd5e90..831468281fbc 100644 --- a/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php +++ b/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php @@ -42,7 +42,6 @@ public function __construct(Application $app) * @return mixed * * @throws \Symfony\Component\HttpKernel\Exception\HttpException - * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ public function handle($request, Closure $next) { diff --git a/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php b/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php index 9cce44c00e3f..4426e4b5d34c 100755 --- a/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php +++ b/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php @@ -67,6 +67,7 @@ use Illuminate\Queue\Console\ForgetFailedCommand as ForgetFailedQueueCommand; use Illuminate\Queue\Console\ListenCommand as QueueListenCommand; use Illuminate\Queue\Console\ListFailedCommand as ListFailedQueueCommand; +use Illuminate\Queue\Console\PruneBatchesCommand as PruneBatchesQueueCommand; use Illuminate\Queue\Console\RestartCommand as QueueRestartCommand; use Illuminate\Queue\Console\RetryBatchCommand as QueueRetryBatchCommand; use Illuminate\Queue\Console\RetryCommand as QueueRetryCommand; @@ -107,6 +108,7 @@ class ArtisanServiceProvider extends ServiceProvider implements DeferrableProvid 'QueueFlush' => 'command.queue.flush', 'QueueForget' => 'command.queue.forget', 'QueueListen' => 'command.queue.listen', + 'QueuePruneBatches' => 'command.queue.prune-batches', 'QueueRestart' => 'command.queue.restart', 'QueueRetry' => 'command.queue.retry', 'QueueRetryBatch' => 'command.queue.retry-batch', @@ -684,6 +686,18 @@ protected function registerQueueListenCommand() }); } + /** + * Register the command. + * + * @return void + */ + protected function registerQueuePruneBatchesCommand() + { + $this->app->singleton('command.queue.prune-batches', function () { + return new PruneBatchesQueueCommand; + }); + } + /** * Register the command. * diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index a8a4a291d0c9..97fcda7827c5 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -327,8 +327,13 @@ protected function createMailgunTransport(array $config) */ protected function createPostmarkTransport(array $config) { + $headers = isset($config['message_stream_id']) ? [ + 'X-PM-Message-Stream' => $config['message_stream_id'], + ] : []; + return tap(new PostmarkTransport( - $config['token'] ?? $this->app['config']->get('services.postmark.token') + $config['token'] ?? $this->app['config']->get('services.postmark.token'), + $headers ), function ($transport) { $transport->registerPlugin(new ThrowExceptionOnFailurePlugin()); }); diff --git a/src/Illuminate/Queue/Console/PruneBatchesCommand.php b/src/Illuminate/Queue/Console/PruneBatchesCommand.php new file mode 100644 index 000000000000..cc25bc53cfb9 --- /dev/null +++ b/src/Illuminate/Queue/Console/PruneBatchesCommand.php @@ -0,0 +1,43 @@ +laravel[BatchRepository::class]; + + if ($repository instanceof PrunableBatchRepository) { + $count = $repository->prune(Carbon::now()->subHours($this->option('hours'))); + } + + $this->info("{$count} entries deleted!"); + } +} diff --git a/src/Illuminate/Queue/Console/RetryCommand.php b/src/Illuminate/Queue/Console/RetryCommand.php index e9120a976962..fe6248800c99 100644 --- a/src/Illuminate/Queue/Console/RetryCommand.php +++ b/src/Illuminate/Queue/Console/RetryCommand.php @@ -93,14 +93,14 @@ protected function getJobIdsByRanges(array $ranges) protected function retryJob($job) { $this->laravel['queue']->connection($job->connection)->pushRaw( - $this->resetAttempts($job->payload), $job->queue + $this->refreshRetryUntil($this->resetAttempts($job->payload)), $job->queue ); } /** * Reset the payload attempts. * - * Applicable to Redis jobs which store attempts in their payload. + * Applicable to Redis and other jobs which store attempts in their payload. * * @param string $payload * @return string @@ -115,4 +115,23 @@ protected function resetAttempts($payload) return json_encode($payload); } + + /** + * Refresh the "retry until" timestamp for the job. + * + * @param string $payload + * @return string + */ + protected function refreshRetryUntil($payload) + { + $payload = json_decode($payload, true); + + $instance = unserialize($payload['data']['command']); + + if (is_object($instance) && method_exists($instance, 'retryUntil')) { + $payload['retryUntil'] = $instance->retryUntil()->timestamp; + } + + return json_encode($payload); + } } diff --git a/src/Illuminate/Queue/DatabaseQueue.php b/src/Illuminate/Queue/DatabaseQueue.php index 961b4e460b04..cc77007c0b2f 100644 --- a/src/Illuminate/Queue/DatabaseQueue.php +++ b/src/Illuminate/Queue/DatabaseQueue.php @@ -47,14 +47,20 @@ class DatabaseQueue extends Queue implements QueueContract, ClearableQueue * @param string $table * @param string $default * @param int $retryAfter + * @param bool $dispatchAfterCommit * @return void */ - public function __construct(Connection $database, $table, $default = 'default', $retryAfter = 60) + public function __construct(Connection $database, + $table, + $default = 'default', + $retryAfter = 60, + $dispatchAfterCommit = false) { $this->table = $table; $this->default = $default; $this->database = $database; $this->retryAfter = $retryAfter; + $this->dispatchAfterCommit = $dispatchAfterCommit; } /** diff --git a/src/Illuminate/Queue/RedisQueue.php b/src/Illuminate/Queue/RedisQueue.php index 3aca40c9c388..79efc0581f24 100644 --- a/src/Illuminate/Queue/RedisQueue.php +++ b/src/Illuminate/Queue/RedisQueue.php @@ -209,11 +209,7 @@ public function pop($queue = null) { $this->migrate($prefixed = $this->getQueue($queue)); - if (empty($nextJob = $this->retrieveNextJob($prefixed))) { - return; - } - - [$job, $reserved] = $nextJob; + [$job, $reserved] = $this->retrieveNextJob($prefixed); if ($reserved) { return new RedisJob( diff --git a/src/Illuminate/Routing/CompiledRouteCollection.php b/src/Illuminate/Routing/CompiledRouteCollection.php index 099156cc4b81..c53954194e06 100644 --- a/src/Illuminate/Routing/CompiledRouteCollection.php +++ b/src/Illuminate/Routing/CompiledRouteCollection.php @@ -252,6 +252,10 @@ public function getRoutesByMethod() }) ->map(function (Collection $routes) { return $routes->mapWithKeys(function (Route $route) { + if ($domain = $route->getDomain()) { + return [$domain.'/'.$route->uri => $route]; + } + return [$route->uri => $route]; })->all(); }) diff --git a/src/Illuminate/Routing/Exceptions/UrlGenerationException.php b/src/Illuminate/Routing/Exceptions/UrlGenerationException.php index 1853b2aff0fc..e0057c9d6bbf 100644 --- a/src/Illuminate/Routing/Exceptions/UrlGenerationException.php +++ b/src/Illuminate/Routing/Exceptions/UrlGenerationException.php @@ -3,6 +3,8 @@ namespace Illuminate\Routing\Exceptions; use Exception; +use Illuminate\Routing\Route; +use Illuminate\Support\Str; class UrlGenerationException extends Exception { @@ -10,10 +12,26 @@ class UrlGenerationException extends Exception * Create a new exception for missing route parameters. * * @param \Illuminate\Routing\Route $route + * @param array $parameters * @return static */ - public static function forMissingParameters($route) + public static function forMissingParameters(Route $route, array $parameters = []) { - return new static("Missing required parameters for [Route: {$route->getName()}] [URI: {$route->uri()}]."); + $parameterLabel = Str::plural('parameter', count($parameters)); + + $message = sprintf( + 'Missing required %s for [Route: %s] [URI: %s]', + $parameterLabel, + $route->getName(), + $route->uri() + ); + + if (count($parameters) > 0) { + $message .= sprintf(' [Missing %s: %s]', $parameterLabel, implode(', ', $parameters)); + } + + $message .= '.'; + + return new static($message); } } diff --git a/src/Illuminate/Routing/RouteUrlGenerator.php b/src/Illuminate/Routing/RouteUrlGenerator.php index 5cc03c1e246c..5f1248966c77 100644 --- a/src/Illuminate/Routing/RouteUrlGenerator.php +++ b/src/Illuminate/Routing/RouteUrlGenerator.php @@ -87,8 +87,8 @@ public function to($route, $parameters = [], $absolute = false) $route ), $parameters); - if (preg_match('/\{.*?\}/', $uri)) { - throw UrlGenerationException::forMissingParameters($route); + if (preg_match_all('/{(.*?)}/', $uri, $matchedMissingParameters)) { + throw UrlGenerationException::forMissingParameters($route, $matchedMissingParameters[1]); } // Once we have ensured that there are no missing parameters in the URI we will encode diff --git a/src/Illuminate/Support/Facades/View.php b/src/Illuminate/Support/Facades/View.php index b85b086c5547..9b66464c9d96 100755 --- a/src/Illuminate/Support/Facades/View.php +++ b/src/Illuminate/Support/Facades/View.php @@ -4,7 +4,7 @@ /** * @method static \Illuminate\Contracts\View\Factory addNamespace(string $namespace, string|array $hints) - * @method static \Illuminate\Contracts\View\Factory first(array $views, \Illuminate\Contracts\Support\Arrayable|array $data = [], array $mergeData = []) + * @method static \Illuminate\Contracts\View\View first(array $views, \Illuminate\Contracts\Support\Arrayable|array $data = [], array $mergeData = []) * @method static \Illuminate\Contracts\View\Factory replaceNamespace(string $namespace, string|array $hints) * @method static \Illuminate\Contracts\View\View file(string $path, array $data = [], array $mergeData = []) * @method static \Illuminate\Contracts\View\View make(string $view, array $data = [], array $mergeData = []) diff --git a/tests/Bus/BusBatchTest.php b/tests/Bus/BusBatchTest.php index 381200daa171..8f4d6c5a11d4 100644 --- a/tests/Bus/BusBatchTest.php +++ b/tests/Bus/BusBatchTest.php @@ -332,6 +332,7 @@ public function test_chain_can_be_added_to_batch() $this->assertEquals(3, $batch->totalJobs); $this->assertEquals(3, $batch->pendingJobs); + $this->assertEquals('test-queue', $chainHeadJob->chainQueue); $this->assertTrue(is_string($chainHeadJob->batchId)); $this->assertTrue(is_string($secondJob->batchId)); $this->assertTrue(is_string($thirdJob->batchId)); diff --git a/tests/Cache/CacheMemcachedStoreTest.php b/tests/Cache/CacheMemcachedStoreTest.php index 5b29dd70b279..b1aad12ad29d 100755 --- a/tests/Cache/CacheMemcachedStoreTest.php +++ b/tests/Cache/CacheMemcachedStoreTest.php @@ -11,7 +11,7 @@ class CacheMemcachedStoreTest extends TestCase { - public function tearDown(): void + protected function tearDown(): void { m::close(); diff --git a/tests/Integration/Foundation/MaintenanceModeTest.php b/tests/Integration/Foundation/MaintenanceModeTest.php index 31f08df44da9..ff93fe41a492 100644 --- a/tests/Integration/Foundation/MaintenanceModeTest.php +++ b/tests/Integration/Foundation/MaintenanceModeTest.php @@ -14,7 +14,7 @@ */ class MaintenanceModeTest extends TestCase { - public function tearDown(): void + protected function tearDown(): void { @unlink(storage_path('framework/down')); } diff --git a/tests/Integration/Routing/CompiledRouteCollectionTest.php b/tests/Integration/Routing/CompiledRouteCollectionTest.php index 22928a4c1f4f..e474e8a461c4 100644 --- a/tests/Integration/Routing/CompiledRouteCollectionTest.php +++ b/tests/Integration/Routing/CompiledRouteCollectionTest.php @@ -490,6 +490,59 @@ public function testTrailingSlashIsTrimmedWhenMatchingCachedRoutes() $this->assertSame('foo', $this->collection()->match($request)->getName()); } + public function testRouteWithSamePathAndSameMethodButDiffDomainNameWithOptionsMethod() + { + $routes = [ + 'foo_domain' => $this->newRoute('GET', 'same/path', [ + 'uses' => 'FooController@index', + 'as' => 'foo', + 'domain' => 'foo.localhost', + ]), + 'bar_domain' => $this->newRoute('GET', 'same/path', [ + 'uses' => 'BarController@index', + 'as' => 'bar', + 'domain' => 'bar.localhost', + ]), + 'no_domain' => $this->newRoute('GET', 'same/path', [ + 'uses' => 'BarController@index', + 'as' => 'no_domain', + ]), + ]; + + $this->routeCollection->add($routes['foo_domain']); + $this->routeCollection->add($routes['bar_domain']); + $this->routeCollection->add($routes['no_domain']); + + $expectedMethods = [ + 'OPTIONS', + ]; + + $this->assertSame($expectedMethods, $this->collection()->match( + Request::create('http://foo.localhost/same/path', 'OPTIONS') + )->methods); + + $this->assertSame($expectedMethods, $this->collection()->match( + Request::create('http://bar.localhost/same/path', 'OPTIONS') + )->methods); + + $this->assertSame($expectedMethods, $this->collection()->match( + Request::create('http://no.localhost/same/path', 'OPTIONS') + )->methods); + + $this->assertEquals([ + 'HEAD' => [ + 'foo.localhost/same/path' => $routes['foo_domain'], + 'bar.localhost/same/path' => $routes['bar_domain'], + 'same/path' => $routes['no_domain'], + ], + 'GET' => [ + 'foo.localhost/same/path' => $routes['foo_domain'], + 'bar.localhost/same/path' => $routes['bar_domain'], + 'same/path' => $routes['no_domain'], + ], + ], $this->collection()->getRoutesByMethod()); + } + /** * Create a new Route object. * diff --git a/tests/Routing/RoutingRouteTest.php b/tests/Routing/RoutingRouteTest.php index 6715aa7297d9..9a9f76e8123f 100644 --- a/tests/Routing/RoutingRouteTest.php +++ b/tests/Routing/RoutingRouteTest.php @@ -1831,7 +1831,7 @@ public function testRouteRedirectStripsMissingStartingForwardSlash() public function testRouteRedirectExceptionWhenMissingExpectedParameters() { $this->expectException(UrlGenerationException::class); - $this->expectExceptionMessage('Missing required parameters for [Route: laravel_route_redirect_destination] [URI: users/{user}].'); + $this->expectExceptionMessage('Missing required parameter for [Route: laravel_route_redirect_destination] [URI: users/{user}] [Missing parameter: user].'); $container = new Container; $router = new Router(new Dispatcher, $container); diff --git a/tests/Routing/RoutingUrlGeneratorTest.php b/tests/Routing/RoutingUrlGeneratorTest.php index b7663b686b17..676f609b15fa 100755 --- a/tests/Routing/RoutingUrlGeneratorTest.php +++ b/tests/Routing/RoutingUrlGeneratorTest.php @@ -550,6 +550,61 @@ public function testUrlGenerationForControllersRequiresPassingOfRequiredParamete $this->assertSame('http://www.foo.com:8080/foo?test=123', $url->route('foo', $parameters)); } + public function provideParametersAndExpectedMeaningfulExceptionMessages() + { + return [ + 'Missing parameters "one", "two" and "three"' => [ + [], + 'Missing required parameters for [Route: foo] [URI: foo/{one}/{two}/{three}/{four?}] [Missing parameters: one, two, three].', + ], + 'Missing parameters "two" and "three"' => [ + ['one' => '123'], + 'Missing required parameters for [Route: foo] [URI: foo/{one}/{two}/{three}/{four?}] [Missing parameters: two, three].', + ], + 'Missing parameters "one" and "three"' => [ + ['two' => '123'], + 'Missing required parameters for [Route: foo] [URI: foo/{one}/{two}/{three}/{four?}] [Missing parameters: one, three].', + ], + 'Missing parameters "one" and "two"' => [ + ['three' => '123'], + 'Missing required parameters for [Route: foo] [URI: foo/{one}/{two}/{three}/{four?}] [Missing parameters: one, two].', + ], + 'Missing parameter "three"' => [ + ['one' => '123', 'two' => '123'], + 'Missing required parameter for [Route: foo] [URI: foo/{one}/{two}/{three}/{four?}] [Missing parameter: three].', + ], + 'Missing parameter "two"' => [ + ['one' => '123', 'three' => '123'], + 'Missing required parameter for [Route: foo] [URI: foo/{one}/{two}/{three}/{four?}] [Missing parameter: two].', + ], + 'Missing parameter "one"' => [ + ['two' => '123', 'three' => '123'], + 'Missing required parameter for [Route: foo] [URI: foo/{one}/{two}/{three}/{four?}] [Missing parameter: one].', + ], + ]; + } + + /** + * @dataProvider provideParametersAndExpectedMeaningfulExceptionMessages + */ + public function testUrlGenerationThrowsExceptionForMissingParametersWithMeaningfulMessage($parameters, $expectedMeaningfulExceptionMessage) + { + $this->expectException(UrlGenerationException::class); + $this->expectExceptionMessage($expectedMeaningfulExceptionMessage); + + $url = new UrlGenerator( + $routes = new RouteCollection, + Request::create('http://www.foo.com:8080/') + ); + + $route = new Route(['GET'], 'foo/{one}/{two}/{three}/{four?}', ['as' => 'foo', function () { + // + }]); + $routes->add($route); + + $url->route('foo', $parameters); + } + public function testForceRootUrl() { $url = new UrlGenerator( diff --git a/tests/View/Blade/BladeComponentTagCompilerTest.php b/tests/View/Blade/BladeComponentTagCompilerTest.php index 6872d38ae4a1..b84030c13d2b 100644 --- a/tests/View/Blade/BladeComponentTagCompilerTest.php +++ b/tests/View/Blade/BladeComponentTagCompilerTest.php @@ -13,7 +13,7 @@ class BladeComponentTagCompilerTest extends AbstractBladeTestCase { - public function tearDown(): void + protected function tearDown(): void { Mockery::close(); } diff --git a/tests/View/ComponentTest.php b/tests/View/ComponentTest.php index 124d954d454e..8049c7aa5bc5 100644 --- a/tests/View/ComponentTest.php +++ b/tests/View/ComponentTest.php @@ -19,7 +19,7 @@ class ComponentTest extends TestCase protected $viewFactory; protected $config; - public function setUp(): void + protected function setUp(): void { $this->config = m::mock(Config::class); diff --git a/tests/View/ViewFactoryTest.php b/tests/View/ViewFactoryTest.php index 52061422074e..ab003c3b9f9d 100755 --- a/tests/View/ViewFactoryTest.php +++ b/tests/View/ViewFactoryTest.php @@ -7,6 +7,7 @@ use Illuminate\Container\Container; use Illuminate\Contracts\Events\Dispatcher as DispatcherContract; use Illuminate\Contracts\View\Engine; +use Illuminate\Contracts\View\View as ViewContract; use Illuminate\Events\Dispatcher; use Illuminate\Filesystem\Filesystem; use Illuminate\Support\HtmlString; @@ -87,6 +88,7 @@ public function testFirstCreatesNewViewInstanceWithProperPath() $factory->addExtension('php', 'php'); $view = $factory->first(['bar', 'view'], ['foo' => 'bar'], ['baz' => 'boom']); + $this->assertInstanceOf(ViewContract::class, $view); $this->assertSame($engine, $view->getEngine()); $this->assertSame($_SERVER['__test.view'], $view); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy