<?php

/*
 * @copyright NetMonsters <team@netmonsters.ru>
 * @link http://netmonsters.ru
 * @package Majestic
 * @subpackage UnitTests
 * @since 2011-11-1
 * 
 * Unit tests for ErrorAction class
 */

require_once dirname(__FILE__) . '/Action_TestCase.php';
require_once dirname(__FILE__) . '/../../app/ErrorAction.php';
require_once dirname(__FILE__) . '/../../exception/GeneralException.php';
require_once dirname(__FILE__) . '/../../exception/ErrorHTTPException.php';
require_once dirname(__FILE__) . '/../../exception/Error404Exception.php';

class ErrorActionTest extends Action_TestCase
{

    private $log;

    public function setUp()
    {
        parent::setUp();

        $this->log = ini_get('error_log');
        ini_set('error_log', '/dev/null');
        set_exit_overload(function () {
            return false;
        });
    }

    /**
     * @runInSeparateProcess
     */
    public function testErrorExceptionNotice()
    {
        $this->setConstants(false);
        $exception = $this->getMock('ErrorException', array(), array('', 0, E_NOTICE));
        $action = new ErrorAction($exception);
        $this->assertSame($exception, $action->exception);
    }

    /**
     * @runInSeparateProcess
     */
    public function testErrorExceptionWarning()
    {
        $this->setConstants(false);
        $exception = $this->getMock('ErrorException', array(), array('', 0, E_WARNING));
        $action = new ErrorAction($exception);
        $this->assertSame($exception, $action->exception);
    }

    /**
     * @runInSeparateProcess
     */
    public function testErrorExceptionError()
    {
        $this->setConstants(false);
        $exception = $this->getMock('ErrorException', array(), array('', 0, E_ERROR));
        $action = new ErrorAction($exception);
        $this->assertSame($exception, $action->exception);
    }

    /**
     * @runInSeparateProcess
     */
    public function testErrorExceptionCustom()
    {
        $this->setConstants(false);
        $exception = $this->getMock('ErrorException', array(), array('', 0, 211));
        $action = new ErrorAction($exception);
        $this->assertSame($exception, $action->exception);
    }


    /**
     * @runInSeparateProcess
     */
    public function testFetchNoTemplate()
    {

        Config::set('DEBUG', false);
        $exception = $this->getMock('ErrorException');
        $controller = FrontController::getInstance();
        $controller->setView('SomeView');
        $action = new ErrorAction($exception);
        $result = $action->fetch();
        $this->assertSame('/actions/500', $result['template']);
    }

    /**
     * @runInSeparateProcess
     */
    public function testError404WithAjax()
    {
        $this->setConstants(false);
        $exception = new Error404Exception('Some message');

        $controller = FrontController::getInstance();
        $controller->setView('SomeView');
        $action = new ErrorAction($exception);
        $action->setAjaxError();
        $this->assertSame($exception, $action->exception);
        $result = $action->fetch();
        $this->assertSame('Some message', $result);
    }

    /**
     * @runInSeparateProcess
     */
    public function testError404NoAjax()
    {
        $this->setConstants(false);
        $exception = new Error404Exception('Some message');

        $controller = FrontController::getInstance();
        $controller->setView('SomeView');
        $action = new ErrorAction($exception);
        $this->assertSame($exception, $action->exception);
        $result = $action->fetch();
        $this->assertSame('/actions/404', $result['template']);
    }

    /**
     * @runInSeparateProcess
     */
    public function testErrorHTTP()
    {
        $this->setConstants(false);
        $exception = new ErrorHTTPException('Some message', 410);

        $controller = FrontController::getInstance();
        $controller->setView('SomeView');
        $action = new ErrorAction($exception);
        $this->assertSame($exception, $action->exception);
        $result = $action->fetch();
        $this->assertSame('/actions/HTTP', $result['template']);
    }

    private function setConstants($val = false)
    {

        Config::set('DEBUG', $val);
    }

    private function header()
    {
        ob_end_clean();
        flush();
    }

    public function tearDown()
    {
        parent::tearDown();
        ini_set('error_log', $this->log);
        unset_exit_overload();
    }
}