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

/**
 * @category   Core
 * @package    Core_Router
 * @subpackage UnitTests
 * @copyright  Copyright (c) 2011. Burza d.o.o. (http://web.burza.hr/en/)
 * @license    proprietary
 * @group      Core_Router
 * @group      Core_Router_Route
 */
class Core_Router_Route_Plugin_AbstractTest extends PHPUnit_Framework_TestCase
{
    /**
     * @var Core_Router_Route_Plugin_Abstract
     */
    protected $_object;

    protected function setUp()
    {
        $this->_object = $this->getMockForAbstractClass('Core_Router_Route_Plugin_Abstract');
    }

    /**
     * @covers Core_Router_Route_Plugin_Abstract::getHeadersRequest
     */
    public function testCanGetRequestedHeaders()
    {
        $object = new Invalid_Router_Route_Plugin_HeadersRequest;
        $this->assertEquals(array('Foo', 'Bar'), $object->getHeadersRequest());
    }

    /**
     * @covers Core_Router_Route_Plugin_Abstract::setName
     * @covers Core_Router_Route_Plugin_Abstract::getName
     */
    public function testCanSetAndGetName()
    {
        $this->_object->setName('foo');
        $this->assertEquals('foo', $this->_object->getName());
    }

    /**
     * @covers Core_Router_Route_Plugin_Abstract::setRoute
     * @covers Core_Router_Route_Plugin_Abstract::getRoute
     */
    public function testCanSetAndGetRoute()
    {
        $route = $this->getMock('Core_Router_Route_Interface');
        $this->_object->setRoute($route);
        $this->assertEquals($route, $this->_object->getRoute());
    }

    /**
     * @covers Core_Router_Route_Plugin_Abstract::setOptions
     */
    public function testCanSetOptions()
    {
        $options = array(
            'name' => 'foo',
        );
        $this->_object->setOptions($options);
        $this->assertEquals('foo', $this->_object->getName());
    }

    /**
     * @covers Core_Router_Route_Plugin_Abstract::__construct
     */
    public function testCanSetOptionsViaConstructor()
    {
        $options = array(
            'name' => 'foo',
        );
        $object = $this->getMockForAbstractClass('Core_Router_Route_Plugin_Abstract', array($options));
        $this->assertEquals('foo', $object->getName());
    }

    /**
     * @covers Core_Router_Route_Plugin_Abstract::setOptions
     */
    public function testSettingUnknownOptionsThrowsAnInvalidArgumentException()
    {
        $this->setExpectedException('InvalidArgumentException');
        $this->_object->setOptions(array('no-such' => 'option'));
    }


    /**
     * @covers Core_Router_Route_Plugin_Abstract::match
     */
    public function testValuesReturnedFromModelWillBeStoredAsRouteValues()
    {
        $route  = $this->getMock('Core_Router_Route_Interface');
        $route
            ->expects($this->once())
            ->method('addValues')
            ->with($this->equalTo(array('some', 'output')));

        $object = $this->getMock('Core_Router_Route_Plugin_Abstract', array('_match', 'getRoute'));
        $object
            ->expects($this->once())
            ->method('getRoute')
            ->will($this->returnValue($route));
        $object
            ->expects($this->once())
            ->method('_match')
            ->with($this->equalTo(array('some', 'input')), $this->equalTo(array()))
            ->will($this->returnValue(array('some', 'output')));

        $this->assertTrue($object->match(array('some', 'input'), array()));
    }

    /**
     * @covers Core_Router_Route_Plugin_Abstract::match
     */
    public function testIfNotAllRequestedHeadersAreInjectedToMatchWillThrowAnInvalidArgumentException()
    {
        $object = new Invalid_Router_Route_Plugin_HeadersRequest;
        $object->headersRequest = array('Foo', 'Bar', 'Bat');

        $this->setExpectedException('InvalidArgumentException');

        // not supplying Bar & Bat
        $object->match(array(), array('Foo' => 23));
    }
}

class Invalid_Router_Route_Plugin_HeadersRequest extends Core_Router_Route_Plugin_Abstract
{
    public $headersRequest = array('Foo', 'Bar');

    public function getHeadersRequest()
    {
        parent::getHeadersRequest();
        return $this->headersRequest;
    }

    protected function _match(array $values, array $request = null)
    {

    }
}

