Description
Thank you @kbond for the awesome test helper traits for Live and Twig components.
However, in some of my new tests that use these traits, I'm running into some issues. All this is PHP 8.2 on Symfony 6.3, with Live/Twig components on the latest 2.11.2
version.
All these tests extend Symfony's KernelTestCase
via my own KernelTestCase
wrapper, where I add a setUp
method to run before all tests cases:
abstract class KernelTestCase extends \Symfony\Bundle\FrameworkBundle\Test\KernelTestCase
{
/** @var TestContainer */
public Container|ContainerInterface $container;
protected function setUp(): void
{
self::bootKernel();
$this->container = static::getContainer();
}
}
I think this is quite a normal configuration.
However, then with some tests I'm running into the following issues:
1) Session not found
Any Twig or Live Component that touches the session, either in PHP or in the template, will throw SessionNotFoundException: There is currently no session available.
when the test is run.
For me this is usually because I have e.g. a Date Range filter stored in the session, and this is then used inside the component to filter e.g. a repository query.
The solution to this is to pass in the value from the session when placing the component in the parent template. i.e.
{{ component('report_income_by_client', { dateRange: app.session.get('dateRange') }) }}
This is actually more elegant in a way, as it keeps the concerns of the component itself to a bare minimum.
Then, in the test, we just pass in the "dateRange" as a parameter that we control from inside the test:
$rendered = $this->renderTwigComponent(
name: ReportIncomeByClientComponent::class,
data: [
'dateRange' => $dateRange, // define this elsewhere in the test
],
);
So this is a working solution that I'm more posting here for future reference than anything else. However, it leads nicely on to the second problem:
2) CSRF token not found
If any of the components under test are rending a form, then I get failures with the following exception:
Symfony\Component\HttpFoundation\Exception\SessionNotFoundException: There is currently no session available.
/var/www/app/vendor/symfony/http-foundation/RequestStack.php:107
/var/www/app/vendor/symfony/security-csrf/TokenStorage/SessionTokenStorage.php:110
/var/www/app/vendor/symfony/security-csrf/TokenStorage/SessionTokenStorage.php:74
/var/www/app/vendor/symfony/security-csrf/CsrfTokenManager.php:69
/var/www/app/vendor/symfony/form/Extension/Csrf/Type/FormTypeCsrfExtension.php:82
/var/www/app/vendor/symfony/form/ResolvedFormType.php:134
/var/www/app/vendor/symfony/form/Extension/DataCollector/Proxy/ResolvedTypeDataCollectorProxy.php:95
/var/www/app/vendor/symfony/form/ResolvedFormType.php:128
/var/www/app/vendor/symfony/form/Extension/DataCollector/Proxy/ResolvedTypeDataCollectorProxy.php:95
/var/www/app/vendor/symfony/form/Form.php:908
/var/www/app/vendor/symfony/ux-live-component/src/ComponentWithFormTrait.php:120
/var/www/app/vendor/symfony/ux-live-component/src/ComponentWithFormTrait.php:95
/var/www/app/vendor/symfony/ux-twig-component/src/ComponentFactory.php:198
/var/www/app/vendor/symfony/ux-twig-component/src/ComponentFactory.php:91
/var/www/app/vendor/symfony/ux-twig-component/src/ComponentFactory.php:65
/var/www/app/vendor/symfony/ux-live-component/src/Test/TestLiveComponent.php:45
/var/www/app/vendor/symfony/ux-live-component/src/Test/InteractsWithLiveComponents.php:36
/var/www/app/tests/integration/ReportIncomeByClientComponentTest.php:22
The way I have sorted this is to disable CSRF protection across the entire "test" environment, but this is not great as I do want it enabled for WebTestCase
but not for KernelTestCase
etc.
// config/packages/framework.php
if ($container->env() === 'test')
{
$framework->test(true);
$framework->csrfProtection()->enabled(false);
}
Is there a sensible way to disable the CSRF protection only inside KernelTestCase
tests? Or indeed just to create a CSRF token that is accepted?
3) Authenticated Users seem to be ignored
The final issue I'm seeing is that these tests seem to ignore any authenticated users I have. In my extended KernelTestCase
base class, I have something like:
public function loginAs(string $username): void
{
$user = $this->container->get(UserRepository::class)->findByUsername($username);
$tokenStorage = $this->container->get(TokenStorageInterface::class);
$token = new TestBrowserToken(roles: [Role::SUPER_ADMIN, Role::USER], user: $user);
$tokenStorage->setToken($token);
}
This works fine in normal tests but seems to be ignored completely during the Twig/Live Component tests, and I just get Symfony\Component\Security\Core\Exception\AccessDeniedException : Access Denied.
on any component that has an IsGranted
attribute defined.
Again, a solution to this is to disable access control across the entire "test" environment, but I don't want to do this as the security restrictions also need to be part of the tested behaviour.
Sorry for the long post - but I figure that all these things are going to be a common issue when testing components, and I have a feeling they are all related together somehow.
Thanks!