84 lines
2.8 KiB
PHP
84 lines
2.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\Permission;
|
|
use App\Models\Role;
|
|
use App\Models\User;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
function grantViewAndManageAccessRights(User $user): void
|
|
{
|
|
foreach (['view access rights', 'manage access rights', 'view user directory', 'manage user directory'] as $name) {
|
|
Permission::firstOrCreate(['name' => $name, 'guard_name' => 'web']);
|
|
}
|
|
$user->givePermissionTo(['view access rights', 'manage access rights', 'view user directory', 'manage user directory']);
|
|
}
|
|
|
|
function queryCountDuring(callable $fn): int
|
|
{
|
|
DB::enableQueryLog();
|
|
DB::flushQueryLog();
|
|
$fn();
|
|
$count = count(DB::getQueryLog());
|
|
DB::disableQueryLog();
|
|
|
|
return $count;
|
|
}
|
|
|
|
test('users datatable query count is bounded regardless of row count', function () {
|
|
$admin = User::factory()->create();
|
|
grantViewAndManageAccessRights($admin);
|
|
User::factory()->count(5)->create()->each(function ($u) {
|
|
$u->assignRole(Role::firstOrCreate(['name' => 'member-'.$u->id, 'guard_name' => 'web'])->name);
|
|
});
|
|
|
|
$baselineCount = queryCountDuring(function () use ($admin) {
|
|
$this->actingAs($admin)->getJson('/users?draw=1&start=0&length=10&columns[0][data]=id');
|
|
});
|
|
|
|
User::factory()->count(20)->create()->each(function ($u) {
|
|
$u->assignRole(Role::firstOrCreate(['name' => 'member-'.$u->id, 'guard_name' => 'web'])->name);
|
|
});
|
|
|
|
$scaledCount = queryCountDuring(function () use ($admin) {
|
|
$this->actingAs($admin)->getJson('/users?draw=1&start=0&length=10&columns[0][data]=id');
|
|
});
|
|
|
|
// 4x more rows should not 4x the query count — eager loading caps it.
|
|
expect($scaledCount - $baselineCount)->toBeLessThan(10);
|
|
});
|
|
|
|
test('roles datatable eagerly loads permissions and creator', function () {
|
|
$admin = User::factory()->create();
|
|
grantViewAndManageAccessRights($admin);
|
|
|
|
foreach (range(1, 5) as $i) {
|
|
$r = Role::create(['name' => 'np1-role-'.$i, 'guard_name' => 'web']);
|
|
$p = Permission::firstOrCreate(['name' => 'np1-perm-'.$i, 'guard_name' => 'web']);
|
|
$r->givePermissionTo($p);
|
|
}
|
|
|
|
$count = queryCountDuring(function () use ($admin) {
|
|
$this->actingAs($admin)->getJson('/roles?draw=1&start=0&length=10&columns[0][data]=id');
|
|
});
|
|
|
|
// Should not run a permission lookup per row.
|
|
expect($count)->toBeLessThan(20);
|
|
});
|
|
|
|
test('permissions datatable eagerly loads roles and creator', function () {
|
|
$admin = User::factory()->create();
|
|
grantViewAndManageAccessRights($admin);
|
|
|
|
foreach (range(1, 8) as $i) {
|
|
Permission::firstOrCreate(['name' => 'eager-perm-'.$i, 'guard_name' => 'web']);
|
|
}
|
|
|
|
$count = queryCountDuring(function () use ($admin) {
|
|
$this->actingAs($admin)->getJson('/permissions?draw=1&start=0&length=10&columns[0][data]=id');
|
|
});
|
|
|
|
expect($count)->toBeLessThan(20);
|
|
});
|