<?php
/**
 * core.framework
 *
 * @category   Core
 * @package    Core_Application
 * @subpackage UnitTests
 * @copyright  Copyright (c) 2013. Burza d.o.o. (http://web.burza.hr/en/)
 * @license    proprietary
 */

/**
 * @category   Core
 * @package    Core_Application
 * @subpackage UnitTests
 * @copyright  Copyright (c) 2013. Burza d.o.o. (http://web.burza.hr/en/)
 * @license    proprietary
 * @group      Core_Application
 * @group      Core_Application_Plugin
 */
class Core_Application_Plugin_EventHandler_AbstractTest extends CoreTest_Container_TestCase
{
    /**
     * @var Core_Application_Plugin_EventHandler_Abstract
     */
    protected $_object;

    protected function setUp()
    {
        $class         = 'Core_Application_Plugin_EventHandler_Abstract';
        $this->_object = $this->getMockForAbstractClass($class, array('EventHandler'));
    }

    protected function tearDown()
    {
        Core_Application::resetInstance();
    }

    /**
     * @covers Core_Application_Plugin_EventHandler_Abstract::setDispatcher
     * @covers Core_Application_Plugin_EventHandler_Abstract::getDispatcher
     */
    public function testCanGetAndSetDispatcher()
    {
        $dispatcher = $this->getMock('Core_Dispatcher');
        $this->_object->setDispatcher($dispatcher);

        $this->assertEquals($dispatcher, $this->_object->getDispatcher());
    }

    /**
     * @covers Core_Application_Plugin_EventHandler_Abstract::getDispatcher
     * @depends testCanGetAndSetDispatcher
     */
    public function testIfDispatcherNotSetWillPullFromApplicationAsDispatcher()
    {
        $dispatcher = $this->getMock('Core_Dispatcher');
        $container  = $this->_mockContainer('Dispatcher', $dispatcher);
        Core_Application::getInstance()->setContainer($container);

        $this->assertEquals($dispatcher, $this->_object->getDispatcher());
    }

    /**
     * @covers Core_Application_Plugin_EventHandler_Abstract::setEventDispatcher
     * @covers Core_Application_Plugin_EventHandler_Abstract::getEventDispatcher
     */
    public function testCanGetAndSetEventDispatcher()
    {
        $eventDispatcher = $this->getMock('Core_Event_Dispatcher');
        $this->_object->setEventDispatcher($eventDispatcher);

        $this->assertEquals($eventDispatcher, $this->_object->getEventDispatcher());
    }

    /**
     * @covers Core_Application_Plugin_EventHandler_Abstract::getEventDispatcher
     * @depends testCanGetAndSetEventDispatcher
     */
    public function testIfEventDispatcherNotSetWillUseDispatcherEventDispatcher()
    {
        $eventDispatcher = $this->getMock('Core_Event_Dispatcher');
        $dispatcher      = $this->getMock('Core_Dispatcher');
        $dispatcher
            ->expects($this->once())
            ->method('getEventDispatcher')
            ->will($this->returnValue($eventDispatcher));
        $this->_object->setDispatcher($dispatcher);

        $this->assertEquals($eventDispatcher, $this->_object->getEventDispatcher());
    }

    /**
     * @covers Core_Application_Plugin_EventHandler_Abstract::setResourceFinder
     * @covers Core_Application_Plugin_EventHandler_Abstract::getResourceFinder
     */
    public function testCanSetAndGetResourceFinder()
    {
        $finder = $this->getMock('Core_Module_ResourceFinder');
        $this->_object->setResourceFinder($finder);

        $this->assertEquals($finder, $this->_object->getResourceFinder());
    }

    /**
     * @covers Core_Application_Plugin_EventHandler_Abstract::getResourceFinder
     */
    public function testIfNoResourceFinderIsSpecifiedItWillPullAnInstanceFromApplicationAsResourceFinder()
    {
        $finder    = $this->getMock('Core_Module_ResourceFinder');
        $container = $this->_mockContainer('ResourceFinder', $finder);
        Core_Application::getInstance()->setContainer($container);

        $this->assertEquals($finder, $this->_object->getResourceFinder());
    }

    /**
     * @covers Core_Application_Plugin_EventHandler_Abstract::init
     * @depends testCanGetAndSetEventDispatcher
     */
    public function testWillSubscribeToDispatcherEventWithDefinedHandler()
    {
        $object          = new Invalid_Application_Plugin_EventHandlerSubscriber('EHS');

        $eventDispatcher = $this->getMock('Core_Event_Dispatcher');
        $eventDispatcher
            ->expects($this->at(0))
            ->method('subscribe')
            ->with(
                $this->equalTo('someEvent'),
                $this->equalTo(array($object, 'eventHandler')),
                $this->equalTo(-10),
                $this->equalTo(null)
            );
        $eventDispatcher
            ->expects($this->at(1))
            ->method('subscribe')
            ->with(
                $this->equalTo('someEvent2'),
                $this->equalTo(array($object, 'eventHandler')),
                $this->equalTo(99),
                $this->equalTo('foo')
            );
        $object->setEventDispatcher($eventDispatcher);

        $object->init();
    }
}

class Invalid_Application_Plugin_EventHandlerSubscriber extends Core_Application_Plugin_EventHandler_Abstract
{
    protected $_subscriptions = array(
        array(
            'event'    => 'someEvent',
            'method'   => 'eventHandler',
            'priority' => -10,
        ),
        array(
            'event'    => 'someEvent2',
            'method'   => 'eventHandler',
            'priority' => 99,
            'filter'   => 'foo',
        )
    );

    public function eventHandler(Core_Event_Interface $event, $data = null)
    {
    }
}