Pest Testing Repeater (extra value added in tests)

Hi all, I'm hoping somebody can help me understand where I'm going wrong. I've set up a repeater action
return CreateAction::make('create_content')
...
->form([
Section::make('Content')
->description('Add your content ')
->schema([
Repeater::make('articles')
->label('')
->addActionLabel('Add More Content')
->schema([
TextArea::make('body')
->label('')
->required(),
]),
]),
])->using(function (array $data, string $model): Model {
// I check my $data['articles'] here
});
return CreateAction::make('create_content')
...
->form([
Section::make('Content')
->description('Add your content ')
->schema([
Repeater::make('articles')
->label('')
->addActionLabel('Add More Content')
->schema([
TextArea::make('body')
->label('')
->required(),
]),
]),
])->using(function (array $data, string $model): Model {
// I check my $data['articles'] here
});
I'm trying to test it as such:
livewire(MyComponent::class)
->callTableAction('create_content', data: ['articles' => [
['body' => 'huh?'],
['body' => 'woah'],
['body' => 'cool'],
],
]);
livewire(MyComponent::class)
->callTableAction('create_content', data: ['articles' => [
['body' => 'huh?'],
['body' => 'woah'],
['body' => 'cool'],
],
]);
However, when I run the test in debug, the $data['articles'] variable has 4 entries - 1 null, and then the 3 I've specified in my test. Normally it wouldn't be a problem, I can just filter out the null value, but when I add in a ->required() to the textfield in the repeater, the test doesn't work (due to the null value, I'm assuming). Has anybody else experienced this, and can you point me to what I'm doing wrong? Thanks so much!
8 Replies
LeandroFerreira
LeandroFerreira5mo ago
Add this before the callTableAction: ->set('data.articles', null)
ShawnVeltman
ShawnVeltman5mo ago
Thanks for responding! That told me there was no $data variable, and when I tried
->set('articles',null)
->set('articles',null)
it didn't make a difference. I'm sure I'm missing something silly & obvious, but I just can't figure it out. Thank you for trying to help!
LeandroFerreira
LeandroFerreira5mo ago
Maybe ->defaultItems(0) in the repeater?
ShawnVeltman
ShawnVeltman5mo ago
You are a godsend, that did it! I was able to set a locked variable for default items, set it to 1 for "real" usage, set it to 0 in the test, and everything works great. Thank you thank you thank you!!!!!
JJSanders
JJSanders5mo ago
May I ask you where you picked up al this testing information? I am stuck with some testing issues though you might have a good resource.
ShawnVeltman
ShawnVeltman5mo ago
I don't have much testing knowledge in Filament, unfortunately (hence my confusion and need for help on this topic!). I've found the Laracasts series on testing in general to be super helpful, and the Filament documents for Filament specific testing are typically pretty great, though I'm sure I'll be back here with plenty more questions as I get better coverage on more of the Filament functionality in my latest app
cheesegrits
cheesegrits3mo ago
@ShawnVeltman (and anyone stumbling across this searching for the same issue). I just ran into this, and figured out I can use the ->set('repeater', null) approach (to remove any defaultItems) by using mountTableAction rather than callTableAction ...
livewire(ListAircraft::class)
->mountTableAction(CreateAction::class)
->set('mountedTableActionsData.0.roles', null)
->setTableActionData(data: [
// ...
'roles' => [
[
'personnel_role_id' => PersonnelRole::factory()->create()->id,
'number' => fake()->numberBetween(0, 100),
],
],
])
->callMountedTableAction()
->assertHasNoTableActionErrors();
livewire(ListAircraft::class)
->mountTableAction(CreateAction::class)
->set('mountedTableActionsData.0.roles', null)
->setTableActionData(data: [
// ...
'roles' => [
[
'personnel_role_id' => PersonnelRole::factory()->create()->id,
'number' => fake()->numberBetween(0, 100),
],
],
])
->callMountedTableAction()
->assertHasNoTableActionErrors();
By using mountTableAction() followed by setTableActionsData() and callMountedTableAction(), rather than the atomic callTableAction(), this enables me to slide that set('roles', null) in there before setting the data. This lest me test repeaters with defaultItems, without changing my form schema.
ShawnVeltman
ShawnVeltman3mo ago
Oh, that's even better - thanks @Hugh Messenger !!