This commit is contained in:
Dan Harrin
2025-04-20 10:57:00 +01:00
parent caed582a2e
commit e3bf27d301
28 changed files with 357 additions and 698 deletions
+2 -2
View File
@@ -1,10 +1,10 @@
---
title: Testing
title: Testing resources
---
## Introduction
All examples in this guide will be written using [Pest](https://pestphp.com). To use Pest's Livewire plugin for testing, you can follow the installation instructions in the Pest documentation on plugins: [Livewire plugin for Pest](https://pestphp.com/docs/plugins#livewire). However, you can easily adapt this to PHPUnit.
All examples in this guide will be written using [Pest](https://pestphp.com). To use Pest's Livewire plugin for testing, you can follow the installation instructions in the Pest documentation on plugins: [Livewire plugin for Pest](https://pestphp.com/docs/plugins#livewire). However, you can easily adapt this to PHPUnit, mostly by switching out the `livewire()` function from Pest with the `Livewire::test()` method.
Since all pages in the app are Livewire components, we're just using Livewire testing helpers everywhere. If you've never tested Livewire components before, please read [this guide](https://livewire.laravel.com/docs/testing) from the Livewire docs.
+3 -296
View File
@@ -4,7 +4,7 @@ title: Testing tables
## Introduction
All examples in this guide will be written using [Pest](https://pestphp.com). To use Pest's Livewire plugin for testing, you can follow the installation instructions in the Pest documentation on plugins: [Livewire plugin for Pest](https://pestphp.com/docs/plugins#livewire). However, you can easily adapt this to PHPUnit.
All examples in this guide will be written using [Pest](https://pestphp.com). To use Pest's Livewire plugin for testing, you can follow the installation instructions in the Pest documentation on plugins: [Livewire plugin for Pest](https://pestphp.com/docs/plugins#livewire). However, you can easily adapt this to PHPUnit, mostly by switching out the `livewire()` function from Pest with the `Livewire::test()` method.
Since the Table Builder works on Livewire components, you can use the [Livewire testing helpers](https://livewire.laravel.com/docs/testing). However, we have many custom testing helpers that you can use for tables:
@@ -175,7 +175,7 @@ it('has an author column', function () {
});
```
You may pass a function as an additional argument in order to assert that a column passes a given "truth test". This is useful for asserting that a column has a specific configuration. You can also pass in a record as the third parameter, which is useful if your check is dependant on which table row is being rendered:
You may pass a function as an additional argument to assert that a column passes a given "truth test". This is useful for asserting that a column has a specific configuration. You can also pass in a record as the third parameter, which is useful if your check is dependant on which table row is being rendered:
```php
use function Pest\Livewire\livewire;
@@ -375,7 +375,7 @@ it('has an author filter', function () {
});
```
You may pass a function as an additional argument in order to assert that a filter passes a given "truth test". This is useful for asserting that a filter has a specific configuration:
You may pass a function as an additional argument to assert that a filter passes a given "truth test". This is useful for asserting that a filter has a specific configuration:
```php
use function Pest\Livewire\livewire;
@@ -389,299 +389,6 @@ it('has an author filter', function () {
});
```
## Actions
### Calling actions
You can call an action by passing its name or class to `callTableAction()`:
```php
use function Pest\Livewire\livewire;
it('can delete posts', function () {
$post = Post::factory()->create();
livewire(PostResource\Pages\ListPosts::class)
->callTableAction(DeleteAction::class, $post);
$this->assertModelMissing($post);
});
```
This example assumes that you have a `DeleteAction` on your table. If you have a custom `Action::make('reorder')`, you may use `callTableAction('reorder')`.
For column actions, you may do the same, using `callTableColumnAction()`:
```php
use function Pest\Livewire\livewire;
it('can copy posts', function () {
$post = Post::factory()->create();
livewire(PostResource\Pages\ListPosts::class)
->callTableColumnAction('copy', $post);
$this->assertDatabaseCount((new Post)->getTable(), 2);
});
```
For bulk actions, you may do the same, passing in multiple records to execute the bulk action against with `callTableBulkAction()`:
```php
use function Pest\Livewire\livewire;
it('can bulk delete posts', function () {
$posts = Post::factory()->count(10)->create();
livewire(PostResource\Pages\ListPosts::class)
->callTableBulkAction(DeleteBulkAction::class, $posts);
foreach ($posts as $post) {
$this->assertModelMissing($post);
}
});
```
To pass an array of data into an action, use the `data` parameter:
```php
use function Pest\Livewire\livewire;
it('can edit posts', function () {
$post = Post::factory()->create();
livewire(PostResource\Pages\ListPosts::class)
->callTableAction(EditAction::class, $post, data: [
'title' => $title = fake()->words(asText: true),
])
->assertHasNoTableActionErrors();
expect($post->refresh())
->title->toBe($title);
});
```
### Execution
To check if an action or bulk action has been halted, you can use `assertTableActionHalted()` / `assertTableBulkActionHalted()`:
```php
use function Pest\Livewire\livewire;
it('will halt delete if post is flagged', function () {
$posts= Post::factory()->count(2)->flagged()->create();
livewire(PostResource\Pages\ListPosts::class)
->callTableAction('delete', $posts->first())
->callTableBulkAction('delete', $posts)
->assertTableActionHalted('delete')
->assertTableBulkActionHalted('delete');
$this->assertModelExists($post);
});
```
### Errors
`assertHasNoTableActionErrors()` is used to assert that no validation errors occurred when submitting the action form.
To check if a validation error has occurred with the data, use `assertHasTableActionErrors()`, similar to `assertHasErrors()` in Livewire:
```php
use function Pest\Livewire\livewire;
it('can validate edited post data', function () {
$post = Post::factory()->create();
livewire(PostResource\Pages\ListPosts::class)
->callTableAction(EditAction::class, $post, data: [
'title' => null,
])
->assertHasTableActionErrors(['title' => ['required']]);
});
```
For bulk actions these methods are called `assertHasTableBulkActionErrors()` and `assertHasNoTableBulkActionErrors()`.
### Pre-filled data
To check if an action or bulk action is pre-filled with data, you can use the `assertTableActionDataSet()` or `assertTableBulkActionDataSet()` method:
```php
use function Pest\Livewire\livewire;
it('can load existing post data for editing', function () {
$post = Post::factory()->create();
livewire(PostResource\Pages\ListPosts::class)
->mountTableAction(EditAction::class, $post)
->assertTableActionDataSet([
'title' => $post->title,
])
->setTableActionData([
'title' => $title = fake()->words(asText: true),
])
->callMountedTableAction()
->assertHasNoTableActionErrors();
expect($post->refresh())
->title->toBe($title);
});
```
You may also find it useful to pass a function to the `assertTableActionDataSet()` and `assertTableBulkActionDataSet()` methods, which allow you to access the form `$state` and perform additional assertions:
```php
use Illuminate\Support\Str;
use function Pest\Livewire\livewire;
it('can automatically generate a slug from the title without any spaces', function () {
$post = Post::factory()->create();
livewire(PostResource\Pages\ListPosts::class)
->mountTableAction(EditAction::class, $post)
->assertTableActionDataSet(function (array $state) use ($post): array {
expect($state['slug'])
->not->toContain(' ');
return [
'slug' => Str::slug($post->title),
];
});
});
```
### Action state
To ensure that an action or bulk action exists or doesn't in a table, you can use the `assertTableActionExists()` / `assertTableActionDoesNotExist()` or `assertTableBulkActionExists()` / `assertTableBulkActionDoesNotExist()` method:
```php
use function Pest\Livewire\livewire;
it('can publish but not unpublish posts', function () {
livewire(PostResource\Pages\ListPosts::class)
->assertTableActionExists('publish')
->assertTableActionDoesNotExist('unpublish')
->assertTableBulkActionExists('publish')
->assertTableBulkActionDoesNotExist('unpublish');
});
```
To ensure different sets of actions exist in the correct order, you can use the various "InOrder" assertions
```php
use function Pest\Livewire\livewire;
it('has all actions in expected order', function () {
livewire(PostResource\Pages\ListPosts::class)
->assertTableActionsExistInOrder(['edit', 'delete'])
->assertTableBulkActionsExistInOrder(['restore', 'forceDelete'])
->assertTableHeaderActionsExistInOrder(['create', 'attach'])
->assertTableEmptyStateActionsExistInOrder(['create', 'toggle-trashed-filter'])
});
```
To ensure that an action or bulk action is enabled or disabled for a user, you can use the `assertTableActionEnabled()` / `assertTableActionDisabled()` or `assertTableBulkActionEnabled()` / `assertTableBulkActionDisabled()` methods:
```php
use function Pest\Livewire\livewire;
it('can not publish, but can delete posts', function () {
$post = Post::factory()->create();
livewire(PostResource\Pages\ListPosts::class)
->assertTableActionDisabled('publish', $post)
->assertTableActionEnabled('delete', $post)
->assertTableBulkActionDisabled('publish')
->assertTableBulkActionEnabled('delete');
});
```
To ensure that an action or bulk action is visible or hidden for a user, you can use the `assertTableActionVisible()` / `assertTableActionHidden()` or `assertTableBulkActionVisible()` / `assertTableBulkActionHidden()` methods:
```php
use function Pest\Livewire\livewire;
it('can not publish, but can delete posts', function () {
$post = Post::factory()->create();
livewire(PostResource\Pages\ListPosts::class)
->assertTableActionHidden('publish', $post)
->assertTableActionVisible('delete', $post)
->assertTableBulkActionHidden('publish')
->assertTableBulkActionVisible('delete');
});
```
### Button Style
To ensure an action or bulk action has the correct label, you can use `assertTableActionHasLabel()` / `assertTableBulkActionHasLabel()` and `assertTableActionDoesNotHaveLabel()` / `assertTableBulkActionDoesNotHaveLabel()`:
```php
use function Pest\Livewire\livewire;
it('delete actions have correct labels', function () {
$post = Post::factory()->create();
livewire(PostResource\Pages\ListPosts::class)
->assertTableActionHasLabel('delete', 'Archive Post')
->assertTableActionDoesNotHaveLabel('delete', 'Delete');
->assertTableBulkActionHasLabel('delete', 'Archive Post')
->assertTableBulkActionDoesNotHaveLabel('delete', 'Delete');
});
```
To ensure an action or bulk action's button is showing the correct icon, you can use `assertTableActionHasIcon()` / `assertTableBulkActionHasIcon()` or `assertTableActionDoesNotHaveIcon()` / `assertTableBulkActionDoesNotHaveIcon()`:
```php
use function Pest\Livewire\livewire;
it('delete actions have correct icons', function () {
$post = Post::factory()->create();
livewire(PostResource\Pages\ListPosts::class)
->assertTableActionHasIcon('delete', 'heroicon-m-archive-box')
->assertTableActionDoesNotHaveIcon('delete', 'heroicon-m-trash');
->assertTableBulkActionHasIcon('delete', 'heroicon-m-archive-box')
->assertTableBulkActionDoesNotHaveIcon('delete', 'heroicon-m-trash');
});
```
To ensure that an action or bulk action's button is displaying the right color, you can use `assertTableActionHasColor()` / `assertTableBulkActionHasColor()` or `assertTableActionDoesNotHaveColor()` / `assertTableBulkActionDoesNotHaveColor()`:
```php
use function Pest\Livewire\livewire;
it('delete actions have correct colors', function () {
$post = Post::factory()->create();
livewire(PostResource\Pages\ListPosts::class)
->assertTableActionHasColor('delete', 'warning')
->assertTableActionDoesNotHaveColor('delete', 'danger');
->assertTableBulkActionHasColor('delete', 'warning')
->assertTableBulkActionDoesNotHaveColor('delete', 'danger');
});
```
### URL
To ensure an action or bulk action has the correct URL traits, you can use `assertTableActionHasUrl()`, `assertTableActionDoesNotHaveUrl()`, `assertTableActionShouldOpenUrlInNewTab()`, and `assertTableActionShouldNotOpenUrlInNewTab()`:
```php
use function Pest\Livewire\livewire;
it('links to the correct Filament sites', function () {
$post = Post::factory()->create();
livewire(PostResource\Pages\ListPosts::class)
->assertTableActionHasUrl('filament', 'https://filamentphp.com/')
->assertTableActionDoesNotHaveUrl('filament', 'https://github.com/filamentphp/filament')
->assertTableActionShouldOpenUrlInNewTab('filament')
->assertTableActionShouldNotOpenUrlInNewTab('github');
});
```
## Summaries
To test that a summary calculation is working, you may use the `assertTableColumnSummarySet()` method:
@@ -1,10 +1,10 @@
---
title: Testing schemas
title: Testing forms
---
## Introduction
All examples in this guide will be written using [Pest](https://pestphp.com). To use Pest's Livewire plugin for testing, you can follow the installation instructions in the Pest documentation on plugins: [Livewire plugin for Pest](https://pestphp.com/docs/plugins#livewire). However, you can easily adapt this to PHPUnit.
All examples in this guide will be written using [Pest](https://pestphp.com). To use Pest's Livewire plugin for testing, you can follow the installation instructions in the Pest documentation on plugins: [Livewire plugin for Pest](https://pestphp.com/docs/plugins#livewire). However, you can easily adapt this to PHPUnit, mostly by switching out the `livewire()` function from Pest with the `Livewire::test()` method.
Since the Form Builder works on Livewire components, you can use the [Livewire testing helpers](https://livewire.laravel.com/docs/testing). However, we have custom testing helpers that you can use with forms:
@@ -132,7 +132,7 @@ it('has a title field', function () {
});
```
You may pass a function as an additional argument in order to assert that a field passes a given "truth test". This is useful for asserting that a field has a specific configuration:
You may pass a function as an additional argument to assert that a field passes a given "truth test". This is useful for asserting that a field has a specific configuration:
```php
use function Pest\Livewire\livewire;
@@ -335,264 +335,3 @@ it('moves to next wizard step only for fooForm', function () {
->assertHasFormErrors(['title'], formName: 'fooForm');
});
```
## Actions
You can call an action by passing its form component name, and then the name of the action to `callFormComponentAction()`:
```php
use function Pest\Livewire\livewire;
it('can send invoices', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callFormComponentAction('customer_id', 'send');
expect($invoice->refresh())
->isSent()->toBeTrue();
});
```
To pass an array of data into an action, use the `data` parameter:
```php
use function Pest\Livewire\livewire;
it('can send invoices', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callFormComponentAction('customer_id', 'send', data: [
'email' => $email = fake()->email(),
])
->assertHasNoFormComponentActionErrors();
expect($invoice->refresh())
->isSent()->toBeTrue()
->recipient_email->toBe($email);
});
```
If you ever need to only set an action's data without immediately calling it, you can use `setFormComponentActionData()`:
```php
use function Pest\Livewire\livewire;
it('can send invoices', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->mountAction('customer_id', 'send')
->setFormComponentActionData([
'email' => $email = fake()->email(),
])
});
```
### Execution
To check if an action has been halted, you can use `assertFormComponentActionHalted()`:
```php
use function Pest\Livewire\livewire;
it('stops sending if invoice has no email address', function () {
$invoice = Invoice::factory(['email' => null])->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callFormComponentAction('customer_id', 'send')
->assertFormComponentActionHalted('customer_id', 'send');
});
```
### Errors
`assertHasNoFormComponentActionErrors()` is used to assert that no validation errors occurred when submitting the action form.
To check if a validation error has occurred with the data, use `assertHasFormComponentActionErrors()`, similar to `assertHasErrors()` in Livewire:
```php
use function Pest\Livewire\livewire;
it('can validate invoice recipient email', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->callFormComponentAction('customer_id', 'send', data: [
'email' => Str::random(),
])
->assertHasFormComponentActionErrors(['email' => ['email']]);
});
```
To check if an action is pre-filled with data, you can use the `assertFormComponentActionDataSet()` method:
```php
use function Pest\Livewire\livewire;
it('can send invoices to the primary contact by default', function () {
$invoice = Invoice::factory()->create();
$recipientEmail = $invoice->company->primaryContact->email;
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->mountAction('customer_id', 'send')
->assertFormComponentActionDataSet([
'email' => $recipientEmail,
])
->callMountedAction()
->assertHasNoFormComponentActionErrors();
expect($invoice->refresh())
->isSent()->toBeTrue()
->recipient_email->toBe($recipientEmail);
});
```
### Action state
To ensure that an action exists or doesn't in a form, you can use the `assertFormComponentActionExists()` or `assertFormComponentActionDoesNotExist()` method:
```php
use function Pest\Livewire\livewire;
it('can send but not unsend invoices', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionExists('customer_id', 'send')
->assertFormComponentActionDoesNotExist('customer_id', 'unsend');
});
```
To ensure an action is hidden or visible for a user, you can use the `assertFormComponentActionHidden()` or `assertFormComponentActionVisible()` methods:
```php
use function Pest\Livewire\livewire;
it('can only print customers', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionHidden('customer_id', 'send')
->assertFormComponentActionVisible('customer_id', 'print');
});
```
To ensure an action is enabled or disabled for a user, you can use the `assertFormComponentActionEnabled()` or `assertFormComponentActionDisabled()` methods:
```php
use function Pest\Livewire\livewire;
it('can only print a customer for a sent invoice', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionDisabled('customer_id', 'send')
->assertFormComponentActionEnabled('customer_id', 'print');
});
```
To check if an action is hidden to a user, you can use the `assertFormComponentActionHidden()` method:
```php
use function Pest\Livewire\livewire;
it('can not send invoices', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionHidden('customer_id', 'send');
});
```
### Button appearance
To ensure an action has the correct label, you can use `assertFormComponentActionHasLabel()` and `assertFormComponentActionDoesNotHaveLabel()`:
```php
use function Pest\Livewire\livewire;
it('send action has correct label', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionHasLabel('customer_id', 'send', 'Email Invoice')
->assertFormComponentActionDoesNotHaveLabel('customer_id', 'send', 'Send');
});
```
To ensure an action's button is showing the correct icon, you can use `assertFormComponentActionHasIcon()` or `assertFormComponentActionDoesNotHaveIcon()`:
```php
use function Pest\Livewire\livewire;
it('when enabled the send button has correct icon', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionEnabled('customer_id', 'send')
->assertFormComponentActionHasIcon('customer_id', 'send', 'envelope-open')
->assertFormComponentActionDoesNotHaveIcon('customer_id', 'send', 'envelope');
});
```
To ensure that an action's button is displaying the right color, you can use `assertFormComponentActionHasColor()` or `assertFormComponentActionDoesNotHaveColor()`:
```php
use function Pest\Livewire\livewire;
it('actions display proper colors', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionHasColor('customer_id', 'delete', 'danger')
->assertFormComponentActionDoesNotHaveColor('customer_id', 'print', 'danger');
});
```
### URL
To ensure an action has the correct URL, you can use `assertFormComponentActionHasUrl()`, `assertFormComponentActionDoesNotHaveUrl()`, `assertFormComponentActionShouldOpenUrlInNewTab()`, and `assertFormComponentActionShouldNotOpenUrlInNewTab()`:
```php
use function Pest\Livewire\livewire;
it('links to the correct Filament sites', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertFormComponentActionHasUrl('customer_id', 'filament', 'https://filamentphp.com/')
->assertFormComponentActionDoesNotHaveUrl('customer_id', 'filament', 'https://github.com/filamentphp/filament')
->assertFormComponentActionShouldOpenUrlInNewTab('customer_id', 'filament')
->assertFormComponentActionShouldNotOpenUrlInNewTab('customer_id', 'github');
});
```
+170 -1
View File
@@ -4,7 +4,7 @@ title: Testing actions
## Introduction
All examples in this guide will be written using [Pest](https://pestphp.com). To use Pest's Livewire plugin for testing, you can follow the installation instructions in the Pest documentation on plugins: [Livewire plugin for Pest](https://pestphp.com/docs/plugins#livewire). However, you can easily adapt this to PHPUnit.
All examples in this guide will be written using [Pest](https://pestphp.com). To use Pest's Livewire plugin for testing, you can follow the installation instructions in the Pest documentation on plugins: [Livewire plugin for Pest](https://pestphp.com/docs/plugins#livewire). However, you can easily adapt this to PHPUnit, mostly by switching out the `livewire()` function from Pest with the `Livewire::test()` method.
Since all actions are mounted to a Livewire component, we're just using Livewire testing helpers everywhere. If you've never tested Livewire components before, please read [this guide](https://livewire.laravel.com/docs/testing) from the Livewire docs.
@@ -170,6 +170,26 @@ it('can send but not unsend invoices', function () {
});
```
You may pass a function as an additional argument to assert that an action passes a given "truth test". This is useful for asserting that an action has a specific configuration:
```php
use Filament\Actions\Action;
use function Pest\Livewire\livewire;
it('has the correct description', function () {
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class, [
'invoice' => $invoice,
])
->assertActionExists('send', function (Action $action): bool {
return $action->getModalDescription() === 'This will send an email to the customer\'s primary address, with the invoice attached as a PDF';
});
});
```
### Hidden actions
To ensure an action is hidden or visible for a user, you can use the `assertActionHidden()` or `assertActionVisible()` methods:
```php
@@ -186,6 +206,8 @@ it('can only print invoices', function () {
});
```
### Disabled actions
To ensure an action is enabled or disabled for a user, you can use the `assertActionEnabled()` or `assertActionDisabled()` methods:
```php
@@ -302,3 +324,150 @@ it('links to the correct Filament sites', function () {
->assertActionShouldNotOpenUrlInNewTab('github');
});
```
## Testing table actions
To test table actions, you can use a `TestAction` object with the `table()` method. This object receives the name of the action you want to test, and replaces the name of the action in any testing method you want to use. For example:
```php
use Filament\Actions\Testing\TestAction;use function Pest\Livewire\livewire;
$invoice = Invoice::factory()->create();
livewire(ListInvoices::class)
->callAction(TestAction::make('send')->table($invoice));
livewire(ListInvoices::class)
->assertActionVisible(TestAction::make('send')->table($invoice))
livewire(ListInvoices::class)
->assertActionExists(TestAction::make('send')->table($invoice))
```
### Testing table header actions
To test a header action, you can use the `table()` method without passing in a specific record to test with:
```php
use Filament\Actions\Testing\TestAction;use function Pest\Livewire\livewire;
livewire(ListInvoices::class)
->callAction(TestAction::make('create')->table());
livewire(ListInvoices::class)
->assertActionVisible(TestAction::make('create')->table())
livewire(ListInvoices::class)
->assertActionExists(TestAction::make('create')->table())
```
### Testing table bulk actions
To test a bulk action, first call `selectTableRecords()` and pass in any records you want to select. Then, use the `TestAction`'s `bulk()` method to specify the action you want to test. For example:
```php
use Filament\Actions\Testing\TestAction;use function Pest\Livewire\livewire;
$invoices = Invoice::factory()->count(3)->create();
livewire(ListInvoices::class)
->selectTableRecords($invoices->pluck('id')->toArray())
->callAction(TestAction::make('send')->table()->bulk());
livewire(ListInvoices::class)
->assertActionVisible(TestAction::make('send')->table()->bulk())
livewire(ListInvoices::class)
->assertActionExists(TestAction::make('send')->table()->bulk())
```
## Testing resource form component actions
If an action belongs to a component in a resource's form, for example, if it is in the `belowContent()` method of a form field, you can use the `TestAction` object with the `schemaComponent()` method. This object receives the name of the action you want to test and replaces the name of the action in any testing method you want to use. The `schemaComponent()` method should receive a `TestSchemaComponent::inResourceForm()` object, which accepts the name of the form component you want to test. For example:
```php
use Filament\Actions\Testing\TestAction;
use Filament\Schemas\Testing\TestSchemaComponent;
use function Pest\Livewire\livewire;
$invoice = Invoice::factory()->create();
livewire(EditInvoice::class)
->callAction(TestAction::make('send')->schemaComponent(TestSchemaComponent::inResourceForm('customer_id')));
livewire(EditInvoice::class)
->assertActionVisible(TestAction::make('send')->schemaComponent(TestSchemaComponent::inResourceForm('customer_id')))
livewire(EditInvoice::class)
->assertActionExists(TestAction::make('send')->schemaComponent(TestSchemaComponent::inResourceForm('customer_id')))
```
## Testing resource infolist component actions
If an action belongs to a component in a resource's infolist, for example, if it is in the `belowContent()` method of an infolist entry, you can use the `TestAction` object with the `schemaComponent()` method. This object receives the name of the action you want to test and replaces the name of the action in any testing method you want to use. The `schemaComponent()` method should receive a `TestSchemaComponent::inResourceInfolist()` object, which accepts the name of the infolist component you want to test. For example:
```php
use Filament\Actions\Testing\TestAction;
use Filament\Schemas\Testing\TestSchemaComponent;
use function Pest\Livewire\livewire;
$invoice = Invoice::factory()->create();
livewire(ViewInvoice::class)
->callAction(TestAction::make('send')->schemaComponent(TestSchemaComponent::inResourceInfolist('customer.name')));
livewire(ViewInvoice::class)
->assertActionVisible(TestAction::make('send')->schemaComponent(TestSchemaComponent::inResourceInfolist('customer.name')))
livewire(ViewInvoice::class)
->assertActionExists(TestAction::make('send')->schemaComponent(TestSchemaComponent::inResourceInfolist('customer.name')))
```
## Testing actions inside another action's schema / form
If an action belongs to a component in another action's `schema()` (or `form()`), for example, if it is in the `belowContent()` method of a form field in an action modal, you can use the `TestAction` object with the `schemaComponent()` method. This object receives the name of the action you want to test and replaces the name of the action in any testing method you want to use. The `schemaComponent()` method should receive a `TestSchemaComponent::inActionSchema()` object, which accepts the name of the action component you want to test. You should pass an array of `TestAction` objects in order, for example:
```php
use Filament\Actions\Testing\TestAction;
use Filament\Schemas\Testing\TestSchemaComponent;
use function Pest\Livewire\livewire;
$invoice = Invoice::factory()->create();
livewire(ManageInvoices::class)
->callAction([
TestAction::make('view')->table($invoice),
TestAction::make('send')->schemaComponent(TestSchemaComponent::inActionSchema('customer.name')),
]);
livewire(ManageInvoices::class)
->assertActionVisible([
TestAction::make('view')->table($invoice),
TestAction::make('send')->schemaComponent(TestSchemaComponent::inActionSchema('customer.name')),
]);
livewire(ManageInvoices::class)
->assertActionExists([
TestAction::make('view')->table($invoice),
TestAction::make('send')->schemaComponent(TestSchemaComponent::inActionSchema('customer.name')),
]);
```
## Testing action arguments
To test action arguments, you can use a `TestAction` object with the `arguments()` method. This object receives the name of the action you want to test and replaces the name of the action in any testing method you want to use. For example:
```php
use Filament\Actions\Testing\TestAction;use function Pest\Livewire\livewire;
$invoice = Invoice::factory()->create();
livewire(ManageInvoices::class)
->callAction(TestAction::make('send')->arguments(['invoice' => $invoice->getKey()]));
livewire(ManageInvoices::class)
->assertActionVisible(TestAction::make('send')->arguments(['invoice' => $invoice->getKey()]))
livewire(ManageInvoices::class)
->assertActionExists(TestAction::make('send')->arguments(['invoice' => $invoice->getKey()]))
```
+1 -1
View File
@@ -4,7 +4,7 @@ title: Testing notifications
## Introduction
All examples in this guide will be written using [Pest](https://pestphp.com). To use Pest's Livewire plugin for testing, you can follow the installation instructions in the Pest documentation on plugins: [Livewire plugin for Pest](https://pestphp.com/docs/plugins#livewire). However, you can easily adapt this to PHPUnit.
All examples in this guide will be written using [Pest](https://pestphp.com). To use Pest's Livewire plugin for testing, you can follow the installation instructions in the Pest documentation on plugins: [Livewire plugin for Pest](https://pestphp.com/docs/plugins#livewire). However, you can easily adapt this to PHPUnit, mostly by switching out the `livewire()` function from Pest with the `Livewire::test()` method.
## Testing session notifications
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Livewire\Features\SupportTesting {
use BackedEnum;
use Closure;
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
class Testable {
public function mountAction(string | TestAction | array $actions, array $arguments = []): static {}
@@ -1,9 +1,11 @@
<?php
namespace Filament\Actions\Testing\Fixtures;
namespace Filament\Actions\Testing;
use Closure;
use Filament\Support\ArrayRecord;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Database\Eloquent\Model;
class TestAction implements Arrayable
{
@@ -96,7 +98,13 @@ class TestAction implements Arrayable
return $array;
}
$array['context']['recordKey'] = $this->table;
if ($this->table instanceof Model) {
$array['context']['recordKey'] = $this->table->getKey();
} elseif (is_array($this->table)) {
$array['context']['recordKey'] = $this->table[ArrayRecord::getKeyName()] ?? null;
} else {
$array['context']['recordKey'] = $this->table;
}
return $array;
}
@@ -9,7 +9,6 @@ use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Actions\Contracts\HasActions;
use Filament\Actions\Exceptions\ActionNotResolvableException;
use Filament\Actions\Testing\Fixtures\TestAction;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Testing\Assert;
+71 -71
View File
@@ -25,14 +25,14 @@ class TestsForms
{
public function fillForm(): Closure
{
return function (array | Closure $state = [], string $formName = 'form'): static {
return function (array | Closure $state = [], string $schemaName = 'form'): static {
/** @phpstan-ignore-next-line */
$this->assertFormExists($formName);
$this->assertFormExists($schemaName);
$livewire = $this->instance();
/** @var Schema $form */
$form = $livewire->{$formName};
$form = $livewire->{$schemaName};
$formStatePath = $form->getStatePath();
@@ -67,14 +67,14 @@ class TestsForms
public function assertFormSet(): Closure
{
return function (array | Closure $state, string $formName = 'form'): static {
return function (array | Closure $state, string $schemaName = 'form'): static {
/** @phpstan-ignore-next-line */
$this->assertFormExists($formName);
$this->assertFormExists($schemaName);
$livewire = $this->instance();
/** @var Schema $form */
$form = $livewire->{$formName};
$form = $livewire->{$schemaName};
$formStatePath = $form->getStatePath();
@@ -94,14 +94,14 @@ class TestsForms
public function assertHasFormErrors(): Closure
{
return function (array $keys = [], string $formName = 'form'): static {
return function (array $keys = [], string $schemaName = 'form'): static {
/** @phpstan-ignore-next-line */
$this->assertFormExists($formName);
$this->assertFormExists($schemaName);
$livewire = $this->instance();
/** @var Schema $form */
$form = $livewire->{$formName};
$form = $livewire->{$schemaName};
$formStatePath = $form->getStatePath();
@@ -123,14 +123,14 @@ class TestsForms
public function assertHasNoFormErrors(): Closure
{
return function (array $keys = [], string $formName = 'form'): static {
return function (array $keys = [], string $schemaName = 'form'): static {
/** @phpstan-ignore-next-line */
$this->assertFormExists($formName);
$this->assertFormExists($schemaName);
$livewire = $this->instance();
/** @var Schema $form */
$form = $livewire->{$formName};
$form = $livewire->{$schemaName};
$formStatePath = $form->getStatePath();
@@ -170,17 +170,17 @@ class TestsForms
public function assertFormComponentExists(): Closure
{
return function (string $componentKey, string | Closure $formName = 'form', ?Closure $checkComponentUsing = null): static {
if ($formName instanceof Closure) {
$checkComponentUsing = $formName;
$formName = 'form';
return function (string $componentKey, string | Closure $schemaName = 'form', ?Closure $checkComponentUsing = null): static {
if ($schemaName instanceof Closure) {
$checkComponentUsing = $schemaName;
$schemaName = 'form';
}
/** @phpstan-ignore-next-line */
$this->assertFormExists($formName);
$this->assertFormExists($schemaName);
/** @var Schema $form */
$form = $this->instance()->{$formName};
$form = $this->instance()->{$schemaName};
/** @var Component | Action | null $component */
$component = $form->getFlatComponents(withHidden: true)[$componentKey] ?? null;
@@ -190,13 +190,13 @@ class TestsForms
Assert::assertInstanceOf(
Component::class,
$component,
"Failed asserting that a component with the key [{$componentKey}] exists on the form with the name [{$formName}] on the [{$livewireClass}] component."
"Failed asserting that a component with the key [{$componentKey}] exists on the form with the name [{$schemaName}] on the [{$livewireClass}] component."
);
if ($checkComponentUsing) {
Assert::assertTrue(
$checkComponentUsing($component),
"Failed asserting that a component with the key [{$componentKey}] and provided configuration exists on the form with the name [{$formName}] on the [{$livewireClass}] component."
"Failed asserting that a component with the key [{$componentKey}] and provided configuration exists on the form with the name [{$schemaName}] on the [{$livewireClass}] component."
);
}
@@ -206,9 +206,9 @@ class TestsForms
public function assertFormComponentDoesNotExist(): Closure
{
return function (string $componentKey, string $formName = 'form'): static {
return function (string $componentKey, string $schemaName = 'form'): static {
/** @var Schema $form */
$form = $this->instance()->{$formName};
$form = $this->instance()->{$schemaName};
$components = $form->getFlatComponents(withHidden: true);
@@ -217,7 +217,7 @@ class TestsForms
Assert::assertArrayNotHasKey(
$componentKey,
$components,
"Failed asserting that a component with the key [{$componentKey}] does not exist on the form named [{$formName}] on the [{$livewireClass}] component."
"Failed asserting that a component with the key [{$componentKey}] does not exist on the form named [{$schemaName}] on the [{$livewireClass}] component."
);
return $this;
@@ -226,17 +226,17 @@ class TestsForms
public function assertFormFieldExists(): Closure
{
return function (string $fieldName, string | Closure $formName = 'form', ?Closure $checkFieldUsing = null): static {
if ($formName instanceof Closure) {
$checkFieldUsing = $formName;
$formName = 'form';
return function (string $fieldName, string | Closure $schemaName = 'form', ?Closure $checkFieldUsing = null): static {
if ($schemaName instanceof Closure) {
$checkFieldUsing = $schemaName;
$schemaName = 'form';
}
/** @phpstan-ignore-next-line */
$this->assertFormExists($formName);
$this->assertFormExists($schemaName);
/** @var Schema $form */
$form = $this->instance()->{$formName};
$form = $this->instance()->{$schemaName};
/** @var ?Field $field */
$field = $form->getFlatFields(withHidden: true)[$fieldName] ?? null;
@@ -246,13 +246,13 @@ class TestsForms
Assert::assertInstanceOf(
Field::class,
$field,
"Failed asserting that a field with the name [{$fieldName}] exists on the form with the name [{$formName}] on the [{$livewireClass}] component."
"Failed asserting that a field with the name [{$fieldName}] exists on the form with the name [{$schemaName}] on the [{$livewireClass}] component."
);
if ($checkFieldUsing) {
Assert::assertTrue(
$checkFieldUsing($field),
"Failed asserting that a field with the name [{$fieldName}] and provided configuration exists on the form with the name [{$formName}] on the [{$livewireClass}] component."
"Failed asserting that a field with the name [{$fieldName}] and provided configuration exists on the form with the name [{$schemaName}] on the [{$livewireClass}] component."
);
}
@@ -262,9 +262,9 @@ class TestsForms
public function assertFormFieldDoesNotExist(): Closure
{
return function (string $fieldName, string $formName = 'form'): static {
return function (string $fieldName, string $schemaName = 'form'): static {
/** @var Schema $form */
$form = $this->instance()->{$formName};
$form = $this->instance()->{$schemaName};
$fields = $form->getFlatFields(withHidden: false);
@@ -273,7 +273,7 @@ class TestsForms
Assert::assertArrayNotHasKey(
$fieldName,
$fields,
"Failed asserting that a field with the name [{$fieldName}] does not exist on the form named [{$formName}] on the [{$livewireClass}] component."
"Failed asserting that a field with the name [{$fieldName}] does not exist on the form named [{$schemaName}] on the [{$livewireClass}] component."
);
return $this;
@@ -282,12 +282,12 @@ class TestsForms
public function assertFormFieldDisabled(): Closure
{
return function (string $fieldName, string $formName = 'form'): static {
return function (string $fieldName, string $schemaName = 'form'): static {
/** @phpstan-ignore-next-line */
$this->assertFormFieldExists($fieldName, $formName);
$this->assertFormFieldExists($fieldName, $schemaName);
/** @var Schema $form */
$form = $this->instance()->{$formName};
$form = $this->instance()->{$schemaName};
/** @var Field $field */
$field = $form->getFlatFields(withHidden: true)[$fieldName];
@@ -295,10 +295,10 @@ class TestsForms
$livewireClass = $this->instance()::class;
/** @phpstan-ignore-next-line */
$this->assertFormFieldExists($fieldName, $formName, function (Field $field) use ($fieldName, $formName, $livewireClass): bool {
$this->assertFormFieldExists($fieldName, $schemaName, function (Field $field) use ($fieldName, $schemaName, $livewireClass): bool {
Assert::assertTrue(
$field->isDisabled(),
"Failed asserting that a field with the name [{$fieldName}] is disabled on the form named [{$formName}] on the [{$livewireClass}] component."
"Failed asserting that a field with the name [{$fieldName}] is disabled on the form named [{$schemaName}] on the [{$livewireClass}] component."
);
return true;
@@ -318,12 +318,12 @@ class TestsForms
public function assertFormFieldEnabled(): Closure
{
return function (string $fieldName, string $formName = 'form'): static {
return function (string $fieldName, string $schemaName = 'form'): static {
/** @phpstan-ignore-next-line */
$this->assertFormFieldExists($fieldName, $formName);
$this->assertFormFieldExists($fieldName, $schemaName);
/** @var Schema $form */
$form = $this->instance()->{$formName};
$form = $this->instance()->{$schemaName};
/** @var Field $field */
$field = $form->getFlatFields(withHidden: true)[$fieldName];
@@ -331,10 +331,10 @@ class TestsForms
$livewireClass = $this->instance()::class;
/** @phpstan-ignore-next-line */
$this->assertFormFieldExists($fieldName, $formName, function (Field $field) use ($fieldName, $formName, $livewireClass): bool {
$this->assertFormFieldExists($fieldName, $schemaName, function (Field $field) use ($fieldName, $schemaName, $livewireClass): bool {
Assert::assertFalse(
$field->isDisabled(),
"Failed asserting that a field with the name [{$fieldName}] is enabled on the form named [{$formName}] on the [{$livewireClass}] component."
"Failed asserting that a field with the name [{$fieldName}] is enabled on the form named [{$schemaName}] on the [{$livewireClass}] component."
);
return true;
@@ -354,12 +354,12 @@ class TestsForms
public function assertFormFieldReadOnly(): Closure
{
return function (string $fieldName, string $formName = 'form'): static {
return function (string $fieldName, string $schemaName = 'form'): static {
/** @phpstan-ignore-next-line */
$this->assertFormFieldExists($fieldName, $formName);
$this->assertFormFieldExists($fieldName, $schemaName);
/** @var Schema $form */
$form = $this->instance()->{$formName};
$form = $this->instance()->{$schemaName};
/** @var TextInput $field */
$field = $form->getFlatFields(withHidden: true)[$fieldName];
@@ -368,7 +368,7 @@ class TestsForms
Assert::assertTrue(
$field->isReadOnly(),
"Failed asserting that a field with the name [{$fieldName}] is read-only on the form named [{$formName}] on the [{$livewireClass}] component."
"Failed asserting that a field with the name [{$fieldName}] is read-only on the form named [{$schemaName}] on the [{$livewireClass}] component."
);
return $this;
@@ -385,12 +385,12 @@ class TestsForms
public function assertFormFieldHidden(): Closure
{
return function (string $fieldName, string $formName = 'form'): static {
return function (string $fieldName, string $schemaName = 'form'): static {
/** @phpstan-ignore-next-line */
$this->assertFormFieldExists($fieldName, $formName);
$this->assertFormFieldExists($fieldName, $schemaName);
/** @var Schema $form */
$form = $this->instance()->{$formName};
$form = $this->instance()->{$schemaName};
$fields = $form->getFlatFields(withHidden: false);
@@ -399,7 +399,7 @@ class TestsForms
Assert::assertArrayNotHasKey(
$fieldName,
$fields,
"Failed asserting that a field with the name [{$fieldName}] is hidden on the form named [{$formName}] on the [{$livewireClass}] component."
"Failed asserting that a field with the name [{$fieldName}] is hidden on the form named [{$schemaName}] on the [{$livewireClass}] component."
);
return $this;
@@ -416,12 +416,12 @@ class TestsForms
public function assertFormFieldVisible(): Closure
{
return function (string $fieldName, string $formName = 'form'): static {
return function (string $fieldName, string $schemaName = 'form'): static {
/** @phpstan-ignore-next-line */
$this->assertFormFieldExists($fieldName, $formName);
$this->assertFormFieldExists($fieldName, $schemaName);
/** @var Schema $form */
$form = $this->instance()->{$formName};
$form = $this->instance()->{$schemaName};
$fields = $form->getFlatFields(withHidden: false);
@@ -430,7 +430,7 @@ class TestsForms
Assert::assertArrayHasKey(
$fieldName,
$fields,
"Failed asserting that a field with the name [{$fieldName}] is visible on the form named [{$formName}] on the [{$livewireClass}] component."
"Failed asserting that a field with the name [{$fieldName}] is visible on the form named [{$schemaName}] on the [{$livewireClass}] component."
);
return $this;
@@ -447,12 +447,12 @@ class TestsForms
public function assertWizardStepExists(): Closure
{
return function (int $step, string $formName = 'form'): static {
return function (int $step, string $schemaName = 'form'): static {
/** @phpstan-ignore-next-line */
$this->assertFormExists($formName);
$this->assertFormExists($schemaName);
/** @var Schema $form */
$form = $this->instance()->{$formName};
$form = $this->instance()->{$schemaName};
/** @var Wizard $wizard */
$wizard = $form->getComponent(fn (Component | Action | ActionGroup $component): bool => $component instanceof Wizard);
@@ -468,12 +468,12 @@ class TestsForms
public function assertWizardCurrentStep(): Closure
{
return function (int $step, string $formName = 'form'): static {
return function (int $step, string $schemaName = 'form'): static {
/** @phpstan-ignore-next-line */
$this->assertFormExists($formName);
$this->assertFormExists($schemaName);
/** @var Schema $form */
$form = $this->instance()->{$formName};
$form = $this->instance()->{$schemaName};
/** @var Wizard $wizard */
$wizard = $form->getComponent(fn (Component | Action | ActionGroup $component): bool => $component instanceof Wizard);
@@ -489,12 +489,12 @@ class TestsForms
public function goToWizardStep(): Closure
{
return function (int $step, string $formName = 'form'): static {
return function (int $step, string $schemaName = 'form'): static {
/** @phpstan-ignore-next-line */
$this->assertWizardStepExists($step, $formName);
$this->assertWizardStepExists($step, $schemaName);
/** @var Schema $form */
$form = $this->instance()->{$formName};
$form = $this->instance()->{$schemaName};
/** @var Wizard $wizard */
$wizard = $form->getComponent(fn (Component | Action | ActionGroup $component): bool => $component instanceof Wizard);
@@ -509,12 +509,12 @@ class TestsForms
public function goToNextWizardStep(): Closure
{
return function (string $formName = 'form'): static {
return function (string $schemaName = 'form'): static {
/** @phpstan-ignore-next-line */
$this->assertFormExists($formName);
$this->assertFormExists($schemaName);
/** @var Schema $form */
$form = $this->instance()->{$formName};
$form = $this->instance()->{$schemaName};
/** @var Wizard $wizard */
$wizard = $form->getComponent(fn (Component | Action | ActionGroup $component): bool => $component instanceof Wizard);
@@ -527,12 +527,12 @@ class TestsForms
public function goToPreviousWizardStep(): Closure
{
return function (string $formName = 'form'): static {
return function (string $schemaName = 'form'): static {
/** @phpstan-ignore-next-line */
$this->assertFormExists($formName);
$this->assertFormExists($schemaName);
/** @var Schema $form */
$form = $this->instance()->{$formName};
$form = $this->instance()->{$schemaName};
/** @var Wizard $wizard */
$wizard = $form->getComponent(fn (Component | Action | ActionGroup $component): bool => $component instanceof Wizard);
@@ -17,10 +17,10 @@ class TestsInfolistActions
{
public function mountInfolistAction(): Closure
{
return function (string $component, string | array $actions, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->mountAction($actions);
@@ -57,10 +57,10 @@ class TestsInfolistActions
public function callInfolistAction(): Closure
{
return function (string $component, string | array $actions, array $data = [], array $arguments = [], string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, array $data = [], array $arguments = [], string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName, $arguments);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName, $arguments);
$this->callAction($actions, $data);
@@ -79,10 +79,10 @@ class TestsInfolistActions
public function assertInfolistActionExists(): Closure
{
return function (string $component, string | array $actions, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionExists($actions);
@@ -92,10 +92,10 @@ class TestsInfolistActions
public function assertInfolistActionDoesNotExist(): Closure
{
return function (string $component, string | array $actions, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionDoesNotExist($actions);
@@ -105,10 +105,10 @@ class TestsInfolistActions
public function assertInfolistActionVisible(): Closure
{
return function (string $component, string | array $actions, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionVisible($actions);
@@ -118,10 +118,10 @@ class TestsInfolistActions
public function assertInfolistActionHidden(): Closure
{
return function (string $component, string | array $actions, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionHidden($actions);
@@ -131,10 +131,10 @@ class TestsInfolistActions
public function assertInfolistActionEnabled(): Closure
{
return function (string $component, string | array $actions, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionEnabled($actions);
@@ -144,10 +144,10 @@ class TestsInfolistActions
public function assertInfolistActionDisabled(): Closure
{
return function (string $component, string | array $actions, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionDisabled($actions);
@@ -157,10 +157,10 @@ class TestsInfolistActions
public function assertInfolistActionHasIcon(): Closure
{
return function (string $component, string | array $actions, string | BackedEnum $icon, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string | BackedEnum $icon, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionHasIcon($actions, $icon);
@@ -170,10 +170,10 @@ class TestsInfolistActions
public function assertInfolistActionDoesNotHaveIcon(): Closure
{
return function (string $component, string | array $actions, string | BackedEnum $icon, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string | BackedEnum $icon, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionDoesNotHaveIcon($actions, $icon);
@@ -183,10 +183,10 @@ class TestsInfolistActions
public function assertInfolistActionHasLabel(): Closure
{
return function (string $component, string | array $actions, string $label, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $label, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionHasLabel($actions, $label);
@@ -196,10 +196,10 @@ class TestsInfolistActions
public function assertInfolistActionDoesNotHaveLabel(): Closure
{
return function (string $component, string | array $actions, string $label, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $label, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionDoesNotHaveLabel($actions, $label);
@@ -209,10 +209,10 @@ class TestsInfolistActions
public function assertInfolistActionHasColor(): Closure
{
return function (string $component, string | array $actions, string | array $color, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string | array $color, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionHasColor($actions, $color);
@@ -222,10 +222,10 @@ class TestsInfolistActions
public function assertInfolistActionDoesNotHaveColor(): Closure
{
return function (string $component, string | array $actions, string | array $color, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string | array $color, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionDoesNotHaveColor($actions, $color);
@@ -235,10 +235,10 @@ class TestsInfolistActions
public function assertInfolistActionHasUrl(): Closure
{
return function (string $component, string | array $actions, string $url, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $url, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionHasUrl($actions, $url);
@@ -248,10 +248,10 @@ class TestsInfolistActions
public function assertInfolistActionDoesNotHaveUrl(): Closure
{
return function (string $component, string | array $actions, string $url, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $url, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionDoesNotHaveUrl($actions, $url);
@@ -261,10 +261,10 @@ class TestsInfolistActions
public function assertInfolistActionShouldOpenUrlInNewTab(): Closure
{
return function (string $component, string | array $actions, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionShouldOpenUrlInNewTab($actions);
@@ -274,10 +274,10 @@ class TestsInfolistActions
public function assertInfolistActionShouldNotOpenUrlInNewTab(): Closure
{
return function (string $component, string | array $actions, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionShouldNotOpenUrlInNewTab($actions);
@@ -287,10 +287,10 @@ class TestsInfolistActions
public function assertInfolistActionMounted(): Closure
{
return function (string $component, string | array $actions, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionMounted($actions);
@@ -300,10 +300,10 @@ class TestsInfolistActions
public function assertInfolistActionNotMounted(): Closure
{
return function (string $component, string | array $actions, string $infolistName = 'infolist'): static {
return function (string $component, string | array $actions, string $schemaName = 'infolist'): static {
/** @var array<array<string, mixed>> $actions */
/** @phpstan-ignore-next-line */
$actions = $this->parseNestedInfolistActions($component, $actions, $infolistName);
$actions = $this->parseNestedInfolistActions($component, $actions, $schemaName);
$this->assertActionNotMounted($actions);
@@ -17,7 +17,7 @@ trait HasUserMenu
if (! Filament::auth()->check()) {
return;
}
$this->userMenuItems = Filament::getUserMenuItems();
foreach ($this->userMenuItems as $action) {
@@ -0,0 +1,37 @@
<?php
namespace Filament\Schemas\Testing;
use Stringable;
class TestSchemaComponent implements Stringable
{
final public function __construct(
protected string $name,
) {}
public static function make(string $name): static
{
return app(static::class, ['name' => $name]);
}
public static function inResourceForm(string $name): static
{
return app(static::class, ['name' => "form.{$name}"]);
}
public static function inResourceInfolist(string $name): static
{
return app(static::class, ['name' => "infolist.{$name}"]);
}
public static function inActionSchema(string $name, int $actionNestingIndex = 0): static
{
return app(static::class, ['name' => "mountedActionSchema{$actionNestingIndex}.{$name}"]);
}
public function __toString()
{
return $this->name;
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
<?php
use Filament\Actions\Action;
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Notifications\Notification;
use Filament\Support\Icons\Heroicon;
use Filament\Tests\Actions\TestCase;
+1 -1
View File
@@ -1,7 +1,7 @@
<?php
use Filament\Actions\Action;
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Forms\Components\TextInput;
use Filament\Support\Icons\Heroicon;
use Filament\Tests\Fixtures\Livewire\Actions;
+3 -3
View File
@@ -111,11 +111,11 @@ it('does not have layout components', function (): void {
it('can go to next wizard step on multiple forms', function (): void {
livewire(TestComponentWithMultipleWizardForms::class)
->assertHasNoFormErrors(formName: 'fooForm')
->assertHasNoFormErrors(formName: 'barForm')
->assertHasNoFormErrors(schemaName: 'fooForm')
->assertHasNoFormErrors(schemaName: 'barForm')
->assertWizardStepExists(2, 'fooForm')
->goToWizardStep(2, formName: 'fooForm')
->goToWizardStep(2, schemaName: 'fooForm')
->assertHasFormErrors(['title'], 'fooForm')
->assertHasNoFormErrors(['title'], 'barForm');
});
+1 -1
View File
@@ -1,7 +1,7 @@
<?php
use Filament\Actions\Action;
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Support\Icons\Heroicon;
use Filament\Tests\Fixtures\Livewire\InfolistActions;
use Filament\Tests\TestCase;
@@ -1,6 +1,6 @@
<?php
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Auth\MultiFactor\EmailCode\Notifications\VerifyEmailCodeAuthentication;
use Filament\Auth\Pages\EditProfile;
use Filament\Facades\Filament;
@@ -1,6 +1,6 @@
<?php
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Auth\MultiFactor\EmailCode\Notifications\VerifyEmailCodeAuthentication;
use Filament\Auth\Pages\Login;
use Filament\Facades\Filament;
@@ -1,6 +1,6 @@
<?php
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Auth\MultiFactor\EmailCode\Notifications\VerifyEmailCodeAuthentication;
use Filament\Auth\Pages\EditProfile;
use Filament\Facades\Filament;
@@ -1,6 +1,6 @@
<?php
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Auth\Pages\EditProfile;
use Filament\Facades\Filament;
use Filament\Tests\Fixtures\Models\User;
@@ -1,6 +1,6 @@
<?php
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Auth\Pages\EditProfile;
use Filament\Facades\Filament;
use Filament\Tests\Fixtures\Models\User;
@@ -1,6 +1,6 @@
<?php
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Auth\Pages\EditProfile;
use Filament\Facades\Filament;
use Filament\Tests\Fixtures\Models\User;
@@ -1,6 +1,6 @@
<?php
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Auth\Pages\Login;
use Filament\Facades\Filament;
use Filament\Forms\Components\TextInput;
@@ -9,7 +9,7 @@ use Filament\Actions\ForceDeleteBulkAction;
use Filament\Actions\ReplicateAction;
use Filament\Actions\RestoreAction;
use Filament\Actions\RestoreBulkAction;
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Actions\ViewAction;
use Filament\Facades\Filament;
use Filament\Tests\Fixtures\Models\Post;
@@ -9,7 +9,7 @@ use Filament\Actions\ForceDeleteBulkAction;
use Filament\Actions\ReplicateAction;
use Filament\Actions\RestoreAction;
use Filament\Actions\RestoreBulkAction;
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Actions\ViewAction;
use Filament\Tests\Fixtures\Models\Department;
use Filament\Tests\Fixtures\Models\Ticket;
@@ -9,7 +9,7 @@ use Filament\Actions\ForceDeleteBulkAction;
use Filament\Actions\ReplicateAction;
use Filament\Actions\RestoreAction;
use Filament\Actions\RestoreBulkAction;
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Actions\ViewAction;
use Filament\Tests\Fixtures\Models\Department;
use Filament\Tests\Fixtures\Models\Ticket;
+1 -1
View File
@@ -3,7 +3,7 @@
use Filament\Actions\Action;
use Filament\Actions\AttachAction;
use Filament\Actions\DeleteAction;
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Support\Icons\Heroicon;
use Filament\Tests\Fixtures\Livewire\PostsTable;
use Filament\Tests\Fixtures\Models\Post;
+1 -1
View File
@@ -1,7 +1,7 @@
<?php
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\Testing\Fixtures\TestAction;
use Filament\Actions\Testing\TestAction;
use Filament\Support\Icons\Heroicon;
use Filament\Tests\Fixtures\Livewire\PostsTable;
use Filament\Tests\Fixtures\Models\Post;