orchestral / testbench

Laravel Testing Helper for Packages Development
https://packages.tools/testbench
MIT License
2.1k stars 136 forks source link

[9.x] Breaking change: routes registered before service providers boot #403

Closed shengslogar closed 5 months ago

shengslogar commented 5 months ago

Description:

Illuminate\Routing\Router is macroable, and third-party packages may extend its functionality in the boot() method of their service provider (e.g. https://laravel.com/docs/11.x/http-client#macros).

In 8.x, defineRoutes was called after getPackageProviders. In 9.x, this commit changed that order, which causes router macros to no longer be available when registering routes:

--- $app->make('Illuminate\Foundation\Bootstrap\BootProviders')->bootstrap($app);

    if ($this->isRunningTestCase() && static::usesTestingConcern(HandlesRoutes::class)) {
       $this->setUpApplicationRoutes($app); // @phpstan-ignore-line
    }

+++ $app->make('Illuminate\Foundation\Bootstrap\BootProviders')->bootstrap($app);

Steps To Reproduce:

  1. composer require orchestra/testbench:9 and a package that macros routes, like glhd/gretel
  2. Mount the corresponding service provider in getPackageProviders (relevant source)
  3. defineRoutes and try to reference the newly-defined macro (->breadcrumb in this case)

The following error is thrown:

BadMethodCallException: Method Illuminate\Routing\Route::breadcrumb does not exist.
<?php

use Orchestra\Testbench\TestCase;
use Glhd\Gretel\Support\GretelServiceProvider;

class Repro extends TestCase
{
    protected function getPackageProviders($app)
    {
        return [GretelServiceProvider::class];
    }

    public function defineRoutes($router)
    {
        $router->get('/profile')
            ->breadcrumb('Profile'); // `->breadcrumb` fails because its macro hasn't been registered
    }
}