Тестування ресурсів · Filament
Автентифікація користувача
Переконайтеся, що у вашому TestCase ви автентифіковані для доступу до застосунку:
use App\Models\User;
protected function setUp(): void
{
parent::setUp();
$this->actingAs(User::factory()->create());
}
Або, якщо ви користуєтеся Pest, для автентифікації можна застосувати функцію beforeEach() на початку файлу з тестами:
use App\Models\User;
beforeEach(function () {
$user = User::factory()->create();
actingAs($user);
});
Тестування сторінки списку ресурсу
Щоб перевірити, чи завантажується сторінка списку, протестуйте її як Livewire-компонент і викличте assertOk(), аби переконатися, що HTTP-відповідь була 200 OK. Метод assertCanSeeTableRecords() перевіряє, чи відображаються записи в таблиці:
use App\Filament\Resources\Users\Pages\ListUsers;
use App\Models\User;
it('can load the page', function () {
$users = User::factory()->count(5)->create();
livewire(ListUsers::class)
->assertOk()
->assertCanSeeTableRecords($users);
});
Про тестування таблиці на сторінці списку читайте в розділі Тестування таблиць. Про тестування дій у шапці сторінки або дій у таблиці читайте в розділі Тестування дій. Нижче кілька типових прикладів інших тестів, які можна запустити на сторінці списку.
Щоб перевірити, що пошук у таблиці працює, скористайтеся методом searchTable() для пошуку конкретного запису. Методи assertCanSeeTableRecords() і assertCanNotSeeTableRecords() перевіряють, чи в таблиці показані потрібні записи:
use App\Filament\Resources\Users\Pages\ListUsers;
use App\Models\User;
it('can search users by `name` or `email`', function () {
$users = User::factory()->count(5)->create();
livewire(ListUsers::class)
->assertCanSeeTableRecords($users)
->searchTable($users->first()->name)
->assertCanSeeTableRecords($users->take(1))
->assertCanNotSeeTableRecords($users->skip(1))
->searchTable($users->last()->email)
->assertCanSeeTableRecords($users->take(-1))
->assertCanNotSeeTableRecords($users->take($users->count() - 1));
});
Щоб перевірити, що сортування таблиці працює, скористайтеся методом sortTable() для сортування таблиці за певною колонкою. Метод assertCanSeeTableRecords() перевіряє, чи записи виводяться в правильному порядку:
use App\Filament\Resources\Users\Pages\ListUsers;
use App\Models\User;
it('can sort users by `name`', function () {
$users = User::factory()->count(5)->create();
livewire(ListUsers::class)
->assertCanSeeTableRecords($users)
->sortTable('name')
->assertCanSeeTableRecords($users->sortBy('name'), inOrder: true)
->sortTable('name', 'desc')
->assertCanSeeTableRecords($users->sortByDesc('name'), inOrder: true);
});
Щоб перевірити, що фільтрація таблиці працює, скористайтеся методом filterTable() для фільтрації таблиці за певною колонкою. Методи assertCanSeeTableRecords() і assertCanNotSeeTableRecords() перевіряють, чи в таблиці показані потрібні записи:
use App\Filament\Resources\Users\Pages\ListUsers;
use App\Models\User;
it('can filter users by `locale`', function () {
$users = User::factory()->count(5)->create();
livewire(ListUsers::class)
->assertCanSeeTableRecords($users)
->filterTable('locale', $users->first()->locale)
->assertCanSeeTableRecords($users->where('locale', $users->first()->locale))
->assertCanNotSeeTableRecords($users->where('locale', '!=', $users->first()->locale));
});
Щоб перевірити, що масові дії в таблиці працюють, скористайтеся методом selectTableRecords(), аби вибрати кілька записів у таблиці. Метод callAction() викликає конкретну дію на вибраних записах:
use App\Filament\Resources\Users\Pages\ListUsers;
use App\Models\User;
use Filament\Actions\Testing\TestAction;
use function Pest\Laravel\assertDatabaseMissing;
it('can bulk delete users', function () {
$users = User::factory()->count(5)->create();
livewire(ListUsers::class)
->assertCanSeeTableRecords($users)
->selectTableRecords($users)
->callAction(TestAction::make(DeleteBulkAction::class)->table()->bulk())
->assertNotified()
->assertCanNotSeeTableRecords($users);
$users->each(fn (User $user) => assertDatabaseMissing($user));
});
Тестування сторінки створення ресурсу
Щоб перевірити, чи завантажується сторінка створення, протестуйте її як Livewire-компонент і викличте assertOk(), аби переконатися, що HTTP-відповідь була 200 OK:
use App\Filament\Resources\Users\Pages\CreateUser;
use App\Models\User;
it('can load the page', function () {
livewire(CreateUser::class)
->assertOk();
});
Про тестування форми на сторінці створення читайте в розділі Тестування схем. Про тестування дій у шапці сторінки чи у формі читайте в розділі Тестування дій. Нижче кілька типових прикладів інших тестів, які можна запустити на сторінці створення.
Щоб перевірити, чи форма коректно створює записи, заповніть поля форми методом fillForm(), а потім створіть запис викликом call('create'). Метод assertNotified() перевіряє, чи показалося сповіщення, а assertRedirect() - чи було перенаправлення користувача на іншу сторінку:
use App\Filament\Resources\Users\Pages\CreateUser;
use App\Models\User;
use function Pest\Laravel\assertDatabaseHas;
it('can create a user', function () {
$newUserData = User::factory()->make();
livewire(CreateUser::class)
->fillForm([
'name' => $newUserData->name,
'email' => $newUserData->email,
])
->call('create')
->assertNotified()
->assertRedirect();
assertDatabaseHas(User::class, [
'name' => $newUserData->name,
'email' => $newUserData->email,
]);
});
Щоб перевірити, чи форма правильно валідує дані, заповніть поля методом fillForm(), а потім викличте call('create'). Метод assertHasFormErrors() перевіряє наявність помилок форми, assertNotNotified() - що жодного сповіщення не показано, а assertNoRedirect() - що користувача не перенаправило на іншу сторінку. У цьому прикладі використано набір даних Pest, щоб перевірити кілька правил без дублювання коду тесту:
use App\Filament\Resources\Users\Pages\CreateUser;
use App\Models\User;
use Illuminate\Support\Str;
it('validates the form data', function (array $data, array $errors) {
$newUserData = User::factory()->make();
livewire(CreateUser::class)
->fillForm([
'name' => $newUserData->name,
'email' => $newUserData->email,
...$data,
])
->call('create')
->assertHasFormErrors($errors)
->assertNotNotified()
->assertNoRedirect();
})->with([
'`name` is required' => [['name' => null], ['name' => 'required']],
'`name` is max 255 characters' => [['name' => Str::random(256)], ['name' => 'max']],
'`email` is a valid email address' => [['email' => Str::random()], ['email' => 'email']],
'`email` is required' => [['email' => null], ['email' => 'required']],
'`email` is max 255 characters' => [['email' => Str::random(256)], ['email' => 'max']],
]);
Тестування сторінки редагування ресурсу
Щоб перевірити, чи завантажується сторінка редагування, протестуйте її як Livewire-компонент і викличте assertOk(), аби переконатися, що HTTP-відповідь була 200 OK. Метод assertSchemaStateSet() перевіряє, чи поля форми мають правильні значення:
use App\Filament\Resources\Users\Pages\EditUser;
use App\Models\User;
it('can load the page', function () {
$user = User::factory()->create();
livewire(EditUser::class, [
'record' => $user->id,
])
->assertOk()
->assertSchemaStateSet([
'name' => $user->name,
'email' => $user->email,
]);
});
Про тестування форми на сторінці редагування читайте в розділі Тестування схем. Про тестування дій у шапці сторінки чи у формі читайте в розділі Тестування дій. Нижче кілька типових прикладів інших тестів, які можна запустити на сторінці редагування.
use App\Filament\Resources\Users\Pages\EditUser;
use App\Models\User;
use function Pest\Laravel\assertDatabaseHas;
it('can update a user', function () {
$user = User::factory()->create();
$newUserData = User::factory()->make();
livewire(EditUser::class, [
'record' => $user->id,
])
->fillForm([
'name' => $newUserData->name,
'email' => $newUserData->email,
])
->call('save')
->assertNotified();
assertDatabaseHas(User::class, [
'id' => $user->id,
'name' => $newUserData->name,
'email' => $newUserData->email,
]);
});
Щоб перевірити, чи форма правильно валідує дані, заповніть поля методом fillForm(), а потім збережіть запис викликом call('save'). Метод assertHasFormErrors() перевіряє наявність помилок форми, а assertNotNotified() - що жодного сповіщення не показано. У цьому прикладі використано набір даних Pest, щоб перевірити кілька правил без дублювання коду тесту:
use App\Filament\Resources\Users\Pages\EditUser;
use App\Models\User;
use Illuminate\Support\Str;
it('validates the form data', function (array $data, array $errors) {
$user = User::factory()->create();
$newUserData = User::factory()->make();
livewire(EditUser::class, [
'record' => $user->id,
])
->fillForm([
'name' => $newUserData->name,
'email' => $newUserData->email,
...$data,
])
->call('save')
->assertHasFormErrors($errors)
->assertNotNotified();
})->with([
'`name` is required' => [['name' => null], ['name' => 'required']],
'`name` is max 255 characters' => [['name' => Str::random(256)], ['name' => 'max']],
'`email` is a valid email address' => [['email' => Str::random()], ['email' => 'email']],
'`email` is required' => [['email' => null], ['email' => 'required']],
'`email` is max 255 characters' => [['email' => Str::random(256)], ['email' => 'max']],
]);
Щоб перевірити, що дія працює, наприклад DeleteAction, викличте дію видалення методом callAction(). Метод assertNotified() перевіряє, чи показалося сповіщення, а assertRedirect() - чи було перенаправлення користувача на іншу сторінку:
use App\Filament\Resources\Users\Pages\EditUser;
use App\Models\User;
use Filament\Actions\DeleteAction;
use function Pest\Laravel\assertDatabaseMissing;
it('can delete a user', function () {
$user = User::factory()->create();
livewire(EditUser::class, [
'record' => $user->id,
])
->callAction(DeleteAction::class)
->assertNotified()
->assertRedirect();
assertDatabaseMissing($user);
});
Тестування сторінки перегляду ресурсу
Щоб перевірити, чи завантажується сторінка перегляду, протестуйте її як Livewire-компонент і викличте assertOk(), аби переконатися, що HTTP-відповідь була 200 OK. Метод assertSchemaStateSet() перевіряє, чи записи infolist мають правильні значення:
use App\Filament\Resources\Users\Pages\ViewUser;
use App\Models\User;
it('can load the page', function () {
$user = User::factory()->create();
livewire(ViewUser::class, [
'record' => $user->id,
])
->assertOk()
->assertSchemaStateSet([
'name' => $user->name,
'email' => $user->email,
]);
});
Про тестування infolist на сторінці перегляду читайте в розділі Тестування схем. Про тестування дій у шапці сторінки чи в infolist читайте в розділі Тестування дій.
Тестування менеджерів звʼязків
Щоб перевірити, чи менеджер звʼязків (relation manager) рендериться на сторінці, наприклад на сторінці редагування ресурсу, скористайтеся методом assertSeeLivewire():
use App\Filament\Resources\Users\Pages\EditUser;
use App\Filament\Resources\Users\RelationManagers\PostsRelationManager;
use App\Models\User;
it('can load the relation manager', function () {
$user = User::factory()->create();
livewire(EditUser::class, [
'record' => $user->id,
])
->assertSeeLivewire(PostsRelationManager::class);
});
Оскільки менеджери звʼязків є Livewire-компонентами, можна тестувати й саму їхню функціональність: чи завантажуються вони успішно з відповіддю 200 OK і чи правильні записи в таблиці. Під час тестування менеджера звʼязків потрібно передати ownerRecord - запис ресурсу, усередині якого ви перебуваєте, і pageClass - клас сторінки, на якій ви перебуваєте:
use App\Filament\Resources\Users\Pages\EditUser;
use App\Filament\Resources\Users\RelationManagers\PostsRelationManager;
use App\Models\Post;
use App\Models\User;
it('can load the relation manager', function () {
$user = User::factory()
->has(Post::factory()->count(5))
->create();
livewire(PostsRelationManager::class, [
'ownerRecord' => $user,
'pageClass' => EditUser::class,
])
->assertOk()
->assertCanSeeTableRecords($user->posts);
});
Пошук, сортування і фільтрацію тестують так само, як на сторінці списку ресурсу.
Можна також тестувати дії, наприклад CreateAction у шапці таблиці:
use App\Filament\Resources\Users\Pages\EditUser;
use App\Filament\Resources\Users\RelationManagers\PostsRelationManager;
use App\Models\Post;
use App\Models\User;
use Filament\Actions\Testing\TestAction;
use function Pest\Laravel\assertDatabaseHas;
it('can create a post', function () {
$user = User::factory()->create();
$newPostData = Post::factory()->make();
livewire(PostsRelationManager::class, [
'ownerRecord' => $user,
'pageClass' => EditUser::class,
])
->callAction(TestAction::make(CreateAction::class)->table(), [
'title' => $newPostData->title,
'content' => $newPostData->content,
])
->assertNotified();
assertDatabaseHas(Post::class, [
'title' => $newPostData->title,
'content' => $newPostData->content,
'user_id' => $user->id,
]);
});
Тестування getFormActions() на сторінках створення / редагування
Коли тестуєте дії з getFormActions() на сторінці ресурсу, використовуйте метод schemaComponent() із ключем form-actions у схемі content. Наприклад, якщо в методі getFormActions() вашої сторінки CreateUser є власна дія Action::make('createAndVerifyEmail'), протестувати її можна так:
use App\Filament\Resources\Users\Pages\CreateUser;
use App\Models\User;
use Filament\Actions\Testing\TestAction;
it('can create a user and verify their email address', function () {
livewire(CreateUser::class)
->fillForm([
'name' => 'Test User',
'email' => 'test@example.com',
])
->callAction(TestAction::make('createAndVerifyEmail')->schemaComponent('form-actions', schema: 'content'));
expect(User::query()->where('email', 'test@example.com')->first())
->hasVerifiedEmail()->toBeTrue();
});
Тестування кількох панелей
Якщо у вас кілька панелей і ви хочете протестувати не ту, що за замовчуванням, потрібно вказати Filament, яку саме панель ви тестуєте. Це можна зробити в методі setUp() тестового класу або на початку конкретного тесту. Зазвичай Filament робить це в middleware, коли ви звертаєтеся до панелі через запит, тож якщо в тесті запиту немає (наприклад, ви тестуєте Livewire-компонент), поточну панель треба встановити вручну:
use Filament\Facades\Filament;
Filament::setCurrentPanel('app'); // Де `app` - це ID панелі, яку ви хочете протестувати.
Тестування мультитенантних панелей
Під час тестування ресурсів у мультитенантних панелях після встановлення тенанта може знадобитися виклик Filament::bootCurrentPanel(), щоб застосувати області видимості тенанта і слухачі подій моделі:
use Filament\Facades\Filament;
$team = Team::factory()->create();
Filament::setTenant($this->team);
Filament::setCurrentPanel('admin');
Filament::bootCurrentPanel();
Перекладаємо з офіційної документації, розділ за розділом, і не ховаємо недоперекладене. Помітили неточність у терміні чи реченні: напишіть, виправимо.