diff --git a/phpunit.xml b/phpunit.xml
index 5bb62923..b4226539 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/src/Bootstrappers/Integrations/FortifyRouteBootstrapper.php b/src/Bootstrappers/Integrations/FortifyRouteBootstrapper.php
index 80c48ed1..2c5712ee 100644
--- a/src/Bootstrappers/Integrations/FortifyRouteBootstrapper.php
+++ b/src/Bootstrappers/Integrations/FortifyRouteBootstrapper.php
@@ -34,7 +34,7 @@ class FortifyRouteBootstrapper implements TenancyBootstrapper
*
* For example:
*
- * FortifyRouteTenancyBootstrapper::$fortifyRedirectMap = [
+ * FortifyRouteBootstrapper::$fortifyRedirectMap = [
* // On logout, redirect the user to the "bye" route in the central app
* 'logout' => [
* 'route_name' => 'bye',
@@ -46,7 +46,7 @@ class FortifyRouteBootstrapper implements TenancyBootstrapper
* 'route_name' => 'welcome',
* 'context' => Context::TENANT,
* ],
- *];
+ * ];
*/
public static array $fortifyRedirectMap = [];
diff --git a/tests/AutomaticModeTest.php b/tests/AutomaticModeTest.php
index 1a0948ea..f34aa7f1 100644
--- a/tests/AutomaticModeTest.php
+++ b/tests/AutomaticModeTest.php
@@ -15,12 +15,18 @@ beforeEach(function () {
Event::listen(TenancyEnded::class, RevertToCentralContext::class);
});
-test('context is switched when tenancy is initialized', function () {
- contextIsSwitchedWhenTenancyInitialized();
-});
+test('context is switched to tenant when initializing tenancy and reverted when ending tenancy', function () {
+ config(['tenancy.bootstrappers' => [
+ MyBootstrapper::class,
+ ]]);
-test('context is reverted when tenancy is ended', function () {
- contextIsSwitchedWhenTenancyInitialized();
+ $tenant = Tenant::create([
+ 'id' => 'acme',
+ ]);
+
+ tenancy()->initialize($tenant);
+
+ expect(app('tenancy_initialized_for_tenant'))->toBe('acme');
tenancy()->end();
@@ -95,22 +101,6 @@ test('central helper doesnt change tenancy state when called in central context'
expect(tenant())->toBeNull();
});
-// todo@tests
-function contextIsSwitchedWhenTenancyInitialized()
-{
- config(['tenancy.bootstrappers' => [
- MyBootstrapper::class,
- ]]);
-
- $tenant = Tenant::create([
- 'id' => 'acme',
- ]);
-
- tenancy()->initialize($tenant);
-
- expect(app('tenancy_initialized_for_tenant'))->toBe('acme');
-}
-
class MyBootstrapper implements TenancyBootstrapper
{
public function bootstrap(\Stancl\Tenancy\Contracts\Tenant $tenant): void
diff --git a/tests/BootstrapperTest.php b/tests/BootstrapperTest.php
index ed6f002f..6367e6cb 100644
--- a/tests/BootstrapperTest.php
+++ b/tests/BootstrapperTest.php
@@ -319,6 +319,41 @@ test('files can get fetched using the storage url', function() {
expect(file_get_contents(public_path($url)))->toBe($centralFileContent);
});
+test('storage_path helper does not change if suffix_storage_path is off', function() {
+ $originalStoragePath = storage_path();
+
+ // todo@tests https://github.com/tenancy-for-laravel/v4/pull/44#issue-2228530362
+
+ config([
+ 'tenancy.bootstrappers' => [FilesystemTenancyBootstrapper::class],
+ 'tenancy.filesystem.suffix_storage_path' => false,
+ ]);
+
+ tenancy()->initialize(Tenant::create());
+
+ $this->assertEquals($originalStoragePath, storage_path());
+});
+
+test('links to storage disks with a configured root are suffixed if not overridden', function() {
+ config([
+ 'filesystems.disks.public.root' => 'http://sample-s3-url.com/my-app',
+ 'tenancy.bootstrappers' => [
+ FilesystemTenancyBootstrapper::class,
+ ],
+ 'tenancy.filesystem.root_override.public' => null,
+ 'tenancy.filesystem.url_override.public' => null,
+ ]);
+
+ $tenant = Tenant::create();
+
+ $expectedStoragePath = storage_path() . '/tenant' . $tenant->getTenantKey(); // /tenant = suffix base
+
+ tenancy()->initialize($tenant);
+
+ // Check suffixing logic
+ expect(storage_path())->toEqual($expectedStoragePath);
+});
+
test('create and delete storage symlinks jobs work', function() {
Event::listen(
TenantCreated::class,
diff --git a/tests/CommandsTest.php b/tests/CommandsTest.php
index 8934248b..ad50ba1a 100644
--- a/tests/CommandsTest.php
+++ b/tests/CommandsTest.php
@@ -232,18 +232,43 @@ test('seed command works', function () {
});
});
-test('database connection is switched to default', function () {
- databaseConnectionSwitchedToDefault();
-});
+test('database connection is switched to default after running commands', function (bool $initializeTenancy) {
+ $tenant = Tenant::create();
-test('database connection is switched to default when tenancy has been initialized', function () {
- tenancy()->initialize(Tenant::create());
+ if ($initializeTenancy) {
+ tenancy()->initialize($tenant);
+ }
- databaseConnectionSwitchedToDefault();
-});
+ $originalDBName = DB::connection()->getDatabaseName();
+
+ Artisan::call('tenants:migrate');
+ expect(DB::connection()->getDatabaseName())->toBe($originalDBName);
+
+ Artisan::call('tenants:seed', ['--class' => ExampleSeeder::class]);
+ expect(DB::connection()->getDatabaseName())->toBe($originalDBName);
+
+ Artisan::call('tenants:rollback');
+ expect(DB::connection()->getDatabaseName())->toBe($originalDBName);
+
+ Artisan::call('tenants:migrate', ['--tenants' => [$tenant->getTenantKey()]]);
+
+ pest()->artisan("tenants:run --tenants={$tenant->getTenantKey()} 'foo foo --b=bar --c=xyz'");
+
+ expect(DB::connection()->getDatabaseName())->toBe($originalDBName);
+})->with([
+ 'tenancy initialized' => true,
+ 'tenancy not initialized' => false,
+]);
test('run command works', function () {
- runCommandWorks();
+ $id = Tenant::create()->getTenantKey();
+
+ Artisan::call('tenants:migrate', ['--tenants' => [$id]]);
+
+ pest()->artisan("tenants:run --tenants=$id 'foo foo --b=bar --c=xyz'")
+ ->expectsOutput("User's name is Test user")
+ ->expectsOutput('foo')
+ ->expectsOutput('xyz');
});
test('install command works', function () {
@@ -404,35 +429,3 @@ test('migrate fresh command only deletes tenant databases if drop_tenant_databas
expect($tenantHasDatabase($tenant))->toBe($shouldHaveDBAfterMigrateFresh);
}
})->with([true, false]);
-
-// todo@tests
-function runCommandWorks(): void
-{
- $id = Tenant::create()->getTenantKey();
-
- Artisan::call('tenants:migrate', ['--tenants' => [$id]]);
-
- pest()->artisan("tenants:run --tenants=$id 'foo foo --b=bar --c=xyz' ")
- ->expectsOutput("User's name is Test user")
- ->expectsOutput('foo')
- ->expectsOutput('xyz');
-}
-
-// todo@tests
-function databaseConnectionSwitchedToDefault()
-{
- $originalDBName = DB::connection()->getDatabaseName();
-
- Artisan::call('tenants:migrate');
- expect(DB::connection()->getDatabaseName())->toBe($originalDBName);
-
- Artisan::call('tenants:seed', ['--class' => ExampleSeeder::class]);
- expect(DB::connection()->getDatabaseName())->toBe($originalDBName);
-
- Artisan::call('tenants:rollback');
- expect(DB::connection()->getDatabaseName())->toBe($originalDBName);
-
- runCommandWorks();
-
- expect(DB::connection()->getDatabaseName())->toBe($originalDBName);
-}
diff --git a/tests/SingleDatabaseTenancyTest.php b/tests/SingleDatabaseTenancyTest.php
index d9f10fc0..8d807523 100644
--- a/tests/SingleDatabaseTenancyTest.php
+++ b/tests/SingleDatabaseTenancyTest.php
@@ -35,30 +35,55 @@ beforeEach(function () {
});
test('primary models are scoped to the current tenant', function () {
- primaryModelsScopedToCurrentTenant();
-});
+ // acme context
+ tenancy()->initialize($acme = Tenant::create([
+ 'id' => 'acme',
+ ]));
-test('primary models are not scoped in the central context', function () {
- primaryModelsScopedToCurrentTenant();
+ $post = Post::create(['text' => 'Foo']);
+ expect($post->tenant_id)->toBe('acme');
+ expect($post->tenant->id)->toBe('acme');
+
+ $post = Post::first();
+
+ expect($post->tenant_id)->toBe('acme');
+ expect($post->tenant->id)->toBe('acme');
+
+ // ======================================
+ // foobar context
+ tenancy()->initialize(Tenant::create([
+ 'id' => 'foobar',
+ ]));
+
+ $post = Post::create(['text' => 'Bar']);
+
+ expect($post->tenant_id)->toBe('foobar');
+ expect($post->tenant->id)->toBe('foobar');
+
+ $post = Post::first();
+
+ expect($post->tenant_id)->toBe('foobar');
+ expect($post->tenant->id)->toBe('foobar');
+
+ // ======================================
+ // acme context again
+
+ tenancy()->initialize($acme);
+
+ $post = Post::first();
+ expect($post->tenant_id)->toBe('acme');
+ expect($post->tenant->id)->toBe('acme');
+
+ // Assert foobar models are inaccessible in acme context
+ expect(Post::count())->toBe(1);
+
+ // Primary models are not scoped in the central context
tenancy()->end();
expect(Post::count())->toBe(2);
});
-test('secondary models are scoped to the current tenant when accessed via primary model', function () {
- secondaryModelsAreScopedToCurrentTenant();
-});
-
-test('secondary models are not scoped to the current tenant when accessed directly', function () {
- secondaryModelsAreScopedToCurrentTenant();
-
- // We're in acme context
- expect(tenant('id'))->toBe('acme');
-
- expect(Comment::count())->toBe(2);
-});
-
test('secondary models ARE scoped to the current tenant when accessed directly and parent relationship trait is used', function () {
$acme = Tenant::create([
'id' => 'acme',
@@ -91,9 +116,37 @@ test('secondary models ARE scoped to the current tenant when accessed directly a
expect(ScopedComment::count())->toBe(2);
});
-test('secondary models are not scoped in the central context', function () {
- secondaryModelsAreScopedToCurrentTenant();
+test('secondary models are scoped correctly', function () {
+ // Secondary models are scoped to the current tenant when accessed via primary model
+ // acme context
+ tenancy()->initialize($acme = Tenant::create([
+ 'id' => 'acme',
+ ]));
+ $post = Post::create(['text' => 'Foo']);
+ $post->comments()->create(['text' => 'Comment text']);
+
+ // ================
+ // foobar context
+ tenancy()->initialize(Tenant::create([
+ 'id' => 'foobar',
+ ]));
+
+ $post = Post::create(['text' => 'Bar']);
+ $post->comments()->create(['text' => 'Comment text 2']);
+
+ // ================
+ // acme context again
+ tenancy()->initialize($acme);
+ expect(Post::count())->toBe(1);
+ expect(Post::first()->comments->count())->toBe(1);
+
+ // Secondary models are not scoped to the current tenant when accessed directly
+ expect(tenant('id'))->toBe('acme');
+
+ expect(Comment::count())->toBe(2);
+
+ // secondary models are not scoped in the central context
tenancy()->end();
expect(Comment::count())->toBe(2);
@@ -225,80 +278,6 @@ test('the model returned by the tenant helper has unique and exists validation r
expect($existsFails)->toBeFalse();
});
-// todo@tests
-function primaryModelsScopedToCurrentTenant()
-{
- // acme context
- tenancy()->initialize($acme = Tenant::create([
- 'id' => 'acme',
- ]));
-
- $post = Post::create(['text' => 'Foo']);
-
- expect($post->tenant_id)->toBe('acme');
- expect($post->tenant->id)->toBe('acme');
-
- $post = Post::first();
-
- expect($post->tenant_id)->toBe('acme');
- expect($post->tenant->id)->toBe('acme');
-
- // ======================================
- // foobar context
- tenancy()->initialize($foobar = Tenant::create([
- 'id' => 'foobar',
- ]));
-
- $post = Post::create(['text' => 'Bar']);
-
- expect($post->tenant_id)->toBe('foobar');
- expect($post->tenant->id)->toBe('foobar');
-
- $post = Post::first();
-
- expect($post->tenant_id)->toBe('foobar');
- expect($post->tenant->id)->toBe('foobar');
-
- // ======================================
- // acme context again
-
- tenancy()->initialize($acme);
-
- $post = Post::first();
- expect($post->tenant_id)->toBe('acme');
- expect($post->tenant->id)->toBe('acme');
-
- // Assert foobar models are inaccessible in acme context
- expect(Post::count())->toBe(1);
-}
-
-// todo@tests
-function secondaryModelsAreScopedToCurrentTenant()
-{
- // acme context
- tenancy()->initialize($acme = Tenant::create([
- 'id' => 'acme',
- ]));
-
- $post = Post::create(['text' => 'Foo']);
- $post->comments()->create(['text' => 'Comment text']);
-
- // ================
- // foobar context
- tenancy()->initialize($foobar = Tenant::create([
- 'id' => 'foobar',
- ]));
-
- $post = Post::create(['text' => 'Bar']);
- $post->comments()->create(['text' => 'Comment text 2']);
-
- // ================
- // acme context again
- tenancy()->initialize($acme);
- expect(Post::count())->toBe(1);
- expect(Post::first()->comments->count())->toBe(1);
-}
-
class Tenant extends TestTenant
{
use HasScopedValidationRules;
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 5d18cda4..ed3b20cc 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -18,9 +18,7 @@ use Stancl\Tenancy\Bootstrappers\RootUrlBootstrapper;
use Stancl\Tenancy\Bootstrappers\MailConfigBootstrapper;
use Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper;
use Stancl\Tenancy\Bootstrappers\UrlGeneratorBootstrapper;
-use Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper;
use Stancl\Tenancy\Bootstrappers\BroadcastingConfigBootstrapper;
-use Stancl\Tenancy\Bootstrappers\FilesystemTenancyBootstrapper;
use Stancl\Tenancy\Bootstrappers\CacheTenancyBootstrapper;
abstract class TestCase extends \Orchestra\Testbench\TestCase