1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-02-05 06:24:04 +00:00

Simplify and clarify core shortest path generation test

This commit is contained in:
lukinovec 2025-06-09 12:38:27 +02:00
parent 8c773245f7
commit cac2649568

View file

@ -333,6 +333,19 @@ test('queries are correctly scoped using RLS', function (bool $forceRls) {
test('table rls manager generates shortest paths that lead to the tenants table correctly', function (bool $scopeByDefault) { test('table rls manager generates shortest paths that lead to the tenants table correctly', function (bool $scopeByDefault) {
TableRLSManager::$scopeByDefault = $scopeByDefault; TableRLSManager::$scopeByDefault = $scopeByDefault;
// Only related to the tenants table through nullable columns (directly through tenant_id and indirectly through post_id)
Schema::create('ratings', function (Blueprint $table) {
$table->id();
$table->foreignId('post_id')->nullable()->comment('rls')->constrained();
// No 'rls' comment should get excluded from path generation when using explicit scoping
$table->string('tenant_id')->nullable();
$table->foreign('tenant_id')->references('id')->on('tenants')->onUpdate('cascade')->onDelete('cascade');
$table->timestamps();
});
/** @var TableRLSManager $manager */ /** @var TableRLSManager $manager */
$manager = app(TableRLSManager::class); $manager = app(TableRLSManager::class);
@ -373,32 +386,11 @@ test('table rls manager generates shortest paths that lead to the tenants table
'foreignId' => 'id', 'foreignId' => 'id',
], ],
], ],
]; // When scoping by default is enabled (implicit scoping),
// the shortest path from the ratings table leads directly through tenant_id.
expect($manager->shortestPaths())->toEqual($expectedShortestPaths); // When scoping by default is disabled (explicit scoping),
// the shortest path leads through post_id.
// Only related to the tenants table through nullable columns tenant_id and indirectly through post_id 'ratings' => $scopeByDefault ? [
Schema::create('ratings', function (Blueprint $table) {
$table->id();
$table->integer('stars')->default(0);
$table->unsignedBigInteger('post_id')->nullable()->comment('rls');
$table->foreign('post_id')->references('id')->on('posts')->onUpdate('cascade')->onDelete('cascade');
// No 'rls' comment should get excluded from path generation when using explicit scoping
$table->string('tenant_id')->nullable();
$table->foreign('tenant_id')->references('id')->on('tenants')->onUpdate('cascade')->onDelete('cascade');
$table->timestamps();
});
// The shortest paths should include a path for the ratings table
// That leads through tenant_id when scoping by default is enabled, that's the shortest path
// When scoping by default is disabled, the shortest path leads through post_id
// This behavior is handled by the manager's shortestPaths() method
$shortestPaths = $manager->shortestPaths();
$expectedShortestPath = $scopeByDefault ? [
[ [
'foreignKey' => 'tenant_id', 'foreignKey' => 'tenant_id',
'foreignTable' => 'tenants', 'foreignTable' => 'tenants',
@ -420,21 +412,21 @@ test('table rls manager generates shortest paths that lead to the tenants table
'foreignTable' => 'tenants', 'foreignTable' => 'tenants',
'foreignId' => 'id', 'foreignId' => 'id',
], ],
],
// Articles table is ignored because it's not related to the tenant table in any way
// Reactions table is ignored because of the 'no-rls' comment on the comment_id column
// Categories table is ignored because of the 'no-rls' comment on the tenant_id column
]; ];
expect($shortestPaths['ratings'])->toBe($expectedShortestPath); expect($manager->shortestPaths())->toEqual($expectedShortestPaths);
// Add non-nullable comment_id foreign key // Add non-nullable comment_id foreign key.
Schema::table('ratings', function (Blueprint $table) { Schema::table('ratings', function (Blueprint $table) {
$table->foreignId('comment_id')->comment('rls')->constrained('comments')->onUpdate('cascade')->onDelete('cascade'); $table->foreignId('comment_id')->comment('rls')->constrained('comments')->onUpdate('cascade')->onDelete('cascade');
}); });
// Non-nullable paths are preferred over nullable paths // Non-nullable paths are preferred over nullable paths.
// The shortest paths should include a path for the ratings table $expectedShortestPaths['ratings'] = [
// That leads through comment_id instead of tenant_id
$shortestPaths = $manager->shortestPaths();
expect($shortestPaths['ratings'])->toBe([
[ [
'foreignKey' => 'comment_id', 'foreignKey' => 'comment_id',
'foreignTable' => 'comments', 'foreignTable' => 'comments',
@ -455,7 +447,11 @@ test('table rls manager generates shortest paths that lead to the tenants table
'foreignTable' => 'tenants', 'foreignTable' => 'tenants',
'foreignId' => 'id', 'foreignId' => 'id',
], ],
]); ];
// The shortest paths should now include a path for the ratings table
// that leads through comment_id instead of tenant_id.
expect($manager->shortestPaths())->toEqual($expectedShortestPaths);
})->with([true, false]); })->with([true, false]);
// https://github.com/archtechx/tenancy/pull/1293 // https://github.com/archtechx/tenancy/pull/1293