Модульное тестирование FOSUserBundle
Я работаю над созданием сайта с fosUserBundle. Мне нужно написать несколько модульных тестов, но я не могу заставить аутентификацию работать правильно для использования с ними. Я попробовал несколько методов, но безуспешно.
Approach1-цепочка поставщиков в настройках безопасности, чтобы сделать стандартный вход, на который я могу положиться. Когда я делаю это, единственная аутентификация, которая работает, - это поставщик in_memory, то есть я могу войти в систему с пользователем admin, но не с любыми пользователями, созданными fosUserBundle
Безопасность.yml
security:
encoders:
"FOSUserBundleModelUserInterface": plaintext
"SymfonyComponentSecurityCoreUserUser": plaintext
providers:
chain_provider:
providers: [in_memory, fos_userbundle]
in_memory:
users:
admin: { password: admin, roles: [ 'ROLE_ADMIN' ] }
fos_userbundle:
id: fos_user.user_manager
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
login_path: /
csrf_provider: form.csrf_provider
default_target_path: /media
logout: true
anonymous: true
http_basic:
provider: in_memory
Метод 2-я создал пользователя в своей настройке модульного теста. Но с помощью этого метода я никогда не смогу войти в систему с пользователем, которого я только что создал, мне не требуется подтверждение пользователя.
public function setUp() {
$kernel = static::createKernel();
$this->repo = $kernel->boot();
$this->repo = $kernel->getContainer();
$userManager = $this->repo->get('fos_user.user_manager');
$email = "testing".(string) self::newRandomNumber()."@test.com";
$un = "test".(string) self::newRandomNumber();
$fn = "testin";
$ln = "laster";
$pwd = "passworD1";
$user = $userManager->createUser();
$user->setEmail($email);
$user->setUsername($un);
$user->setFirstName($fn);
$user->setLastName($ln);
$user->setPlainPassword($pwd);
$user->setBimStaff(True);
// Persist the user to the database
$userManager->updateUser($user);
$this->user = $user;
$this->client = static::createClient();
$crawler = $this->client->request('GET', '/');
$form = $crawler->selectButton('Login')->form();
// set some values
$un = 'Lucas'.self::newRandomNumber();
$form['_username'] = $un;
$form['_password'] = $pwd;
// submit the form
$crawler = $this->client->submit($form);
print_r($this->client->getResponse());
$this->client->followRedirects();
}
Я пробовал как войти в форму, так и обычную аутентификацию http, но ни то, ни другое не работает.
Любое одно имеет какие-либо советы?
Спасибо, Кори
2 ответа:
Хм, похоже, что если вы цепочка поставщиков в безопасности вы не можете использовать только один из поставщиков, по крайней мере, это решило проблему для меня.
По какой-то причине, как только я поменял обоих провайдеров на// security.yml providers: chain_provider: providers: [in_memory, fos_userbundle] in_memory: users: admin: { password: admin, roles: [ 'ROLE_ADMIN' ] } fos_userbundle: id: fos_user.user_manager firewalls: main: pattern: ^/ form_login: provider: chain_provider login_path: / csrf_provider: form.csrf_provider default_target_path: /media logout: true anonymous: true http_basic: provider: chain_providerchain_provider, он начал сотрудничать.Мой модульный тест теперь выглядит так
public function setUp() { $kernel = static::createKernel(); $this->repo = $kernel->boot(); $this->repo = $kernel->getContainer(); $this->client = static::createClient(array(), array( 'PHP_AUTH_USER' => 'admin', 'PHP_AUTH_PW' => 'admin', )); $this->client->followRedirects(); }
При копировании этого я бы предложил использовать более надежные пароли для ваших пользователей:)
У меня была та же проблема, но я хотел, чтобы Вариант 2 работал. Ваш пример был почти там и помог мне. Я думаю, что причина, по которой он не работал для вас, заключается в том, что пользователь не был включен. Конструктор пользователей в FOSUserBundle по умолчанию создает отключенных пользователей, поэтому необходимо вызвать
$user->setEnable(true)Вот мой рабочий пример
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\BrowserKit\Cookie; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; class MyControllerTest extends WebTestCase { private $client = null; public function setUp() { $this->client = static::createClient(); } private function logIn() { $session = $this->client->getContainer()->get('session'); $userManager = $this->client->getContainer()->get('fos_user.user_manager'); $user=$userManager->findUserByUsername('tester'); if (!$user) { $user = $userManager->createUser(); $user->setEmail('test@example.com'); $user->setUsername('tester'); $user->setPlainPassword('foo'); $user->setEnabled(true); $user->addRole('ROLE_SUPER_ADMIN'); $userManager->updateUser($user); } $firewall = 'main_firewall'; $token = new UsernamePasswordToken($user, null, $firewall, array('ROLE_SUPER_ADMIN')); $session->set('_security_'.$firewall, serialize($token)); $session->save(); $cookie = new Cookie($session->getName(), $session->getId()); $this->client->getCookieJar()->set($cookie); } public function testCompleteScenario() { $this->logIn(); $crawler = $this->client->request('GET', '/foo/'); $this->assertEquals(200, $this->client->getResponse()->getStatusCode(), "Unexpected HTTP status code for GET /foo/".$this->client->getResponse()->getContent()); } }