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

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

    protected function setUp()
    {
        $this->_object = $this->getMock('Core_Validate_Abstract', array('_isValid'));
    }
    
    /**
     * @covers Core_Validate_Abstract::setTranslator
     * @covers Core_Validate_Abstract::getTranslator
     */
    public function testSetAndGetTranslator()
    {
        $translator = $this->getMock('Zend_Translate');
        $this->_object->setTranslator($translator);

        $this->assertEquals($translator, $this->_object->getTranslator());
    }
    
    /**
     * @covers Core_Validate_Abstract::getTranslator
     */
    public function testIfTranslatorNotSetWillTryToFetchItFromParent()
    {
        $translator = $this->getMock('Zend_Translate');
        $parent     = $this->getMock('Core_Form', array('getTranslator'));
        $parent
            ->expects($this->once())
            ->method('getTranslator')
            ->will($this->returnValue($translator));
        $this->_object->setOwner($parent);

        $this->assertEquals($translator, $this->_object->getTranslator());
    }
    
    /**
     * @covers Core_Validate_Abstract::__construct
     */
    public function testCanSetOptionsViaConstructor()
    {
        $options = array(
            'name'         => 'someName',
            'errorMessage' => 'This is some error!',
        );
        $object = $this->getMock('Core_Validate_Abstract', array('_isValid'), array($options));
        $this->assertEquals('someName', $object->getName());
        $this->assertEquals('This is some error!', $object->getErrorMessage());
    }

    /**
     * @covers Core_Validate_Abstract::setOptions
     */
    public function testCanSetOptions()
    {
        $options = array(
            'name'         => 'someName',
            'errorMessage' => 'This is some error!',
        );
        $this->_object->setOptions($options);
        $this->assertEquals('someName', $this->_object->getName());
        $this->assertEquals('This is some error!', $this->_object->getErrorMessage());
    }

    /**
     * @covers Core_Validate_Abstract::setOptions
     */
    public function testSettingAnInvalidOptionThrowsAnInvalidArgumentException()
    {
        $this->setExpectedException('InvalidArgumentException');
        $options = array(
            'something-invalid'  => 'bla bla',
        );
        $this->_object->setOptions($options);
    }

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

    /**
     * @covers Core_Validate_Abstract::setErrorMessage
     * @covers Core_Validate_Abstract::getErrorMessage
     */
    public function testCanSetAndGetErrorMessage()
    {
        $this->_object->setErrorMessage('alert!');
        $this->assertEquals('alert!', $this->_object->getErrorMessage());
    }

    /**
     * @covers Core_Validate_Abstract::getErrorMessage
     */
    public function testFetchingErrorMessageWillReturnGlobalErrorMessageIfNoLocalErrorMessageSet()
    {
        $this->assertEquals('Oh noez!', $this->_object->getErrorMessage('Oh noez!'));
    }
    
    
    /**
     * @covers Core_Form_Element_Abstract::getErrorMessage
     * @covers Core_Form_Element_Abstract::<protected>
     */
    public function testWillTranslateDefaultErrorMessageIfTranslatorAvailable()
    {
        $translator = $this->getMock('Zend_Translate', array('translate'), array(), '', false);
        $translator
            ->expects($this->once())
            ->method('translate')
            ->with($this->equalTo('Default error message'))
            ->will($this->returnValue('Tvornicki ugradjena poruka o gresci'));
        
        $object = new Invalid_Validate_Maxlength;
        $object->setTranslator($translator);
        
        $this->assertEquals('Tvornicki ugradjena poruka o gresci', $object->getErrorMessage());
    }
    
    /**
     * @covers Core_Form_Element_Abstract::getErrorMessage
     * @covers Core_Form_Element_Abstract::<protected>
     */
    public function testWillTranslateGlobalErrorMessageIfTranslatorAvailable()
    {
        $translator = $this->getMock('Zend_Translate', array('translate'), array(), '', false);
        $translator
            ->expects($this->once())
            ->method('translate')
            ->with($this->equalTo('Local error'))
            ->will($this->returnValue('Lokalna greska'));
        
        $this->_object
            ->setErrorMessage('Local error')
            ->setTranslator($translator);
        
        $this->assertEquals('Lokalna greska', $this->_object->getErrorMessage());
    }
    
    /**
     * @covers Core_Form_Element_Abstract::getErrorMessage
     * @covers Core_Form_Element_Abstract::<protected>
     */
    public function testWillNotTranslateParentErrorMessageIfTranslatorAvailable()
    {
        $translator = $this->getMock('Zend_Translate', array('translate'), array(), '', false);
        $translator
            ->expects($this->never())
            ->method('translate');
        
        $this->_object->setTranslator($translator);
        
        $this->assertEquals('Not translated', $this->_object->getErrorMessage('Not translated'));
    }

    /**
     * @covers Core_Validate_Abstract::getErrorMessage
     */
    public function testFetchingErrorMessageWillReturnDefaultErrorMessageIfNoLocalOrGlobalMessageSet()
    {
        $this->assertEquals('Invalid entry', $this->_object->getErrorMessage());
    }

    /**
     * @covers Core_Validate_Abstract::isValid
     * @covers Core_Validate_Abstract::<protected>
     */
    public function testWillValidateValueWithValidatorSpecificMethod()
    {
        $object = $this->getMock('Core_Validate_Abstract', array('_isValid'));
        $object
            ->expects($this->once())
            ->method('_isValid')
            ->with($this->equalTo('bla'))
            ->will($this->returnValue(true));

        $this->assertTrue($object->isValid('bla'));
    }

    /**
     * @covers Core_Validate_Abstract::getAngularRepresentation
     * @covers Core_Validate_Abstract::<protected>
     */
    public function testCanGetAngularRepresentation()
    {
        $object = new Invalid_Validate_Maxlength;
        $this->assertEquals(
            array(
                'maxlength' => array(
                    'attribName'   => 'maxlength',
                    'errorMessage' => 'Oh noez!',
                    'config'       => 10,
                )
            ),
            $object->getAngularRepresentation('Oh noez!')
        );
    }

    /**
     * @covers Core_Validate_Abstract::getAngularRepresentation
     * @covers Core_Validate_Abstract::<protected>
     */
    public function testAngularRepresentationIsNotDefinedByDefault()
    {
        $this->assertEmpty($this->_object->getAngularRepresentation());
    }
}

class Invalid_Validate_Maxlength extends Core_Validate_Abstract
{
    protected $_defaultErrorMessage = 'Default error message';
    protected $_angularType   = 'maxlength';
    protected $_angularConfig = 10;

    protected function _isValid($value)
    {
        return false;
    }
}