mrtnzlml-archive / testbench

:green_apple: Simple integration testing tool for Nette applications
http://zlml.cz/jednoduche-testovani-pro-uplne-kazdeho
41 stars 13 forks source link

Http Return code - cli sapi vs cgi sapi #34

Closed Valicek1 closed 8 years ago

Valicek1 commented 8 years ago

When using TPresenter, $this->getReturnCode is always '200'

ErrorPresenter.php:

<?php

namespace App\Presenters;

use Nette,
    App\Model,
    Nette\Diagnostics\Debugger;

/**
 * Error presenter.
 */
class ErrorPresenter extends BasePresenter
{

    /**
     * @param  Exception
     * @return void
     */

    public function actionDefault($exception)
    {

        if ($exception instanceof Nette\Application\BadRequestException) {
            $code = $exception->getCode();
        } else {
            $code = 500;
        }
        /** @var Nette\Http\IResponse $response */
        $response = $this->context->getService("http.response");
        $response->setCode($code);

    }

    public function renderDefault($exception)
    {

        if ($exception instanceof Nette\Application\BadRequestException) {
            $code = $exception->getCode();
            // load template 403.latte or 404.latte or ... 4xx.latte
            $this->setView(in_array($code, array(403, 404, 405, 410, 500)) ? $code : '4xx');
            // log to access.log
            Debugger::log("HTTP code $code: {$exception->getMessage()} in {$exception->getFile()}:{$exception->getLine()}",
                'access');
        } else {
            $this->setView('500'); // load template 500.latte
            Debugger::log($exception, Debugger::ERROR); // and log exception
        }

        if ($this->isAjax()) { // AJAX request? Note this error in payload.
            $this->payload->error = TRUE;
            $this->terminate();
        }
    }

}

Error:default

$r = $this->check("Error:default"); # sets code to 500
Assert::same(500, $this->getReturnCode()); # CLI -> FAIL(200); CGI -> OK
Assert::same(500, $this->getContainer()->getService('http.response')->getCode());  # CLI -> OK; CGI -> OK

Error:default - 404 not found (Passed exception with code as parameter)

$exc = new Nette\Application\BadRequestException("Not Found", 404);
$this->check("Error:default", ["exception" => $exc]);
Assert::same(404, $this->getReturnCode()); # CLI -> FAIL(200); CGI -> OK
Assert::same(404, $this->getContainer()->getService('http.response')->getCode()); # Both OK

Nette Tester 1.7 used as default one PHP-CGI (cgi-fcgi) SAPI, but dev-master (2.x) uses as default SAPI CLI.

Maybe, checkAction could have fourth parameter returnCode defaulting 200 to be able to easily test for example the ErrorPresenter and other situations with HTTP codes different from 200.

mrtnzlml commented 8 years ago

It's not always 200, but I'll look into it. Thanks for those reports... :)

Valicek1 commented 8 years ago

Made some tests... Maybe, it isn't caused by SAPI, but by combination of my code and how your code works. Tester grabs the exception that was thrown and then extracts code. If no exception is thrown, return is 200. But in my error presenter, there is no error thrown. Nette passes catched exception as parameter (and I do the same in my test case) to the ErrorPresenter - and presenters work is to set correct HTTP Status Code.

Maybe, it would be nice to implement something like this:

// ....
// nearly to the end of TPresenter::check
// no exception was thrown - try to get real httpCode from response
$this->__testbench_httpCode = $container->getService('http.response')->getCode());

return $response;
//.... 
Valicek1 commented 8 years ago

After some tests, I have figured out that Errors were not caused by testbench, but nette tester itself. And yes, it was under CGI/FCGI only - look at this piece of code. My shame, I'm sorry for this issue.

mrtnzlml commented 8 years ago

So there is nothing I can solve or improve? May I close this issue?

Valicek1 commented 8 years ago

Yes, this can be closed. I'll do.