diff --git a/src/Bootstrappers/RootUrlBootstrapper.php b/src/Bootstrappers/RootUrlBootstrapper.php index 6a5236736..3a6501690 100644 --- a/src/Bootstrappers/RootUrlBootstrapper.php +++ b/src/Bootstrappers/RootUrlBootstrapper.php @@ -7,7 +7,6 @@ use Closure; use Illuminate\Config\Repository; use Illuminate\Contracts\Foundation\Application; -use Illuminate\Routing\UrlGenerator; use Stancl\Tenancy\Contracts\TenancyBootstrapper; use Stancl\Tenancy\Contracts\Tenant; @@ -36,28 +35,46 @@ class RootUrlBootstrapper implements TenancyBootstrapper protected string|null $originalRootUrl = null; + /** + * You may want to selectively enable or disable this bootstrapper in specific tests. + * For instance, when using `Livewire::test()` this bootstrapper can cause problems, + * due to an internal Livewire route, so you may want to disable it, while in tests + * that are generating URLs in things like mails, the bootstrapper should be used + * just like in any queued job. + */ + public static bool $rootUrlOverrideInTests = false; + public function __construct( - protected UrlGenerator $urlGenerator, protected Repository $config, protected Application $app, ) {} public function bootstrap(Tenant $tenant): void { - if ($this->app->runningInConsole() && static::$rootUrlOverride) { - $this->originalRootUrl = $this->urlGenerator->to('/'); + if (static::$rootUrlOverride === null) { + return; + } - $newRootUrl = (static::$rootUrlOverride)($tenant, $this->originalRootUrl); + if (! $this->app->runningInConsole()) { + return; + } - $this->urlGenerator->forceRootUrl($newRootUrl); - $this->config->set('app.url', $newRootUrl); + if ($this->app->runningUnitTests() && ! static::$rootUrlOverrideInTests) { + return; } + + $this->originalRootUrl = $this->app['url']->to('/'); + + $newRootUrl = (static::$rootUrlOverride)($tenant, $this->originalRootUrl); + + $this->app['url']->forceRootUrl($newRootUrl); + $this->config->set('app.url', $newRootUrl); } public function revert(): void { if ($this->originalRootUrl) { - $this->urlGenerator->forceRootUrl($this->originalRootUrl); + $this->app['url']->forceRootUrl($this->originalRootUrl); $this->config->set('app.url', $this->originalRootUrl); } } diff --git a/src/Bootstrappers/UrlGeneratorBootstrapper.php b/src/Bootstrappers/UrlGeneratorBootstrapper.php index e3bb4a99b..15116760d 100644 --- a/src/Bootstrappers/UrlGeneratorBootstrapper.php +++ b/src/Bootstrappers/UrlGeneratorBootstrapper.php @@ -37,7 +37,7 @@ public function bootstrap(Tenant $tenant): void public function revert(): void { - $this->app->bind('url', fn () => $this->originalUrlGenerator); + $this->app->extend('url', fn () => $this->originalUrlGenerator); } /** @@ -47,24 +47,22 @@ public function revert(): void */ protected function useTenancyUrlGenerator(): void { - $this->app->extend('url', function (UrlGenerator $urlGenerator, Application $app) { - $newGenerator = new TenancyUrlGenerator( - $app['router']->getRoutes(), - $urlGenerator->getRequest(), - $app['config']->get('app.asset_url'), - ); + $newGenerator = new TenancyUrlGenerator( + $this->app['router']->getRoutes(), + $this->originalUrlGenerator->getRequest(), + $this->app['config']->get('app.asset_url'), + ); - $newGenerator->defaults($urlGenerator->getDefaultParameters()); + $newGenerator->defaults($this->originalUrlGenerator->getDefaultParameters()); - $newGenerator->setSessionResolver(function () { - return $this->app['session'] ?? null; - }); - - $newGenerator->setKeyResolver(function () { - return $this->app->make('config')->get('app.key'); - }); + $newGenerator->setSessionResolver(function () { + return $this->app['session'] ?? null; + }); - return $newGenerator; + $newGenerator->setKeyResolver(function () { + return $this->app->make('config')->get('app.key'); }); + + $this->app->extend('url', fn () => $newGenerator); } } diff --git a/tests/Bootstrappers/RootUrlBootstrapperTest.php b/tests/Bootstrappers/RootUrlBootstrapperTest.php index ee17a802e..c25a8bae0 100644 --- a/tests/Bootstrappers/RootUrlBootstrapperTest.php +++ b/tests/Bootstrappers/RootUrlBootstrapperTest.php @@ -10,18 +10,23 @@ use Stancl\Tenancy\Listeners\RevertToCentralContext; use Stancl\Tenancy\Bootstrappers\RootUrlBootstrapper; use Stancl\Tenancy\Middleware\InitializeTenancyBySubdomain; +use Stancl\Tenancy\Bootstrappers\UrlGeneratorBootstrapper; +use Stancl\Tenancy\Middleware\InitializeTenancyByPath; +use Stancl\Tenancy\Overrides\TenancyUrlGenerator; beforeEach(function () { Event::listen(TenancyInitialized::class, BootstrapTenancy::class); Event::listen(TenancyEnded::class, RevertToCentralContext::class); RootUrlBootstrapper::$rootUrlOverride = null; + RootUrlBootstrapper::$rootUrlOverrideInTests = true; }); afterEach(function () { RootUrlBootstrapper::$rootUrlOverride = null; + RootUrlBootstrapper::$rootUrlOverrideInTests = false; }); -test('root url bootstrapper overrides the root url when tenancy gets initialized and reverts the url to the central one after tenancy ends', function() { +test('root url bootstrapper overrides the root url when tenancy gets initialized and reverts the url to the central one when ending tenancy', function() { config(['tenancy.bootstrappers' => [RootUrlBootstrapper::class]]); Route::group([