I have a Symfony 4.4 project. Login, authentication, and authorization work fine on web.
To simulate authentication in unit tests, I'm using Symfony's example.
...but that's not working. The user is not authenticated in the unit test. I get an Unauthorized with error message "Full authentication is required to access this resource."
My test:
namespace App\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
class DefaultControllerTest extends WebTestCase
{
private $client = null;
public function setUp()
{
$this->client = static::createClient();
}
public function testJsonUserEndpoint()
{
$this->logIn();
$crawler = $this->client->request('GET', '/json/user');
$this->assertNotContains('invalid_credentials', $this->client->getResponse()->getContent());
}
private function logIn()
{
$user = self::$container->get(EntityManagerInterface::class)->getRepository(User::class)->findOneByMail('test106@test.com');
$session = $this->client->getContainer()->get('session');
$firewallName = 'main';
$firewallContext = 'main';
$token = new PostAuthenticationGuardToken($user, $firewallName, ['ROLE_USER']);
$session->set('_security_'.$firewallContext, serialize($token));
$session->save();
$cookie = new Cookie($session->getName(), $session->getId());
$this->client->getCookieJar()->set($cookie);
}
}
My firewall:
main:
anonymous:
secret: '%env(APP_SECRET)%'
remember_me:
always_remember_me: true
secret: '%env(APP_SECRET)%'
provider: session_user_provider
guard:
authenticators:
- App\Security\Authenticator\LoginAuthenticator
- App\Security\Authenticator\MobileBridgeAuthenticator
- App\Security\Authenticator\BearerTokenAuthenticator
- App\Security\Authenticator\HashAuthenticator
- App\Security\Authenticator\ClientAuthenticator
entry_point: App\Security\Authenticator\LoginAuthenticator
logout:
path: execute_logout
target: render_login
Unit test failure:
1) App\Tests\Controller\DefaultControllerTest::testJsonUserEndpoint
Failed asserting that '{"status":"invalid_credentials","errors":["Invalid Credentials"],"debug":"Full authentication is required to access this resource.","error":"Unauthorized"}' does not contain "invalid_credentials".
How can I authenticate a user in my unit tests without using the login form?