Что бы я сделал в этом случае, так это создал CustomWebTestCase
, который расширяет Symfony WebTestCase
. В классе я бы создал метод, который выполняет аутентификацию для меня.
Вот пример кода:
namespace Company\MyBundle\Classes;
use Symfony\Bundle\FrameworkBundle\Client;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\User\User;
abstract class CustomWebTestCase extends WebTestCase
{
/**
* @param array|null $roles
* @return \Symfony\Bundle\FrameworkBundle\Client
*/
protected static function createAuthenticatedClient(array $roles = null) {
// Assign default user roles if no roles have been passed.
if($roles == null) {
$role = new Role('ROLE_SUPER_ADMIN');
$roles = array($role);
} else {
$tmpRoles = array();
foreach($roles as $role)
{
$role = new Role($role, $role);
$tmpRoles[] = $role;
}
$roles = $tmpRoles;
}
$user = new User('test_super_admin', 'passwd', $roles);
return self::createAuthentication(static::createClient(), $user);
}
private static function createAuthentication(Client $client, User $user) {
// Read below regarding config_test.yml!
$session = $client->getContainer()->get('session');
// Authenticate
$firewall = 'user_area'; // This MUST MATCH the name in your security.firewalls.->user_area<-
$token = new UsernamePasswordToken($user, null, $firewall, $user->getRoles());
$session->set('_security_'.$firewall, serialize($token));
$session->save();
// Save authentication
$cookie = new Cookie($session->getName(), $session->getId());
$client->getCookieJar()->set($cookie);
return $client;
}
}
Приведенный выше код напрямую создаст действительный сеанс пользователя и полностью пропустит брандмауэр. Поэтому вы можете создать любой $user
, какой захотите, и он все равно будет действительным. Важная часть кода находится в методе createAuthentication
. Вот что делает магия аутентификации.
Еще одна вещь, о которой стоит упомянуть — убедитесь, что вы установили framework.session.storage_id
в session.storage.mock_file
в своем config_test.yml
, чтобы Symfony автоматически имитировала сеансы вместо того, чтобы вам приходилось иметь дело с этим в каждом тестовом случае:
framework:
session:
storage_id: session.storage.mock_file
Теперь в вашем тестовом случае вы просто расширите MyWebTestCase
и вызовете метод createAuthenticatedClient()
:
class MyTest extends CustomWebTestCase {
public function testSomething() {
//Create authoried and unauthorized clients.
$authenticatedClient = self::createAuthenticatedClient(array("ROLE_SUPER_ADMIN"));
$unauthorizedClient = self::createAuthenticatedClient(array("ROLE_INSUFFICIENT_PERMISSIONS"));
// Check if the page behaves properly when the user doesn't have necessary role(s).
$unauthorizedClient->request('GET', '/secured-page');
$response = $unauthorizedClient->getResponse();
$this->assertFalse($response->isSuccessful());
$this->assertEquals(403, $response->getStatusCode(), "This request should have failed!");
// Check if the page behaves properly when the user HAS the necessary role(s)
$authenticatedClient->request('GET', '/secured-page');
$response = $authenticatedClient->getResponse();
$this->assertTrue($response->isSuccessful());
$this->assertEquals(200, $response->getStatusCode(), "This request should be working!");
}
}
Вы также можете увидеть пример в официальной документации Symfony.
person
tftd
schedule
06.03.2016