Как написать функциональный тест с аутентификацией пользователя?

Я пишу функциональный тест для страницы, требующей аутентификации пользователя. Я использую плагин sfDoctrineGuard.

Как аутентифицировать пользователя в моем тесте?

Должен ли я входить в каждый тест через экран входа?

Вот мой неправильный код:

$b->post('/sfGuardAuth/signin',
       array('signin[password]' => 'password',
             'signin[username]' => 'user',
             'signin[_csrf_token]' => '7bd809388ed8bf763fc5fccc255d042e'))->
       with('response')->begin()->
         checkElement('h2', 'Welcome Humans')->
       end()

Спасибо


person Christopher Altman    schedule 07.10.2010    source источник


Ответы (2)



Сложность входа в систему заключается в том, что тестовый браузер стирает объект контекста перед каждым запросом (см. sfBrowser::call()).

Вы можете аутентифицировать пользователя, внедрив прослушиватель, который будет вызывать пользовательский метод signIn(), когда событие context.load_factories срабатывает во время инициализации контекста:

function signin( sfEvent $event )
{
  /* @var $user sfGuardSecurityUser */
  if( ! $user = $event->getSubject()->getUser() )
  {
    throw new RuntimeException('User object not created.');
  }

  if( ! $user instanceof sfGuardSecurityUser )
  {
    throw new LogicException(sprintf(
      'Cannot log in %s; sfGuardSecurityUser expected.',
        get_class($user)
    ));
  }

  if( $user->isAuthenticated() )
  {
    $user->signOut();
  }

  /* Magic happens here: */
  $user->signIn($desired_user_to_log_in_as);

  $event->getSubject()->getEventDispatcher()->notify(new sfEvent(
    $this,
    'application.log',
    array(sprintf('User is logged in as "%s".', $user->getUsername()))
  ));
}

/* Set signin() to fire when the browser inits the context for subsequent
 *  requests.
 */
$b->addListener('context.load_factories', 'signin');

Это заставит браузер выполнять вход пользователя для всех последующих запросов. Обратите внимание, что sfBrowser нет метода removeListener().

Взято из sfJwtPhpUnitPlugin (ФД: я ведущий разработчик этого проекта).

person Community    schedule 17.12.2011
comment
Удивительный! Просто хочу сказать, что когда метод входа определен в каком-либо дочернем классе sfTestFunctional, вложение слушателя должно вызываться следующим образом: $b-›addListener('context.load_factories', array($b, 'signin')); - person Dmitriy; 05.01.2012
comment
Мне нужно было принудительно войти в систему позже в процессе начальной загрузки symfony, потому что myUser моего приложения зависит от маршрута. Поэтому вместо этого я использовал $b-›addListener('controller.change_action', 'signin'). - person cmc; 09.02.2016