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

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

    /**
     * Sets up the fixture, for example, opens a network connection.
     * This method is called before a test is executed.
     */
    protected function setUp()
    {
        $this->_object = new Core_Embed;
    }
    
    protected function tearDown()
    {
        Core_Application::resetInstance();
    }

    /**
     * @covers Core_Embed::setFormat
     * @covers Core_Embed::getFormat
     */
    public function testCanSetAndGetFormat()
    {
        $this->_object->setFormat('xml');
        $this->assertEquals('xml', $this->_object->getFormat());
    }

    /**
     * @covers Core_Embed::setMaxWidth
     * @covers Core_Embed::getMaxWidth
     */
    public function testCanSetAndGetMaxWidth()
    {
        $this->_object->setMaxWidth(299);
        $this->assertEquals(299, $this->_object->getMaxWidth());
    }

    /**
     * @covers Core_Embed::setMaxHeight
     * @covers Core_Embed::getMaxHeight
     */
    public function testCanSetAndGetMaxHeight()
    {
        $this->_object->setMaxHeight(123);
        $this->assertEquals(123, $this->_object->getMaxHeight());
    }
    
    /**
     * @covers Core_Embed::setHttpClient
     * @covers Core_Embed::getHttpClient
     */
    public function testCanSetAndGetHttpClient()
    {
        $httpClient = $this->getMock('Zend_Http_Client');
        $this->_object->setHttpClient($httpClient);
        $this->assertEquals($httpClient, $this->_object->getHttpClient());
    }

    /**
     * @covers Core_Embed::getHttpClient
     */
    public function testIfNoHttpClientInstanceGivenCreateANewZendHttpClient()
    {
        $this->assertInstanceOf('Zend_Http_Client', $this->_object->getHttpClient());
    }
    
    /**
     * @covers Core_Embed::setPluginLoader
     * @covers Core_Embed::getPluginLoader
     */
    public function testCanSetAndGetPluginLoader()
    {
        $pluginLoader = $this->getMock('Core_Loader_PluginLoader');
        $this->_object->setPluginLoader($pluginLoader);
        $this->assertSame($pluginLoader, $this->_object->getPluginLoader());
    }

    /**
     * @covers Core_Embed::getPluginLoader
     */
    public function testIfNoRequestIsSetGetRequestWillPullItFromApplicationInstanceAsPluginLoader()
    {
        $pluginLoader = $this->getMock('Core_Loader_PluginLoader');
        $container    = $this->_mockContainer('PluginLoader', $pluginLoader);
        Core_Application::getInstance()->setContainer($container);
        $this->assertSame($pluginLoader, $this->_object->getPluginLoader());
    }
    
    /**
     * @covers Core_Embed::get
     */
    public function testQueryingAnUnknownAddressWillDoAHeadRequestToInspectIt()
    {
        $this->_object
            ->setHttpClient($this->_mockHttpClient('text/unknown'))
            ->setPluginLoader($this->_mockPluginLoader('Fallback'));
        
        $this->_object->get('http://www.example.invalid');
    }
    
    /**
     * @covers Core_Embed::get
     * @covers Core_Embed::<protected>
     * @depends testQueryingAnUnknownAddressWillDoAHeadRequestToInspectIt
     */
    public function testWillCreateFallbackParserForUnknownMimeType()
    {        
        $this->_object
            ->setHttpClient($this->_mockHttpClient('unknown/mimetype'))
            ->setPluginLoader($this->_mockPluginLoader('Fallback'));
        
        $this->_object->get('http://www.example.invalid');
    }
    
    /**
     * @covers Core_Embed::get
     * @covers Core_Embed::<protected>
     * @depends testQueryingAnUnknownAddressWillDoAHeadRequestToInspectIt
     */
    public function testWillCreateMarkupParserForXML()
    {        
        $this->_object
            ->setHttpClient($this->_mockHttpClient('text/xml'))
            ->setPluginLoader($this->_mockPluginLoader('Markup'));
        
        $this->_object->get('http://www.example.invalid');
    }
    
    /**
     * @covers Core_Embed::get
     * @covers Core_Embed::<protected>
     * @depends testQueryingAnUnknownAddressWillDoAHeadRequestToInspectIt
     */
    public function testWillCreateImageParserForJPEG()
    {        
        $this->_object
            ->setHttpClient($this->_mockHttpClient('image/jpeg'))
            ->setPluginLoader($this->_mockPluginLoader('Image'));
        
        $this->_object->get('http://www.example.invalid');
    }
    
    /**
     * @covers Core_Embed::get
     * @covers Core_Embed::<protected>
     * @depends testQueryingAnUnknownAddressWillDoAHeadRequestToInspectIt
     */
    public function testWillCreateImageParserForPNG()
    {        
        $this->_object
            ->setHttpClient($this->_mockHttpClient('image/png'))
            ->setPluginLoader($this->_mockPluginLoader('Image'));
        
        $this->_object->get('http://www.example.invalid');
    }
    
    /**
     * @covers Core_Embed::get
     * @covers Core_Embed::<protected>
     * @depends testQueryingAnUnknownAddressWillDoAHeadRequestToInspectIt
     */
    public function testWillCreateImageParserForGIF()
    {        
        $this->_object
            ->setHttpClient($this->_mockHttpClient('image/gif'))
            ->setPluginLoader($this->_mockPluginLoader('Image'));
        
        $this->_object->get('http://www.example.invalid');
    }
    
    /**
     * @covers Core_Embed::get
     * @covers Core_Embed::<protected>
     * @depends testQueryingAnUnknownAddressWillDoAHeadRequestToInspectIt
     */
    public function testWillCreateMarkupParserForHTML()
    {        
        $this->_object
            ->setHttpClient($this->_mockHttpClient('text/html'))
            ->setPluginLoader($this->_mockPluginLoader('Markup'));
        
        $this->_object->get('http://www.example.invalid');
    }
    
    /**
     * @covers Core_Embed::get
     * @covers Core_Embed::<protected>
     * @depends testQueryingAnUnknownAddressWillDoAHeadRequestToInspectIt
     */
    public function testEncodingInContentTypeWillBeStripped()
    {        
        $this->_object
            ->setHttpClient($this->_mockHttpClient('text/html; charset=ISO-8859-2'))
            ->setPluginLoader($this->_mockPluginLoader('Markup'));
        
        $this->_object->get('http://www.example.invalid');
    }
    
    protected function _mockContainer($name, $value)
    {
        // mock the container
        $container = $this->getMock('Core_Yadif_Container', array('getComponent'));
        $container
            ->expects($this->once())
            ->method('getComponent')
            ->with($this->equalTo($name))
            ->will($this->returnValue($value));

        return $container;
    }
    
    protected function _mockHttpClient($type)
    {
        $response = $this->getMock('Zend_Http_Response', array('getHeader'), array(null, array()));
        $response
            ->expects($this->once())
            ->method('getHeader')
            ->with($this->equalTo('Content-Type'))
            ->will($this->returnValue($type));
        $httpClient = $this->getMock('Zend_Http_Client', array('request', 'setUri'));
        $httpClient
            ->expects($this->once())
            ->method('request')
            ->with($this->equalTo('HEAD'))
            ->will($this->returnValue($response));
        
        return $httpClient;
    }
    
    protected function _mockPluginLoader($type, $url = 'http://www.example.invalid')
    {
        $response = $this->getMock('Core_Embed_Response', array('setFormat', 'get'), array(array()));
        $parser   = $this->getMock('Core_Embed_Parser_Abstract', array('_parse', 'get', 'setFormat'));
        $parser
            ->expects($this->once())
            ->method('get')
            ->with($this->equalTo($url))
            ->will($this->returnValue($response));
        $pluginLoader = $this->getMock('Core_Loader_PluginLoader', array('initializeEmbedParserPlugin'));
        $pluginLoader
            ->expects($this->once())
            ->method('initializeEmbedParserPlugin')
            ->with($this->equalTo($type))
            ->will($this->returnValue($parser));
        
        return $pluginLoader;
    }
}
