Модульное тестирование 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_provider
chain_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()); } }