How can I make Twig's {{ app.user }} not null inside tests?

Viewed 396

I have a Symfony test case where I test the authentication to the admin area of my website. Here is the test case (very simple, indeed) :

public function setUp()
{
    $this->client = static::createClient();
}

/* ... */ 

public function testAdminHomepageAllowsAdmins(): void
{
    $this->logInAs('admin@website.com', ['ROLE_SUPER_ADMIN']);
    $this->client->request('GET', '/admin');
    self::assertResponseStatusCodeSame(Response::HTTP_OK);
}

private function logInAs(string $name = 'user@website.com', array $roles = ['ROLE_USER']): void
{
    $session = self::$container->get('session');
    $firewall = 'main';

    $token = new UsernamePasswordToken($name, null, $firewall, $roles);

    $session->set('_security_'.$firewall, serialize($token));
    $session->save();

    $cookie = new Cookie($session->getName(), $session->getId());
    $this->client->getCookieJar()->set($cookie);
}

The problem is that my code fails because the response bears a 500 HTTP Status Code with the following message sent by Symfony :

Impossible to access an attribute ("email") on a null variable. (500 Internal Server Error)

I know that the source of the error is TWIG, apparently, setting the UsernamePasswordToken is not enough for the Twig variable {{ app.user }} - It is set to null, and therefore when I call :

<span class="navbar-text">
    Logged in as {{ app.user.email }} - <a href="{{ path('app_logout') }}">Log out</a>
</span>

In my template, an exception is sent. What I would like to do is making the test pass without changing the TWIG template. I only want to modify the code which is in my test case.

Note that it does not work even with a "functional" logIn method, like this :

private function logInAs(string $email, string $plainPassword): void
{
    $csrfToken = $this->client->getContainer()->get('security.csrf.token_manager')->getToken('authenticate');
    $this->client->request('POST', '/login', [
        'email' => $email,
        'password' => $plainPassword,
        '_csrf_token' => $csrfToken
    ]);
    $this->client->followRedirect();
}
0 Answers
Related