F
Filament4w ago
Exi

callInfolistAction() returns getInfolist() on null while testing a Infolist Action

What I am trying to do I have an Infolist Action (CreateApiTokenAction) that generates an API token for a user. In the UI everything works as expected—clicking the action creates the token and shows a success notification. What I did 1. Added the action to my user view page (ViewUser), inside the hintActions() of a TextEntry. 2. Wrote a test that authenticates a user and calls the action with callInfolistAction(). My issue / the error Running the test throws:
Error : Call to a member function getInfolist() on null
vendor/filament/infolists/src/Testing/TestsActions.php:542
Error : Call to a member function getInfolist() on null
vendor/filament/infolists/src/Testing/TestsActions.php:542
Digging in, $this->instance() inside TestsActions.php is null, so getInfolist() naturally fails. Code
// app/Filament/Actions/Infolists/CreateApiTokenAction.php
<?php

declare(strict_types=1);

namespace App\Filament\Actions\Infolists;

use App\Models\User;
use Filament\Infolists\Components\Actions\Action;
use Filament\Notifications\Notification;
use Illuminate\Database\Eloquent\Model;

final class CreateApiTokenAction extends Action
{
protected function setUp(): void
{
parent::setUp();

$this->label('Create token')
->icon('heroicon-m-key')
->color('info')
->action(function (Model $record): void {
/** @var User $record */
$record->createToken('api', ['*']);

Notification::make()
->title('Token created')
->body('API token generated successfully.')
->success()
->send();
});
}

public static function getDefaultName(): ?string
{
return 'createApiToken';
}
}
// app/Filament/Actions/Infolists/CreateApiTokenAction.php
<?php

declare(strict_types=1);

namespace App\Filament\Actions\Infolists;

use App\Models\User;
use Filament\Infolists\Components\Actions\Action;
use Filament\Notifications\Notification;
use Illuminate\Database\Eloquent\Model;

final class CreateApiTokenAction extends Action
{
protected function setUp(): void
{
parent::setUp();

$this->label('Create token')
->icon('heroicon-m-key')
->color('info')
->action(function (Model $record): void {
/** @var User $record */
$record->createToken('api', ['*']);

Notification::make()
->title('Token created')
->body('API token generated successfully.')
->success()
->send();
});
}

public static function getDefaultName(): ?string
{
return 'createApiToken';
}
}
// app/Filament/Resources/UserResource/Pages/ViewUser.php
<?php

declare(strict_types=1);

namespace App\Filament\Resources\UserResource\Pages;

use App\Filament\Actions\Infolists\CreateApiTokenAction;
use App\Filament\Resources\UserResource;
use App\Models\User;
use Filament\Actions;
use Filament\Infolists;
use Filament\Infolists\Infolist;
use Filament\Resources\Pages\ViewRecord;

final class ViewUser extends ViewRecord
{
protected static string $resource = UserResource::class;

public function infolist(Infolist $infolist): Infolist
{
return $infolist->schema([
Infolists\Components\TextEntry::make('token')
->state(fn (?User $record) => $record?->tokens()->where('name', 'api')->first()?->token)
->hintActions([
CreateApiTokenAction::make(),
]),
]);
}

protected function getHeaderActions(): array
{
return [
Actions\EditAction::make(),
];
}
}
// app/Filament/Resources/UserResource/Pages/ViewUser.php
<?php

declare(strict_types=1);

namespace App\Filament\Resources\UserResource\Pages;

use App\Filament\Actions\Infolists\CreateApiTokenAction;
use App\Filament\Resources\UserResource;
use App\Models\User;
use Filament\Actions;
use Filament\Infolists;
use Filament\Infolists\Infolist;
use Filament\Resources\Pages\ViewRecord;

final class ViewUser extends ViewRecord
{
protected static string $resource = UserResource::class;

public function infolist(Infolist $infolist): Infolist
{
return $infolist->schema([
Infolists\Components\TextEntry::make('token')
->state(fn (?User $record) => $record?->tokens()->where('name', 'api')->first()?->token)
->hintActions([
CreateApiTokenAction::make(),
]),
]);
}

protected function getHeaderActions(): array
{
return [
Actions\EditAction::make(),
];
}
}
// tests/Feature/Filament/Actions/Infolists/CreateApiTokenActionTest.php
it('can create a token', function () {
actingAs(user()); // helper that returns an admin user

$record = \App\Models\User::factory()->create();

livewire(\App\Filament\Resources\UserResource\Pages\ViewUser::class, [
'record' => $record->getRouteKey(),
])->callInfolistAction('token', ['createApiToken']);

expect($record->refresh())
->tokens()->count()->toBe(1);
});
// tests/Feature/Filament/Actions/Infolists/CreateApiTokenActionTest.php
it('can create a token', function () {
actingAs(user()); // helper that returns an admin user

$record = \App\Models\User::factory()->create();

livewire(\App\Filament\Resources\UserResource\Pages\ViewUser::class, [
'record' => $record->getRouteKey(),
])->callInfolistAction('token', ['createApiToken']);

expect($record->refresh())
->tokens()->count()->toBe(1);
});
1 Reply

Did you find this page helpful?