diff --git a/README.md b/README.md index 0fa89c3f..7b05abae 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,13 @@ The `make:filament-test` command supports the following options: This package generates comprehensive PEST tests for your Filament resources. Here's a complete list of currently working tests: +### Form Record Tests +- **CanCreateRecordTest** - Tests that a record can be created +- **CanValidateCreateFormTest** - Tests that the create form validates input correctly + - [x] Max + - [x] Min + - [x] Required + ### Page Rendering Tests - **CanRenderCreatePageTest** - Tests that the create page renders correctly - **CanRenderEditPageTest** - Tests that the edit page renders correctly @@ -73,6 +80,9 @@ This package generates comprehensive PEST tests for your Filament resources. Her All tests are automatically generated based on your Filament resource configuration and will only run when the relevant features are present in your resource (e.g., search tests only run if you have searchable columns). +## Known Issues +- Validation of RichEditor fields is not supported, this is due to the complexity of handling rich text content in tests. + ## Credits - [CodeWithDennis](https://github.com/CodeWithDennis) diff --git a/resources/views/can-create-record.blade.php b/resources/views/can-create-record.blade.php deleted file mode 100644 index ff48f6d1..00000000 --- a/resources/views/can-create-record.blade.php +++ /dev/null @@ -1,19 +0,0 @@ -it('can create a record', function (): void { -$record = {{ $modelClass }}::factory()->make(); -$image = UploadedFile::fake()->image('gold.jpg'); - -livewire({{ $createPageClass }}::class) -->fillForm([ -'name' => $record->name, -'description' => $record->description, -'image' => $image, -]) -->call('create') -->assertNotified(); - -assertDatabaseHas({{ $modelClass }}, [ -'name' => $record->name, -'description' => $record->description, -'image' => 'images/badges/'.str($record->name)->slug().'-badge-gold.jpg', -]); -}); \ No newline at end of file diff --git a/resources/views/form-validation-rules.blade.php b/resources/views/form-validation-rules.blade.php deleted file mode 100644 index 39cba1ac..00000000 --- a/resources/views/form-validation-rules.blade.php +++ /dev/null @@ -1,19 +0,0 @@ -describe('validation', function (): void { - it('validates the form data', function (array $data, array $errors): void { - $record = {{ $modelClass }}::factory()->create(); - $newRecordData = {{ $modelClass }}::factory()->make(); - - livewire({{ $editPageClass }}::class, ['record' => $record->id]) - ->fillForm([ - 'name' => $newRecordData->name, - ...$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']], - '`description` is max 255 characters' => [['description' => Str::random(256)], ['description' => 'max']], - ]); -}); \ No newline at end of file diff --git a/resources/views/resources/pages/create/can-create-record.blade.php b/resources/views/resources/pages/create/can-create-record.blade.php new file mode 100644 index 00000000..2b8801d6 --- /dev/null +++ b/resources/views/resources/pages/create/can-create-record.blade.php @@ -0,0 +1,20 @@ +@php use Filament\Forms\Components\RichEditor; @endphp +it('can create a record', function (): void { + $record = {{ $getResourceModel() }}::factory()->make(); + + livewire({{ $getPageClass('create') }}::class) + ->fillForm([ + @foreach($getResourceFormFields() as $key => $field) + '{{ $key }}' => $record->{{ $key }}, + @endforeach + ]) + ->call('create') + ->assertHasNoFormErrors() + ->assertNotified(); + + $this->assertDatabaseHas({{ $getResourceModel() }}::class, [ + @foreach($getResourceFormFields() as $key => $field) + '{{ $key }}' => $record->{{ $key }}, + @endforeach + ]); +}); diff --git a/resources/views/resources/pages/create/can-validate-create-form-data.blade.php b/resources/views/resources/pages/create/can-validate-create-form-data.blade.php new file mode 100644 index 00000000..5dcf24d9 --- /dev/null +++ b/resources/views/resources/pages/create/can-validate-create-form-data.blade.php @@ -0,0 +1,21 @@ +it('validates form data field :dataset', function (array $data, array $errors): void { + $record = {{ $getResourceModel() }}::factory()->make(); + + livewire({{ $getPageClass('create') }}::class) + ->fillForm([ + ...$data + ]) + ->call('create') + ->assertHasFormErrors($errors) + ->assertNotified(); +})->with([ + @foreach($getResourceFormFieldsByRulePrefix('required') as $key => $field) + '`{{ $key }}` is required' => [['{{ $key }}' => null], ['{{ $key }}' => 'required']], + @endforeach + @foreach($getResourceFormFieldsByRulePrefix('max') as $key => $field) + '`{{ $key }}` is max {{ $getRuleValue($field, 'max') }} characters' => [['{{ $key }}' => Illuminate\Support\Str::random({{ $getRuleValue($field, 'max') + 1 }})], ['{{ $key }}' => 'max']], + @endforeach + @foreach($getResourceFormFieldsByRulePrefix('min') as $key => $field) + '`{{ $key }}` is min {{ $getRuleValue($field, 'min') }} characters' => [['{{ $key }}' => Illuminate\Support\Str::random({{ $getRuleValue($field, 'min') - 1 }})], ['{{ $key }}' => 'min']], + @endforeach +]); diff --git a/src/Commands/FilamentTestsCommand.php b/src/Commands/FilamentTestsCommand.php index 61b1d635..b8d3ce6e 100644 --- a/src/Commands/FilamentTestsCommand.php +++ b/src/Commands/FilamentTestsCommand.php @@ -6,7 +6,9 @@ use CodeWithDennis\FilamentTests\Concerns\Commands\InteractsWithUserInput; use CodeWithDennis\FilamentTests\TestRenderers\BaseTest; use CodeWithDennis\FilamentTests\TestRenderers\BeforeEach; +use CodeWithDennis\FilamentTests\TestRenderers\Resources\Pages\Create\CanCreateRecordTest; use CodeWithDennis\FilamentTests\TestRenderers\Resources\Pages\Create\CanRenderCreatePageTest; +use CodeWithDennis\FilamentTests\TestRenderers\Resources\Pages\Create\CanValidateCreateFormData; use CodeWithDennis\FilamentTests\TestRenderers\Resources\Pages\Edit\CanDeleteRecordTest; use CodeWithDennis\FilamentTests\TestRenderers\Resources\Pages\Edit\CanRenderEditPageTest; use CodeWithDennis\FilamentTests\TestRenderers\Resources\Pages\Edit\HasHeaderActionTest; @@ -89,6 +91,8 @@ protected function getRenderers(): array ShowsHeaderActionTest::class, HidesHeaderActionTest::class, HasFilterTest::class, + CanCreateRecordTest::class, + CanValidateCreateFormData::class, ]; } } diff --git a/src/Concerns/Resources/InteractsWithSchemas.php b/src/Concerns/Resources/InteractsWithSchemas.php index 52c0428c..805bd25d 100644 --- a/src/Concerns/Resources/InteractsWithSchemas.php +++ b/src/Concerns/Resources/InteractsWithSchemas.php @@ -2,6 +2,7 @@ namespace CodeWithDennis\FilamentTests\Concerns\Resources; +use Closure; use Filament\Forms\Components\Field; use Filament\Infolists\Components\Entry; use Filament\Resources\Pages\EditRecord; @@ -22,6 +23,31 @@ public function getResourceFormFields(): array return $this->getResourceForm()->getFlatFields(true); } + public function getResourceFormFieldsByRulePrefix(string $prefix): array + { + return collect($this->getResourceFormFields()) + ->filter( + fn (Field $field): bool => array_any( + $field->getValidationRules(), + fn (Closure|string $rule): bool => is_string($rule) && str_starts_with($rule, $prefix) + ) + ) + ->all(); + } + + public function getRuleValue(Field $field, string $ruleName): ?string + { + foreach ($field->getValidationRules() as $rule) { + if (is_string($rule) && str_starts_with($rule, $ruleName.':')) { + [, $value] = explode(':', $rule, 2); + + return $value; + } + } + + return null; + } + public function getResourceFormFieldKeys(): array { return collect($this->getResourceFormFields()) diff --git a/src/TestRenderers/Resources/Pages/Create/CanCreateRecordTest.php b/src/TestRenderers/Resources/Pages/Create/CanCreateRecordTest.php new file mode 100644 index 00000000..3927738a --- /dev/null +++ b/src/TestRenderers/Resources/Pages/Create/CanCreateRecordTest.php @@ -0,0 +1,15 @@ +hasPage('create'); + } +} diff --git a/src/TestRenderers/Resources/Pages/Create/CanValidateCreateFormData.php b/src/TestRenderers/Resources/Pages/Create/CanValidateCreateFormData.php new file mode 100644 index 00000000..379e56a6 --- /dev/null +++ b/src/TestRenderers/Resources/Pages/Create/CanValidateCreateFormData.php @@ -0,0 +1,15 @@ +hasPage('create'); + } +}