mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 13:54:03 +00:00
Refactor tests
This commit is contained in:
parent
8b9b913c88
commit
889d58b787
2 changed files with 23 additions and 57 deletions
|
|
@ -4,30 +4,18 @@ declare(strict_types=1);
|
||||||
|
|
||||||
use Stancl\Tenancy\Bootstrappers\DatabaseCacheBootstrapper;
|
use Stancl\Tenancy\Bootstrappers\DatabaseCacheBootstrapper;
|
||||||
use Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper;
|
use Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper;
|
||||||
use Illuminate\Support\Facades\Event;
|
|
||||||
use Stancl\Tenancy\Events\TenantCreated;
|
|
||||||
use Stancl\JobPipeline\JobPipeline;
|
|
||||||
use Stancl\Tenancy\Jobs\CreateDatabase;
|
|
||||||
use Stancl\Tenancy\Tests\Etc\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
|
||||||
use Stancl\Tenancy\Events\TenancyEnded;
|
|
||||||
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
beforeEach(function () {
|
use function Stancl\Tenancy\Tests\withBootstrapping;
|
||||||
Event::listen(
|
use function Stancl\Tenancy\Tests\withCacheTables;
|
||||||
TenantCreated::class,
|
use function Stancl\Tenancy\Tests\withTenantDatabases;
|
||||||
JobPipeline::make([CreateDatabase::class])->send(function (TenantCreated $event) {
|
|
||||||
return $event->tenant;
|
|
||||||
})->toListener()
|
|
||||||
);
|
|
||||||
|
|
||||||
Event::listen(TenancyInitialized::class, BootstrapTenancy::class);
|
beforeEach(function () {
|
||||||
Event::listen(TenancyEnded::class, RevertToCentralContext::class);
|
withBootstrapping();
|
||||||
|
withCacheTables();
|
||||||
|
withTenantDatabases(true);
|
||||||
|
|
||||||
DatabaseCacheBootstrapper::$stores = null;
|
DatabaseCacheBootstrapper::$stores = null;
|
||||||
|
|
||||||
|
|
@ -47,66 +35,38 @@ afterEach(function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('DatabaseCacheBootstrapper switches the database cache store connections correctly', function () {
|
test('DatabaseCacheBootstrapper switches the database cache store connections correctly', function () {
|
||||||
// Original connections (store and lock) are 'central' in the config
|
|
||||||
expect(config('cache.stores.database.connection'))->toBe('central');
|
expect(config('cache.stores.database.connection'))->toBe('central');
|
||||||
expect(config('cache.stores.database.lock_connection'))->toBe('central');
|
expect(config('cache.stores.database.lock_connection'))->toBe('central');
|
||||||
// The actual connection used by the cache store is 'central'
|
|
||||||
expect(Cache::store()->getConnection()->getName())->toBe('central');
|
expect(Cache::store()->getConnection()->getName())->toBe('central');
|
||||||
// Cache locks also use the 'central' connection
|
|
||||||
expect(Cache::lock('foo')->getConnectionName())->toBe('central');
|
expect(Cache::lock('foo')->getConnectionName())->toBe('central');
|
||||||
|
|
||||||
tenancy()->initialize(Tenant::create());
|
tenancy()->initialize(Tenant::create());
|
||||||
|
|
||||||
// Initializing tenancy should make both connections 'tenant'
|
|
||||||
expect(config('cache.stores.database.connection'))->toBe('tenant');
|
expect(config('cache.stores.database.connection'))->toBe('tenant');
|
||||||
expect(config('cache.stores.database.lock_connection'))->toBe('tenant');
|
expect(config('cache.stores.database.lock_connection'))->toBe('tenant');
|
||||||
// The actual connection used by the cache store and locks is now 'tenant'
|
|
||||||
// Purging the database cache store forces the CacheManager to resolve a new instance of
|
|
||||||
// the database store, using the connection names specified in the config ('tenant')
|
|
||||||
expect(Cache::store()->getConnection()->getName())->toBe('tenant');
|
expect(Cache::store()->getConnection()->getName())->toBe('tenant');
|
||||||
expect(Cache::lock('foo')->getConnectionName())->toBe('tenant');
|
expect(Cache::lock('foo')->getConnectionName())->toBe('tenant');
|
||||||
|
|
||||||
tenancy()->end();
|
tenancy()->end();
|
||||||
|
|
||||||
// Ending tenancy should change both connections back to the original ('central')
|
|
||||||
expect(config('cache.stores.database.connection'))->toBe('central');
|
expect(config('cache.stores.database.connection'))->toBe('central');
|
||||||
expect(config('cache.stores.database.lock_connection'))->toBe('central');
|
expect(config('cache.stores.database.lock_connection'))->toBe('central');
|
||||||
// The actual connection used by the cache store and the cache locks is now 'central' again
|
|
||||||
expect(Cache::store()->getConnection()->getName())->toBe('central');
|
expect(Cache::store()->getConnection()->getName())->toBe('central');
|
||||||
expect(Cache::lock('foo')->getConnectionName())->toBe('central');
|
expect(Cache::lock('foo')->getConnectionName())->toBe('central');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cache is separated correctly when using DatabaseCacheBootstrapper', function() {
|
test('cache is separated correctly when using DatabaseCacheBootstrapper', function() {
|
||||||
// DB query for verifying that the cache is stored
|
// We need the prefix later for lower-level assertions. Let's store it
|
||||||
// in the cache table of the current DB connection
|
// once now and reuse this variable rather than re-fetching it to make
|
||||||
// under the passed key (the key in the DB is prefixed by the default cache prefix).
|
// it clear that the scoping does NOT come from a prefix change.
|
||||||
$getCacheUsingDbQuery = function (string $cacheKey) {
|
|
||||||
// Prefix the cache key with the default cache prefix
|
|
||||||
$databaseCacheKey = config('cache.prefix') . $cacheKey;
|
|
||||||
|
|
||||||
return DB::selectOne("SELECT * FROM `cache` WHERE `key` = '{$databaseCacheKey}'")?->value;
|
$cachePrefix = config('cache.prefix');
|
||||||
};
|
$getCacheUsingDbQuery = fn (string $cacheKey) =>
|
||||||
|
DB::selectOne("SELECT * FROM `cache` WHERE `key` = '{$cachePrefix}{$cacheKey}'")?->value;
|
||||||
// Create the cache table in the central DB
|
|
||||||
Schema::create('cache', function (Blueprint $table) {
|
|
||||||
$table->string('key')->primary();
|
|
||||||
$table->mediumText('value');
|
|
||||||
$table->integer('expiration');
|
|
||||||
});
|
|
||||||
|
|
||||||
$tenant = Tenant::create();
|
$tenant = Tenant::create();
|
||||||
$tenant2 = Tenant::create();
|
$tenant2 = Tenant::create();
|
||||||
|
|
||||||
// Create the cache table in tenant DBs
|
|
||||||
// With DatabaseCacheBootstrapper, cache will be saved in these tenant DBs instead of the central DB
|
|
||||||
tenancy()->runForMultiple([$tenant, $tenant2], function () {
|
|
||||||
Schema::create('cache', function (Blueprint $table) {
|
|
||||||
$table->string('key')->primary();
|
|
||||||
$table->mediumText('value');
|
|
||||||
$table->integer('expiration');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Write to cache in central context
|
// Write to cache in central context
|
||||||
cache()->set('foo', 'central');
|
cache()->set('foo', 'central');
|
||||||
expect(Cache::get('foo'))->toBe('central');
|
expect(Cache::get('foo'))->toBe('central');
|
||||||
|
|
@ -118,19 +78,16 @@ test('cache is separated correctly when using DatabaseCacheBootstrapper', functi
|
||||||
|
|
||||||
// Central cache doesn't leak to tenant context
|
// Central cache doesn't leak to tenant context
|
||||||
expect(Cache::has('foo'))->toBeFalse();
|
expect(Cache::has('foo'))->toBeFalse();
|
||||||
// Verify that the 'foo' cache key doesn't exist in the tenant's DB using a direct DB query
|
|
||||||
expect($getCacheUsingDbQuery('foo'))->toBeNull();
|
expect($getCacheUsingDbQuery('foo'))->toBeNull();
|
||||||
|
|
||||||
cache()->set('foo', 'bar');
|
cache()->set('foo', 'bar');
|
||||||
expect(Cache::get('foo'))->toBe('bar');
|
expect(Cache::get('foo'))->toBe('bar');
|
||||||
// Verify that the 'foo' cache key is 'bar' using a direct DB query
|
|
||||||
expect($getCacheUsingDbQuery('foo'))->toContain('bar');
|
expect($getCacheUsingDbQuery('foo'))->toContain('bar');
|
||||||
|
|
||||||
tenancy()->initialize($tenant2);
|
tenancy()->initialize($tenant2);
|
||||||
|
|
||||||
// Assert one tenant's cache doesn't leak to another tenant
|
// Assert one tenant's cache doesn't leak to another tenant
|
||||||
expect(Cache::has('foo'))->toBeFalse();
|
expect(Cache::has('foo'))->toBeFalse();
|
||||||
// The 'foo' cache key in another tenant's database shouldn't exist
|
|
||||||
expect($getCacheUsingDbQuery('foo'))->toBeNull();
|
expect($getCacheUsingDbQuery('foo'))->toBeNull();
|
||||||
|
|
||||||
cache()->set('foo', 'xyz');
|
cache()->set('foo', 'xyz');
|
||||||
|
|
@ -151,7 +108,6 @@ test('cache is separated correctly when using DatabaseCacheBootstrapper', functi
|
||||||
});
|
});
|
||||||
|
|
||||||
test('DatabaseCacheBootstrapper auto-detects all database driver stores by default', function() {
|
test('DatabaseCacheBootstrapper auto-detects all database driver stores by default', function() {
|
||||||
// Configure multiple stores with different drivers
|
|
||||||
config([
|
config([
|
||||||
'cache.stores.database' => [
|
'cache.stores.database' => [
|
||||||
'driver' => 'database',
|
'driver' => 'database',
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,22 @@ use Stancl\Tenancy\Tests\TestCase;
|
||||||
use Stancl\JobPipeline\JobPipeline;
|
use Stancl\JobPipeline\JobPipeline;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Stancl\Tenancy\Events\TenancyEnded;
|
||||||
|
use Stancl\Tenancy\Events\TenancyInitialized;
|
||||||
use Stancl\Tenancy\Jobs\CreateDatabase;
|
use Stancl\Tenancy\Jobs\CreateDatabase;
|
||||||
use Stancl\Tenancy\Events\TenantCreated;
|
use Stancl\Tenancy\Events\TenantCreated;
|
||||||
use Stancl\Tenancy\Jobs\MigrateDatabase;
|
use Stancl\Tenancy\Jobs\MigrateDatabase;
|
||||||
|
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
||||||
|
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
||||||
|
|
||||||
uses(TestCase::class)->in(__DIR__);
|
uses(TestCase::class)->in(__DIR__);
|
||||||
|
|
||||||
|
function withBootstrapping()
|
||||||
|
{
|
||||||
|
Event::listen(TenancyInitialized::class, BootstrapTenancy::class);
|
||||||
|
Event::listen(TenancyEnded::class, RevertToCentralContext::class);
|
||||||
|
}
|
||||||
|
|
||||||
function withTenantDatabases(bool $migrate = false)
|
function withTenantDatabases(bool $migrate = false)
|
||||||
{
|
{
|
||||||
Event::listen(TenantCreated::class, JobPipeline::make($migrate
|
Event::listen(TenantCreated::class, JobPipeline::make($migrate
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue