Плагины Zend_Test & Controller для ACL (перенаправление)

Я подозреваю, что существует проблема с перенаправлением плагинов контроллера при использовании в Zend Test?

У меня есть плагин контроллера, такой как http://pastie.org/1422639 Я поставил эхо-операторы для отладки. У меня есть код для перенаправления на вход, если пользователь не вошел в систему

if (!$auth->hasIdentity()) {
  echo 'no id, ';
  // redirect to login page
  $req->setDispatched(true);
  $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');echo 'got redir, ';
  $redirector->gotoUrl('/auth/login?returnUrl=' . urlencode($req->getRequestUri()));echo 'redirecting, ';
} ...

Я считаю, что при модульном тестировании, например,

$this->dispatch('/projects');

Вывод, который я получил, был

проекты (хорошо, я запросил страницу проектов / контроллер), без идентификатора (хорошо, я не вошел в систему), получил перенаправление (у меня перенаправитель в порядке), перенаправление (кажется, перенаправление нормально...), ошибка (но Добрался до контроллера ошибок) нет ресурса,

Кажется, причина, по которой я попал в контроллер ошибок, в том, что я все еще попал на страницу проектов / индекса. в действии index я предположил, что пользователь вошел в систему. Но когда он пытается получить вошедшего в систему пользователя

$user = \Zend_Auth::getInstance()->getIdentity();

Это не удается...

Как я могу иметь редиректоры, работающие в Zend Test? Или не проблема с редиректорами?

1 ответ

Решение

Это проблема из двух частей. Во-первых, по умолчанию перенаправитель вызывает PHP exit после перенаправления, что приводит к прекращению выполнения Zend_Test. В ваших тестах вы должны настроить редиректор, чтобы не делать этого. Что-то вроде этого:

$redirector = new Zend_Controller_Action_Helper_Redirector();
if (APPLICATION_ENV == 'testing') {
    $redirector->setExit(false);
}
$redirector->gotoUrl("/blah/blah");

Но проблема в плагинах контроллеров заключается в том, что после использования перенаправителя невозможно предотвратить переход Zend Framework в цикл диспетчеризации и попытку выполнить метод действия в любом случае. Я читал в различных постах (не помню, где это было случайно), что это известная проблема в Zend Framework, которую разработчики планируют решить. Сейчас я работаю над этим, добавив такой метод в мой контроллер ошибок:

public function pluginRedirectorAction() {
    $this->_helper->layout()->disableLayout();
    $this->_helper->viewRenderer->setNoRender();

    $code = $this->_getParam('code');
    $uri = $this->_getParam('uri');

    if (APPLICATION_ENV == 'testing') {
        $this->_helper->redirector->setExit(false);
    }
    $this->_helper->redirector->setCode($code);
    $this->_helper->redirector->gotoUrl($uri);
}

Затем в моих плагинах контроллера у меня есть собственный метод для вызова перенаправления:

protected function redirect($code, $uri) {
    $redirector = new Zend_Controller_Action_Helper_Redirector();

    if (APPLICATION_ENV == 'testing') {
        $request = $this->getRequest();
        $request->setModuleName('default');
        $request->setControllerName('error');
        $request->setActionName('plugin-redirector');
        $request->setParam('code', $code);  
        $request->setParam('uri', $uri);

        $redirector->setExit(false);
    }

    $redirector->setCode($code);
    $redirector->gotoUrl($uri);
}

Делая это, вы перемещаете фактический вызов перенаправителя на уровень контроллера вашего приложения, что позволяет модульному тестированию работать должным образом (иначе $this->assertRedirectTo('/blah/blah');.) Это изменяет запрос, чтобы указать на pluginRedirectorAction() метод в вашем контроллере ошибок, показанном выше. Перенаправления в плагинах вашего контроллера теперь называются так:

return $this->redirect(307, '/somewhere/else');

Но это не будет работать изнутри routeStartup() метод, потому что ZF запускает маршрутизатор сразу после этого, что переопределит параметры запроса, которые redirect() указанный метод Вам придется переделать плагин вашего плагина, чтобы вызвать ваши перенаправления с routeShutdown() или другие методы, которые вызываются даже позже в цикле отправки. (Я только проверил это в routeShutdown().)

Другие вопросы по тегам