From bd6583b6af31ca0410de7240348dc8362e5dea87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Fri, 2 Aug 2019 19:54:10 +0200 Subject: [PATCH 01/15] Create .styleci.yml --- .styleci.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .styleci.yml diff --git a/.styleci.yml b/.styleci.yml new file mode 100644 index 00000000..2a6c92f2 --- /dev/null +++ b/.styleci.yml @@ -0,0 +1,4 @@ +preset: laravel +disabled: +- concat_without_spaces +- ternary_operator_spaces From eceacd9422afccbef482b91b1355acfb5c343e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Fri, 2 Aug 2019 20:01:10 +0200 Subject: [PATCH 02/15] Apply fixes from StyleCI (#80) --- src/CacheManager.php | 2 +- src/Commands/TenantList.php | 2 +- src/DatabaseManager.php | 6 +++--- src/GlobalCacheFacade.php | 2 +- src/Interfaces/StorageDriver.php | 9 +++++++++ src/Interfaces/TenantDatabaseManager.php | 4 ++-- src/Jobs/QueuedTenantDatabaseCreator.php | 2 +- src/Jobs/QueuedTenantDatabaseDeleter.php | 2 +- src/StorageDrivers/RedisStorageDriver.php | 13 +++++++++---- src/TenancyServiceProvider.php | 8 +++----- src/TenantManager.php | 18 +++++++++++------- src/Traits/BootstrapsTenancy.php | 10 +++++----- src/Traits/HasATenantsOption.php | 2 +- tests/BootstrapsTenancyTest.php | 8 ++++---- tests/CacheManagerTest.php | 2 +- tests/CommandsTest.php | 10 +++++----- tests/DataSeparationTest.php | 20 ++++++++++---------- tests/DatabaseManagerTest.php | 2 +- tests/GlobalCacheTest.php | 8 ++++---- tests/ReidentificationTest.php | 3 +-- tests/TenantAssetTest.php | 2 +- tests/TenantDatabaseManagerTest.php | 2 +- tests/TenantManagerTest.php | 8 ++++---- tests/TenantStorageTest.php | 6 ++---- tests/TestCase.php | 2 +- 25 files changed, 83 insertions(+), 70 deletions(-) diff --git a/src/CacheManager.php b/src/CacheManager.php index 6e37f417..d3b31ea2 100644 --- a/src/CacheManager.php +++ b/src/CacheManager.php @@ -10,7 +10,7 @@ class CacheManager extends BaseCacheManager { $tags = [config('tenancy.cache.tag_base') . tenant('uuid')]; - if ($method === "tags") { + if ($method === 'tags') { if (\count($parameters) !== 1) { throw new \Exception("Method tags() takes exactly 1 argument. {count($parameters)} passed."); } diff --git a/src/Commands/TenantList.php b/src/Commands/TenantList.php index 94eae4c6..6a8fc400 100644 --- a/src/Commands/TenantList.php +++ b/src/Commands/TenantList.php @@ -37,7 +37,7 @@ class TenantList extends Command */ public function handle() { - $this->info("Listing all tenants."); + $this->info('Listing all tenants.'); tenancy()->all()->each(function ($tenant) { $this->line("[Tenant] uuid: {$tenant['uuid']} @ {$tenant['domain']}"); }); diff --git a/src/DatabaseManager.php b/src/DatabaseManager.php index a5bae6bd..47bee9fc 100644 --- a/src/DatabaseManager.php +++ b/src/DatabaseManager.php @@ -90,7 +90,7 @@ class DatabaseManager public function getDriver(): ?string { - return config("database.connections.tenant.driver"); + return config('database.connections.tenant.driver'); } public function createTenantConnection(string $database_name) @@ -98,11 +98,11 @@ class DatabaseManager // Create the `tenancy` database connection. $based_on = config('tenancy.database.based_on') ?: config('database.default'); config()->set([ - 'database.connections.tenant' => config('database.connections.' . $based_on) + 'database.connections.tenant' => config('database.connections.' . $based_on), ]); // Change DB name - $database_name = $this->getDriver() === "sqlite" ? database_path($database_name) : $database_name; + $database_name = $this->getDriver() === 'sqlite' ? database_path($database_name) : $database_name; config()->set(['database.connections.tenant.database' => $database_name]); } } diff --git a/src/GlobalCacheFacade.php b/src/GlobalCacheFacade.php index ba2f8fad..bc4d9317 100644 --- a/src/GlobalCacheFacade.php +++ b/src/GlobalCacheFacade.php @@ -10,4 +10,4 @@ class GlobalCacheFacade extends Facade { return 'globalCache'; } -} \ No newline at end of file +} diff --git a/src/Interfaces/StorageDriver.php b/src/Interfaces/StorageDriver.php index 8dbcf91e..83dcae4a 100644 --- a/src/Interfaces/StorageDriver.php +++ b/src/Interfaces/StorageDriver.php @@ -5,13 +5,22 @@ namespace Stancl\Tenancy\Interfaces; interface StorageDriver { public function identifyTenant(string $domain): array; + public function getAllTenants(array $uuids = []): array; + public function getTenantById(string $uuid, array $fields = []): array; + public function getTenantIdByDomain(string $domain): ?string; + public function createTenant(string $domain, string $uuid): array; + public function deleteTenant(string $uuid): bool; + public function get(string $uuid, string $key); + public function getMany(string $uuid, array $keys): array; + public function put(string $uuid, string $key, $value); + public function putMany(string $uuid, array $values): array; } diff --git a/src/Interfaces/TenantDatabaseManager.php b/src/Interfaces/TenantDatabaseManager.php index 89bb330e..3abc8698 100644 --- a/src/Interfaces/TenantDatabaseManager.php +++ b/src/Interfaces/TenantDatabaseManager.php @@ -8,7 +8,7 @@ interface TenantDatabaseManager * Create a database. * * @param string $name Name of the database. - * @return boolean + * @return bool */ public function createDatabase(string $name): bool; @@ -16,7 +16,7 @@ interface TenantDatabaseManager * Delete a database. * * @param string $name Name of the database. - * @return boolean + * @return bool */ public function deleteDatabase(string $name): bool; } diff --git a/src/Jobs/QueuedTenantDatabaseCreator.php b/src/Jobs/QueuedTenantDatabaseCreator.php index f23f6442..d8eb90d1 100644 --- a/src/Jobs/QueuedTenantDatabaseCreator.php +++ b/src/Jobs/QueuedTenantDatabaseCreator.php @@ -5,8 +5,8 @@ namespace Stancl\Tenancy\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; -use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; use Stancl\Tenancy\Interfaces\TenantDatabaseManager; class QueuedTenantDatabaseCreator implements ShouldQueue diff --git a/src/Jobs/QueuedTenantDatabaseDeleter.php b/src/Jobs/QueuedTenantDatabaseDeleter.php index ba3e5bc7..cf3a964e 100644 --- a/src/Jobs/QueuedTenantDatabaseDeleter.php +++ b/src/Jobs/QueuedTenantDatabaseDeleter.php @@ -5,8 +5,8 @@ namespace Stancl\Tenancy\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; -use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; use Stancl\Tenancy\Interfaces\TenantDatabaseManager; class QueuedTenantDatabaseDeleter implements ShouldQueue diff --git a/src/StorageDrivers/RedisStorageDriver.php b/src/StorageDrivers/RedisStorageDriver.php index b604c9b8..50e1fb8e 100644 --- a/src/StorageDrivers/RedisStorageDriver.php +++ b/src/StorageDrivers/RedisStorageDriver.php @@ -20,6 +20,7 @@ class RedisStorageDriver implements StorageDriver if (! $id) { throw new \Exception("Tenant could not be identified on domain {$domain}"); } + return $this->getTenantById($id); } @@ -33,7 +34,7 @@ class RedisStorageDriver implements StorageDriver public function getTenantById(string $uuid, array $fields = []): array { $fields = (array) $fields; - + if (! $fields) { return $this->redis->hgetall("tenants:$uuid"); } @@ -50,14 +51,15 @@ class RedisStorageDriver implements StorageDriver { $this->redis->hmset("domains:$domain", 'tenant_id', $uuid); $this->redis->hmset("tenants:$uuid", 'uuid', json_encode($uuid), 'domain', json_encode($domain)); + return $this->redis->hgetall("tenants:$uuid"); } /** - * @inheritDoc + * {@inheritdoc} * * @param string $id - * @return boolean + * @return bool * @todo Make tenant & domain deletion atomic. */ public function deleteTenant(string $id): bool @@ -69,6 +71,7 @@ class RedisStorageDriver implements StorageDriver } $this->redis->del("domains:$domain"); + return (bool) $this->redis->del("tenants:$id"); } @@ -91,7 +94,7 @@ class RedisStorageDriver implements StorageDriver return substr($hash, strlen($redis_prefix)); }, $this->redis->scan(null, $redis_prefix.'tenants:*')); } - + return array_map(function ($tenant) { return $this->redis->hgetall($tenant); }, $hashes); @@ -110,12 +113,14 @@ class RedisStorageDriver implements StorageDriver public function put(string $uuid, string $key, $value) { $this->redis->hset("tenants:$uuid", $key, $value); + return $value; } public function putMany(string $uuid, array $values): array { $this->redis->hmset("tenants:$uuid", $values); + return $values; } } diff --git a/src/TenancyServiceProvider.php b/src/TenancyServiceProvider.php index c5b0b3f6..12005e9f 100644 --- a/src/TenancyServiceProvider.php +++ b/src/TenancyServiceProvider.php @@ -3,16 +3,14 @@ namespace Stancl\Tenancy; use Stancl\Tenancy\Commands\Seed; -use Stancl\Tenancy\TenantManager; -use Stancl\Tenancy\DatabaseManager; +use Illuminate\Cache\CacheManager; use Stancl\Tenancy\Commands\Migrate; -use Stancl\Tenancy\Commands\Rollback; use Illuminate\Support\Facades\Route; +use Stancl\Tenancy\Commands\Rollback; use Illuminate\Support\ServiceProvider; use Stancl\Tenancy\Commands\TenantList; use Stancl\Tenancy\Interfaces\StorageDriver; use Stancl\Tenancy\Interfaces\ServerConfigManager; -use Illuminate\Cache\CacheManager; class TenancyServiceProvider extends ServiceProvider { @@ -39,7 +37,7 @@ class TenancyServiceProvider extends ServiceProvider $this->loadRoutesFrom(__DIR__ . '/routes.php'); Route::middlewareGroup('tenancy', [ - \Stancl\Tenancy\Middleware\InitializeTenancy::class + \Stancl\Tenancy\Middleware\InitializeTenancy::class, ]); $this->app->register(TenantRouteServiceProvider::class); diff --git a/src/TenantManager.php b/src/TenantManager.php index 8299ee15..b76a84a8 100644 --- a/src/TenantManager.php +++ b/src/TenantManager.php @@ -23,7 +23,7 @@ class TenantManager * @var StorageDriver */ protected $storage; - + /** * Database manager. * @@ -49,6 +49,7 @@ class TenantManager { $this->setTenant($this->identify($domain)); $this->bootstrap(); + return $this->tenant; } @@ -57,7 +58,7 @@ class TenantManager $domain = $domain ?: $this->currentDomain(); if (! $domain) { - throw new \Exception("No domain supplied nor detected."); + throw new \Exception('No domain supplied nor detected.'); } $tenant = $this->storage->identifyTenant($domain); @@ -79,7 +80,7 @@ class TenantManager $tenant = $this->jsonDecodeArrayValues($this->storage->createTenant($domain, (string) \Webpatser\Uuid\Uuid::generate(1, $domain))); $this->database->create($this->getDatabaseName($tenant)); - + return $tenant; } @@ -98,6 +99,7 @@ class TenantManager public function getTenantById(string $uuid, $fields = []) { $fields = (array) $fields; + return $this->jsonDecodeArrayValues($this->storage->getTenantById($uuid, $fields)); } @@ -165,6 +167,7 @@ class TenantManager public function getDatabaseName($tenant = []): string { $tenant = $tenant ?: $this->tenant; + return $this->app['config']['tenancy.database.prefix'] . $tenant['uuid'] . $this->app['config']['tenancy.database.suffix']; } @@ -179,7 +182,7 @@ class TenantManager $tenant = $this->jsonDecodeArrayValues($tenant); $this->tenant = $tenant; - + return $tenant; } @@ -219,6 +222,7 @@ class TenantManager { $this->setTenant($this->storage->getTenantById($uuid)); $this->bootstrap(); + return $this->tenant; } @@ -252,9 +256,9 @@ class TenantManager { if (\is_null($uuid)) { if (! isset($this->tenant['uuid'])) { - throw new \Exception("No UUID supplied (and no tenant is currently identified)."); + throw new \Exception('No UUID supplied (and no tenant is currently identified).'); } - + $uuid = $this->tenant['uuid']; // If $uuid is the uuid of the current tenant, put @@ -313,7 +317,7 @@ class TenantManager if (\is_null($attribute)) { return $this->tenant; } - + return $this->tenant[(string) $attribute]; } } diff --git a/src/Traits/BootstrapsTenancy.php b/src/Traits/BootstrapsTenancy.php index b53ce25f..5f2b74d3 100644 --- a/src/Traits/BootstrapsTenancy.php +++ b/src/Traits/BootstrapsTenancy.php @@ -13,7 +13,7 @@ trait BootstrapsTenancy /** * Was tenancy initialized/bootstrapped? * - * @var boolean + * @var bool */ public $initialized = false; @@ -53,7 +53,7 @@ trait BootstrapsTenancy foreach ($connections as $connection) { $prefix = $this->app['config']['tenancy.redis.prefix_base'] . $this->tenant['uuid']; $client = Redis::connection($connection)->client(); - + try { $this->originalSettings['redis'][$connection] = $client->getOption($client::OPT_PREFIX); $client->setOption($client::OPT_PREFIX, $prefix); @@ -67,7 +67,7 @@ trait BootstrapsTenancy { foreach ($connections as $connection) { $client = Redis::connection($connection)->client(); - + try { $client->setOption($client::OPT_PREFIX, $this->originalSettings['redis'][$connection]); } catch (\Throwable $t) { @@ -106,12 +106,12 @@ trait BootstrapsTenancy // Storage facade foreach ($this->app['config']['tenancy.filesystem.disks'] as $disk) { $old['disks'][$disk] = Storage::disk($disk)->getAdapter()->getPathPrefix(); - + if ($root = str_replace('%storage_path%', storage_path(), $this->app['config']["tenancy.filesystem.root_override.{$disk}"])) { Storage::disk($disk)->getAdapter()->setPathPrefix($root); } else { $root = $this->app['config']["filesystems.disks.{$disk}.root"]; - + Storage::disk($disk)->getAdapter()->setPathPrefix($root . "/{$suffix}"); } } diff --git a/src/Traits/HasATenantsOption.php b/src/Traits/HasATenantsOption.php index 5eadc3d4..1dc055af 100644 --- a/src/Traits/HasATenantsOption.php +++ b/src/Traits/HasATenantsOption.php @@ -9,7 +9,7 @@ trait HasATenantsOption protected function getOptions() { return array_merge([ - ['tenants', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, '', null] + ['tenants', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, '', null], ], parent::getOptions()); } } diff --git a/tests/BootstrapsTenancyTest.php b/tests/BootstrapsTenancyTest.php index a3751a1c..6a3a9263 100644 --- a/tests/BootstrapsTenancyTest.php +++ b/tests/BootstrapsTenancyTest.php @@ -57,7 +57,7 @@ class BootstrapsTenancyTest extends TestCase Config::set('database.redis.client', 'predis'); Redis::setDriver('predis'); Config::set('tenancy.redis.tenancy', true); - + $this->expectException(PhpRedisNotInstalledException::class); $this->initTenancy(); } @@ -72,16 +72,16 @@ class BootstrapsTenancyTest extends TestCase } $this->initTenancy(); - + $new_storage_path = storage_path(); - $this->assertEquals($old_storage_path . "/" . config('tenancy.filesystem.suffix_base') . tenant('uuid'), $new_storage_path); + $this->assertEquals($old_storage_path . '/' . config('tenancy.filesystem.suffix_base') . tenant('uuid'), $new_storage_path); foreach (config('tenancy.filesystem.disks') as $disk) { $suffix = config('tenancy.filesystem.suffix_base') . tenant('uuid'); $current_path_prefix = \Storage::disk($disk)->getAdapter()->getPathPrefix(); if ($override = config("tenancy.filesystem.root_override.{$disk}")) { - $correct_path_prefix = str_replace("%storage_path%", storage_path(), $override); + $correct_path_prefix = str_replace('%storage_path%', storage_path(), $override); } else { if ($base = $old_storage_facade_roots[$disk]) { $correct_path_prefix = $base . "/$suffix/"; diff --git a/tests/CacheManagerTest.php b/tests/CacheManagerTest.php index b8ce09f9..fe884182 100644 --- a/tests/CacheManagerTest.php +++ b/tests/CacheManagerTest.php @@ -51,7 +51,7 @@ class CacheManagerTest extends TestCase tenancy()->init('bar.localhost'); $this->assertNotSame('bar', cache()->get('foo')); - + cache()->put('foo', 'xyz', 1); $this->assertSame('xyz', cache()->get('foo')); } diff --git a/tests/CommandsTest.php b/tests/CommandsTest.php index 046c2998..3998719d 100644 --- a/tests/CommandsTest.php +++ b/tests/CommandsTest.php @@ -2,9 +2,9 @@ namespace Stancl\Tenancy\Tests; -use Illuminate\Support\Facades\Artisan; -use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Schema; +use Illuminate\Support\Facades\Artisan; use Stancl\Tenancy\Tests\Etc\ExampleSeeder; class CommandsTest extends TestCase @@ -47,7 +47,7 @@ class CommandsTest extends TestCase { $tenant = tenant()->create('test.localhost'); Artisan::call('tenants:migrate', [ - '--tenants' => [$tenant['uuid']] + '--tenants' => [$tenant['uuid']], ]); $this->assertFalse(Schema::hasTable('users')); @@ -79,7 +79,7 @@ class CommandsTest extends TestCase public function database_connection_is_switched_to_default_after_migrating_or_seeding_or_rolling_back() { $originalDBName = DB::connection()->getDatabaseName(); - + Artisan::call('tenants:migrate'); $this->assertSame($originalDBName, DB::connection()->getDatabaseName()); @@ -94,7 +94,7 @@ class CommandsTest extends TestCase public function database_connection_is_switched_to_default_after_migrating_or_seeding_or_rolling_back_when_tenancy_has_been_initialized() { tenancy()->init('localhost'); - + $this->database_connection_is_switched_to_default_after_migrating_or_seeding_or_rolling_back(); } } diff --git a/tests/DataSeparationTest.php b/tests/DataSeparationTest.php index 14deb808..7a635c23 100644 --- a/tests/DataSeparationTest.php +++ b/tests/DataSeparationTest.php @@ -2,11 +2,11 @@ namespace Stancl\Tenancy\Tests; -use Illuminate\Support\Facades\Redis; -use Illuminate\Support\Facades\Cache; -use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\Redis; +use Illuminate\Support\Facades\Storage; class DataSeparationTest extends TestCase { @@ -19,7 +19,7 @@ class DataSeparationTest extends TestCase $tenant1 = tenancy()->create('tenant1.localhost'); $tenant2 = tenancy()->create('tenant2.localhost'); \Artisan::call('tenants:migrate', [ - '--tenants' => [$tenant1['uuid'], $tenant2['uuid']] + '--tenants' => [$tenant1['uuid'], $tenant2['uuid']], ]); tenancy()->init('tenant1.localhost'); @@ -31,7 +31,7 @@ class DataSeparationTest extends TestCase 'remember_token' => Str::random(10), ]); $this->assertSame('foo', User::first()->name); - + tenancy()->init('tenant2.localhost'); $this->assertSame(null, User::first()); @@ -52,7 +52,7 @@ class DataSeparationTest extends TestCase $tenant3 = tenancy()->create('tenant3.localhost'); \Artisan::call('tenants:migrate', [ - '--tenants' => [$tenant1['uuid'], $tenant3['uuid']] + '--tenants' => [$tenant1['uuid'], $tenant3['uuid']], ]); tenancy()->init('tenant3.localhost'); @@ -72,7 +72,7 @@ class DataSeparationTest extends TestCase tenancy()->init('tenant1.localhost'); Redis::set('foo', 'bar'); $this->assertSame('bar', Redis::get('foo')); - + tenancy()->init('tenant2.localhost'); $this->assertSame(null, Redis::get('foo')); Redis::set('foo', 'xyz'); @@ -99,7 +99,7 @@ class DataSeparationTest extends TestCase tenancy()->init('tenant1.localhost'); Cache::put('foo', 'bar', 60); $this->assertSame('bar', Cache::get('foo')); - + tenancy()->init('tenant2.localhost'); $this->assertSame(null, Cache::get('foo')); Cache::put('foo', 'xyz', 60); @@ -126,7 +126,7 @@ class DataSeparationTest extends TestCase tenancy()->init('tenant1.localhost'); Storage::disk('public')->put('foo', 'bar'); $this->assertSame('bar', Storage::disk('public')->get('foo')); - + tenancy()->init('tenant2.localhost'); $this->assertFalse(Storage::disk('public')->exists('foo')); Storage::disk('public')->put('foo', 'xyz'); @@ -148,4 +148,4 @@ class DataSeparationTest extends TestCase class User extends \Illuminate\Database\Eloquent\Model { protected $guarded = []; -} \ No newline at end of file +} diff --git a/tests/DatabaseManagerTest.php b/tests/DatabaseManagerTest.php index c96161fd..e6d7c2cf 100644 --- a/tests/DatabaseManagerTest.php +++ b/tests/DatabaseManagerTest.php @@ -13,7 +13,7 @@ class DatabaseManagerTest extends TestCase tenancy()->init(); tenancy()->disconnectDatabase(); $new_connection_name = app(\Illuminate\Database\DatabaseManager::class)->connection()->getName(); - + $this->assertSame($old_connection_name, $new_connection_name); $this->assertNotEquals('tenant', $new_connection_name); } diff --git a/tests/GlobalCacheTest.php b/tests/GlobalCacheTest.php index bdbcedfe..8d517a17 100644 --- a/tests/GlobalCacheTest.php +++ b/tests/GlobalCacheTest.php @@ -19,16 +19,16 @@ class GlobalCacheTest extends TestCase tenant()->create('foo.localhost'); tenancy()->init('foo.localhost'); $this->assertSame('bar', GlobalCache::get('foo')); - + GlobalCache::put(['abc' => 'xyz'], 1); cache(['def' => 'ghi'], 10); $this->assertSame('ghi', cache('def')); - + tenancy()->end(); $this->assertSame('xyz', GlobalCache::get('abc')); $this->assertSame('bar', GlobalCache::get('foo')); $this->assertSame(null, cache('def')); - + tenant()->create('bar.localhost'); tenancy()->init('bar.localhost'); $this->assertSame('xyz', GlobalCache::get('abc')); @@ -40,4 +40,4 @@ class GlobalCacheTest extends TestCase tenancy()->init('foo.localhost'); $this->assertSame('ghi', cache('def')); } -} \ No newline at end of file +} diff --git a/tests/ReidentificationTest.php b/tests/ReidentificationTest.php index eeba2e52..d372af98 100644 --- a/tests/ReidentificationTest.php +++ b/tests/ReidentificationTest.php @@ -27,7 +27,7 @@ class ReidentificationTest extends TestCase $current_path_prefix = \Storage::disk($disk)->getAdapter()->getPathPrefix(); if ($override = config("tenancy.filesystem.root_override.{$disk}")) { - $correct_path_prefix = str_replace("%storage_path%", storage_path(), $override); + $correct_path_prefix = str_replace('%storage_path%', storage_path(), $override); } else { if ($base = $originals[$disk]) { $correct_path_prefix = $base . "/$suffix/"; @@ -49,7 +49,6 @@ class ReidentificationTest extends TestCase tenant()->create('second.localhost'); tenancy()->init('second.localhost'); - $suffix = config('tenancy.filesystem.suffix_base') . tenant('uuid'); $this->assertSame($original . "/$suffix", storage_path()); } diff --git a/tests/TenantAssetTest.php b/tests/TenantAssetTest.php index 985a782e..01f1fd28 100644 --- a/tests/TenantAssetTest.php +++ b/tests/TenantAssetTest.php @@ -10,7 +10,7 @@ class TenantAssetTest extends TestCase $filename = 'testfile' . $this->randomString(10); \Storage::disk('public')->put($filename, 'bar'); $path = storage_path("app/public/$filename"); - + // response()->file() returns BinaryFileResponse whose content is // inaccessible via getContent, so ->assertSee() can't be used $this->get(tenant_asset($filename))->assertSuccessful(); diff --git a/tests/TenantDatabaseManagerTest.php b/tests/TenantDatabaseManagerTest.php index dc68ac03..9f6e911b 100644 --- a/tests/TenantDatabaseManagerTest.php +++ b/tests/TenantDatabaseManagerTest.php @@ -139,7 +139,7 @@ class TenantDatabaseManagerTest extends TestCase config()->set('tenancy.queue_database_deletion', true); $db_name = 'testdatabase' . $this->randomString(10) . '.sqlite'; app(DatabaseManager::class)->delete($db_name, 'sqlite'); - + Queue::assertPushed(QueuedTenantDatabaseDeleter::class); } } diff --git a/tests/TenantManagerTest.php b/tests/TenantManagerTest.php index ea24ff0e..7fdd443a 100644 --- a/tests/TenantManagerTest.php +++ b/tests/TenantManagerTest.php @@ -66,7 +66,7 @@ class TenantManagerTest extends TestCase public function getTenantById_works() { $tenant = tenant()->create('foo.localhost'); - + $this->assertSame($tenant, tenancy()->getTenantById($tenant['uuid'])); } @@ -120,7 +120,7 @@ class TenantManagerTest extends TestCase tenant()->create('foo.localhost'); tenancy()->init('foo.localhost'); - + $this->assertNotSame($originals['databaseName'], DB::connection()->getDatabaseName()); $this->assertNotSame($originals['storage_path'], storage_path()); $this->assertNotSame($originals['storage_root'], Storage::disk('local')->getAdapter()->getPathPrefix()); @@ -146,7 +146,7 @@ class TenantManagerTest extends TestCase tenant()->create('foo.localhost'); tenancy()->init('foo.localhost'); - + $this->assertNotSame($originals['databaseName'], DB::connection()->getDatabaseName()); $this->assertNotSame($originals['storage_path'], storage_path()); $this->assertNotSame($originals['storage_root'], Storage::disk('local')->getAdapter()->getPathPrefix()); @@ -182,7 +182,7 @@ class TenantManagerTest extends TestCase $tenant = tenant()->create('foo.localhost'); tenant()->delete($tenant['uuid']); $this->assertSame([], tenancy()->all()->toArray()); - + $tenant = tenant()->create('foo.localhost'); $this->assertSame([$tenant], tenancy()->all()->toArray()); } diff --git a/tests/TenantStorageTest.php b/tests/TenantStorageTest.php index bfbfa368..aaa4209b 100644 --- a/tests/TenantStorageTest.php +++ b/tests/TenantStorageTest.php @@ -2,15 +2,13 @@ namespace Stancl\Tenancy\Tests; -use Stancl\Tenancy\Interfaces\StorageDriver; - class TenantStorageTest extends TestCase { /** @test */ public function deleting_a_tenant_works() { $abc = tenant()->create('abc.localhost'); - + $this->assertTrue(tenant()->all()->contains($abc)); tenant()->delete($abc['uuid']); @@ -110,7 +108,7 @@ class TenantStorageTest extends TestCase public function put_returns_the_key_value_pairs_when_a_single_argument_is_used() { $value = ['foo' => 'bar', 'abc' => 'xyz']; - + $this->assertSame($value, tenancy()->put($value)); } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 200c70b0..6851d2e8 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -10,7 +10,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase public $autoInitTenancy = true; /** - * Setup the test environment + * Setup the test environment. * * @return void */ From 7c598ae2fe2a45496652e890659607907c385da9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sat, 3 Aug 2019 21:25:00 +0200 Subject: [PATCH 03/15] wip --- .gitignore | 1 + phpunit.xml | 1 + test | 24 +++++++++++++++++++++++- tests/TenantStorageTest.php | 2 -- tests/TestCase.php | 21 +++++++++++++++++++++ 5 files changed, 46 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 53129d62..fd3181fd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ vendor/ .vscode/ psysh .phpunit.result.cache +phpunit_var_*.xml \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml index 26f7e0b2..d4f07804 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -30,5 +30,6 @@ + \ No newline at end of file diff --git a/test b/test index b22f03b1..67ce4feb 100755 --- a/test +++ b/test @@ -2,4 +2,26 @@ # for development docker-compose up -d -docker-compose exec test vendor/bin/phpunit "$@" \ No newline at end of file + +# Specify variant using `export VARIANT=1` +if [[ -z "${VARIANT}" ]]; then + variants=(1 2) +else + variants=( $VARIANT ) +fi + +for variant in "${variants[@]}" + do + export filename_base="phpunit_var_$variant" + + (cat phpunit.xml | sed -e "s/\"STANCL_TENANCY_TEST_VARIANT\" value=\"1\"/\"STANCL_TENANCY_TEST_VARIANT\" value=\"$variant\"/g") > "$filename_base.xml" + + printf "Test variant: $variant\n\n" + + docker-compose exec test vendor/bin/phpunit \ + --configuration "$filename_base.xml" \ + --coverage-php "$filename_base.cov" \ + "$@" +done + +# todo merge cov reports diff --git a/tests/TenantStorageTest.php b/tests/TenantStorageTest.php index bfbfa368..1c885e31 100644 --- a/tests/TenantStorageTest.php +++ b/tests/TenantStorageTest.php @@ -2,8 +2,6 @@ namespace Stancl\Tenancy\Tests; -use Stancl\Tenancy\Interfaces\StorageDriver; - class TenantStorageTest extends TestCase { /** @test */ diff --git a/tests/TestCase.php b/tests/TestCase.php index 200c70b0..e1659a8b 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -9,6 +9,13 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase public $autoCreateTenant = true; public $autoInitTenancy = true; + private function checkRequirements(): void + { + parent::checkRequirements(); + + dd($this->getAnnotations()); + } + /** * Setup the test environment * @@ -81,6 +88,20 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase 'tenancy.redis.prefixed_connections' => ['default'], 'tenancy.migrations_directory' => database_path('../migrations'), ]); + + switch((string) env('STANCL_TENANCY_TEST_VARIANT', '1')) { + case '2': + $app['config']->set([ + 'tenancy.redis.tenancy' => true, + 'database.redis.client' => 'phpredis', + ]); + break; + default: + $app['config']->set([ + 'tenancy.redis.tenancy' => false, + 'database.redis.client' => 'predis', + ]); + }; } protected function loadDotEnv() From 89990799f2f6be540e254bf19aac8d8486b993db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sun, 4 Aug 2019 17:40:44 +0200 Subject: [PATCH 04/15] add phpunit.xml variations --- .gitignore | 3 +- .travis.yml | 8 +- Dockerfile | 10 +- README.md | 2 +- clover.xml | 592 +++++++++++++++++++++++++++++++++++++++++++++ composer.json | 3 +- test | 42 ++-- tests/TestCase.php | 2 +- 8 files changed, 628 insertions(+), 34 deletions(-) create mode 100644 clover.xml diff --git a/.gitignore b/.gitignore index fd3181fd..2a8d8538 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ vendor/ .vscode/ psysh .phpunit.result.cache -phpunit_var_*.xml \ No newline at end of file +phpunit_var_*.xml +coverage/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index ff31db18..dfe0af41 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,6 @@ php: services: - docker -before_install: - - docker-compose up -d - install: - travis_retry docker-compose exec test composer require --no-interaction "laravel/framework:$LARAVEL_VERSION" "orchestra/testbench:$TESTBENCH_VERSION" @@ -19,10 +16,7 @@ before_script: - export DB_USERNAME=root DB_PASSWORD="" DB_DATABASE=tenancy CODECOV_TOKEN="24382d15-84e7-4a55-bea4-c4df96a24a9b" - cat vendor/laravel/framework/src/Illuminate/Foundation/Application.php| grep 'const VERSION' -script: docker-compose exec test vendor/bin/phpunit -v --coverage-clover=coverage.xml - -after_script: - - docker-compose down +script: ./test after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/Dockerfile b/Dockerfile index a6727e03..a6512668 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,15 @@ RUN apt-get update \ && php -r "readfile('http://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \ && mkdir /run/php -RUN apt-get install php7.2-redis +RUN apt-get install -y php7.2-redis + +RUN apt-get install -y python3 + +RUN apt-get install -y php7.2-dev php-pear +RUN pecl install xdebug +# RUN echo '' > /etc/php/7.2/cli/conf.d/20-xdebug.ini +# RUN echo 'zend_extension=/usr/lib/php/20170718/xdebug.so' >> /etc/php/7.2/cli/php.ini +RUN echo 'zend_extension=/usr/lib/php/20170718/xdebug.so' > /etc/php/7.2/cli/conf.d/20-xdebug.ini RUN apt-get -y autoremove \ && apt-get clean \ diff --git a/README.md b/README.md index 3f0fa9bb..d09f9aa7 100644 --- a/README.md +++ b/README.md @@ -553,7 +553,7 @@ However, you still need to reload nginx configuration to apply the changes to co ### With Docker -If you have Docker installed, simply run `docker-compose exec test vendor/bin/phpunit -v`. If you need to run the tests multiple times during development, run `./test` to run the tests. This script runs `docker-compose up -d` and phpunit via the `test` container. When you're done testing, run `docker-compose down` to shut down the containers. +If you have Docker installed, simply run `./test`. When you're done testing, run `docker-compose down` to shut down the containers. ### Without Docker diff --git a/clover.xml b/clover.xml new file mode 100644 index 00000000..a5f1b9a4 --- /dev/null +++ b/clover.xml @@ -0,0 +1,592 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/composer.json b/composer.json index 6e55ab95..cdcbe6c8 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,8 @@ "psy/psysh": "@stable", "laravel/framework": "5.8.*||5.7.*", "orchestra/testbench": "~3.7||~3.8", - "league/flysystem-aws-s3-v3": "~1.0" + "league/flysystem-aws-s3-v3": "~1.0", + "phpunit/phpcov": "^6.0" }, "autoload": { "psr-4": { diff --git a/test b/test index 67ce4feb..0d9f4044 100755 --- a/test +++ b/test @@ -1,27 +1,25 @@ -#!/bin/bash +#!/usr/bin/env python3 +from os import system +import argparse -# for development -docker-compose up -d +system('docker-compose up -d') -# Specify variant using `export VARIANT=1` -if [[ -z "${VARIANT}" ]]; then - variants=(1 2) -else - variants=( $VARIANT ) -fi +parser = argparse.ArgumentParser() +parser.add_argument("--variants", default='1,2', + help="Comma-separated values. Which test variants should be run.") +args, other = parser.parse_known_args() -for variant in "${variants[@]}" - do - export filename_base="phpunit_var_$variant" - - (cat phpunit.xml | sed -e "s/\"STANCL_TENANCY_TEST_VARIANT\" value=\"1\"/\"STANCL_TENANCY_TEST_VARIANT\" value=\"$variant\"/g") > "$filename_base.xml" - - printf "Test variant: $variant\n\n" +variants = args.variants.split(',') - docker-compose exec test vendor/bin/phpunit \ - --configuration "$filename_base.xml" \ - --coverage-php "$filename_base.cov" \ - "$@" -done +for variant in variants: + filename_base = "phpunit_var_" + variant + with open('phpunit.xml', 'r') as inp, open(filename_base + '.xml', 'w') as out: + out.write(inp.read().replace('"STANCL_TENANCY_TEST_VARIANT" value="1"', + '"STANCL_TENANCY_TEST_VARIANT" value="%s"' % variant)) -# todo merge cov reports + print("Test variant: %s\n" % variant) + + system('docker-compose exec test vendor/bin/phpunit --configuration "%s" --coverage-php %s %s' + % (filename_base + '.xml', 'coverage/' + filename_base + '.cov', ' '.join(other))) + +system("docker-compose exec test vendor/bin/phpcov merge --clover clover.xml coverage/") diff --git a/tests/TestCase.php b/tests/TestCase.php index e1659a8b..f9a67463 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -89,7 +89,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase 'tenancy.migrations_directory' => database_path('../migrations'), ]); - switch((string) env('STANCL_TENANCY_TEST_VARIANT', '1')) { + switch ((string) env('STANCL_TENANCY_TEST_VARIANT', '1')) { case '2': $app['config']->set([ 'tenancy.redis.tenancy' => true, From ce9e9edbe22bdd2ae3236ab8662472e0896842d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sun, 4 Aug 2019 17:41:53 +0200 Subject: [PATCH 05/15] remove clover.xml --- .gitignore | 3 +- clover.xml | 592 ----------------------------------------------------- 2 files changed, 2 insertions(+), 593 deletions(-) delete mode 100644 clover.xml diff --git a/.gitignore b/.gitignore index 2a8d8538..9df52aa7 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ vendor/ psysh .phpunit.result.cache phpunit_var_*.xml -coverage/ \ No newline at end of file +coverage/ +clover.xml diff --git a/clover.xml b/clover.xml deleted file mode 100644 index a5f1b9a4..00000000 --- a/clover.xml +++ /dev/null @@ -1,592 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 0ff607d1d845cc442ac62e72fc0c78df5579e01b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sun, 4 Aug 2019 17:43:25 +0200 Subject: [PATCH 06/15] styleci --- tests/TestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/TestCase.php b/tests/TestCase.php index a282a573..a2beeafc 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -101,7 +101,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase 'tenancy.redis.tenancy' => false, 'database.redis.client' => 'predis', ]); - }; + } } protected function loadDotEnv() From fe6ce82045f621d5b243fd8e4285d2a9cac33522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sun, 4 Aug 2019 17:45:09 +0200 Subject: [PATCH 07/15] fix .travis.yml --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index dfe0af41..46a0083f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,9 @@ php: services: - docker +before_install: + - docker-compose up -d + install: - travis_retry docker-compose exec test composer require --no-interaction "laravel/framework:$LARAVEL_VERSION" "orchestra/testbench:$TESTBENCH_VERSION" From 0dc8c80a02efbee5676cc72e648e108037ca5268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sun, 4 Aug 2019 20:04:25 +0200 Subject: [PATCH 08/15] Fix Redis scan for predis, make phpunit use multiple configs (e.g. different Redis drivers) --- src/StorageDrivers/RedisStorageDriver.php | 22 +++++++++++++--------- test | 1 + tests/BootstrapsTenancyTest.php | 5 +++++ tests/DataSeparationTest.php | 4 ++++ tests/TenantManagerTest.php | 8 ++++++++ tests/TestCase.php | 10 ++++++---- 6 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/StorageDrivers/RedisStorageDriver.php b/src/StorageDrivers/RedisStorageDriver.php index 50e1fb8e..af055b12 100644 --- a/src/StorageDrivers/RedisStorageDriver.php +++ b/src/StorageDrivers/RedisStorageDriver.php @@ -82,17 +82,21 @@ class RedisStorageDriver implements StorageDriver }, $uuids); if (! $hashes) { - // Apparently, the PREFIX is applied to all functions except scan(). - // Therefore, if the `tenancy` Redis connection has a prefix set - // (and PhpRedis is used), prepend the prefix to the search. - $redis_prefix = ''; + // Prefix is applied to all functions except scan(). + // This code applies the correct prefix manually. + $redis_prefix = config('database.redis.options.prefix'); + if (config('database.redis.client') === 'phpredis') { - $redis_prefix = $this->redis->getOption($this->redis->client()::OPT_PREFIX); + $redis_prefix = $this->redis->getOption($this->redis->client()::OPT_PREFIX) ?? $redis_prefix; + $all_keys = $this->redis->scan(null, $redis_prefix . 'tenants:*'); + } else { + $all_keys = $this->redis->scan(null, 'MATCH', $redis_prefix . 'tenants:*')[1]; } - $hashes = array_map(function ($hash) use ($redis_prefix) { - // Left strip $redis_prefix from $hash - return substr($hash, strlen($redis_prefix)); - }, $this->redis->scan(null, $redis_prefix.'tenants:*')); + + $hashes = array_map(function ($key) use ($redis_prefix) { + // Left strip $redis_prefix from $key + return substr($key, strlen($redis_prefix)); + }, $all_keys); } return array_map(function ($tenant) { diff --git a/test b/test index 0d9f4044..0d11eef3 100755 --- a/test +++ b/test @@ -22,4 +22,5 @@ for variant in variants: system('docker-compose exec test vendor/bin/phpunit --configuration "%s" --coverage-php %s %s' % (filename_base + '.xml', 'coverage/' + filename_base + '.cov', ' '.join(other))) +# todo delete folder contents first? system("docker-compose exec test vendor/bin/phpcov merge --clover clover.xml coverage/") diff --git a/tests/BootstrapsTenancyTest.php b/tests/BootstrapsTenancyTest.php index 6a3a9263..fc0d761f 100644 --- a/tests/BootstrapsTenancyTest.php +++ b/tests/BootstrapsTenancyTest.php @@ -24,6 +24,10 @@ class BootstrapsTenancyTest extends TestCase /** @test */ public function redis_is_prefixed() { + if (! config('tenancy.redis.tenancy')) { + $this->markTestSkipped('Redis tenancy disabled.'); + } + $this->initTenancy(); foreach (config('tenancy.redis.prefixed_connections', ['default']) as $connection) { $prefix = config('tenancy.redis.prefix_base') . tenant('uuid'); @@ -35,6 +39,7 @@ class BootstrapsTenancyTest extends TestCase /** @test */ public function predis_is_supported() { + // No setDriver() before that version. if (app()->version() < 'v5.8.27') { $this->markTestSkipped(); } diff --git a/tests/DataSeparationTest.php b/tests/DataSeparationTest.php index 7a635c23..89790df0 100644 --- a/tests/DataSeparationTest.php +++ b/tests/DataSeparationTest.php @@ -66,6 +66,10 @@ class DataSeparationTest extends TestCase /** @test */ public function redis_is_separated() { + if (! config('tenancy.redis.tenancy')) { + $this->markTestSkipped('Redis tenancy disabled.'); + } + tenancy()->create('tenant1.localhost'); tenancy()->create('tenant2.localhost'); diff --git a/tests/TenantManagerTest.php b/tests/TenantManagerTest.php index 7fdd443a..050c729a 100644 --- a/tests/TenantManagerTest.php +++ b/tests/TenantManagerTest.php @@ -186,4 +186,12 @@ class TenantManagerTest extends TestCase $tenant = tenant()->create('foo.localhost'); $this->assertSame([$tenant], tenancy()->all()->toArray()); } + + /** @test */ + public function all_returns_a_list_of_all_tenants() + { + $tenant1 = tenant()->create('foo.localhost'); + $tenant2 = tenant()->create('bar.localhost'); + $this->assertEqualsCanonicalizing([$tenant1, $tenant2], tenant()->all()->toArray()); + } } diff --git a/tests/TestCase.php b/tests/TestCase.php index a2beeafc..815e5d3d 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -63,6 +63,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase 'database.redis.client' => 'phpredis', 'database.redis.cache.host' => env('TENANCY_TEST_REDIS_HOST', '127.0.0.1'), 'database.redis.default.host' => env('TENANCY_TEST_REDIS_HOST', '127.0.0.1'), + 'database.redis.options.prefix' => 'foo', 'database.redis.tenancy' => [ 'host' => env('TENANCY_TEST_REDIS_HOST', '127.0.0.1'), 'password' => env('TENANCY_TEST_REDIS_PASSWORD', null), @@ -70,6 +71,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase // Use the #14 Redis database unless specified otherwise. // Make sure you don't store anything in this db! 'database' => env('TENANCY_TEST_REDIS_DB', 14), + 'prefix' => 'abc', // todo unrelated to tenancy, but this doesn't seem to have an effect? try to replicate in a fresh laravel installation ], 'tenancy.database' => [ 'based_on' => 'sqlite', @@ -92,14 +94,14 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase switch ((string) env('STANCL_TENANCY_TEST_VARIANT', '1')) { case '2': $app['config']->set([ - 'tenancy.redis.tenancy' => true, - 'database.redis.client' => 'phpredis', + 'tenancy.redis.tenancy' => false, + 'database.redis.client' => 'predis', ]); break; default: $app['config']->set([ - 'tenancy.redis.tenancy' => false, - 'database.redis.client' => 'predis', + 'tenancy.redis.tenancy' => true, + 'database.redis.client' => 'phpredis', ]); } } From 8fd32a67a93b0b4c48495492865ff9d8dc5a1e22 Mon Sep 17 00:00:00 2001 From: stancl Date: Sun, 4 Aug 2019 18:04:35 +0000 Subject: [PATCH 09/15] Apply fixes from StyleCI --- src/StorageDrivers/RedisStorageDriver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StorageDrivers/RedisStorageDriver.php b/src/StorageDrivers/RedisStorageDriver.php index af055b12..82faebdb 100644 --- a/src/StorageDrivers/RedisStorageDriver.php +++ b/src/StorageDrivers/RedisStorageDriver.php @@ -85,7 +85,7 @@ class RedisStorageDriver implements StorageDriver // Prefix is applied to all functions except scan(). // This code applies the correct prefix manually. $redis_prefix = config('database.redis.options.prefix'); - + if (config('database.redis.client') === 'phpredis') { $redis_prefix = $this->redis->getOption($this->redis->client()::OPT_PREFIX) ?? $redis_prefix; $all_keys = $this->redis->scan(null, $redis_prefix . 'tenants:*'); From bc2a5cd12a982ee28aad4a4bbee09df9d0992040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sun, 4 Aug 2019 20:17:33 +0200 Subject: [PATCH 10/15] Remove support for Laravel 5.7 --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 46a0083f..ae2f21fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ env: - - LARAVEL_VERSION="5.7.*" TESTBENCH_VERSION="~3.7" REDIS_DRIVER=phpredis - LARAVEL_VERSION="5.8.*" TESTBENCH_VERSION="~3.8" REDIS_DRIVER=phpredis language: php From 221dbbdbc84611b17e4cfc4112f66b7fdc5af430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sun, 4 Aug 2019 20:18:46 +0200 Subject: [PATCH 11/15] update readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d09f9aa7..30e37be9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # [stancl/tenancy](https://stancl.github.io/tenancy/) -[![Laravel 5.7+](https://img.shields.io/badge/laravel-5.7+-red.svg)](https://laravel.com) +[![Laravel 5.8](https://img.shields.io/badge/laravel-5.8-red.svg)](https://laravel.com) [![Latest Stable Version](https://poser.pugx.org/stancl/tenancy/version)](https://packagist.org/packages/stancl/tenancy) [![Travis CI build](https://travis-ci.com/stancl/tenancy.svg?branch=master)](https://travis-ci.com/stancl/tenancy) [![codecov](https://codecov.io/gh/stancl/tenancy/branch/master/graph/badge.svg)](https://codecov.io/gh/stancl/tenancy) @@ -76,7 +76,7 @@ If you'd like to be notified about new versions and related stuff, [sign up for ### Requirements -- Laravel 5.7 or 5.8 +- Laravel 5.8 ### Installing the package @@ -226,7 +226,7 @@ You can also seed the database in the same way. The only difference is the comma ### Starting a session as a tenant -This runs `TenantManager::bootstrap()` which switches the DB connection, prefixes Redis, changes filesystem root paths, etc. +This switches the DB connection, prefixes Redis, changes filesystem root paths and tags cache. ```php tenancy()->init(); From 65b38827d5a2fa183838a9dce9fb6a157fd7e859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sun, 4 Aug 2019 20:24:48 +0200 Subject: [PATCH 12/15] drop 5.7 support --- composer.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index cdcbe6c8..59ee0810 100644 --- a/composer.json +++ b/composer.json @@ -10,15 +10,15 @@ } ], "require": { - "illuminate/support": "5.8.*||5.7.*", + "illuminate/support": "5.8.*", "webpatser/laravel-uuid": "^3.0", "predis/predis": "^1.1" }, "require-dev": { - "vlucas/phpdotenv": "^2.2||^3.3", + "vlucas/phpdotenv": "^3.3", "psy/psysh": "@stable", - "laravel/framework": "5.8.*||5.7.*", - "orchestra/testbench": "~3.7||~3.8", + "laravel/framework": "5.8.*", + "orchestra/testbench": "~3.8", "league/flysystem-aws-s3-v3": "~1.0", "phpunit/phpcov": "^6.0" }, From cb3bb112a38337b71b7c0a998b97c71049675cfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sun, 4 Aug 2019 20:37:04 +0200 Subject: [PATCH 13/15] v1.6.1 --- CHANGELOG-1.x.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG-1.x.md b/CHANGELOG-1.x.md index eefa74eb..fe5caaca 100644 --- a/CHANGELOG-1.x.md +++ b/CHANGELOG-1.x.md @@ -1,5 +1,17 @@ # Release Notes for 1.x +## [v1.6.1 (2019-08-04)](https://github.com/stancl/tenancy/compare/v1.6.0...v1.6.1) + +Multiple phpunit.xml configs are now generated to run the tests with different configurations, such as different Redis drivers. + +### Fixed + +- `tenancy()->all()` with predis [`0dc8c80`](https://github.com/stancl/tenancy/commit/0dc8c80a02efbee5676cc72e648e108037ca5268) + +### Dropped + +- Laravel 5.7 support [`65b3882`](https://github.com/stancl/tenancy/commit/65b38827d5a2fa183838a9dce9fb6a157fd7e859) + ## [v1.6.0 (2019-07-30)](https://github.com/stancl/tenancy/compare/v1.5.1...v1.6.0) ### Added From 13048002ef687c3c85207df1fbf8b09ce89fb430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Sun, 4 Aug 2019 20:42:50 +0200 Subject: [PATCH 14/15] remove loadDotEnv() --- tests/TestCase.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/TestCase.php b/tests/TestCase.php index 815e5d3d..7cc55500 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -56,7 +56,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase protected function getEnvironmentSetUp($app) { if (file_exists(__DIR__ . '/../.env')) { - $this->loadDotEnv(); + \Dotenv\Dotenv::create(__DIR__ . '/..')->load(); } $app['config']->set([ @@ -106,15 +106,6 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase } } - protected function loadDotEnv() - { - if (app()::VERSION > '5.8.0') { - \Dotenv\Dotenv::create(__DIR__ . '/..')->load(); - } else { - (new \Dotenv\Dotenv(__DIR__ . '/..'))->load(); - } - } - protected function getPackageProviders($app) { return [\Stancl\Tenancy\TenancyServiceProvider::class]; From 85b2274d1d9aba4989e918b45ce049cc42a995b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Tue, 6 Aug 2019 15:44:28 +0200 Subject: [PATCH 15/15] Fix #67 --- README.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 30e37be9..31f03153 100644 --- a/README.md +++ b/README.md @@ -54,12 +54,14 @@ You won't have to change a thing in your application's code.\* - [`tenants:list`](#-tenants-list-) - [`tenants:migrate`, `tenants:rollback`, `tenants:seed`](#-tenants-migrate----tenants-rollback----tenants-seed-) + [Tenant migrations](#tenant-migrations) + * [Testing](#testing) - [Tips](#tips) * [HTTPS certificates](#https-certificates) + [1. Use nginx with the lua module](#1-use-nginx-with-the-lua-module) + [2. Add a simple server block for each tenant](#2-add-a-simple-server-block-for-each-tenant) + [Generating certificates](#generating-certificates) -- [Testing](#testing) +- [Development](#development) + * [Running tests](#running-tests) + [With Docker](#with-docker) + [Without Docker](#without-docker) @@ -511,6 +513,17 @@ Database seeding completed successfully. Tenant migrations are located in `database/migrations/tenant`, so you should move your tenant migrations there. +## Testing + +To test your multi-tenant application, simply run the following at the beginning of every test: + +```php +tenant()->create('test.localhost') +tenancy()->init('test.localhost') +``` + +To do this automatically, you can make this part of your `TestCase::setUp()` method. [Here](https://github.com/stancl/tenancy/blob/13048002ef687c3c85207df1fbf8b09ce89fb430/tests/TestCase.php#L31-L37)'s how this package handles it. + # Tips - If you create a tenant using the interactive console (`artisan tinker`) and use sqlite, you might need to change the database's permissions and/or ownership (`chmod`/`chown`) so that the web application can access it. @@ -549,7 +562,9 @@ Creating this config dynamically from PHP is not easy, but is probably feasible. However, you still need to reload nginx configuration to apply the changes to configuration. This is problematic and I'm not sure if there is a simple and secure way to do this from PHP. -# Testing +# Development + +## Running tests ### With Docker