Cannot get user from Security Context in test environment
Asked Answered
G

2

6

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.

Gera answered 30/5, 2013 at 11:36 Comment(0)
N
5

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);
Noh answered 30/5, 2013 at 13:37 Comment(0)
B
0

You have to create the token first in order to access it from the security context.

$firewallName = 'main';
$role = 'ROLE_USER';

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

Example adapted to your case from here.

Brachial answered 30/5, 2013 at 12:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.