<?php
/**
 * This Software is the property of Data Development and is protected
 * by copyright law - it is NOT Freeware.
 *
 * Any unauthorized use of this software without a valid license
 * is a violation of the license agreement and will be prosecuted by
 * civil and criminal law.
 *
 * http://www.shopmodule.com
 *
 * @copyright © Dł Data Development, Thomas Dartsch
 * @author    Dł Data Development - Daniel Seifert <support@shopmodule.com>
 * @link      http://www.oxidmodule.com
 */

class d3ordermanager_unit_models_actions_d3ordermanageractionexecutemethodTest extends OxidTestCase
{
    /** @var d3ordermanager_action_executemethod */
    protected $_oAction;
    /** @var PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount */
    protected $_oSpy;

    protected $_sMethodName = 'myCustomMethodName';

    /**
     * setup basic requirements
     */
    public function setUp()
    {
        parent::setUp();

        $oOrderManager = oxNew('d3ordermanager');
        $oOrder = oxNew('oxorder');

        $this->_oAction = $this->getProxyClass(
            'd3ordermanager_action_executemethod',
            array($oOrderManager, $oOrder)
        );

        // set valid licence for private "_isAllowed", which isn't mockable
        $this->_setOMValidEditionLicence();
    }

    public function tearDown()
    {
        parent::tearDown();

        unset($this->_oAction);
    }

    public function testStartAction_DontExecuteAction()
    {
        $oManagerMock = $this->getMock('d3ordermanager', array('getValue'));
        $oManagerMock->expects($this->any())->method('getValue')->will($this->returnCallback(array($this, 'getManagerValues1')));
        $this->_oAction->setManager($oManagerMock);

        /** @var oxorder|PHPUnit_Framework_MockObject_MockObject $oOrderMock */
        $oOrderMock = $this->getMock('oxorder', array($this->_sMethodName));
        $oOrderMock->expects($this->_oSpy = $this->any())->method($this->_sMethodName);
        $this->_oAction->setOrder($oOrderMock);

        /** @var d3ordermanager_action_executemethod|PHPUnit_Framework_MockObject_MockObject $oActionMock */
        $oActionMock = $this->getMock(
            'd3ordermanager_action_executemethod',
            array('canExecuteAction', 'canExecuteMethod', 'hasRequiredValues'),
            array($this->_oAction->getManager(), $this->_oAction->getOrder())
        );
        $oActionMock->expects($this->any())->method('canExecuteAction')->will($this->returnValue(false));
        $oActionMock->expects($this->any())->method('canExecuteMethod')->will($this->returnValue(true));
        $oActionMock->expects($this->any())->method('hasRequiredValues')->will($this->returnValue(true));

        $oActionMock->startAction();
        $this->assertEquals(
            0, 
            count($this->_oSpy->getInvocations())
        );
    }

    public function testStartAction_DontExecuteJob()
    {
        $oManagerMock = $this->getMock('d3ordermanager', array('getValue'));
        $oManagerMock->expects($this->any())->method('getValue')->will($this->returnCallback(array($this, 'getManagerValues1')));
        $this->_oAction->setManager($oManagerMock);

        /** @var oxorder|PHPUnit_Framework_MockObject_MockObject $oOrderMock */
        $oOrderMock = $this->getMock('oxorder', array($this->_sMethodName));
        $oOrderMock->expects($this->_oSpy = $this->any())->method($this->_sMethodName);
        $this->_oAction->setOrder($oOrderMock);

        /** @var d3ordermanager_action_executemethod|PHPUnit_Framework_MockObject_MockObject $oActionMock */
        $oActionMock = $this->getMock(
            'd3ordermanager_action_executemethod',
            array('canExecuteAction', 'canExecuteMethod', 'hasRequiredValues'),
            array($this->_oAction->getManager(), $this->_oAction->getOrder())
        );
        $oActionMock->expects($this->any())->method('canExecuteAction')->will($this->returnValue(true));
        $oActionMock->expects($this->any())->method('canExecuteMethod')->will($this->returnValue(false));
        $oActionMock->expects($this->any())->method('hasRequiredValues')->will($this->returnValue(true));

        $oActionMock->startAction();
        $this->assertEquals(
            0,
            count($this->_oSpy->getInvocations())
        );
    }

    public function testStartAction_MissingValues()
    {
        $oManagerMock = $this->getMock('d3ordermanager', array('getValue'));
        $oManagerMock->expects($this->any())->method('getValue')->will($this->returnCallback(array($this, 'getManagerValues1')));
        $this->_oAction->setManager($oManagerMock);

        /** @var oxorder|PHPUnit_Framework_MockObject_MockObject $oOrderMock */
        $oOrderMock = $this->getMock('oxorder', array($this->_sMethodName));
        $oOrderMock->expects($this->_oSpy = $this->any())->method($this->_sMethodName);
        $this->_oAction->setOrder($oOrderMock);

        /** @var d3ordermanager_action_executemethod|PHPUnit_Framework_MockObject_MockObject $oActionMock */
        $oActionMock = $this->getMock(
            'd3ordermanager_action_executemethod',
            array('canExecuteAction', 'canExecuteMethod', 'hasRequiredValues'),
            array($this->_oAction->getManager(), $this->_oAction->getOrder())
        );
        $oActionMock->expects($this->any())->method('canExecuteAction')->will($this->returnValue(true));
        $oActionMock->expects($this->any())->method('canExecuteMethod')->will($this->returnValue(true));
        $oActionMock->expects($this->any())->method('hasRequiredValues')->will($this->returnValue(false));

        $oActionMock->startAction();
        $this->assertEquals(
            0,
            count($this->_oSpy->getInvocations())
        );
    }

    public function testStartAction_Ok()
    {
        $oManagerMock = $this->getMock('d3ordermanager', array('getValue'));
        $oManagerMock->expects($this->any())->method('getValue')->will($this->returnCallback(array($this, 'getManagerValues1')));
        $this->_oAction->setManager($oManagerMock);

        /** @var oxorder|PHPUnit_Framework_MockObject_MockObject $oOrderMock */
        $oOrderMock = $this->getMock('oxorder', array($this->_sMethodName));
        $oOrderMock->expects($this->_oSpy = $this->any())->method($this->_sMethodName);
        $this->_oAction->setOrder($oOrderMock);

        /** @var d3ordermanager_action_executemethod|PHPUnit_Framework_MockObject_MockObject $oActionMock */
        $oActionMock = $this->getMock(
            'd3ordermanager_action_executemethod',
            array('canExecuteAction', 'canExecuteMethod', 'hasRequiredValues'),
            array($this->_oAction->getManager(), $this->_oAction->getOrder())
        );
        $oActionMock->expects($this->any())->method('canExecuteAction')->will($this->returnValue(true));
        $oActionMock->expects($this->any())->method('canExecuteMethod')->will($this->returnValue(true));
        $oActionMock->expects($this->any())->method('hasRequiredValues')->will($this->returnValue(true));

        $oActionMock->startAction();
        $this->assertEquals(
            1,
            count($this->_oSpy->getInvocations())
        );
    }

    public function testCanExecuteAction_disabledAction()
    {
        $oManagerMock = $this->getMock('d3ordermanager', array('getValue'));
        $oManagerMock->expects($this->any())->method('getValue')->will($this->returnCallback(array($this, 'getManagerValues')));
        $this->_oAction->setManager($oManagerMock);

        $this->assertFalse($this->_oAction->canExecuteAction());
        $this->assertFalse($this->_oAction->isActive());
    }

    /**
     * @return bool|null
     */
    public function getManagerValues()
    {
        $aArgs = func_get_args();

        switch ($aArgs[0]) {
            case 'blActionOrderExecuteMethod_status':
                return false;
            case 'sActionExecuteMethod_name':
                return null;
        }

        $this->fail('Unknown variable '.$aArgs[0]);
        return null;
    }

    public function testCanExecuteAction_unvalidLicence()
    {
        // private method _isAllowed isn't mockable
        $this->_setOMUnvalidEditionLicence();
        $oManagerMock = $this->getMock('d3ordermanager', array('getValue'));
        $oManagerMock->expects($this->any())->method('getValue')->will($this->returnCallback(array($this, 'getManagerValues1')));
        $this->_oAction->setManager($oManagerMock);

        /** @var d3ordermanager_action_executemethod|PHPUnit_Framework_MockObject_MockObject $oActionMock */
        $oActionMock = $this->getMock(
            'd3ordermanager_action_executemethod',
            array('isCommonExecutable'),
            array($this->_oAction->getManager(), $this->_oAction->getOrder())
        );
        $oActionMock->expects($this->any())->method('isCommonExecutable')->will($this->returnValue(true));

        $this->assertFalse($oActionMock->canExecuteAction());
        $this->assertFalse($oActionMock->isActive());
    }

    /**
     * @return bool|null
     */
    public function getManagerValues1()
    {
        $aArgs = func_get_args();

        switch ($aArgs[0]) {
            case 'blActionOrderExecuteMethod_status':
                return true;
            case 'sActionExecuteMethod_name':
                return $this->_sMethodName;
            case 'blItemMailSend':
                return null;
        }

        $this->fail('Unknown variable '.$aArgs[0]);
        return null;
    }

    public function testCanExecuteAction_managernotexecutable()
    {
        $oManagerMock = $this->getMock('d3ordermanager', array('getValue'));
        $oManagerMock->expects($this->any())->method('getValue')->will($this->returnCallback(array($this, 'getManagerValues1')));
        $this->_oAction->setManager($oManagerMock);

        /** @var d3ordermanager_action_executemethod|PHPUnit_Framework_MockObject_MockObject $oActionMock */
        $oActionMock = $this->getMock(
            'd3ordermanager_action_executemethod',
            array('isCommonExecutable'),
            array($this->_oAction->getManager(), $this->_oAction->getOrder())
        );
        $oActionMock->expects($this->any())->method('isCommonExecutable')->will($this->returnValue(false));

        $this->assertFalse($oActionMock->canExecuteAction());
        $this->assertFalse($oActionMock->isActive());
    }

    public function testCanExecuteAction_ok()
    {
        $oManagerMock = $this->getMock('d3ordermanager', array('getValue'));
        $oManagerMock->expects($this->any())->method('getValue')->will($this->returnCallback(array($this, 'getManagerValues1')));
        $this->_oAction->setManager($oManagerMock);

        /** @var d3ordermanager_action_executemethod|PHPUnit_Framework_MockObject_MockObject $oActionMock */
        $oActionMock = $this->getMock(
            'd3ordermanager_action_executemethod',
            array('isCommonExecutable'),
            array($this->_oAction->getManager(), $this->_oAction->getOrder())
        );
        $oActionMock->expects($this->any())->method('isCommonExecutable')->will($this->returnValue(true));

        $this->assertTrue($oActionMock->canExecuteAction());
        $this->assertTrue($oActionMock->isActive());
    }

    public function testCanExecuteMethod_nok()
    {
        $oManagerMock = $this->getMock('d3ordermanager', array('getValue'));
        $oManagerMock->expects($this->any())->method('getValue')->will($this->returnValue(false));
        $this->_oAction->setManager($oManagerMock);

        $this->assertFalse($this->_oAction->canExecuteMethod());
    }

    public function testCanExecuteMethod_ok()
    {
        $oManagerMock = $this->getMock('d3ordermanager', array('getValue'));
        $oManagerMock->expects($this->any())->method('getValue')->will($this->returnValue(true));
        $this->_oAction->setManager($oManagerMock);

        $this->assertTrue($this->_oAction->canExecuteMethod());
    }

    public function testHasRequiredValues_nok()
    {
        $oManagerMock = $this->getMock('d3ordermanager', array('getValue'));
        $oManagerMock->expects($this->any())->method('getValue')->will($this->returnCallback(array($this, 'getManagerValues')));
        $this->_oAction->setManager($oManagerMock);

        $this->assertFalse($this->_oAction->hasRequiredValues());
    }

    public function testHasRequiredValues_ok()
    {
        /** @var oxorder|PHPUnit_Framework_MockObject_MockObject $oOrderMock */
        $oOrderMock = $this->getMock('oxorder', array($this->_sMethodName));
        $oOrderMock->expects($this->any())->method($this->_sMethodName);
        $this->_oAction->setOrder($oOrderMock);

        $oManagerMock = $this->getMock('d3ordermanager', array('getValue'));
        $oManagerMock->expects($this->any())->method('getValue')->will($this->returnCallback(array($this, 'getManagerValues1')));
        $this->_oAction->setManager($oManagerMock);

        $this->assertTrue($this->_oAction->hasRequiredValues());
    }

    public function testGetTplName()
    {
        $this->assertEquals('d3ordermanager_action_executemethod.tpl', $this->_oAction->getTplName());
    }

    public function testIsAllowed()
    {
        $blRet = $this->_oAction->isAllowed();
        $this->assertTrue($blRet);

        $this->_setOMUnvalidEditionLicence();
        $blRet = $this->_oAction->isAllowed();
        $this->assertFalse($blRet);
    }

    protected function _setOMValidEditionLicence()
    {
        $this->_oAction->getManager()->d3getModCfg()->assign(
            array(
                'oxserial'  => '635WUdaNThGNlNEYVZJY0dsVUJZVHpDc2tWQm5UejVXdTZ4eU5OS1lXTjhXUzFoQTQ1SW1YdUlacG13K
1dhOFNoclZBTUFwTzdyNml4NWN3dFc0VG1SK0NkNEg0RERNWU43dllreXRLOTVnVmVxaE1xS3ZpcDZSS
nh4a0RnS1RsZXlHeUR4QmFzQmxMa1B3MmcrQmdBQW1tUXVmYko4QkNxWFFHd295OUliQVg5WXZvWk8wT
Wh5OHRJS3RlekJBWmppMmk3YkhtakdhRFVqV3NQMmUxTExLSk1VQ0VCMnM4dVcwRGpqS3ppWnhPTDRVY
k5tQkJGMndLVmhjblcxUm1VWTM1SlZkcEdsTnkxcGI0ZnZOZVlCV08yK3RQbGxpVWMwbEYxdy9TaXBId
FlsY1ZkVVFMUFZkR1VVZnI0UmZzdDg5MEpDTG41SE5SZjYyYkVmMjRlVVVFcGRSNVdHdVNjUHdYc0VPN
EdIajkrdEFBZjRnSlBlaTNvT2s1NUQ1cUtrSFhTOW1HSkpOSUlqUENBaDNXamtvSm45RWt0VmZreklJe
nphZzNXRERtd3RSOG5LTUJzZkdCZzRKMWUxUmJRMHp2U0ViOWdNbG91YWdyVGI1Z3F1QjE5aXppZXJqU
GcyMWtVcUlvUmdXL0I1VS8xbkNWdU04TlBzSkpSZmJvSmljVDgvRU1BQ1pNQWgwU3p1cHVjKytYZ3NwS
Wd3SEh3M0UxVUYrZVBhb0dVRWh1Y01kVDlocnhpRG1Mb0dPVS9CcU0ybFZSUktGZ1EyNk5PNmVISEduK
2E4Mk1OZTZKYWw2ZkdNRWlacHhWb2pneEtqQ2IrNHFBS2RmR21TNlYwQmczeWNRZWZIVnRBQUlDV2F2U
UdJSUhaTVhzcXAzM3V0VnFwR3pqUktEL3RGWkN5Nm52T2ROekZzQVRBRFdOeEhhZVRwcDlKbyswZkdBU
W0xU2o1WGRBPT0=',
            )
        );
        $sStoreKey = $this->_oAction->getManager()->d3getModCfg()->d3GetModId() . '#serial';
        d3_cfg_mod_datastore::getInstance()->deleteStore($sStoreKey);
    }

    protected function _setOMUnvalidEditionLicence()
    {
        $this->_oAction->getManager()->d3getModCfg()->assign(
            array(
                'oxserial'  => 'GvEemVJUlZzWjFCbUNvdnpWYzh6SFU4TzBVVCs5WmNOSGJYOVozVno2TzZpeGVCcFIyNTA3MnYvdEFqN
zVtYnhwRXAxcUlucUZrY2dMMmlxQmVBNzhuUTQ2T0tWVWhZQlVBc0RvajNnczBmM09EeTYxWjBFNFdQN
XlJVXh4ZEt5MjhTblU1dkVkT25QZGppbzRaTkl2SG4vdDV6NlRKVzNqcTZjbEhxcC96WVZFSkVaalhnQ
2MwcnVZQjEzUW8zaktLRFBJSVcvM1NxYlBXWXpXWXVMaEU2K3NRRXVHZ0ZwSmxEUjlHWG56bm1QcHM3R
DBlaVdXVDJpdWJISmJ2YU1LVmFKYTQ5aVRlOEZnUjF3SzJrbHVJaEgzWUR5TDRETmRJTEljZHRlaThHd
1RPVHdIMndTbVFWU3pNUHZFMEQwQjFjUlBZLzlsUmRlL3ViNUVNV2Mrc04wZk1XT2lBTzl0a1RSLyswZ
zRDYVVhSU11SGlBazNRT25Kamc0UzR5UVo3V1h6akJMbytYR25waHU3Vi9rK252aWg2ME9iRzFtQ2F0V
ngxNjlTekF6QzEwZDZVWDY4dFM0eXNXb3VoOHcyNUxkRTg3Q29ld1pIbWh4bVJhV1BKWkZ0MEc0NHAwV
GZRUnI5SjVlZnVzS3lxUHd2Zis0dUtRY09TK1B3QnVaZmxnQTVwRW1ub3FWSWwyR3dhMUM0VXZzMS9jb
Eh6YW4xcktia3QxN1BZamNLTWVkbEJpQXVHbWFQWDh1c2xZQ0Zzd0w5UHRvZnBEaE0zaDZ5YmpjY2srZ
m1VVi92YVBaZTUwNFlYQzBvUmtHdVlVZ0VXUERBVmo0NDUvc0xVV3Vobm1KenF1UWp5Q2tZOTN4Yzd1e
GU0bzc4RlJ0VjRnZVRpWDlmQ2hqb1pmWVpZTWtQTExPRjZMNFpYUWluTDk4Tm5JdmRTenMrSWQ1SzFiN
HZCYWpiRTZyR3U3Q29SNmVHWkgwUzQ2VktsSUVVPQ==',
            )
        );
        $sStoreKey = $this->_oAction->getManager()->d3getModCfg()->d3GetModId() . '#serial';
        d3_cfg_mod_datastore::getInstance()->deleteStore($sStoreKey);
    }
}
