I am suspecting that there's a problem with Controller Plugins redirecting when used in Zend Test?
I have a controller plugin like http://pastie.org/1422639 I have put echo statements for debugging. I have code for redirecting to login if user is not logged in
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, ';
} ...
I find that when unit tesing, eg
$this->dispatch('/projects');
The output I got was
projects (ok I requested the projects page/controller), no id (ok, I am not logged in), got redir (I got the redirector ok), redirecting (it seem to be redirecting ok ...), error (but I got to the error controller) no resource,
the reason why I got to the error controller it seems is I still got to the projects/index page. in the index action, I assumed that the user is logged in. But when it tries to get the logged in user
$user = \Zend_Auth::getInstance()->getIdentity();
It fails ...
How can I have redirectors working in Zend Test? Or maybe its not a problem with redirectors?
It's a two-part problem. First, the redirector by default calls PHP's
exit
after redirecting, which causes Zend_Test to cease execution. In your tests, you have to configure the redirector not to do that. Something like this:But the problem in Controller Plugins is that after using a redirector, there's no way to prevent Zend Framework from going into the dispatch loop and trying to execute an action method anyway. I've read in various form posts (can't remember where offhand) that this is a known issue in Zend Framework which the developers are planning to address. For now, I work around this by adding a method like this into my Error Controller:
Then in my controller plugins, I have a custom method for calling a redirect:
By doing this, you move the actual call to the redirector into the controller layer of your app, which enables unit testing to work properly (a.k.a.
$this->assertRedirectTo('/blah/blah');
.) This modifies the request to point to thepluginRedirectorAction()
method in your Error Controller shown above. Redirects within your controller plugins are now called like this:But it won't work from within the
routeStartup()
method because ZF fires up the router right after that, which will override the request parameters that theredirect()
method specified. You'll have to rework the plumbing of your plugin to call your redirects fromrouteShutdown()
or other methods that are called even later in the dispatch cycle. (I've only tested this withinrouteShutdown()
.)