Description
Note : The technique described here was working perfectly with Symfony 2.0.16, upgrading to Symfony 2.1 RC1 introduced the problem described in this ticket.
The Issue
When trying to set an authentication token inside a WebTestCase, the token is nullified after the first call made to:
$client->request('GET', '/');
Please refer to the following files on pastebin.com:
and on symfony/symfony here on GitHub:
AuthTestCase
I have created an abstract base class in my project, called AuthTestCase, that extends WebTestCase. It has a method called loginAs() which allows a functional test to login a user, so I can proceed with tests that require a user to be logged in. See the following excerpt from AuthTestCase.php:
$token = new UsernamePasswordToken($user, $user->getPassword(), 'main', $user->getRoles());
self::$kernel->getContainer()->get('security.context')->setToken($token);
After calling loginAs() in my functional test, it appears as if the token has been set successfully, when inspecting with XDebug.
After ->loginAs() and before $client->request()
After calling $client->request('GET', '/'), token is now NULL
Note the address reference in the watch window *@140734957951456*, just to clarify that we are not looking at a different object here!
After the call to $client->getRequest(), however, the token is null, meaning the test fails, as it sees no user as authenticated / logged in. The test fails as we expect a 200 HTTP Response, but getting a 302 Redirect to /login.
I traced around and stepped some code with XDebug, and found that the token gets nullified in : ContextListener.php:77
if (null === $session || null === $token = $session->get('_security_'.$this->contextKey)) {
$this->context->setToken(null);
}
The user assigned to the token exists in the DB, and is successfully being fetched, and the UserPasswordToken appears to be valid.
The only way I can get these tests to pass, like they did when I was still on Symfony 2.0.16, is by commenting out ContextListener.php:77
\\ $this->context->setToken(null);
I hope someone can find a fix for this, as it's quite important to be able to set authentication tokens, and user password tokens during WebTestCase test methods. Otherwise, how does one do functional tests on for example, admin consoles where a specific user role and authentication is required?
If I am doing authenticated functional tests wrong, and Symfony 2.1 has a different mechanism for doing authenticated tests, please give me a shout.