filamentphp / filament

A collection of beautiful full-stack components for Laravel. The perfect starting point for your next app. Using Livewire, Alpine.js and Tailwind CSS.
https://filamentphp.com
MIT License
19.45k stars 2.97k forks source link

Test helpers create invalid to Builder json order #10767

Closed fritz-c closed 6 months ago

fritz-c commented 10 months ago

Package

filament/filament

Package Version

v3.1.43

Laravel Version

10.40.0

Livewire Version

v3.3.5

PHP Version

8.2.9

Problem description

When testing resources that use the Repeater component, the fillForm method, due to its approach of deep-filling data one value at a time, will create invalid states that do not occur in normal use. In my repro, the itemLabel callback has an assumption that $state is pre-loaded with the keys corresponding to the repeater items' schema, with each key's value initialized to null when nothing has been set yet.

// From the resource:
->itemLabel(function (array $state): ?string {
    if (! $state['author'] || ! $state['title']) {
        return null;
    }

    return "{$state['author']}: {$state['title']}";
})

This assumption is valid when rendering the form normally, but is not correct when in the test environment using the test helpers, causing errors.

// This fails due to an absent 'title' key in $state
it('populates multiple fields in schema', function () {
    livewire(CreateArticle::class)
        ->fillForm(['quotes' => [[
            'author' => 'Sally',
            'title' => 'Foo',
            'body' => 'Bar',
        ]]])
        ->call('create')
        ->assertHasNoFormErrors();
});

Expected behavior

The livewire test helper and its fillForm method should initialize form state for tests in a fashion identical to normal form rendering.

Steps to reproduce

See the repro README

But since your automation seems to be care about character length, here's a dump of the repro steps from there.

Setup and reproduction

cp .env.example .env
touch database/database.sqlite
composer install
php artisan migrate:fresh --seed
php artisan test

Reproduction repository

https://github.com/fritz-c/filament-repeater-test-bug

Relevant log output

% php artisan test

   PASS  Tests\Unit\ExampleTest
  ✓ that true is true                                                                                                            0.01s

   FAIL  Tests\Feature\ExampleTest
  ⨯ it populates multiple fields in schema                                                                                       0.21s
  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   FAILED  Tests\Feature\ExampleTest > it populates multiple fields in schema                                           ViewException
  Undefined array key "title" (View: /path/to/filament-repeater-test-bug/vendor/filament/forms/resources/views/components/repeater.blade.php) (View: /path/to/filament-repeater-test-bug/vendor/filament/forms/resources/views/components/repeater.blade.php) (View: /path/to/filament-repeater-test-bug/vendor/filament/forms/resources/views/components/repeater.blade.php)

  at app/Filament/Resources/ArticleResource.php:26
     22▕         return $form
     23▕             ->schema([
     24▕                 Repeater::make('quotes')
     25▕                     ->itemLabel(function (array $state): ?string {
  ➜  26▕                         if (! $state['author'] || ! $state['title']) {
     27▕                             return null;
     28▕                         }
     29▕
     30▕                         return "{$state['author']}: {$state['title']}";

  1   app/Filament/Resources/ArticleResource.php:26
      +2 vendor frames

  4   app/Filament/Resources/ArticleResource.php:26
      NunoMaduro\Collision\Exceptions\TestException::("Undefined array key "title" (View: /path/to/filament-repeater-test-bug/vendor/filament/forms/resources/views/components/repeater.blade.php) (View: /path/to/filament-repeater-test-bug/vendor/filament/forms/resources/views/components/repeater.blade.php)")

  Tests:    1 failed, 1 passed (2 assertions)
  Duration: 0.28s
github-actions[bot] commented 10 months ago

Hey @fritz-c! We're sorry to hear that you've hit this issue. 💛

However, it doesn't look like you've provided much information on how to replicate the issue. Please edit your original post with clear steps we need to take.

github-actions[bot] commented 10 months ago

Thank you for providing reproduction steps! Reopening the issue now.

danharrin commented 10 months ago

Similar to #10246

danharrin commented 6 months ago

12759 adds additional documentation and a new ::fake() method for testing without UUIDs