F
Filament3mo ago
Geoff.

Macro is not working when testing with Pest

Hello all I am using this plugin https://github.com/outer-web/filament-translatable-fields and when I want to write a test now I am getting the error that translatable does not exist. How to add the plugin also in the test environment? Here is the error: Illuminate\View\ViewException: Method Filament\Forms\Components\TextInput::translatable does not exist. Here is the test:
it('can validate form', function () {
$rules = [
'description' => ['required', 'max:255'],
'code' => ['required', 'max:6'],
'type' => ['required',Rule::enum(FoodBeverage::class)],
'vat_id' => ['required', 'exists:vat_codes,id'],
];
livewire(CreateProductGroup::class)
->fillForm([
'description' => '',
'code' => '',
])
->call('create')
->assertHasFormErrors($rules);
});
it('can validate form', function () {
$rules = [
'description' => ['required', 'max:255'],
'code' => ['required', 'max:6'],
'type' => ['required',Rule::enum(FoodBeverage::class)],
'vat_id' => ['required', 'exists:vat_codes,id'],
];
livewire(CreateProductGroup::class)
->fillForm([
'description' => '',
'code' => '',
])
->call('create')
->assertHasFormErrors($rules);
});
GitHub
GitHub - outer-web/filament-translatable-fields
Contribute to outer-web/filament-translatable-fields development by creating an account on GitHub.
Solution:
Yeah, I will just add
Filament::bootCurrentPanel();
Filament::bootCurrentPanel();
to my setup before each test. This is working
Jump to solution
32 Replies
Dennis Koch
Dennis Koch3mo ago
Do you have more than 1 panel? And is this your default panel? Looking at the plugin, the Macro is registered during Plugin::boot(). So we need to figure out why the plugin is not booted.
Geoff.
Geoff.3mo ago
Yes I have mor than 1 panel, this is on my app panel and the other panel is the admin panel
Dennis Koch
Dennis Koch3mo ago
I guess admin panel is the default one?
Geoff.
Geoff.3mo ago
Ye indeed But Plugin is registered on the AppPanelProvider
Dennis Koch
Dennis Koch3mo ago
So you need to set the current panel. I found this in another thread:
\Filament\Facades\Filament::setCurrentPanel(
\Filament\Facades\Filament::getPanel('app')
);
\Filament\Facades\Filament::setCurrentPanel(
\Filament\Facades\Filament::getPanel('app')
);
https://discord.com/channels/883083792112300104/1169961796208185464/1170996029659820203
Geoff.
Geoff.3mo ago
Thats already in my test
\Filament\Facades\Filament::setCurrentPanel(\Filament\Facades\Filament::getPanel('app'));
\Filament\Facades\Filament::setTenant($store, true);
\Filament\Facades\Filament::setCurrentPanel(\Filament\Facades\Filament::getPanel('app'));
\Filament\Facades\Filament::setTenant($store, true);
Dennis Koch
Dennis Koch3mo ago
Where did you put this? Because it's not included in your code above?
Geoff.
Geoff.3mo ago
Ah it is on a function i run before each test
public function TenantLogin(): void
{
tenancy()->initialize(getTenant());
$user = \App\Models\App\User::query()->where('name', 'admin')->first();
$store = Store::query()->where('slug', 'test')->first();

$this->actingAs($user);

\Filament\Facades\Filament::setCurrentPanel(\Filament\Facades\Filament::getPanel('app'));
\Filament\Facades\Filament::setTenant($store, true);
}
public function TenantLogin(): void
{
tenancy()->initialize(getTenant());
$user = \App\Models\App\User::query()->where('name', 'admin')->first();
$store = Store::query()->where('slug', 'test')->first();

$this->actingAs($user);

\Filament\Facades\Filament::setCurrentPanel(\Filament\Facades\Filament::getPanel('app'));
\Filament\Facades\Filament::setTenant($store, true);
}
beforeEach(function () {
createTenantDatabase();
$this->TenantLogin();
});
beforeEach(function () {
createTenantDatabase();
$this->TenantLogin();
});
Dennis Koch
Dennis Koch3mo ago
Hm. Looks good to me. Can you make sure the code is running? And output Filament::getCurrentPanel() after setting it and just before your test code is running?
Geoff.
Geoff.3mo ago
ds(Filament::getCurrentPanel());
\Filament\Facades\Filament::setCurrentPanel(\Filament\Facades\Filament::getPanel('app'));
ds(Filament::getCurrentPanel());
ds(Filament::getCurrentPanel());
\Filament\Facades\Filament::setCurrentPanel(\Filament\Facades\Filament::getPanel('app'));
ds(Filament::getCurrentPanel());
First log is giving admin and second one is giving app
Dennis Koch
Dennis Koch3mo ago
And if you put it right before livewire(CreateProductGroup::class)? Is it still app?
Geoff.
Geoff.3mo ago
Yeah still app
Dennis Koch
Dennis Koch3mo ago
Hm weird. Let me reconstruct this quickly
Geoff.
Geoff.3mo ago
When I ds in the boot function I don't get any log
Dennis Koch
Dennis Koch3mo ago
Boot of the plugin? Yeah, that's what I am trying to figure out 😅
Geoff.
Geoff.3mo ago
Yeah indeed 😄
Dennis Koch
Dennis Koch3mo ago
What if you do it in Filament\Panel::boot()? ds($this->id)?
Geoff.
Geoff.3mo ago
Where to put this?
Dennis Koch
Dennis Koch3mo ago
vendor/filament/filament/src/Panel.php
Geoff.
Geoff.3mo ago
Ok, its logging nothing and when going to the webpage it is logging correct
Dennis Koch
Dennis Koch3mo ago
Hm. Actually I don't know where we are booting Panels. If you boot it manually that could work, but not sure whether that's the ideal solution:
$panel = Filament::getPanel('app');
Filament::setCurrentPanel($panel);
$panel->boot();
$panel = Filament::getPanel('app');
Filament::setCurrentPanel($panel);
$panel->boot();
Geoff.
Geoff.3mo ago
Yeah thats working.
Dennis Koch
Dennis Koch3mo ago
@Dan Harrin Sorry to tag you, but can you maybe shed some light on where Panels are booted and how we could test a different panel? Manual booting feels a bit hacky.
Geoff.
Geoff.3mo ago
Really appreciate the help btw I think this could be ok to use
Dan Harrin
Dan Harrin3mo ago
panels are booted by middleware based on the current route
Geoff.
Geoff.3mo ago
Filament::bootCurrentPanel();
Filament::bootCurrentPanel();
Dan Harrin
Dan Harrin3mo ago
you could boot in the setUp() of the test case if you want it to apply to multiple tests
Dennis Koch
Dennis Koch3mo ago
I thought so. But since we are directly testing the LW components there is no nicer way then manually setting the current panel and booting, right?
Dan Harrin
Dan Harrin3mo ago
no, but as i said you can extract it
Solution
Geoff.
Geoff.3mo ago
Yeah, I will just add
Filament::bootCurrentPanel();
Filament::bootCurrentPanel();
to my setup before each test. This is working
Geoff.
Geoff.3mo ago
Thanks for the help ❤️
Simon
Simon3mo ago
Hi, Simon here, the developer of the package mentioned here. I see a solution has been found. Is there anything I could change in the package itself to make this easier/better or am I registering the macro correctly in the boot() method of the plugin?