Права ламаються тихо: забута перевірка не дає помилки, вона просто дозволяє зайве. Тому їх тестують на двох рівнях.
1. Правило - напряму, через can():
it('lets only the author edit a draft', function () {
$author = User::factory()->create();
$post = Post::factory()->draft()->for($author)->create();
expect($author->can('update', $post))->toBeTrue()
->and(User::factory()->create()->can('update', $post))->toBeFalse();
});
can() проходить увесь шлях: before, саму політику, after. Тест швидкий і точно вказує, яке правило зламалося.
2. Ендпойнт - що перевірку справді викликають:
it('forbids editing someone else\'s post', function () {
$post = Post::factory()->create();
$this->actingAs(User::factory()->create())
->put("/posts/{$post->id}", ['title' => 'Чуже'])
->assertForbidden();
expect($post->fresh()->title)->not->toBe('Чуже');
});
Ідеальна політика нічого не варта, якщо контролер її не викликав - цей тест ловить саме таке.
Що варто покривати обов'язково:
- «користувач A не бачить і не змінює даних користувача B» для кожного ресурсу;
- гість, звичайний користувач, власник, адмін - матриця ролей для ключових дій;
- списки й експорт, а не лише окремі сторінки;
denyAsNotFound()- що повертається саме 404.
Архітектурний тест на кшталт «кожен метод контролера, що змінює дані, викликає Gate::authorize» складно написати надійно, тому покладаються на тести ендпойнтів.
Докладніше в документації: Авторизація через модель користувача