mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 15:54:03 +00:00
* Run cache tests on all supported drivers * update ci healthcheck for memcached * remove memcached healthcheck * fix typos in test comments, expand internal.md [ci skip] * add empty line [ci skip] * switch to using $store->setPrefix() * add dynamodb * refactor try-finally to try-catch * remove unnecessary clearResolvedInstances() call * add dual Cache:: and cache() assertions * add apc * Flush APCu cache in test setup * Revert "add dual Cache:: and cache() assertions" This reverts commit a0bab162fbe2dd0d25e7056ceca4fb7ce54efc77. * phpstan fix * Add logic for scoping 'file' disks to FilesystemTenancyBootstrapper * minor changes, add todos * refactor how the session.connection is used in the DB session bootstrapper * add session forgery prevention logic to the db session bootstrapper * only use the fs bootstrapper for file disk in 'cache data is separated' dataset * minor session scoping test changes * Add session scoping logic to FilesystemTenancyBootstrapper, correctly update disk roots even with storage_path_tenancy disabled * Fix code style (php-cs-fixer) * update docblock * make not-null check more explicit * separate bootstrapper tests, fix swapped test names for two tests * refactor cache bootstrapper tests * resolve global cache todo * expand tests: session separation tests, more filesystem separation assertions; change prefix_base-type config keys to templates/formats * add apc session scoping test, various session separation bugfixes * phpstan + minor logic fixes * prefix_format -> prefix * fix database session separation test * revert composer.json changes, update laravel dependencies to expected next release * only run session scoping logic in cache bootstrapper for redis, memcached, dynamodb, apc; update gitattributes * tenancy.central_domains -> tenancy.identification.central_domains * db session separation test: add datasets --------- Co-authored-by: PHP CS Fixer <phpcsfixer@example.com>
145 lines
4.6 KiB
PHP
145 lines
4.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use Illuminate\Support\Facades\Event;
|
|
use Illuminate\Support\Facades\Route;
|
|
use Stancl\JobPipeline\JobPipeline;
|
|
use Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper;
|
|
use Stancl\Tenancy\Bootstrappers\DatabaseSessionBootstrapper;
|
|
use Stancl\Tenancy\Events;
|
|
use Stancl\Tenancy\Events\TenantCreated;
|
|
use Stancl\Tenancy\Jobs\CreateDatabase;
|
|
use Stancl\Tenancy\Listeners;
|
|
use Stancl\Tenancy\Middleware\InitializeTenancyByDomain;
|
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
|
|
|
/**
|
|
* This collection of regression tests verifies that SessionTenancyBootstrapper
|
|
* fully fixes the issue described here https://github.com/archtechx/tenancy/issues/547
|
|
*
|
|
* This means: using the DB session driver and:
|
|
* 1) switching to the central context from tenant requests, OR
|
|
* 2) switching to the tenant context from central requests
|
|
*/
|
|
|
|
beforeEach(function () {
|
|
config(['session.driver' => 'database']);
|
|
config(['tenancy.bootstrappers' => [DatabaseTenancyBootstrapper::class]]);
|
|
|
|
Event::listen(
|
|
TenantCreated::class,
|
|
JobPipeline::make([CreateDatabase::class])->send(function (TenantCreated $event) {
|
|
return $event->tenant;
|
|
})->toListener()
|
|
);
|
|
|
|
Event::listen(Events\TenancyInitialized::class, Listeners\BootstrapTenancy::class);
|
|
Event::listen(Events\TenancyEnded::class, Listeners\RevertToCentralContext::class);
|
|
|
|
// Sessions table for central database
|
|
pest()->artisan('migrate', [
|
|
'--path' => __DIR__ . '/../Etc/session_migrations',
|
|
'--realpath' => true,
|
|
])->assertExitCode(0);
|
|
});
|
|
|
|
test('central helper can be used in tenant requests', function (bool $enabled, bool $shouldThrow) {
|
|
if ($enabled) {
|
|
config()->set(
|
|
'tenancy.bootstrappers',
|
|
array_merge(config('tenancy.bootstrappers'), [DatabaseSessionBootstrapper::class]),
|
|
);
|
|
}
|
|
|
|
$tenant = Tenant::create();
|
|
|
|
$tenant->domains()->create(['domain' => 'foo.localhost']);
|
|
|
|
// run for tenants
|
|
pest()->artisan('tenants:migrate', [
|
|
'--path' => __DIR__ . '/../Etc/session_migrations',
|
|
'--realpath' => true,
|
|
])->assertExitCode(0);
|
|
|
|
Route::middleware(['web', InitializeTenancyByDomain::class])->get('/bar', function () {
|
|
session(['message' => 'tenant session']);
|
|
|
|
tenancy()->central(function () {
|
|
return 'central results';
|
|
});
|
|
|
|
return session('message');
|
|
});
|
|
|
|
// We initialize tenancy before making the request, since sessions work a bit differently in tests
|
|
// and we need the DB session handler to use the tenant connection (as it does in a real app on tenant requests).
|
|
tenancy()->initialize($tenant);
|
|
|
|
try {
|
|
$this->withoutExceptionHandling()
|
|
->get('http://foo.localhost/bar')
|
|
->assertOk()
|
|
->assertSee('tenant session');
|
|
|
|
if ($shouldThrow) {
|
|
pest()->fail('Exception not thrown');
|
|
}
|
|
} catch (Throwable $e) {
|
|
if ($shouldThrow) {
|
|
pest()->assertTrue(true); // empty assertion to make the test pass
|
|
} else {
|
|
pest()->fail('Exception thrown: ' . $e->getMessage());
|
|
}
|
|
}
|
|
})->with([
|
|
['enabled' => false, 'shouldThrow' => true],
|
|
['enabled' => true, 'shouldThrow' => false],
|
|
]);
|
|
|
|
test('tenant run helper can be used on central requests', function (bool $enabled, bool $shouldThrow) {
|
|
if ($enabled) {
|
|
config()->set(
|
|
'tenancy.bootstrappers',
|
|
array_merge(config('tenancy.bootstrappers'), [DatabaseSessionBootstrapper::class]),
|
|
);
|
|
}
|
|
|
|
Tenant::create();
|
|
|
|
// run for tenants
|
|
pest()->artisan('tenants:migrate', [
|
|
'--path' => __DIR__ . '/../Etc/session_migrations',
|
|
'--realpath' => true,
|
|
])->assertExitCode(0);
|
|
|
|
Route::middleware(['web'])->get('/bar', function () {
|
|
session(['message' => 'central session']);
|
|
|
|
Tenant::first()->run(function () {
|
|
return 'tenant results';
|
|
});
|
|
|
|
return session('message');
|
|
});
|
|
|
|
try {
|
|
$this->withoutExceptionHandling()
|
|
->get('http://localhost/bar')
|
|
->assertOk()
|
|
->assertSee('central session');
|
|
|
|
if ($shouldThrow) {
|
|
pest()->fail('Exception not thrown');
|
|
}
|
|
} catch (Throwable $e) {
|
|
if ($shouldThrow) {
|
|
pest()->assertTrue(true); // empty assertion to make the test pass
|
|
} else {
|
|
pest()->fail('Exception thrown: ' . $e->getMessage());
|
|
}
|
|
}
|
|
})->with([
|
|
['enabled' => false, 'shouldThrow' => true],
|
|
['enabled' => true, 'shouldThrow' => false],
|
|
]);
|