<?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_ModelTest extends CoreTest_Container_TestCase
{
    /**
     * @var Core_Router_Route_Plugin_Model
     */
    protected $_object;

    protected function setUp()
    {
        $this->_object = new Core_Router_Route_Plugin_Model;
    }

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

    /**
     * @covers Core_Router_Route_Plugin_Model::setOptions
     */
    public function testWhenSettingOptionsWillSkipModel()
    {
        $options = array(
            'model' => $this->getMock('Core_Router_Route_Plugin_Model_Interface'),
        );
        $this->_object->setOptions($options);

        $this->setExpectedException('InvalidArgumentException');
        $this->_object->getModel();
    }

    /**
     * @covers Core_Router_Route_Plugin_Model::setMap
     * @covers Core_Router_Route_Plugin_Model::getMap
     */
    public function testCanSetAndGetMap()
    {
        $map = array('code' => 'category');
        $this->_object->setMap($map);
        $this->assertEquals($map, $this->_object->getMap());
    }

    /**
     * @covers Core_Router_Route_Plugin_Model::setComponent
     * @covers Core_Router_Route_Plugin_Model::getComponent
     */
    public function testCanGetAndSetComponent()
    {
        $this->_object->setComponent('foo');

        $this->assertEquals('foo', $this->_object->getComponent());
    }

    /**
     * @covers Core_Router_Route_Plugin_Model::getComponent
     */
    public function testIfComponentNotSetWillThrowAnInvalidArgumentException()
    {
        $this->setExpectedException('InvalidArgumentException');

        $this->_object->getComponent();
    }

    /**
     * @covers Core_Router_Route_Plugin_Model::setModel
     * @covers Core_Router_Route_Plugin_Model::getModel
     */
    public function testCanGetAndSetModel()
    {
        $model = $this->getMock('Core_Router_Route_Plugin_Model_Interface');
        $this->_object->setModel($model);

        $this->assertEquals($model, $this->_object->getModel());
    }

    /**
     * @covers Core_Router_Route_Plugin_Model::getModel
     */
    public function testIfModelNotSetItWillFetchNamedComponentInstanceFromContainer()
    {
        $model  = $this->getMock('Core_Router_Route_Plugin_Model_Interface');
        $this->_setupMockedModel($model);

        $this->assertEquals($model, $this->_object->getModel());
    }

    /**
     * @covers Core_Router_Route_Plugin_Model::getModel
     * @depends testIfModelNotSetItWillFetchNamedComponentInstanceFromContainer
     */
    public function testComponentMustBeCore_Router_Route_Plugin_Model_InterfaceOrWillThrowAnInvalidArgumentException()
    {
        $this->_setupMockedModel($this->getMock('stdClass'));
        $this->setExpectedException('InvalidArgumentException');

        $this->_object->getModel();
    }

    /**
     * @covers Core_Router_Route_Plugin_Model::match
     * @covers Core_Router_Route_Plugin_Model::<protected>
     */
    public function testWillMatchUsingModel()
    {
        $values = array('a' => 1, 'b' => 2);
        $model  = $this->getMock('Core_Router_Route_Plugin_Model_Interface');
        $model
            ->expects($this->once())
            ->method('match')
            ->with($this->equalTo($values))
            ->will($this->returnValue(true));
        $this->_object->setModel($model);

        $this->assertTrue($this->_object->match($values));
    }

    /**
     * @covers Core_Router_Route_Plugin_Model::match
     * @covers Core_Router_Route_Plugin_Model::<protected>
     */
    public function testWillRemapValuesSentToModelUsingMap()
    {
        $values   = array('category' => 'vijesti', 'bla' => 94,  'id' => 234);
        $map      = array('category' => 'code', 'id' => 'entity_id');
        $remapped = array('code' => 'vijesti', 'entity_id' => 234);

        $model  = $this->getMock('Core_Router_Route_Plugin_Model_Interface');
        $model
            ->expects($this->once())
            ->method('match')
            ->with($this->equalTo($remapped));
        $this->_object
            ->setMap($map)
            ->setModel($model);

        $this->_object->match($values);
    }

    /**
     * @covers Core_Router_Route_Plugin_Model::match
     * @covers Core_Router_Route_Plugin_Model::<protected>
     */
    public function testValuesNotPresentInValuesButRequestedInMapWillBeSentAsNull()
    {
        $values   = array('category' => 'vijesti');
        $map      = array('category' => 'code', 'id' => 'id');
        $remapped = array('code' => 'vijesti', 'id' => null);

        $model  = $this->getMock('Core_Router_Route_Plugin_Model_Interface');
        $model
            ->expects($this->once())
            ->method('match')
            ->with($this->equalTo($remapped));
        $this->_object
            ->setMap($map)
            ->setModel($model);

        $this->_object->match($values);
    }

    protected function _setupMockedModel($model, $name = 'lookupModel')
    {
        $container = $this->_mockContainer($name, $model);
        Core_Application::getInstance()->setContainer($container);
        $this->_object->setComponent($name);
    }
}
