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

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

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

    /**
     * @covers Core_Form_Element_MultiValue_Collection::setRawValue
     */
    public function testSettingEmptyRawValueWillSetNull()
    {
        $this->_object->setRawValue('');

        $this->assertEquals(array(), $this->_object->getRawValue());
    }

    /**
     * @covers Core_Form_Element_MultiValue_Collection::setPossibleValues
     * @covers Core_Form_Element_MultiValue_Collection::getPossibleValues
     */
    public function testCanSetAndGetPossibleValuesAndAddElementLabelsFromPossibleValues()
    {
        $element = $this->getMock('Core_Form_Element_Abstract', array('setLabel'));
        $element
            ->expects($this->at(0))
            ->method('setLabel')
            ->with($this->equalTo('Label for a'));
        $element
            ->expects($this->at(1))
            ->method('setLabel')
            ->with($this->equalTo('Label for b'));

        $object = $this->getMock('Core_Form_Element_MultiValue_Collection', array('getElement', 'removeElement', '_configureValidator'));
        $object
            ->expects($this->at(0))
            ->method('getElement')
            ->with($this->equalTo('a'))
            ->will($this->returnValue($element));
        $object
            ->expects($this->at(1))
            ->method('getElement')
            ->with($this->equalTo('b'))
            ->will($this->returnValue($element));
        $object->setPossibleValues(array('a' => 'Label for a', 'b' => 'Label for b'));

        $this->assertEquals(array('a' => 'Label for a', 'b' => 'Label for b'), $object->getPossibleValues());
    }

    /**
     * @covers Core_Form_Element_MultiValue_Collection::setPossibleValues
     */
    public function testWillClearPreviousElementsWhenSettingNewPossibleValues()
    {
        $element = $this->getMock('Core_Form_Element_Abstract', array('setLabel'));
        $element
            ->expects($this->at(0))
            ->method('setLabel')
            ->with($this->equalTo('Old label for a'));
        $element
            ->expects($this->at(1))
            ->method('setLabel')
            ->with($this->equalTo('Old label for b'));
        $element
            ->expects($this->at(2))
            ->method('setLabel')
            ->with($this->equalTo('New label for a'));
        $element
            ->expects($this->at(3))
            ->method('setLabel')
            ->with($this->equalTo('New label for d'));

        $object = $this->getMock('Core_Form_Element_MultiValue_Collection', array('getElement', 'removeElement', '_configureValidator'));
        $object
            ->expects($this->at(0))
            ->method('getElement')
            ->with($this->equalTo('a'))
            ->will($this->returnValue($element));
        $object
            ->expects($this->at(1))
            ->method('getElement')
            ->with($this->equalTo('b'))
            ->will($this->returnValue($element));
        $object
            ->expects($this->at(3))
            ->method('removeElement')
            ->with($this->equalTo('a'));
        $object
            ->expects($this->at(4))
            ->method('removeElement')
            ->with($this->equalTo('b'));
        $object
            ->expects($this->at(5))
            ->method('getElement')
            ->with($this->equalTo('a'))
            ->will($this->returnValue($element));
        $object
            ->expects($this->at(6))
            ->method('getElement')
            ->with($this->equalTo('d'))
            ->will($this->returnValue($element));
        $object
            ->setPossibleValues(array('a' => 'Old label for a', 'b' => 'Old label for b'))
            ->setPossibleValues(array('a' => 'New label for a', 'd' => 'New label for d'));
    }

    /**
     * @covers Core_Form_Element_MultiValue_Collection::setPossibleValues
     */
    public function testWillAutoAddInArrayValidatorWhenSettingPossibleValues()
    {
        $possibleValues  = array('a' => 'Label for a', 'b' => 'Label for b');

        $object          = new Invalid_Form_Element_MultiValue_Collection_Invalid;
        $object->test    = $this;
        $object->options = array('array' => array('a', 'b'));

        $object->setPossibleValues($possibleValues);
    }

    /**
     * @covers Core_Form_Element_MultiValue_Collection::isValid
     * @covers Core_Form_Element_MultiValue_Collection::<protected>
     */
    public function testWillUseCollectionToValidateAgainst()
    {
        $validator = $this->getMockForAbstractClass('Core_Validate_Array_Abstract', array(), '', true, true, true, array('isValid'));
        $validator
            ->expects($this->once())
            ->method('isValid')
            ->with($this->equalTo(array('raw', 'values')))
            ->will($this->returnValue(true));
        $object = $this->getMock('Core_Form_Element_MultiValue_Collection', array('getValidators', 'getRawValues'));
        $object
            ->expects($this->once())
            ->method('getRawValues')
            ->will($this->returnValue(array('raw', 'values')));
        $object
            ->expects($this->once())
            ->method('getValidators')
            ->will($this->returnValue(array($validator)));

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

class Invalid_Form_Element_MultiValue_Collection_Invalid extends Core_Form_Element_MultiValue_Collection
{
    public $test;
    public $options = array();

    public function getElement($name)
    {
        return $this->test->getMock('Core_Form_Element_Abstract', array('getLabel'));
    }

    public function removeElement($name)
    {
    }

    public function hasValidator($name)
    {
        return true;
    }

    public function getValidator($name)
    {
        $validator = $this->test->getMockForAbstractClass('Core_Validate_Abstract', array(), '', true, true, true, array('setOptions'));
        $validator
            ->expects($this->test->once())
            ->method('setOptions')
            ->with($this->test->equalTo($this->options));
        return $validator;
    }
}