mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 15:54:03 +00:00
[4.x] Invalidate resolver cache on delete (#1329)
* Invalidate resolver cache on delete * Fix code style (php-cs-fixer) --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
8960a83047
commit
37a0f1a713
3 changed files with 55 additions and 13 deletions
|
|
@ -4,16 +4,13 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Stancl\Tenancy\Database\Concerns;
|
namespace Stancl\Tenancy\Database\Concerns;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Stancl\Tenancy\Contracts\Tenant;
|
|
||||||
use Stancl\Tenancy\Tenancy;
|
use Stancl\Tenancy\Tenancy;
|
||||||
|
|
||||||
trait InvalidatesResolverCache
|
trait InvalidatesResolverCache
|
||||||
{
|
{
|
||||||
public static function bootInvalidatesResolverCache(): void
|
public static function bootInvalidatesResolverCache(): void
|
||||||
{
|
{
|
||||||
static::saved(function (Tenant&Model $tenant) {
|
static::saved(Tenancy::invalidateResolverCache(...));
|
||||||
Tenancy::invalidateResolverCache($tenant);
|
static::deleting(Tenancy::invalidateResolverCache(...));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ declare(strict_types=1);
|
||||||
namespace Stancl\Tenancy\Database\Concerns;
|
namespace Stancl\Tenancy\Database\Concerns;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Stancl\Tenancy\Resolvers\Contracts\CachedTenantResolver;
|
|
||||||
use Stancl\Tenancy\Tenancy;
|
use Stancl\Tenancy\Tenancy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -15,13 +14,9 @@ trait InvalidatesTenantsResolverCache
|
||||||
{
|
{
|
||||||
public static function bootInvalidatesTenantsResolverCache(): void
|
public static function bootInvalidatesTenantsResolverCache(): void
|
||||||
{
|
{
|
||||||
static::saved(function (Model $model) {
|
$invalidateCache = static fn (Model $model) => Tenancy::invalidateResolverCache($model->tenant);
|
||||||
foreach (Tenancy::cachedResolvers() as $resolver) {
|
|
||||||
/** @var CachedTenantResolver $resolver */
|
|
||||||
$resolver = app($resolver);
|
|
||||||
|
|
||||||
$resolver->invalidateCache($model->tenant);
|
static::saved($invalidateCache);
|
||||||
}
|
static::deleting($invalidateCache);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ use Stancl\Tenancy\Resolvers\PathTenantResolver;
|
||||||
use Stancl\Tenancy\Resolvers\DomainTenantResolver;
|
use Stancl\Tenancy\Resolvers\DomainTenantResolver;
|
||||||
use Illuminate\Support\Facades\Route as RouteFacade;
|
use Illuminate\Support\Facades\Route as RouteFacade;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Stancl\Tenancy\Contracts\TenantCouldNotBeIdentifiedException;
|
||||||
|
use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedOnDomainException;
|
||||||
use Stancl\Tenancy\Middleware\InitializeTenancyByPath;
|
use Stancl\Tenancy\Middleware\InitializeTenancyByPath;
|
||||||
use Stancl\Tenancy\Resolvers\RequestDataTenantResolver;
|
use Stancl\Tenancy\Resolvers\RequestDataTenantResolver;
|
||||||
use function Stancl\Tenancy\Tests\pest;
|
use function Stancl\Tenancy\Tests\pest;
|
||||||
|
|
@ -84,6 +86,34 @@ test('cache is invalidated when the tenant is updated', function (string $resolv
|
||||||
RequestDataTenantResolver::class,
|
RequestDataTenantResolver::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
test('cache is invalidated when the tenant is deleted', function (string $resolver) {
|
||||||
|
DB::statement('SET FOREIGN_KEY_CHECKS=0;'); // allow deleting the tenant
|
||||||
|
$tenant = Tenant::create(['id' => $tenantKey = 'acme']);
|
||||||
|
$tenant->createDomain($tenantKey);
|
||||||
|
|
||||||
|
DB::enableQueryLog();
|
||||||
|
|
||||||
|
config(['tenancy.identification.resolvers.' . $resolver . '.cache' => true]);
|
||||||
|
|
||||||
|
expect($tenant->is(app($resolver)->resolve(getResolverArgument($resolver, $tenantKey))))->toBeTrue();
|
||||||
|
expect(DB::getQueryLog())->not()->toBeEmpty();
|
||||||
|
|
||||||
|
DB::flushQueryLog();
|
||||||
|
|
||||||
|
expect($tenant->is(app($resolver)->resolve(getResolverArgument($resolver, $tenantKey))))->toBeTrue();
|
||||||
|
expect(DB::getQueryLog())->toBeEmpty();
|
||||||
|
|
||||||
|
$tenant->delete();
|
||||||
|
DB::flushQueryLog();
|
||||||
|
|
||||||
|
expect(fn () => app($resolver)->resolve(getResolverArgument($resolver, $tenantKey)))->toThrow(TenantCouldNotBeIdentifiedException::class);
|
||||||
|
expect(DB::getQueryLog())->not()->toBeEmpty(); // Cache was invalidated, so the DB was queried
|
||||||
|
})->with([
|
||||||
|
DomainTenantResolver::class,
|
||||||
|
PathTenantResolver::class,
|
||||||
|
RequestDataTenantResolver::class,
|
||||||
|
]);
|
||||||
|
|
||||||
test('cache is invalidated when a tenants domain is changed', function () {
|
test('cache is invalidated when a tenants domain is changed', function () {
|
||||||
$tenant = Tenant::create(['id' => $tenantKey = 'acme']);
|
$tenant = Tenant::create(['id' => $tenantKey = 'acme']);
|
||||||
$tenant->createDomain($tenantKey);
|
$tenant->createDomain($tenantKey);
|
||||||
|
|
@ -110,6 +140,26 @@ test('cache is invalidated when a tenants domain is changed', function () {
|
||||||
pest()->assertNotEmpty(DB::getQueryLog()); // not empty
|
pest()->assertNotEmpty(DB::getQueryLog()); // not empty
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('cache is invalidated when a tenants domain is deleted', function () {
|
||||||
|
$tenant = Tenant::create(['id' => $tenantKey = 'acme']);
|
||||||
|
$tenant->createDomain($tenantKey);
|
||||||
|
|
||||||
|
DB::enableQueryLog();
|
||||||
|
|
||||||
|
config(['tenancy.identification.resolvers.' . DomainTenantResolver::class . '.cache' => true]);
|
||||||
|
|
||||||
|
expect($tenant->is(app(DomainTenantResolver::class)->resolve('acme')))->toBeTrue();
|
||||||
|
DB::flushQueryLog();
|
||||||
|
expect($tenant->is(app(DomainTenantResolver::class)->resolve('acme')))->toBeTrue();
|
||||||
|
expect(DB::getQueryLog())->toBeEmpty(); // empty
|
||||||
|
|
||||||
|
$tenant->domains->first()->delete();
|
||||||
|
DB::flushQueryLog();
|
||||||
|
|
||||||
|
expect(fn () => $tenant->is(app(DomainTenantResolver::class)->resolve('acme')))->toThrow(TenantCouldNotBeIdentifiedOnDomainException::class);
|
||||||
|
expect(DB::getQueryLog())->not()->toBeEmpty(); // Cache was invalidated, so the DB was queried
|
||||||
|
});
|
||||||
|
|
||||||
test('PathTenantResolver forgets the tenant route parameter when the tenant is resolved from cache', function() {
|
test('PathTenantResolver forgets the tenant route parameter when the tenant is resolved from cache', function() {
|
||||||
config(['tenancy.identification.resolvers.' . PathTenantResolver::class . '.cache' => true]);
|
config(['tenancy.identification.resolvers.' . PathTenantResolver::class . '.cache' => true]);
|
||||||
DB::enableQueryLog();
|
DB::enableQueryLog();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue