From 6f4b9f486c03c202a2af864351cadcda005b33f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Mon, 11 May 2020 03:37:47 +0200 Subject: [PATCH] Bootstrapper tests --- assets/config.php | 2 +- docker-compose.yml | 3 + src/Commands/Migrate.php | 22 ++- src/Contracts/Tenant.php | 4 + src/Contracts/TenantDatabaseManager.php | 6 +- src/Database/Models/Tenant.php | 14 +- src/DatabaseConfig.php | 3 +- src/DatabaseManager.php | 53 ++---- src/Events/Contracts/DomainEvent.php | 2 +- src/Events/Contracts/TenantEvent.php | 2 +- src/Events/Listeners/JobPipeline.php | 7 +- src/Jobs/CreateDatabase.php | 6 +- src/Tenancy.php | 17 +- .../CacheTenancyBootstrapper.php | 15 ++ .../DatabaseTenancyBootstrapper.php | 7 +- src/TenancyServiceProvider.php | 3 +- .../SQLiteDatabaseManager.php | 6 +- src/helpers.php | 8 +- tests/v3/BootstrapperTest.php | 156 +++++++++++++++++- tests/v3/JobPipelineTest.php | 9 +- 20 files changed, 266 insertions(+), 79 deletions(-) diff --git a/assets/config.php b/assets/config.php index 357c4b26..a90e849b 100644 --- a/assets/config.php +++ b/assets/config.php @@ -8,7 +8,7 @@ use Stancl\Tenancy\Database\Models\Tenant; return [ 'tenant_model' => Tenant::class, 'domain_model' => Domain::class, - 'internal_prefix' => 'tenancy_', + 'internal_column_prefix' => 'tenancy_', 'central_connection' => 'central', 'template_tenant_connection' => null, diff --git a/docker-compose.yml b/docker-compose.yml index fafd6316..d5315fb9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,6 +16,9 @@ services: DB_PASSWORD: password DB_USERNAME: root DB_DATABASE: main + TENANCY_TEST_REDIS_HOST: redis + TENANCY_TEST_MYSQL_HOST: mysql + TENANCY_TEST_PGSQL_HOST: postgres stdin_open: true tty: true mysql: diff --git a/src/Commands/Migrate.php b/src/Commands/Migrate.php index d10bcd06..18e082fe 100644 --- a/src/Commands/Migrate.php +++ b/src/Commands/Migrate.php @@ -7,6 +7,7 @@ namespace Stancl\Tenancy\Commands; use Illuminate\Console\Command; use Illuminate\Database\Console\Migrations\MigrateCommand; use Illuminate\Database\Migrations\Migrator; +use Stancl\Tenancy\Contracts\TenantWithDatabase; use Stancl\Tenancy\DatabaseManager; use Stancl\Tenancy\Events\DatabaseMigrated; use Stancl\Tenancy\Traits\DealsWithMigrations; @@ -56,15 +57,20 @@ class Migrate extends MigrateCommand return; } - tenancy()->all($this->option('tenants'))->each(function ($tenant) { - $this->line("Tenant: {$tenant['id']}"); + tenancy() + ->query() + ->when($this->option('tenants'), function ($query) { + $query->whereIn(tenancy()->model()->getTenantKeyName(), $this->option('tenants')); + }) + ->each(function (TenantWithDatabase $tenant) { + $this->line("Tenant: {$tenant['id']}"); - $tenant->run(function () { - // Migrate - parent::handle(); + $tenant->run(function () { + // Migrate + parent::handle(); + }); + + event(new DatabaseMigrated($tenant)); }); - - event(new DatabaseMigrated($tenant)); - }); } } diff --git a/src/Contracts/Tenant.php b/src/Contracts/Tenant.php index ce7a7d98..831e399b 100644 --- a/src/Contracts/Tenant.php +++ b/src/Contracts/Tenant.php @@ -2,8 +2,12 @@ namespace Stancl\Tenancy\Contracts; +/** + * @see \Stancl\Tenancy\Database\Models\Tenant + */ interface Tenant { public function getTenantKeyName(): string; public function getTenantKey(): string; + public function run(callable $callback); } \ No newline at end of file diff --git a/src/Contracts/TenantDatabaseManager.php b/src/Contracts/TenantDatabaseManager.php index 55aefebf..107198f1 100644 --- a/src/Contracts/TenantDatabaseManager.php +++ b/src/Contracts/TenantDatabaseManager.php @@ -4,8 +4,6 @@ declare(strict_types=1); namespace Stancl\Tenancy\Contracts; -use Stancl\Tenancy\Tenant; - interface TenantDatabaseManager { /** @@ -18,12 +16,12 @@ interface TenantDatabaseManager /** * Create a database. */ - public function createDatabase(Tenant $tenant): bool; + public function createDatabase(TenantWithDatabase $tenant): bool; /** * Delete a database. */ - public function deleteDatabase(Tenant $tenant): bool; + public function deleteDatabase(TenantWithDatabase $tenant): bool; /** * Does a database exist. diff --git a/src/Database/Models/Tenant.php b/src/Database/Models/Tenant.php index c24224f1..1aa70002 100644 --- a/src/Database/Models/Tenant.php +++ b/src/Database/Models/Tenant.php @@ -8,7 +8,7 @@ use Stancl\Tenancy\Events; use Stancl\Tenancy\Contracts; // todo @property -class Tenant extends Model implements Contracts\Tenant +class Tenant extends Model implements Contracts\TenantWithDatabase { use Concerns\CentralConnection, Concerns\HasADataColumn, Concerns\GeneratesIds, Concerns\HasADataColumn { Concerns\HasADataColumn::getCasts as dataColumnCasts; @@ -41,7 +41,7 @@ class Tenant extends Model implements Contracts\Tenant public static function internalPrefix(): string { - return config('tenancy.database_prefix'); + return config('tenancy.internal_column_prefix'); } /** @@ -76,15 +76,15 @@ class Tenant extends Model implements Contracts\Tenant public function run(callable $callback) { - // todo new logic with the manager - $originalTenant = $this->manager->getTenant(); + $originalTenant = tenant(); - $this->manager->initializeTenancy($this); + tenancy()->initialize($this); $result = $callback($this); - $this->manager->endTenancy($this); if ($originalTenant) { - $this->manager->initializeTenancy($originalTenant); + tenancy()->initialize($originalTenant); + } else { + tenancy()->end(); } return $result; diff --git a/src/DatabaseConfig.php b/src/DatabaseConfig.php index df081311..bc5af906 100644 --- a/src/DatabaseConfig.php +++ b/src/DatabaseConfig.php @@ -93,7 +93,7 @@ class DatabaseConfig { return $this->tenant->getInternal('db_connection') ?? config('tenancy.template_tenant_connection') - ?? DatabaseManager::$originalDefaultConnectionName; + ?? config('tenancy.central_connection'); } /** @@ -105,6 +105,7 @@ class DatabaseConfig $templateConnection = config("database.connections.{$template}"); + // todo move a lot of this logic to the tenant DB manager so that we dont have to deal with the separators & modifying DB names here $databaseName = $this->getName(); if (($manager = $this->manager()) instanceof ModifiesDatabaseNameForConnection) { /** @var ModifiesDatabaseNameForConnection $manager */ diff --git a/src/DatabaseManager.php b/src/DatabaseManager.php index e7ef2390..ca90b9ec 100644 --- a/src/DatabaseManager.php +++ b/src/DatabaseManager.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Stancl\Tenancy; use Closure; +use Illuminate\Config\Repository; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Database\DatabaseManager as BaseDatabaseManager; use Illuminate\Foundation\Application; @@ -18,58 +19,43 @@ use Stancl\Tenancy\Jobs\QueuedTenantDatabaseDeleter; /** * @internal Class is subject to breaking changes in minor and patch versions. */ -// todo rewrite everything class DatabaseManager { - /** @var string */ - public static $originalDefaultConnectionName; - /** @var Application */ protected $app; /** @var BaseDatabaseManager */ protected $database; - /** @var TenantManager */ - protected $tenancy; + /** @var Repository */ + protected $config; - public function __construct(Application $app, BaseDatabaseManager $database) + public function __construct(Application $app, BaseDatabaseManager $database, Repository $config) { $this->app = $app; $this->database = $database; - static::$originalDefaultConnectionName = $app['config']['database.default']; - } - - /** - * Set the TenantManager instance, used to dispatch tenancy events. - */ - public function withTenantManager(Tenancy $tenantManager): self - { - $this->tenancy = $tenantManager; - - return $this; + $this->config = $config; } /** * Connect to a tenant's database. */ - public function connect(TenantWithDatabase $tenant) + public function connectToTenant(TenantWithDatabase $tenant) { $this->createTenantConnection($tenant); $this->setDefaultConnection('tenant'); - $this->switchConnection('tenant'); + $this->database->purge('tenant'); } /** * Reconnect to the default non-tenant connection. */ - public function reconnect() + public function reconnectToCentral() { - if ($this->tenancy->initialized) { + if (tenancy()->initialized) { $this->database->purge('tenant'); } - $this->setDefaultConnection(static::$originalDefaultConnectionName); - $this->switchConnection(static::$originalDefaultConnectionName); + $this->setDefaultConnection($this->config->get('tenancy.central_connection')); } /** @@ -78,25 +64,17 @@ class DatabaseManager public function setDefaultConnection(string $connection) { $this->app['config']['database.default'] = $connection; + $this->database->setDefaultConnection($connection); } /** * Create the tenant database connection. */ - public function createTenantConnection(Tenant $tenant) + public function createTenantConnection(TenantWithDatabase $tenant) { $this->app['config']['database.connections.tenant'] = $tenant->database()->connection(); } - /** - * Switch the application's connection. - */ - public function switchConnection(string $connection) - { - $this->database->reconnect($connection); - $this->database->setDefaultConnection($connection); - } - /** * Check if a tenant can be created. * @@ -104,7 +82,7 @@ class DatabaseManager * @throws DatabaseManagerNotRegisteredException * @throws TenantDatabaseAlreadyExistsException */ - public function ensureTenantCanBeCreated(Tenant $tenant): void + public function ensureTenantCanBeCreated(TenantWithDatabase $tenant): void { if ($tenant->database()->manager()->databaseExists($database = $tenant->database()->getName())) { throw new TenantDatabaseAlreadyExistsException($database); @@ -119,8 +97,9 @@ class DatabaseManager * @return void * @throws DatabaseManagerNotRegisteredException */ - public function createDatabase(Tenant $tenant, array $afterCreating = []) + public function createDatabase(TenantWithDatabase $tenant, array $afterCreating = []) { + // todo get rid of aftercreating logic $afterCreating = array_merge( $afterCreating, $this->tenancy->event('database.creating', $tenant->database()->getName(), $tenant) @@ -168,7 +147,7 @@ class DatabaseManager * * @throws DatabaseManagerNotRegisteredException */ - public function deleteDatabase(Tenant $tenant) + public function deleteDatabase(TenantWithDatabase $tenant) { $database = $tenant->database()->getName(); $manager = $tenant->database()->manager(); diff --git a/src/Events/Contracts/DomainEvent.php b/src/Events/Contracts/DomainEvent.php index 5e896afd..f24cf508 100644 --- a/src/Events/Contracts/DomainEvent.php +++ b/src/Events/Contracts/DomainEvent.php @@ -3,7 +3,7 @@ namespace Stancl\Tenancy\Events\Contracts; use Illuminate\Queue\SerializesModels; -use Stancl\Tenancy\Database\Models\Domain; +use Stancl\Tenancy\Contracts\Domain; abstract class DomainEvent { diff --git a/src/Events/Contracts/TenantEvent.php b/src/Events/Contracts/TenantEvent.php index 56d43a28..93470327 100644 --- a/src/Events/Contracts/TenantEvent.php +++ b/src/Events/Contracts/TenantEvent.php @@ -3,7 +3,7 @@ namespace Stancl\Tenancy\Events\Contracts; use Illuminate\Queue\SerializesModels; -use Stancl\Tenancy\Database\Models\Tenant; +use Stancl\Tenancy\Contracts\Tenant; abstract class TenantEvent { diff --git a/src/Events/Listeners/JobPipeline.php b/src/Events/Listeners/JobPipeline.php index 07b519e8..4b344f6b 100644 --- a/src/Events/Listeners/JobPipeline.php +++ b/src/Events/Listeners/JobPipeline.php @@ -61,7 +61,7 @@ class JobPipeline implements ShouldQueue public function handle(): void { foreach ($this->jobs as $job) { - app($job)->handle($this->passable); + app()->call([new $job(...$this->passable), 'handle']); } } @@ -82,7 +82,10 @@ class JobPipeline implements ShouldQueue { $clone = clone $this; - $clone->passable = ($clone->send)(...$listenerArgs); + $passable = ($clone->send)(...$listenerArgs); + $passable = is_array($passable) ? $passable : [$passable]; + + $clone->passable = $passable; unset($clone->send); return $clone; diff --git a/src/Jobs/CreateDatabase.php b/src/Jobs/CreateDatabase.php index e196d38b..5cad079c 100644 --- a/src/Jobs/CreateDatabase.php +++ b/src/Jobs/CreateDatabase.php @@ -6,16 +6,18 @@ namespace Stancl\Tenancy\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -use Stancl\Tenancy\Database\Models\Tenant; +use Stancl\Tenancy\Contracts\TenantWithDatabase; +use Stancl\Tenancy\Contracts\Tenant; class CreateDatabase implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - /** @var Tenant */ + /** @var TenantWithDatabase|Model */ protected $tenant; public function __construct(Tenant $tenant) diff --git a/src/Tenancy.php b/src/Tenancy.php index 053baa18..62b72dda 100644 --- a/src/Tenancy.php +++ b/src/Tenancy.php @@ -2,12 +2,14 @@ namespace Stancl\Tenancy; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Model; use Stancl\Tenancy\Contracts\TenancyBootstrapper; use Stancl\Tenancy\Contracts\Tenant; class Tenancy { - /** @var Tenant|null */ + /** @var Tenant|Model|null */ public $tenant; /** @var callable|null */ @@ -48,4 +50,17 @@ class Tenancy return $resolve($this->tenant); } + + public function query(): Builder + { + return $this->model()->query(); + } + + /** @return Tenant|Model */ + public function model() + { + $class = config('tenancy.tenant_model'); + + return new $class; + } } diff --git a/src/TenancyBootstrappers/CacheTenancyBootstrapper.php b/src/TenancyBootstrappers/CacheTenancyBootstrapper.php index 8564bd44..f799bc3f 100644 --- a/src/TenancyBootstrappers/CacheTenancyBootstrapper.php +++ b/src/TenancyBootstrappers/CacheTenancyBootstrapper.php @@ -6,6 +6,7 @@ namespace Stancl\Tenancy\TenancyBootstrappers; use Illuminate\Cache\CacheManager; use Illuminate\Contracts\Foundation\Application; +use Illuminate\Support\Facades\Cache; use Stancl\Tenancy\CacheManager as TenantCacheManager; use Stancl\Tenancy\Contracts\TenancyBootstrapper; use Stancl\Tenancy\Contracts\Tenant; @@ -25,6 +26,8 @@ class CacheTenancyBootstrapper implements TenancyBootstrapper public function start(Tenant $tenant) { + $this->resetFacadeCache(); + $this->originalCache = $this->originalCache ?? $this->app['cache']; $this->app->extend('cache', function () { return new TenantCacheManager($this->app); @@ -33,10 +36,22 @@ class CacheTenancyBootstrapper implements TenancyBootstrapper public function end() { + $this->resetFacadeCache(); + $this->app->extend('cache', function () { return $this->originalCache; }); $this->originalCache = null; } + + /** + * This wouldn't be necessary, but is needed when a call to the + * facade has been made prior to bootstrapping tenancy. The + * facade has its own cache, separate from the container. + */ + public function resetFacadeCache() + { + Cache::clearResolvedInstances(); + } } diff --git a/src/TenancyBootstrappers/DatabaseTenancyBootstrapper.php b/src/TenancyBootstrappers/DatabaseTenancyBootstrapper.php index 9780af8a..de70a146 100644 --- a/src/TenancyBootstrappers/DatabaseTenancyBootstrapper.php +++ b/src/TenancyBootstrappers/DatabaseTenancyBootstrapper.php @@ -8,6 +8,7 @@ use Stancl\Tenancy\Contracts\TenancyBootstrapper; use Stancl\Tenancy\DatabaseManager; use Stancl\Tenancy\Exceptions\TenantDatabaseDoesNotExistException; use Stancl\Tenancy\Contracts\TenantWithDatabase; +use Stancl\Tenancy\Contracts\Tenant; class DatabaseTenancyBootstrapper implements TenancyBootstrapper { @@ -19,8 +20,10 @@ class DatabaseTenancyBootstrapper implements TenancyBootstrapper $this->database = $database; } - public function start(TenantWithDatabase $tenant) + public function start(Tenant $tenant) { + /** @var TenantWithDatabase $tenant */ + $database = $tenant->database()->getName(); if (! $tenant->database()->manager()->databaseExists($database)) { throw new TenantDatabaseDoesNotExistException($database); @@ -31,6 +34,6 @@ class DatabaseTenancyBootstrapper implements TenancyBootstrapper public function end() { - $this->database->revertToCentral(); + $this->database->reconnectToCentral(); } } diff --git a/src/TenancyServiceProvider.php b/src/TenancyServiceProvider.php index 9644576f..1310222f 100644 --- a/src/TenancyServiceProvider.php +++ b/src/TenancyServiceProvider.php @@ -8,10 +8,9 @@ use Illuminate\Cache\CacheManager; use Illuminate\Contracts\Http\Kernel; use Illuminate\Support\Facades\Route; use Illuminate\Support\ServiceProvider; -use Stancl\Tenancy\Database\Models\Tenant; -use Stancl\Tenancy\Database\TenantObserver; use Stancl\Tenancy\StorageDrivers\Database\DatabaseStorageDriver; use Stancl\Tenancy\TenancyBootstrappers\FilesystemTenancyBootstrapper; +use Stancl\Tenancy\Contracts\Tenant; class TenancyServiceProvider extends ServiceProvider { diff --git a/src/TenantDatabaseManagers/SQLiteDatabaseManager.php b/src/TenantDatabaseManagers/SQLiteDatabaseManager.php index 19407ce9..f3c110d5 100644 --- a/src/TenantDatabaseManagers/SQLiteDatabaseManager.php +++ b/src/TenantDatabaseManagers/SQLiteDatabaseManager.php @@ -6,7 +6,7 @@ namespace Stancl\Tenancy\TenantDatabaseManagers; use Stancl\Tenancy\Contracts\ModifiesDatabaseNameForConnection; use Stancl\Tenancy\Contracts\TenantDatabaseManager; -use Stancl\Tenancy\Tenant; +use Stancl\Tenancy\Contracts\TenantWithDatabase; class SQLiteDatabaseManager implements TenantDatabaseManager, ModifiesDatabaseNameForConnection { @@ -15,7 +15,7 @@ class SQLiteDatabaseManager implements TenantDatabaseManager, ModifiesDatabaseNa return 'database'; } - public function createDatabase(Tenant $tenant): bool + public function createDatabase(TenantWithDatabase $tenant): bool { try { return fclose(fopen(database_path($tenant->database()->getName()), 'w')); @@ -24,7 +24,7 @@ class SQLiteDatabaseManager implements TenantDatabaseManager, ModifiesDatabaseNa } } - public function deleteDatabase(Tenant $tenant): bool + public function deleteDatabase(TenantWithDatabase $tenant): bool { try { return unlink(database_path($tenant->database()->getName())); diff --git a/src/helpers.php b/src/helpers.php index bcec0434..44e5039f 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -2,8 +2,8 @@ declare(strict_types=1); -use Stancl\Tenancy\Database\Models\Tenant; use Stancl\Tenancy\Tenancy; +use Stancl\Tenancy\Contracts\Tenant; if (! function_exists('tenancy')) { /** @return Tenancy */ @@ -18,10 +18,14 @@ if (! function_exists('tenant')) { * Get a key from the current tenant's storage. * * @param string|null $key - * @return Tenant|mixed + * @return Tenant|null|mixed */ function tenant($key = null) { + if (! app()->bound(Tenant::class)) { + return null; + } + if (is_null($key)) { return app(Tenant::class); } diff --git a/tests/v3/BootstrapperTest.php b/tests/v3/BootstrapperTest.php index d9c93c05..c07bf0e9 100644 --- a/tests/v3/BootstrapperTest.php +++ b/tests/v3/BootstrapperTest.php @@ -2,37 +2,185 @@ namespace Stancl\Tenancy\Tests\v3; +use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Event; +use Illuminate\Support\Facades\Redis; +use Illuminate\Support\Facades\Storage; +use Stancl\Tenancy\Database\Models\Tenant; +use Stancl\Tenancy\Events\Listeners\BootstrapTenancy; +use Stancl\Tenancy\Events\Listeners\JobPipeline; +use Stancl\Tenancy\Events\Listeners\RevertToCentralContext; +use Stancl\Tenancy\Events\TenancyEnded; +use Stancl\Tenancy\Events\TenancyInitialized; +use Stancl\Tenancy\Events\TenantCreated; +use Stancl\Tenancy\Jobs\CreateDatabase; +use Stancl\Tenancy\TenancyBootstrappers\CacheTenancyBootstrapper; +use Stancl\Tenancy\TenancyBootstrappers\DatabaseTenancyBootstrapper; +use Stancl\Tenancy\TenancyBootstrappers\FilesystemTenancyBootstrapper; +use Stancl\Tenancy\TenancyBootstrappers\RedisTenancyBootstrapper; use Stancl\Tenancy\Tests\TestCase; class BootstrapperTest extends TestCase { + public $mockConsoleOutput = false; + + public function setUp(): void + { + parent::setUp(); + + Event::listen( + TenantCreated::class, + JobPipeline::make([CreateDatabase::class])->send(function (TenantCreated $event) { + return $event->tenant; + })->toListener() + ); + + Event::listen(TenancyInitialized::class, BootstrapTenancy::class); + Event::listen(TenancyEnded::class, RevertToCentralContext::class); + } + /** @test */ public function database_data_is_separated() { - + config(['tenancy.bootstrappers' => [ + DatabaseTenancyBootstrapper::class + ]]); + + $tenant1 = Tenant::create(); + $tenant2 = Tenant::create(); + + $this->artisan('tenants:migrate'); + + tenancy()->initialize($tenant1); + + // Create Foo user + DB::table('users')->insert(['name' => 'Foo', 'email' => 'foo@bar.com', 'password' => 'secret']); + $this->assertCount(1, DB::table('users')->get()); + + tenancy()->initialize($tenant2); + + // Assert Foo user is not in this DB + $this->assertCount(0, DB::table('users')->get()); + // Create Bar user + DB::table('users')->insert(['name' => 'Bar', 'email' => 'bar@bar.com', 'password' => 'secret']); + $this->assertCount(1, DB::table('users')->get()); + + tenancy()->initialize($tenant1); + + // Assert Bar user is not in this DB + $this->assertCount(1, DB::table('users')->get()); + $this->assertSame('Foo', DB::table('users')->first()->name); } /** @test */ public function cache_data_is_separated() { + config([ + 'tenancy.bootstrappers' => [ + CacheTenancyBootstrapper::class + ], + 'cache.default' => 'redis', + ]); + + $tenant1 = Tenant::create(); + $tenant2 = Tenant::create(); + + cache()->set('foo', 'central'); + $this->assertSame('central', Cache::get('foo')); + + tenancy()->initialize($tenant1); + + // Assert central cache doesn't leak to tenant context + $this->assertFalse(Cache::has('foo')); + + cache()->set('foo', 'bar'); + $this->assertSame('bar', Cache::get('foo')); + + tenancy()->initialize($tenant2); + + // Assert one tenant's data doesn't leak to another tenant + $this->assertFalse(Cache::has('foo')); + + cache()->set('foo', 'xyz'); + $this->assertSame('xyz', Cache::get('foo')); + + tenancy()->initialize($tenant1); + // Asset data didn't leak to original tenant + $this->assertSame('bar', Cache::get('foo')); + + tenancy()->end(); + + // Asset central is still the same + $this->assertSame('central', Cache::get('foo')); } /** @test */ public function redis_data_is_separated() { - + config(['tenancy.bootstrappers' => [ + RedisTenancyBootstrapper::class + ]]); + + $tenant1 = Tenant::create(); + $tenant2 = Tenant::create(); + + tenancy()->initialize($tenant1); + Redis::set('foo', 'bar'); + $this->assertSame('bar', Redis::get('foo')); + + tenancy()->initialize($tenant2); + $this->assertSame(null, Redis::get('foo')); + Redis::set('foo', 'xyz'); + Redis::set('abc', 'def'); + $this->assertSame('xyz', Redis::get('foo')); + $this->assertSame('def', Redis::get('abc')); + + tenancy()->initialize($tenant1); + $this->assertSame('bar', Redis::get('foo')); + $this->assertSame(null, Redis::get('abc')); + + $tenant3 = Tenant::create(); + tenancy()->initialize($tenant3); + $this->assertSame(null, Redis::get('foo')); + $this->assertSame(null, Redis::get('abc')); } /** @test */ public function filesystem_data_is_separated() { - + config(['tenancy.bootstrappers' => [ + FilesystemTenancyBootstrapper::class + ]]); + + $tenant1 = Tenant::create(); + $tenant2 = Tenant::create(); + + tenancy()->initialize($tenant1); + Storage::disk('public')->put('foo', 'bar'); + $this->assertSame('bar', Storage::disk('public')->get('foo')); + + tenancy()->initialize($tenant2); + $this->assertFalse(Storage::disk('public')->exists('foo')); + Storage::disk('public')->put('foo', 'xyz'); + Storage::disk('public')->put('abc', 'def'); + $this->assertSame('xyz', Storage::disk('public')->get('foo')); + $this->assertSame('def', Storage::disk('public')->get('abc')); + + tenancy()->initialize($tenant1); + $this->assertSame('bar', Storage::disk('public')->get('foo')); + $this->assertFalse(Storage::disk('public')->exists('abc')); + + $tenant3 = Tenant::create(); + tenancy()->initialize($tenant3); + $this->assertFalse(Storage::disk('public')->exists('foo')); + $this->assertFalse(Storage::disk('public')->exists('abc')); } /** @test */ public function queue_data_is_separated() { - + // todo } } diff --git a/tests/v3/JobPipelineTest.php b/tests/v3/JobPipelineTest.php index 4eea7f37..f5b3c6a3 100644 --- a/tests/v3/JobPipelineTest.php +++ b/tests/v3/JobPipelineTest.php @@ -9,6 +9,7 @@ use Stancl\Tenancy\Events\Listeners\JobPipeline; use Stancl\Tenancy\Events\TenantCreated; use Stancl\Tenancy\Tests\TestCase; +// todo the shouldQueue() doesnt make sense? test if it really works or if its just because of sync queue driver class JobPipelineTest extends TestCase { /** @test */ @@ -19,7 +20,7 @@ class JobPipelineTest extends TestCase ])->toListener()); $this->assertFalse(app()->bound('foo')); - + Tenant::create(); $this->assertSame('bar', app('foo')); @@ -60,6 +61,12 @@ class JobPipelineTest extends TestCase $this->assertSame('first job changed property', app('foo')); } + + /** @test */ + public function send_can_return_multiple_arguments() + { + // todo + } } class FooJob