1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2025-12-12 23:34:03 +00:00

Resolver refactor, path identification improvements (#41)

* resolver refactor

* Fix code style (php-cs-fixer)

* make tenant column used in PathTenantResolver configurable, fix phpstan errors, minor improvements

* support binding route fields, write tests for customizable tenant columns

* Invalidate cache for all possible columns in path resolver

* implement proper cache separation logic for different columns used by PathTenantResolver

* improve return type

---------

Co-authored-by: PHP CS Fixer <phpcsfixer@example.com>
This commit is contained in:
Samuel Štancl 2024-03-28 03:18:11 +01:00 committed by GitHub
parent dc430666ba
commit 0c11f29c19
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 370 additions and 88 deletions

View file

@ -3,8 +3,11 @@
declare(strict_types=1);
use Illuminate\Contracts\Http\Kernel;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Schema;
use Stancl\Tenancy\Exceptions\RouteIsMissingTenantParameterException;
use Stancl\Tenancy\Exceptions\TenantColumnNotWhitelistedException;
use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedByPathException;
use Stancl\Tenancy\Middleware\InitializeTenancyByPath;
use Stancl\Tenancy\Resolvers\PathTenantResolver;
@ -15,6 +18,7 @@ beforeEach(function () {
config(['tenancy.identification.resolvers.' . PathTenantResolver::class . '.tenant_parameter_name' => 'tenant']);
InitializeTenancyByPath::$onFail = null;
Tenant::$extraCustomColumns = [];
Route::group([
'prefix' => '/{tenant}',
@ -160,3 +164,84 @@ test('central route can have a parameter with the same name as the tenant parame
expect(tenancy()->initialized)->toBeFalse();
});
test('the tenant model column can be customized in the config', function () {
config(['tenancy.identification.resolvers.' . PathTenantResolver::class . '.tenant_model_column' => 'slug']);
Tenant::$extraCustomColumns = ['slug'];
Schema::table('tenants', function (Blueprint $table) {
$table->string('slug')->unique();
});
$tenant = Tenant::create([
'slug' => 'acme',
]);
Route::get('/{tenant}/foo', function () {
return tenant()->getTenantKey();
})->middleware(InitializeTenancyByPath::class);
$this->withoutExceptionHandling();
pest()->get('/acme/foo')->assertSee($tenant->getTenantKey());
expect(fn () => pest()->get($tenant->id . '/foo'))->toThrow(TenantCouldNotBeIdentifiedByPathException::class);
Tenant::$extraCustomColumns = []; // static property reset
});
test('the tenant model column can be customized in the route definition', function () {
Tenant::$extraCustomColumns = ['slug'];
config(['tenancy.identification.resolvers.' . PathTenantResolver::class . '.allowed_extra_model_columns' => ['slug']]);
Schema::table('tenants', function (Blueprint $table) {
$table->string('slug')->unique();
});
$tenant = Tenant::create([
'slug' => 'acme',
]);
Route::get('/{tenant}/foo', function () {
return tenant()->getTenantKey();
})->middleware(InitializeTenancyByPath::class);
Route::get('/{tenant:slug}/bar', function () {
return tenant()->getTenantKey();
})->middleware(InitializeTenancyByPath::class);
$this->withoutExceptionHandling();
// No binding field defined
pest()->get($tenant->getTenantKey() . '/foo')->assertSee($tenant->getTenantKey());
expect(fn () => pest()->get('/acme/foo'))->toThrow(TenantCouldNotBeIdentifiedByPathException::class);
// Binding field defined
pest()->get('/acme/bar')->assertSee($tenant->getTenantKey());
expect(fn () => pest()->get($tenant->id . '/bar'))->toThrow(TenantCouldNotBeIdentifiedByPathException::class);
Tenant::$extraCustomColumns = []; // static property reset
});
test('any extra model column needs to be whitelisted', function () {
Tenant::$extraCustomColumns = ['slug'];
Schema::table('tenants', function (Blueprint $table) {
$table->string('slug')->unique();
});
$tenant = Tenant::create([
'slug' => 'acme',
]);
Route::get('/{tenant:slug}/foo', function () {
return tenant()->getTenantKey();
})->middleware(InitializeTenancyByPath::class);
$this->withoutExceptionHandling();
expect(fn () => pest()->get('/acme/foo'))->toThrow(TenantColumnNotWhitelistedException::class);
// After whitelisting the column it works
config(['tenancy.identification.resolvers.' . PathTenantResolver::class . '.allowed_extra_model_columns' => ['slug']]);
pest()->get('/acme/foo')->assertSee($tenant->getTenantKey());
Tenant::$extraCustomColumns = []; // static property reset
});