Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot get user from Security Context in test environment

I'm trying to test an API call method which is securized using Basic Auth and which needs to retrieve the user from the security context.

My config_test.yml file (I'm using in-memory database for test env):

imports:
    - { resource: config_dev.yml }

doctrine:
    dbal:
        driver: pdo_sqlite
        path: :memory:
        memory: true
    orm:
        auto_generate_proxy_classes: %kernel.debug%
        auto_mapping: true

framework:
    test: ~
    session: ~ 
    profiler:
        enabled: false

web_profiler:
    toolbar: false
    intercept_redirects: false

swiftmailer:
    disable_delivery: true

I've created a test where I instantiate a client as follows:

    $options =  array(
        'environment' => 'test',
        'debug'       => true,
    );

    $this->client = static::createClient($options);

The test looks like:

public function testProfileAction()
{
    $mockUser = new User();
    $mockUser->setUsername("user");
    $mockUser->setEmail("[email protected]");
    $mockUser->setName("User");
    $mockUser->setSurname("User");
    $mockUser->setPlainPassword("1234567890");
    $this->em->persist($mockUser);
    $this->em->flush();

    $crawler = $this->client->request('GET', '/api/1/user/profile', array(), array(), array(
        'PHP_AUTH_USER' => 'user',
        'PHP_AUTH_PW'   => '1234567890',
    ));
    $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
}

And the method needs to get the user from the security context.

$user = $this->get('security.context')->getToken()->getUser();

But, running the tests I always get a 401 instead of a 200. Dumping the $user variable in method is always null.

I'm using Symfony 2.2 and FOSUserBundle.

Thanks in advance.

like image 382
Gabriel Gcia Fdez Avatar asked May 30 '13 11:05

Gabriel Gcia Fdez


1 Answers

I had the same problem. As @nifr say, you have to create the token, but you also you have to serialize it and create the cookie. Here is how I did it.

$token = new UsernamePasswordToken($mockUser, null, $firewallName, array($role));
self::$kernel->getContainer()->get('security.context')->setToken($token);
self::$kernel->getContainer()->get('session')->set('security'.$firewallName, serialize($token));
self::$kernel->getContainer()->get('session')->save();

$cookie = new Cookie(self::$kernel->getContainer()->get('session')->getName(),     self::$kernel->getContainer()->get('session')->getId());
$this->client->getCookieJar()->set($cookie);
like image 116
dgil Avatar answered Sep 30 '22 18:09

dgil