Files

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);
});