<?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';

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()
    {
        if (!defined('DEBUG')) {
            define('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 = $this->getMock('Error404Exception', array('getMessage', 'getFile', 'getLine', 'getTrace'));
        $exception->expects($this->once())
                ->method('getTrace')
                ->will($this->returnValue(array('one' => array('class' => 'AjaxAction'))));

        $action = new ErrorAction($exception);
        $this->assertSame($exception, $action->exception);
    }

    /**
     * @runInSeparateProcess
     */
    public function testError404NoAjax()
    {
        $this->setConstants(false);
        $exception = $this->getMock('Error404Exception', array('getMessage', 'getFile', 'getLine', 'getTrace'));
        $exception->expects($this->once())
                ->method('getTrace')
                ->will($this->returnValue(array('one' => array('class' => 'Action'))));

        $action = new ErrorAction($exception);
        $this->assertSame($exception, $action->exception);
    }

    private function setConstants($val = false)
    {
        if (!defined('DEBUG')) {
            define('DEBUG', $val);
        }
    }

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

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