From 36afb7dbddce3f1d2e0d8c55b6ddc65bba923b8b Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Wed, 23 Nov 2022 10:03:25 +0500 Subject: [PATCH 01/35] wip --- assets/config.php | 3 +++ src/Features/CrossDomainRedirect.php | 5 +++++ src/TenancyServiceProvider.php | 4 ++++ tests/Features/RedirectTest.php | 17 +++++++++++++++++ 4 files changed, 29 insertions(+) diff --git a/assets/config.php b/assets/config.php index 3778e1076..3bd68b978 100644 --- a/assets/config.php +++ b/assets/config.php @@ -283,6 +283,9 @@ // Stancl\Tenancy\Features\TelescopeTags::class, // Stancl\Tenancy\Features\UniversalRoutes::class, // Stancl\Tenancy\Features\TenantConfig::class, // https://tenancyforlaravel.com/docs/v3/features/tenant-config + ], + + 'tenant_unaware_features' => [ // Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect ], diff --git a/src/Features/CrossDomainRedirect.php b/src/Features/CrossDomainRedirect.php index a48be6eac..ee4bf1d7e 100644 --- a/src/Features/CrossDomainRedirect.php +++ b/src/Features/CrossDomainRedirect.php @@ -10,6 +10,11 @@ class CrossDomainRedirect implements Feature { + public function __construct(protected Tenancy $tenancy) + { + dd($this->tenancy); + } + public function bootstrap(Tenancy $tenancy): void { RedirectResponse::macro('domain', function (string $domain) { diff --git a/src/TenancyServiceProvider.php b/src/TenancyServiceProvider.php index ded96f359..f4e18dba9 100644 --- a/src/TenancyServiceProvider.php +++ b/src/TenancyServiceProvider.php @@ -36,6 +36,10 @@ public function register(): void return $tenancy; }); + foreach ($this->app['config']['tenancy.tenant_unaware_features'] ?? [] as $feature) { + $this->app[$feature]->bootstrap(); + } + // Make it possible to inject the current tenant by typehinting the Tenant contract. $this->app->bind(Tenant::class, function ($app) { return $app[Tenancy::class]->tenant; diff --git a/tests/Features/RedirectTest.php b/tests/Features/RedirectTest.php index 7aca2e928..db673f999 100644 --- a/tests/Features/RedirectTest.php +++ b/tests/Features/RedirectTest.php @@ -34,3 +34,20 @@ expect(tenant_route('foo.localhost', 'foo', ['a' => 'as', 'b' => 'df']))->toBe('http://foo.localhost/abcdef/as/df'); expect(tenant_route('foo.localhost', 'foo', []))->toBe('http://foo.localhost/abcdef'); }); + +test('redirect from central to tenant works fine', function () { + config([ + 'tenancy.features' => [CrossDomainRedirect::class], + ]); + + Route::get('/foobar', function () { + return 'Foo'; + })->name('home'); + + Route::get('/redirect', function () { + return redirect()->route('home')->domain('abcd'); + }); + + pest()->get('/redirect') + ->assertRedirect('http://abcd/foobar'); +}); From 5bbd09576ed5d5607f9207db493bd13fbd88e4db Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Wed, 23 Nov 2022 16:17:44 +0500 Subject: [PATCH 02/35] tenantUnwareFeature interface --- src/Contracts/TenantUnwareFeature.php | 10 ++++++++++ src/Features/CrossDomainRedirect.php | 12 +++--------- 2 files changed, 13 insertions(+), 9 deletions(-) create mode 100644 src/Contracts/TenantUnwareFeature.php diff --git a/src/Contracts/TenantUnwareFeature.php b/src/Contracts/TenantUnwareFeature.php new file mode 100644 index 000000000..498774c95 --- /dev/null +++ b/src/Contracts/TenantUnwareFeature.php @@ -0,0 +1,10 @@ +tenancy); - } - - public function bootstrap(Tenancy $tenancy): void + public function bootstrap(): void { RedirectResponse::macro('domain', function (string $domain) { /** @var RedirectResponse $this */ From a6c0fa21c4268b9e9dd66c9837e082a53de01f0d Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Wed, 23 Nov 2022 16:19:03 +0500 Subject: [PATCH 03/35] Update RedirectTest.php --- tests/Features/RedirectTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Features/RedirectTest.php b/tests/Features/RedirectTest.php index db673f999..a9ea92fa7 100644 --- a/tests/Features/RedirectTest.php +++ b/tests/Features/RedirectTest.php @@ -50,4 +50,4 @@ pest()->get('/redirect') ->assertRedirect('http://abcd/foobar'); -}); +})->skip('Incomplete'); From c0d0dc99dec606a6b17351ba49b96d20b9a5d553 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Fri, 25 Nov 2022 11:00:22 +0500 Subject: [PATCH 04/35] wip --- assets/config.php | 3 --- src/Contracts/Feature.php | 4 +--- src/Contracts/TenantUnwareFeature.php | 10 ---------- src/Features/CrossDomainRedirect.php | 10 ++++++++-- src/Features/TelescopeTags.php | 3 +-- src/Features/TenantConfig.php | 3 +-- src/Features/UniversalRoutes.php | 3 +-- src/Features/UserImpersonation.php | 4 ++-- src/Listeners/BootstrapFeatures.php | 23 +++++++++++++++++++++++ src/TenancyServiceProvider.php | 11 +---------- 10 files changed, 38 insertions(+), 36 deletions(-) delete mode 100644 src/Contracts/TenantUnwareFeature.php create mode 100644 src/Listeners/BootstrapFeatures.php diff --git a/assets/config.php b/assets/config.php index 3bd68b978..3778e1076 100644 --- a/assets/config.php +++ b/assets/config.php @@ -283,9 +283,6 @@ // Stancl\Tenancy\Features\TelescopeTags::class, // Stancl\Tenancy\Features\UniversalRoutes::class, // Stancl\Tenancy\Features\TenantConfig::class, // https://tenancyforlaravel.com/docs/v3/features/tenant-config - ], - - 'tenant_unaware_features' => [ // Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect ], diff --git a/src/Contracts/Feature.php b/src/Contracts/Feature.php index 742899815..25363cf5b 100644 --- a/src/Contracts/Feature.php +++ b/src/Contracts/Feature.php @@ -4,10 +4,8 @@ namespace Stancl\Tenancy\Contracts; -use Stancl\Tenancy\Tenancy; - /** Additional features, like Telescope tags and tenant redirects. */ interface Feature { - public function bootstrap(Tenancy $tenancy): void; + public function bootstrap(): void; } diff --git a/src/Contracts/TenantUnwareFeature.php b/src/Contracts/TenantUnwareFeature.php deleted file mode 100644 index 498774c95..000000000 --- a/src/Contracts/TenantUnwareFeature.php +++ /dev/null @@ -1,10 +0,0 @@ -macro('impersonate', function (Tenant $tenant, string $userId, string $redirectUrl, string $authGuard = null): ImpersonationToken { + Tenancy::macro('impersonate', function (Tenant $tenant, string $userId, string $redirectUrl, string $authGuard = null): ImpersonationToken { return ImpersonationToken::create([ Tenancy::tenantKeyColumn() => $tenant->getTenantKey(), 'user_id' => $userId, diff --git a/src/Listeners/BootstrapFeatures.php b/src/Listeners/BootstrapFeatures.php new file mode 100644 index 000000000..8ebbd6eca --- /dev/null +++ b/src/Listeners/BootstrapFeatures.php @@ -0,0 +1,23 @@ +app['config']['tenancy.features'] ?? [] as $feature) { + $this->app[$feature]->bootstrap($event->tenancy); + } + } +} diff --git a/src/TenancyServiceProvider.php b/src/TenancyServiceProvider.php index f4e18dba9..3a27c5da7 100644 --- a/src/TenancyServiceProvider.php +++ b/src/TenancyServiceProvider.php @@ -27,16 +27,7 @@ public function register(): void // Make sure Tenancy is stateful. $this->app->singleton(Tenancy::class); - // Make sure features are bootstrapped as soon as Tenancy is instantiated. - $this->app->extend(Tenancy::class, function (Tenancy $tenancy) { - foreach ($this->app['config']['tenancy.features'] ?? [] as $feature) { - $this->app[$feature]->bootstrap($tenancy); - } - - return $tenancy; - }); - - foreach ($this->app['config']['tenancy.tenant_unaware_features'] ?? [] as $feature) { + foreach ($this->app['config']['tenancy.features'] ?? [] as $feature) { $this->app[$feature]->bootstrap(); } From 4c20e30fcc9d7e129977bbecfd6d3158e6ddaa49 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Fri, 25 Nov 2022 15:16:07 +0500 Subject: [PATCH 05/35] wip --- assets/config.php | 3 +++ src/Features/UniversalRoutes.php | 1 + src/TenancyServiceProvider.php | 8 +++++++- tests/Features/RedirectTest.php | 4 ++-- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/assets/config.php b/assets/config.php index 3778e1076..3bd68b978 100644 --- a/assets/config.php +++ b/assets/config.php @@ -283,6 +283,9 @@ // Stancl\Tenancy\Features\TelescopeTags::class, // Stancl\Tenancy\Features\UniversalRoutes::class, // Stancl\Tenancy\Features\TenantConfig::class, // https://tenancyforlaravel.com/docs/v3/features/tenant-config + ], + + 'tenant_unaware_features' => [ // Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect ], diff --git a/src/Features/UniversalRoutes.php b/src/Features/UniversalRoutes.php index b0f8c757c..653131799 100644 --- a/src/Features/UniversalRoutes.php +++ b/src/Features/UniversalRoutes.php @@ -10,6 +10,7 @@ use Stancl\Tenancy\Contracts\Feature; use Stancl\Tenancy\Middleware; +// todo this got deleted in v4. class UniversalRoutes implements Feature { public static string $middlewareGroup = 'universal'; diff --git a/src/TenancyServiceProvider.php b/src/TenancyServiceProvider.php index 3a27c5da7..3e124bd5c 100644 --- a/src/TenancyServiceProvider.php +++ b/src/TenancyServiceProvider.php @@ -27,7 +27,13 @@ public function register(): void // Make sure Tenancy is stateful. $this->app->singleton(Tenancy::class); - foreach ($this->app['config']['tenancy.features'] ?? [] as $feature) { + $this->app->resolving(Tenancy::class, function (Tenancy $tenancy, $app) { + foreach ($this->app['config']['tenancy.features'] ?? [] as $feature) { + $this->app[$feature]->bootstrap(); + } + }); + + foreach ($this->app['config']['tenancy.tenant_unaware_features'] ?? [] as $feature) { $this->app[$feature]->bootstrap(); } diff --git a/tests/Features/RedirectTest.php b/tests/Features/RedirectTest.php index a9ea92fa7..9dfcb1ca6 100644 --- a/tests/Features/RedirectTest.php +++ b/tests/Features/RedirectTest.php @@ -8,7 +8,7 @@ test('tenant redirect macro replaces only the hostname', function () { config([ - 'tenancy.features' => [CrossDomainRedirect::class], + 'tenancy.tenant_unaware_features' => [CrossDomainRedirect::class], ]); Route::get('/foobar', function () { @@ -37,7 +37,7 @@ test('redirect from central to tenant works fine', function () { config([ - 'tenancy.features' => [CrossDomainRedirect::class], + 'tenancy.tenant_unaware_features' => [CrossDomainRedirect::class], ]); Route::get('/foobar', function () { From 399a78cf07d88d1697d1ee5a0444b57f51af0173 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Fri, 25 Nov 2022 15:31:45 +0500 Subject: [PATCH 06/35] add test --- assets/config.php | 2 +- tests/Features/RedirectTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/config.php b/assets/config.php index 3bd68b978..ec0c5642f 100644 --- a/assets/config.php +++ b/assets/config.php @@ -286,7 +286,7 @@ ], 'tenant_unaware_features' => [ - // Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect + Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect ], /** diff --git a/tests/Features/RedirectTest.php b/tests/Features/RedirectTest.php index 9dfcb1ca6..71b1114b5 100644 --- a/tests/Features/RedirectTest.php +++ b/tests/Features/RedirectTest.php @@ -50,4 +50,4 @@ pest()->get('/redirect') ->assertRedirect('http://abcd/foobar'); -})->skip('Incomplete'); +}); From 9b788e59d0a28373be615ebad833d2993bd25bc7 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Fri, 25 Nov 2022 15:36:55 +0500 Subject: [PATCH 07/35] Update CrossDomainRedirect.php --- src/Features/CrossDomainRedirect.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Features/CrossDomainRedirect.php b/src/Features/CrossDomainRedirect.php index 6eb6698f8..4907b4f5e 100644 --- a/src/Features/CrossDomainRedirect.php +++ b/src/Features/CrossDomainRedirect.php @@ -10,11 +10,6 @@ class CrossDomainRedirect implements Feature { - public function __construct( - protected Tenancy $tenancy - ) { - } - public function bootstrap(): void { RedirectResponse::macro('domain', function (string $domain) { From 08666637030a700c93dc4dbb681891d210e25091 Mon Sep 17 00:00:00 2001 From: PHP CS Fixer Date: Fri, 25 Nov 2022 10:39:38 +0000 Subject: [PATCH 08/35] Fix code style (php-cs-fixer) --- src/Features/CrossDomainRedirect.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Features/CrossDomainRedirect.php b/src/Features/CrossDomainRedirect.php index 4907b4f5e..577862745 100644 --- a/src/Features/CrossDomainRedirect.php +++ b/src/Features/CrossDomainRedirect.php @@ -6,7 +6,6 @@ use Illuminate\Http\RedirectResponse; use Stancl\Tenancy\Contracts\Feature; -use Stancl\Tenancy\Tenancy; class CrossDomainRedirect implements Feature { From f98a02aa9d04ddeeebd9c92354b38cf1e3e6aa4c Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Fri, 25 Nov 2022 15:45:01 +0500 Subject: [PATCH 09/35] trigger CI From 7b95becb3d9a17668d8dc73dcdf877571110c056 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Fri, 25 Nov 2022 16:15:59 +0500 Subject: [PATCH 10/35] Delete BootstrapFeatures.php --- src/Listeners/BootstrapFeatures.php | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 src/Listeners/BootstrapFeatures.php diff --git a/src/Listeners/BootstrapFeatures.php b/src/Listeners/BootstrapFeatures.php deleted file mode 100644 index 8ebbd6eca..000000000 --- a/src/Listeners/BootstrapFeatures.php +++ /dev/null @@ -1,23 +0,0 @@ -app['config']['tenancy.features'] ?? [] as $feature) { - $this->app[$feature]->bootstrap($event->tenancy); - } - } -} From 7125e1f3cc673d2b5aa5b39261655e2b294a4432 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Fri, 25 Nov 2022 17:36:22 +0500 Subject: [PATCH 11/35] Update UniversalRoutes.php --- src/Features/UniversalRoutes.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Features/UniversalRoutes.php b/src/Features/UniversalRoutes.php index 653131799..b0f8c757c 100644 --- a/src/Features/UniversalRoutes.php +++ b/src/Features/UniversalRoutes.php @@ -10,7 +10,6 @@ use Stancl\Tenancy\Contracts\Feature; use Stancl\Tenancy\Middleware; -// todo this got deleted in v4. class UniversalRoutes implements Feature { public static string $middlewareGroup = 'universal'; From 250f927d3322c47a067cf24fba00a698377bc35b Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Mon, 28 Nov 2022 10:53:35 +0500 Subject: [PATCH 12/35] test name and other improvements --- tests/Features/RedirectTest.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/Features/RedirectTest.php b/tests/Features/RedirectTest.php index 71b1114b5..7808961d9 100644 --- a/tests/Features/RedirectTest.php +++ b/tests/Features/RedirectTest.php @@ -35,10 +35,9 @@ expect(tenant_route('foo.localhost', 'foo', []))->toBe('http://foo.localhost/abcdef'); }); -test('redirect from central to tenant works fine', function () { - config([ - 'tenancy.tenant_unaware_features' => [CrossDomainRedirect::class], - ]); +// Check that `domain()` can be called on a redirect before tenancy is used (regression test for #949) +test('redirect from central to tenant works', function () { + // `CrossDomainRedirect` feature already enabled in config Route::get('/foobar', function () { return 'Foo'; From be6b2f82486d06db635008b823d1030137942ee0 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Mon, 28 Nov 2022 11:23:30 +0500 Subject: [PATCH 13/35] remove `tenant_unaware_features` key and use static function --- assets/config.php | 3 --- src/Contracts/Feature.php | 2 ++ src/Features/CrossDomainRedirect.php | 5 +++++ src/Features/TelescopeTags.php | 5 +++++ src/Features/TenantConfig.php | 5 +++++ src/Features/UniversalRoutes.php | 5 +++++ src/Features/UserImpersonation.php | 5 +++++ src/TenancyServiceProvider.php | 10 +++++++--- tests/Features/RedirectTest.php | 4 +--- 9 files changed, 35 insertions(+), 9 deletions(-) diff --git a/assets/config.php b/assets/config.php index ec0c5642f..4c3f0cb2e 100644 --- a/assets/config.php +++ b/assets/config.php @@ -283,9 +283,6 @@ // Stancl\Tenancy\Features\TelescopeTags::class, // Stancl\Tenancy\Features\UniversalRoutes::class, // Stancl\Tenancy\Features\TenantConfig::class, // https://tenancyforlaravel.com/docs/v3/features/tenant-config - ], - - 'tenant_unaware_features' => [ Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect ], diff --git a/src/Contracts/Feature.php b/src/Contracts/Feature.php index 25363cf5b..b30316220 100644 --- a/src/Contracts/Feature.php +++ b/src/Contracts/Feature.php @@ -8,4 +8,6 @@ interface Feature { public function bootstrap(): void; + + public static function alwaysBootstrap(): bool; } diff --git a/src/Features/CrossDomainRedirect.php b/src/Features/CrossDomainRedirect.php index 577862745..20d906f1e 100644 --- a/src/Features/CrossDomainRedirect.php +++ b/src/Features/CrossDomainRedirect.php @@ -27,4 +27,9 @@ public function bootstrap(): void return $this; }); } + + public static function alwaysBootstrap(): bool + { + return true; + } } diff --git a/src/Features/TelescopeTags.php b/src/Features/TelescopeTags.php index 225049df8..16a8ee70d 100644 --- a/src/Features/TelescopeTags.php +++ b/src/Features/TelescopeTags.php @@ -32,4 +32,9 @@ public function bootstrap(): void return $tags; }); } + + public static function alwaysBootstrap(): bool + { + return false; + } } diff --git a/src/Features/TenantConfig.php b/src/Features/TenantConfig.php index d268680b4..deacec685 100644 --- a/src/Features/TenantConfig.php +++ b/src/Features/TenantConfig.php @@ -69,4 +69,9 @@ public function unsetTenantConfig(): void $this->config->set($key, $value); } } + + public static function alwaysBootstrap(): bool + { + return false; + } } diff --git a/src/Features/UniversalRoutes.php b/src/Features/UniversalRoutes.php index b0f8c757c..a667a3fbf 100644 --- a/src/Features/UniversalRoutes.php +++ b/src/Features/UniversalRoutes.php @@ -60,4 +60,9 @@ public static function routeHasMiddleware(Route $route, string $middleware): boo return false; } + + public static function alwaysBootstrap(): bool + { + return false; + } } diff --git a/src/Features/UserImpersonation.php b/src/Features/UserImpersonation.php index 5a6bf0d99..008956254 100644 --- a/src/Features/UserImpersonation.php +++ b/src/Features/UserImpersonation.php @@ -50,4 +50,9 @@ public static function makeResponse(string|ImpersonationToken $token, int $ttl = return redirect($token->redirect_url); } + + public static function alwaysBootstrap(): bool + { + return false; + } } diff --git a/src/TenancyServiceProvider.php b/src/TenancyServiceProvider.php index 3e124bd5c..a8239ed98 100644 --- a/src/TenancyServiceProvider.php +++ b/src/TenancyServiceProvider.php @@ -29,12 +29,16 @@ public function register(): void $this->app->resolving(Tenancy::class, function (Tenancy $tenancy, $app) { foreach ($this->app['config']['tenancy.features'] ?? [] as $feature) { - $this->app[$feature]->bootstrap(); + if (! $feature::alwaysBootstrap()) { // avoid bootstrapping already bootstrapped features + $this->app[$feature]->bootstrap(); + } } }); - foreach ($this->app['config']['tenancy.tenant_unaware_features'] ?? [] as $feature) { - $this->app[$feature]->bootstrap(); + foreach ($this->app['config']['tenancy.features'] ?? [] as $feature) { + if ($feature::alwaysBootstrap()) { + $this->app[$feature]->bootstrap(); + } } // Make it possible to inject the current tenant by typehinting the Tenant contract. diff --git a/tests/Features/RedirectTest.php b/tests/Features/RedirectTest.php index 7808961d9..847b0cdff 100644 --- a/tests/Features/RedirectTest.php +++ b/tests/Features/RedirectTest.php @@ -7,9 +7,7 @@ use Stancl\Tenancy\Tests\Etc\Tenant; test('tenant redirect macro replaces only the hostname', function () { - config([ - 'tenancy.tenant_unaware_features' => [CrossDomainRedirect::class], - ]); + // `CrossDomainRedirect` feature already enabled in config Route::get('/foobar', function () { return 'Foo'; From 55560563b5065b3c6f594fb636f64c5704017dba Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Wed, 30 Nov 2022 12:21:43 +0500 Subject: [PATCH 14/35] separate TestCase for redirect tests --- assets/config.php | 2 +- tests/Pest.php | 11 ++++- .../Features/RedirectTest.php | 40 +++++++++++++++---- tests/WithoutTenancy/TestCase.php | 13 ++++++ 4 files changed, 56 insertions(+), 10 deletions(-) rename tests/{ => WithoutTenancy}/Features/RedirectTest.php (51%) create mode 100644 tests/WithoutTenancy/TestCase.php diff --git a/assets/config.php b/assets/config.php index 4c3f0cb2e..3778e1076 100644 --- a/assets/config.php +++ b/assets/config.php @@ -283,7 +283,7 @@ // Stancl\Tenancy\Features\TelescopeTags::class, // Stancl\Tenancy\Features\UniversalRoutes::class, // Stancl\Tenancy\Features\TenantConfig::class, // https://tenancyforlaravel.com/docs/v3/features/tenant-config - Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect + // Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect ], /** diff --git a/tests/Pest.php b/tests/Pest.php index d7ca8c22c..3181e41a4 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -2,9 +2,16 @@ use Stancl\Tenancy\Tests\TestCase; -uses(TestCase::class)->in(__DIR__); +uses(TestCase::class)->in(...filesAndFolder()); -function pest(): TestCase +function pest(): \Orchestra\Testbench\TestCase { return Pest\TestSuite::getInstance()->test; } + +function filesAndFolder(): array +{ + $dirs = scandir(__DIR__); + + return array_filter($dirs, fn($dir) => ! in_array($dir, ['.', '..', 'WithoutTenancy'], true)); +} diff --git a/tests/Features/RedirectTest.php b/tests/WithoutTenancy/Features/RedirectTest.php similarity index 51% rename from tests/Features/RedirectTest.php rename to tests/WithoutTenancy/Features/RedirectTest.php index 847b0cdff..61b130350 100644 --- a/tests/Features/RedirectTest.php +++ b/tests/WithoutTenancy/Features/RedirectTest.php @@ -4,10 +4,16 @@ use Illuminate\Support\Facades\Route; use Stancl\Tenancy\Features\CrossDomainRedirect; +use Stancl\Tenancy\TenancyServiceProvider; use Stancl\Tenancy\Tests\Etc\Tenant; +use Stancl\Tenancy\Tests\WithoutTenancy\TestCase; + +uses(TestCase::class); test('tenant redirect macro replaces only the hostname', function () { - // `CrossDomainRedirect` feature already enabled in config + config()->set('tenancy.features', [CrossDomainRedirect::class]); + + $this->app->register(new TenancyServiceProvider($this->app)); Route::get('/foobar', function () { return 'Foo'; @@ -17,7 +23,7 @@ return redirect()->route('home')->domain('abcd'); }); - $tenant = Tenant::create(); + $tenant = Tenant::create(['id' => 'foo']); // todo automatic id generation is not working tenancy()->initialize($tenant); pest()->get('/redirect') @@ -34,8 +40,12 @@ }); // Check that `domain()` can be called on a redirect before tenancy is used (regression test for #949) -test('redirect from central to tenant works', function () { - // `CrossDomainRedirect` feature already enabled in config +test('redirect from central to tenant works', function (bool $enabled, bool $shouldThrow) { + if ($enabled) { + config()->set('tenancy.features', [CrossDomainRedirect::class]); + } + + $this->app->register(new TenancyServiceProvider($this->app)); Route::get('/foobar', function () { return 'Foo'; @@ -45,6 +55,22 @@ return redirect()->route('home')->domain('abcd'); }); - pest()->get('/redirect') - ->assertRedirect('http://abcd/foobar'); -}); + try { + pest()->get('/redirect') + ->assertRedirect('http://abcd/foobar'); + + if ($shouldThrow) { + pest()->fail('Exception not thrown'); + } + } catch (Throwable $e) { + if ($shouldThrow) { + pest()->assertTrue(true); // empty assertion to make the test pass + } else { + pest()->fail('Exception thrown: ' . $e->getMessage()); + } + } + +})->with([ + ['enabled' => false, 'shouldThrow' => true], + ['enabled' => true, 'shouldThrow' => false], +]); diff --git a/tests/WithoutTenancy/TestCase.php b/tests/WithoutTenancy/TestCase.php new file mode 100644 index 000000000..3b630115b --- /dev/null +++ b/tests/WithoutTenancy/TestCase.php @@ -0,0 +1,13 @@ + Date: Wed, 30 Nov 2022 12:36:13 +0500 Subject: [PATCH 15/35] function improvements --- tests/Pest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Pest.php b/tests/Pest.php index 3181e41a4..ba34ee1e6 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -2,16 +2,16 @@ use Stancl\Tenancy\Tests\TestCase; -uses(TestCase::class)->in(...filesAndFolder()); +uses(TestCase::class)->in(...filesAndFoldersExcluding(['WithoutTenancy'])); function pest(): \Orchestra\Testbench\TestCase { return Pest\TestSuite::getInstance()->test; } -function filesAndFolder(): array +function filesAndFoldersExcluding(array $exclude = []): array { $dirs = scandir(__DIR__); - return array_filter($dirs, fn($dir) => ! in_array($dir, ['.', '..', 'WithoutTenancy'], true)); + return array_filter($dirs, fn($dir) => ! in_array($dir, array_merge(['.', '..'], $exclude) , true)); } From 068cee83ee201b531b8aed9e2c3963421ff63940 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Wed, 30 Nov 2022 13:42:45 +0500 Subject: [PATCH 16/35] move only one test to without tenancy folder --- assets/config.php | 2 +- tests/Features/RedirectTest.php | 36 +++++++++++++++++++ .../WithoutTenancy/Features/RedirectTest.php | 30 ---------------- 3 files changed, 37 insertions(+), 31 deletions(-) create mode 100644 tests/Features/RedirectTest.php diff --git a/assets/config.php b/assets/config.php index 3778e1076..4c3f0cb2e 100644 --- a/assets/config.php +++ b/assets/config.php @@ -283,7 +283,7 @@ // Stancl\Tenancy\Features\TelescopeTags::class, // Stancl\Tenancy\Features\UniversalRoutes::class, // Stancl\Tenancy\Features\TenantConfig::class, // https://tenancyforlaravel.com/docs/v3/features/tenant-config - // Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect + Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect ], /** diff --git a/tests/Features/RedirectTest.php b/tests/Features/RedirectTest.php new file mode 100644 index 000000000..3c90321ca --- /dev/null +++ b/tests/Features/RedirectTest.php @@ -0,0 +1,36 @@ +app->register(new TenancyServiceProvider($this->app)); + + Route::get('/foobar', function () { + return 'Foo'; + })->name('home'); + + Route::get('/redirect', function () { + return redirect()->route('home')->domain('abcd'); + }); + + $tenant = Tenant::create(['id' => 'foo']); + tenancy()->initialize($tenant); + + pest()->get('/redirect') + ->assertRedirect('http://abcd/foobar'); +}); + +test('tenant route helper generates correct url', function () { + Route::get('/abcdef/{a?}/{b?}', function () { + return 'Foo'; + })->name('foo'); + + expect(tenant_route('foo.localhost', 'foo', ['a' => 'as', 'b' => 'df']))->toBe('http://foo.localhost/abcdef/as/df'); + expect(tenant_route('foo.localhost', 'foo', []))->toBe('http://foo.localhost/abcdef'); +}); diff --git a/tests/WithoutTenancy/Features/RedirectTest.php b/tests/WithoutTenancy/Features/RedirectTest.php index 61b130350..d0737e62a 100644 --- a/tests/WithoutTenancy/Features/RedirectTest.php +++ b/tests/WithoutTenancy/Features/RedirectTest.php @@ -5,40 +5,10 @@ use Illuminate\Support\Facades\Route; use Stancl\Tenancy\Features\CrossDomainRedirect; use Stancl\Tenancy\TenancyServiceProvider; -use Stancl\Tenancy\Tests\Etc\Tenant; use Stancl\Tenancy\Tests\WithoutTenancy\TestCase; uses(TestCase::class); -test('tenant redirect macro replaces only the hostname', function () { - config()->set('tenancy.features', [CrossDomainRedirect::class]); - - $this->app->register(new TenancyServiceProvider($this->app)); - - Route::get('/foobar', function () { - return 'Foo'; - })->name('home'); - - Route::get('/redirect', function () { - return redirect()->route('home')->domain('abcd'); - }); - - $tenant = Tenant::create(['id' => 'foo']); // todo automatic id generation is not working - tenancy()->initialize($tenant); - - pest()->get('/redirect') - ->assertRedirect('http://abcd/foobar'); -}); - -test('tenant route helper generates correct url', function () { - Route::get('/abcdef/{a?}/{b?}', function () { - return 'Foo'; - })->name('foo'); - - expect(tenant_route('foo.localhost', 'foo', ['a' => 'as', 'b' => 'df']))->toBe('http://foo.localhost/abcdef/as/df'); - expect(tenant_route('foo.localhost', 'foo', []))->toBe('http://foo.localhost/abcdef'); -}); - // Check that `domain()` can be called on a redirect before tenancy is used (regression test for #949) test('redirect from central to tenant works', function (bool $enabled, bool $shouldThrow) { if ($enabled) { From 8f9b21dad1487023681bf08aeddc73fb18439b21 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Wed, 30 Nov 2022 13:45:15 +0500 Subject: [PATCH 17/35] Update RedirectTest.php --- tests/Features/RedirectTest.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/Features/RedirectTest.php b/tests/Features/RedirectTest.php index 3c90321ca..ddc799790 100644 --- a/tests/Features/RedirectTest.php +++ b/tests/Features/RedirectTest.php @@ -9,8 +9,6 @@ test('tenant redirect macro replaces only the hostname', function () { // `CrossDomainRedirect` feature already enabled in config - $this->app->register(new TenancyServiceProvider($this->app)); - Route::get('/foobar', function () { return 'Foo'; })->name('home'); @@ -19,7 +17,7 @@ return redirect()->route('home')->domain('abcd'); }); - $tenant = Tenant::create(['id' => 'foo']); + $tenant = Tenant::create(); tenancy()->initialize($tenant); pest()->get('/redirect') From ec1c2e6c744d4731d473c6a1d7593eceb1183450 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Wed, 30 Nov 2022 13:45:46 +0500 Subject: [PATCH 18/35] Update RedirectTest.php --- tests/Features/RedirectTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Features/RedirectTest.php b/tests/Features/RedirectTest.php index ddc799790..3929094d3 100644 --- a/tests/Features/RedirectTest.php +++ b/tests/Features/RedirectTest.php @@ -3,7 +3,6 @@ declare(strict_types=1); use Illuminate\Support\Facades\Route; -use Stancl\Tenancy\TenancyServiceProvider; use Stancl\Tenancy\Tests\Etc\Tenant; test('tenant redirect macro replaces only the hostname', function () { From afb942b6bea90733d2585bc292f6e28122aed83f Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Thu, 1 Dec 2022 13:30:52 +0500 Subject: [PATCH 19/35] enable feature in TestCase --- assets/config.php | 2 +- tests/TestCase.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/assets/config.php b/assets/config.php index 4c3f0cb2e..3778e1076 100644 --- a/assets/config.php +++ b/assets/config.php @@ -283,7 +283,7 @@ // Stancl\Tenancy\Features\TelescopeTags::class, // Stancl\Tenancy\Features\UniversalRoutes::class, // Stancl\Tenancy\Features\TenantConfig::class, // https://tenancyforlaravel.com/docs/v3/features/tenant-config - Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect + // Stancl\Tenancy\Features\CrossDomainRedirect::class, // https://tenancyforlaravel.com/docs/v3/features/cross-domain-redirect ], /** diff --git a/tests/TestCase.php b/tests/TestCase.php index 7b9deea0e..791747ddb 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -12,6 +12,7 @@ use Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper; use Stancl\Tenancy\Facades\GlobalCache; use Stancl\Tenancy\Facades\Tenancy; +use Stancl\Tenancy\Features\CrossDomainRedirect; use Stancl\Tenancy\TenancyServiceProvider; use Stancl\Tenancy\Tests\Etc\Tenant; @@ -117,6 +118,8 @@ protected function getEnvironmentSetUp($app) protected function getPackageProviders($app) { + config()->set('tenancy.features', [CrossDomainRedirect::class]); // todo (Samuel) use proper approach to enable feature in right place + return [ TenancyServiceProvider::class, ]; From 76c9a052df56a48fff1347f7bbf68ec47d8e9c7d Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Thu, 1 Dec 2022 13:31:08 +0500 Subject: [PATCH 20/35] todo for moving test to separate folder --- tests/Pest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Pest.php b/tests/Pest.php index ba34ee1e6..c27c6d531 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -2,7 +2,7 @@ use Stancl\Tenancy\Tests\TestCase; -uses(TestCase::class)->in(...filesAndFoldersExcluding(['WithoutTenancy'])); +uses(TestCase::class)->in(...filesAndFoldersExcluding(['WithoutTenancy'])); // todo move all tests to a separate folder function pest(): \Orchestra\Testbench\TestCase { From 258582112cbfedeb39b2a2100281f15bfc020e41 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Thu, 1 Dec 2022 13:32:17 +0500 Subject: [PATCH 21/35] use proper return type --- tests/Pest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Pest.php b/tests/Pest.php index c27c6d531..99c1bbcc4 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -4,7 +4,7 @@ uses(TestCase::class)->in(...filesAndFoldersExcluding(['WithoutTenancy'])); // todo move all tests to a separate folder -function pest(): \Orchestra\Testbench\TestCase +function pest(): TestCase { return Pest\TestSuite::getInstance()->test; } From 654a988af133ccd8857a13b793f157fbcdffd616 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Mon, 20 Feb 2023 15:39:23 +0100 Subject: [PATCH 22/35] Add bootstrapFeatures static property and method --- src/TenancyServiceProvider.php | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/TenancyServiceProvider.php b/src/TenancyServiceProvider.php index a8239ed98..b10fd4eca 100644 --- a/src/TenancyServiceProvider.php +++ b/src/TenancyServiceProvider.php @@ -17,6 +17,8 @@ class TenancyServiceProvider extends ServiceProvider { + public static $bootstrapFeatures = true; + /* Register services. */ public function register(): void { @@ -27,18 +29,8 @@ public function register(): void // Make sure Tenancy is stateful. $this->app->singleton(Tenancy::class); - $this->app->resolving(Tenancy::class, function (Tenancy $tenancy, $app) { - foreach ($this->app['config']['tenancy.features'] ?? [] as $feature) { - if (! $feature::alwaysBootstrap()) { // avoid bootstrapping already bootstrapped features - $this->app[$feature]->bootstrap(); - } - } - }); - - foreach ($this->app['config']['tenancy.features'] ?? [] as $feature) { - if ($feature::alwaysBootstrap()) { - $this->app[$feature]->bootstrap(); - } + if (static::bootstrapFeatures()) { + $this->bootstrapFeatures(); } // Make it possible to inject the current tenant by typehinting the Tenant contract. @@ -149,4 +141,21 @@ public function boot(): void return $instance; }); } + + public static function bootstrapFeatures(): void + { + foreach (config('tenancy.features') ?? [] as $feature) { + if ($feature::alwaysBootstrap()) { + app($feature)->bootstrap(); + } + } + + app()->resolving(Tenancy::class, function (Tenancy $tenancy, $app) { + foreach (config('tenancy.features') ?? [] as $feature) { + if (! $feature::alwaysBootstrap()) { // Avoid bootstrapping already bootstrapped features + $app[$feature]->bootstrap(); + } + } + }); + } } From 92a464520f91acc7e9a9a2b4fb18ac14dbc2d73e Mon Sep 17 00:00:00 2001 From: lukinovec Date: Mon, 20 Feb 2023 15:39:51 +0100 Subject: [PATCH 23/35] Delete setting `tenancy.features` in `getPackageProviders()` --- tests/TestCase.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/TestCase.php b/tests/TestCase.php index 791747ddb..3fb487662 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -8,7 +8,6 @@ use Illuminate\Foundation\Application; use Illuminate\Support\Facades\Redis; use PDO; -use Stancl\Tenancy\Bootstrappers\BatchTenancyBootstrapper; use Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper; use Stancl\Tenancy\Facades\GlobalCache; use Stancl\Tenancy\Facades\Tenancy; @@ -118,8 +117,6 @@ protected function getEnvironmentSetUp($app) protected function getPackageProviders($app) { - config()->set('tenancy.features', [CrossDomainRedirect::class]); // todo (Samuel) use proper approach to enable feature in right place - return [ TenancyServiceProvider::class, ]; From 241cf1fd210bfcde1d148b2cdc77a5be57ed1602 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Mon, 20 Feb 2023 15:41:06 +0100 Subject: [PATCH 24/35] Delete WithoutTenancy directory, move tests --- tests/Features/RedirectTest.php | 45 +++++++++++++++++- .../WithoutTenancy/Features/RedirectTest.php | 46 ------------------- tests/WithoutTenancy/TestCase.php | 13 ------ 3 files changed, 43 insertions(+), 61 deletions(-) delete mode 100644 tests/WithoutTenancy/Features/RedirectTest.php delete mode 100644 tests/WithoutTenancy/TestCase.php diff --git a/tests/Features/RedirectTest.php b/tests/Features/RedirectTest.php index 3929094d3..4c836fab6 100644 --- a/tests/Features/RedirectTest.php +++ b/tests/Features/RedirectTest.php @@ -2,11 +2,15 @@ declare(strict_types=1); -use Illuminate\Support\Facades\Route; use Stancl\Tenancy\Tests\Etc\Tenant; +use Illuminate\Support\Facades\Route; +use Stancl\Tenancy\TenancyServiceProvider; +use Stancl\Tenancy\Features\CrossDomainRedirect; test('tenant redirect macro replaces only the hostname', function () { - // `CrossDomainRedirect` feature already enabled in config + config()->set('tenancy.features', [CrossDomainRedirect::class]); + + TenancyServiceProvider::bootstrapFeatures(); Route::get('/foobar', function () { return 'Foo'; @@ -31,3 +35,40 @@ expect(tenant_route('foo.localhost', 'foo', ['a' => 'as', 'b' => 'df']))->toBe('http://foo.localhost/abcdef/as/df'); expect(tenant_route('foo.localhost', 'foo', []))->toBe('http://foo.localhost/abcdef'); }); + +// Check that `domain()` can be called on a redirect before tenancy is used (regression test for #949) +test('redirect from central to tenant works', function (bool $enabled, bool $shouldThrow) { + if ($enabled) { + config()->set('tenancy.features', [CrossDomainRedirect::class]); + + TenancyServiceProvider::bootstrapFeatures(); + } + + + Route::get('/foobar', function () { + return 'Foo'; + })->name('home'); + + Route::get('/redirect', function () { + return redirect()->route('home')->domain('abcd'); + }); + + try { + pest()->get('/redirect') + ->assertRedirect('http://abcd/foobar'); + + if ($shouldThrow) { + pest()->fail('Exception not thrown'); + } + } catch (Throwable $e) { + if ($shouldThrow) { + pest()->assertTrue(true); // empty assertion to make the test pass + } else { + pest()->fail('Exception thrown: ' . $e->getMessage()); + } + } + +})->with([ + ['enabled' => false, 'shouldThrow' => true], + ['enabled' => true, 'shouldThrow' => false], +]); diff --git a/tests/WithoutTenancy/Features/RedirectTest.php b/tests/WithoutTenancy/Features/RedirectTest.php deleted file mode 100644 index d0737e62a..000000000 --- a/tests/WithoutTenancy/Features/RedirectTest.php +++ /dev/null @@ -1,46 +0,0 @@ -set('tenancy.features', [CrossDomainRedirect::class]); - } - - $this->app->register(new TenancyServiceProvider($this->app)); - - Route::get('/foobar', function () { - return 'Foo'; - })->name('home'); - - Route::get('/redirect', function () { - return redirect()->route('home')->domain('abcd'); - }); - - try { - pest()->get('/redirect') - ->assertRedirect('http://abcd/foobar'); - - if ($shouldThrow) { - pest()->fail('Exception not thrown'); - } - } catch (Throwable $e) { - if ($shouldThrow) { - pest()->assertTrue(true); // empty assertion to make the test pass - } else { - pest()->fail('Exception thrown: ' . $e->getMessage()); - } - } - -})->with([ - ['enabled' => false, 'shouldThrow' => true], - ['enabled' => true, 'shouldThrow' => false], -]); diff --git a/tests/WithoutTenancy/TestCase.php b/tests/WithoutTenancy/TestCase.php deleted file mode 100644 index 3b630115b..000000000 --- a/tests/WithoutTenancy/TestCase.php +++ /dev/null @@ -1,13 +0,0 @@ - Date: Tue, 21 Feb 2023 10:48:24 +0100 Subject: [PATCH 25/35] Update RedirectTest --- tests/Features/RedirectTest.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/Features/RedirectTest.php b/tests/Features/RedirectTest.php index 4c836fab6..d2046d374 100644 --- a/tests/Features/RedirectTest.php +++ b/tests/Features/RedirectTest.php @@ -7,6 +7,10 @@ use Stancl\Tenancy\TenancyServiceProvider; use Stancl\Tenancy\Features\CrossDomainRedirect; +beforeAll(function () { + TenancyServiceProvider::$bootstrapFeatures = false; +}); + test('tenant redirect macro replaces only the hostname', function () { config()->set('tenancy.features', [CrossDomainRedirect::class]); @@ -40,10 +44,10 @@ test('redirect from central to tenant works', function (bool $enabled, bool $shouldThrow) { if ($enabled) { config()->set('tenancy.features', [CrossDomainRedirect::class]); - - TenancyServiceProvider::bootstrapFeatures(); } + TenancyServiceProvider::bootstrapFeatures(); + Route::get('/foobar', function () { return 'Foo'; From 06b62b85cd362cac5d3689636aded57595c10f18 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Tue, 21 Feb 2023 10:49:53 +0100 Subject: [PATCH 26/35] Delete extra line --- tests/Features/RedirectTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Features/RedirectTest.php b/tests/Features/RedirectTest.php index d2046d374..8379b7e6c 100644 --- a/tests/Features/RedirectTest.php +++ b/tests/Features/RedirectTest.php @@ -48,7 +48,6 @@ TenancyServiceProvider::bootstrapFeatures(); - Route::get('/foobar', function () { return 'Foo'; })->name('home'); From 8cbc855b0acddc31f7efd8a4191ced564fa5f426 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Thu, 23 Feb 2023 15:18:12 +0100 Subject: [PATCH 27/35] Fix merge errors --- src/Features/UserImpersonation.php | 8 +++++--- tests/Pest.php | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Features/UserImpersonation.php b/src/Features/UserImpersonation.php index da599ae0f..d07117bf5 100644 --- a/src/Features/UserImpersonation.php +++ b/src/Features/UserImpersonation.php @@ -4,12 +4,12 @@ namespace Stancl\Tenancy\Features; -use Illuminate\Http\RedirectResponse; +use Stancl\Tenancy\Tenancy; use Illuminate\Support\Facades\Auth; -use Stancl\Tenancy\Contracts\Feature; use Stancl\Tenancy\Contracts\Tenant; +use Illuminate\Http\RedirectResponse; +use Stancl\Tenancy\Contracts\Feature; use Stancl\Tenancy\Database\Models\ImpersonationToken; -use Stancl\Tenancy\Tenancy; class UserImpersonation implements Feature { @@ -56,6 +56,8 @@ public static function makeResponse(string|ImpersonationToken $token, int $ttl = public static function alwaysBootstrap(): bool { return false; + } + public static function isImpersonating(): bool { return session()->has('tenancy_impersonating'); diff --git a/tests/Pest.php b/tests/Pest.php index 61dabfb1f..99f57cd05 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -18,6 +18,8 @@ function filesAndFoldersExcluding(array $exclude = []): array $dirs = scandir(__DIR__); return array_filter($dirs, fn($dir) => ! in_array($dir, array_merge(['.', '..'], $exclude) , true)); +} + function withTenantDatabases() { Event::listen(TenantCreated::class, JobPipeline::make([CreateDatabase::class])->send(function (TenantCreated $event) { From a5695939d2306053380556ed02f71e22eff9fbbc Mon Sep 17 00:00:00 2001 From: lukinovec Date: Thu, 23 Feb 2023 15:28:25 +0100 Subject: [PATCH 28/35] Update ViteBundler --- src/Features/ViteBundler.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Features/ViteBundler.php b/src/Features/ViteBundler.php index e3fee2fa5..295e49b33 100644 --- a/src/Features/ViteBundler.php +++ b/src/Features/ViteBundler.php @@ -4,10 +4,10 @@ namespace Stancl\Tenancy\Features; -use Illuminate\Foundation\Application; -use Stancl\Tenancy\Contracts\Feature; -use Stancl\Tenancy\Tenancy; use Stancl\Tenancy\Vite; +use Stancl\Tenancy\Contracts\Feature; +use Illuminate\Foundation\Application; +use Illuminate\Foundation\Vite as BaseVite; class ViteBundler implements Feature { @@ -19,8 +19,13 @@ public function __construct(Application $app) $this->app = $app; } - public function bootstrap(Tenancy $tenancy): void + public function bootstrap(): void + { + $this->app->singleton(BaseVite::class, Vite::class); + } + + public static function alwaysBootstrap(): bool { - $this->app->singleton(\Illuminate\Foundation\Vite::class, Vite::class); + return false; } } From 6873c544acb6ba01aa3cd42f52909c9f22c5411e Mon Sep 17 00:00:00 2001 From: PHP CS Fixer Date: Thu, 23 Feb 2023 14:28:57 +0000 Subject: [PATCH 29/35] Fix code style (php-cs-fixer) --- src/Features/UserImpersonation.php | 6 +++--- src/Features/ViteBundler.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Features/UserImpersonation.php b/src/Features/UserImpersonation.php index d07117bf5..280acbc5a 100644 --- a/src/Features/UserImpersonation.php +++ b/src/Features/UserImpersonation.php @@ -4,12 +4,12 @@ namespace Stancl\Tenancy\Features; -use Stancl\Tenancy\Tenancy; -use Illuminate\Support\Facades\Auth; -use Stancl\Tenancy\Contracts\Tenant; use Illuminate\Http\RedirectResponse; +use Illuminate\Support\Facades\Auth; use Stancl\Tenancy\Contracts\Feature; +use Stancl\Tenancy\Contracts\Tenant; use Stancl\Tenancy\Database\Models\ImpersonationToken; +use Stancl\Tenancy\Tenancy; class UserImpersonation implements Feature { diff --git a/src/Features/ViteBundler.php b/src/Features/ViteBundler.php index 295e49b33..34b118e74 100644 --- a/src/Features/ViteBundler.php +++ b/src/Features/ViteBundler.php @@ -4,10 +4,10 @@ namespace Stancl\Tenancy\Features; -use Stancl\Tenancy\Vite; -use Stancl\Tenancy\Contracts\Feature; use Illuminate\Foundation\Application; use Illuminate\Foundation\Vite as BaseVite; +use Stancl\Tenancy\Contracts\Feature; +use Stancl\Tenancy\Vite; class ViteBundler implements Feature { From bcf777da6b791f8d83d4cfe25d793cad647baf0f Mon Sep 17 00:00:00 2001 From: lukinovec Date: Thu, 23 Feb 2023 15:32:24 +0100 Subject: [PATCH 30/35] Fix `$bootstrapFeatures` property --- src/TenancyServiceProvider.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TenancyServiceProvider.php b/src/TenancyServiceProvider.php index 6971b199f..f50d20028 100644 --- a/src/TenancyServiceProvider.php +++ b/src/TenancyServiceProvider.php @@ -14,7 +14,7 @@ class TenancyServiceProvider extends ServiceProvider { - public static $bootstrapFeatures = true; + public static bool $bootstrapFeatures = true; /* Register services. */ public function register(): void @@ -27,7 +27,7 @@ public function register(): void $this->app->singleton(Tenancy::class); if (static::bootstrapFeatures()) { - $this->bootstrapFeatures(); + $this->bootstrapFeatures; } // Make it possible to inject the current tenant by typehinting the Tenant contract. From e75aefb65e5ce9960d9fcd564f054556b7fb0c01 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Thu, 23 Feb 2023 15:36:30 +0100 Subject: [PATCH 31/35] Fix method/property --- src/TenancyServiceProvider.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TenancyServiceProvider.php b/src/TenancyServiceProvider.php index f50d20028..2f7df3a4c 100644 --- a/src/TenancyServiceProvider.php +++ b/src/TenancyServiceProvider.php @@ -26,8 +26,8 @@ public function register(): void // Make sure Tenancy is stateful. $this->app->singleton(Tenancy::class); - if (static::bootstrapFeatures()) { - $this->bootstrapFeatures; + if ($this->bootstrapFeatures) { + static::bootstrapFeatures(); } // Make it possible to inject the current tenant by typehinting the Tenant contract. From 3e6dd646ae20a616a5615d856a0fdc924c41e057 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Thu, 23 Feb 2023 15:38:36 +0100 Subject: [PATCH 32/35] Don't access static property as non-static --- src/TenancyServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TenancyServiceProvider.php b/src/TenancyServiceProvider.php index 2f7df3a4c..538463cc2 100644 --- a/src/TenancyServiceProvider.php +++ b/src/TenancyServiceProvider.php @@ -26,7 +26,7 @@ public function register(): void // Make sure Tenancy is stateful. $this->app->singleton(Tenancy::class); - if ($this->bootstrapFeatures) { + if (static::$bootstrapFeatures) { static::bootstrapFeatures(); } From 91f8adb6985c5881dff0955177eaea1a570f09b5 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Thu, 23 Feb 2023 16:22:52 +0100 Subject: [PATCH 33/35] Bootstrap features manually in tests --- tests/Features/TenantConfigTest.php | 34 +++++++++++++-------------- tests/Features/ViteBundlerTest.php | 3 +++ tests/TenantUserImpersonationTest.php | 3 +++ 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/tests/Features/TenantConfigTest.php b/tests/Features/TenantConfigTest.php index 5c12c5f07..c6e135f44 100644 --- a/tests/Features/TenantConfigTest.php +++ b/tests/Features/TenantConfigTest.php @@ -2,13 +2,23 @@ declare(strict_types=1); +use Stancl\Tenancy\Tests\Etc\Tenant; use Illuminate\Support\Facades\Event; use Stancl\Tenancy\Events\TenancyEnded; -use Stancl\Tenancy\Events\TenancyInitialized; use Stancl\Tenancy\Features\TenantConfig; +use Stancl\Tenancy\TenancyServiceProvider; +use Stancl\Tenancy\Events\TenancyInitialized; use Stancl\Tenancy\Listeners\BootstrapTenancy; use Stancl\Tenancy\Listeners\RevertToCentralContext; -use Stancl\Tenancy\Tests\Etc\Tenant; + +beforeEach(function() { + config([ + 'tenancy.features' => [TenantConfig::class], + 'tenancy.bootstrappers' => [], + ]); + + TenancyServiceProvider::bootstrapFeatures(); +}); afterEach(function () { TenantConfig::$storageToConfigMap = []; @@ -16,10 +26,7 @@ test('nested tenant values are merged', function () { expect(config('whitelabel.theme'))->toBeNull(); - config([ - 'tenancy.features' => [TenantConfig::class], - 'tenancy.bootstrappers' => [], - ]); + Event::listen(TenancyInitialized::class, BootstrapTenancy::class); Event::listen(TenancyEnded::class, RevertToCentralContext::class); @@ -37,11 +44,8 @@ }); test('config is merged and removed', function () { - expect(config('services.paypal'))->toBe(null); - config([ - 'tenancy.features' => [TenantConfig::class], - 'tenancy.bootstrappers' => [], - ]); + expect(config('services.paypal'))->toBeNull(); + Event::listen(TenancyInitialized::class, BootstrapTenancy::class); Event::listen(TenancyEnded::class, RevertToCentralContext::class); @@ -64,13 +68,9 @@ 'private' => null, ], config('services.paypal')); }); - test('the value can be set to multiple config keys', function () { - expect(config('services.paypal'))->toBe(null); - config([ - 'tenancy.features' => [TenantConfig::class], - 'tenancy.bootstrappers' => [], - ]); + expect(config('services.paypal'))->toBeNull(); + Event::listen(TenancyInitialized::class, BootstrapTenancy::class); Event::listen(TenancyEnded::class, RevertToCentralContext::class); diff --git a/tests/Features/ViteBundlerTest.php b/tests/Features/ViteBundlerTest.php index 0d4c9069c..26e646db2 100644 --- a/tests/Features/ViteBundlerTest.php +++ b/tests/Features/ViteBundlerTest.php @@ -6,6 +6,7 @@ use Stancl\Tenancy\Tests\Etc\Tenant; use Stancl\Tenancy\Vite as StanclVite; use Stancl\Tenancy\Features\ViteBundler; +use Stancl\Tenancy\TenancyServiceProvider; test('vite helper uses our custom class', function() { $vite = app(Vite::class); @@ -17,6 +18,8 @@ 'tenancy.features' => [ViteBundler::class], ]); + TenancyServiceProvider::bootstrapFeatures(); + $tenant = Tenant::create(); tenancy()->initialize($tenant); diff --git a/tests/TenantUserImpersonationTest.php b/tests/TenantUserImpersonationTest.php index 1e72c604e..7deaadb4d 100644 --- a/tests/TenantUserImpersonationTest.php +++ b/tests/TenantUserImpersonationTest.php @@ -15,6 +15,7 @@ use Stancl\Tenancy\Events\TenancyEnded; use Stancl\Tenancy\Jobs\CreateDatabase; use Stancl\Tenancy\Events\TenantCreated; +use Stancl\Tenancy\TenancyServiceProvider; use Stancl\Tenancy\Events\TenancyInitialized; use Stancl\Tenancy\Features\UserImpersonation; use Stancl\Tenancy\Listeners\BootstrapTenancy; @@ -41,6 +42,8 @@ ], ]); + TenancyServiceProvider::bootstrapFeatures(); + Event::listen( TenantCreated::class, JobPipeline::make([CreateDatabase::class])->send(function (TenantCreated $event) { From 34547f75f63dbf89f84675d54fef08991c79b275 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Thu, 23 Feb 2023 16:23:13 +0100 Subject: [PATCH 34/35] Always bootstrap TenantConfig --- src/Features/TenantConfig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Features/TenantConfig.php b/src/Features/TenantConfig.php index deacec685..cb119f6ec 100644 --- a/src/Features/TenantConfig.php +++ b/src/Features/TenantConfig.php @@ -72,6 +72,6 @@ public function unsetTenantConfig(): void public static function alwaysBootstrap(): bool { - return false; + return true; } } From f9e027757fa8a6b9ac53983425f0f51687ec0755 Mon Sep 17 00:00:00 2001 From: lukinovec Date: Thu, 23 Feb 2023 16:23:22 +0100 Subject: [PATCH 35/35] Update ViteBundler constructor --- src/Features/ViteBundler.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Features/ViteBundler.php b/src/Features/ViteBundler.php index 34b118e74..dbe6651b1 100644 --- a/src/Features/ViteBundler.php +++ b/src/Features/ViteBundler.php @@ -11,12 +11,9 @@ class ViteBundler implements Feature { - /** @var Application */ - protected $app; - - public function __construct(Application $app) - { - $this->app = $app; + public function __construct( + protected Application $app + ) { } public function bootstrap(): void