<?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
 * @group      tidy
 * @group      pecl
 */
class Core_Embed_Parser_MarkupTest extends PHPUnit_Framework_TestCase
{
    /**
     * @var Core_Embed_Parser_Markup
     */
    protected $_object;

    /**
     * Sets up the fixture, for example, opens a network connection.
     * This method is called before a test is executed.
     */
    protected function setUp()
    {
        if (!function_exists('tidy_repair_string')) {
            $this->markTestSkipped('Core_Embed_Parser_Markup needs Tidy PECL to be enabled, skipping');
        }

        $this->_object = new Core_Embed_Parser_Markup;
    }

    /**
     * @param string $body       Response body
     * @param array  $properties Properties to match
     * @param string $type       Response type
     *
     * @covers Core_Embed_Parser_Markup::get
     * @covers Core_Embed_Parser_Markup::<protected>
     * @dataProvider responseToProperties
     */
    public function testWillFindProperty($body, array $properties, $type = 'text/html; charset=UTF-8')
    {
        $this->_defineResponse($body, $type);
        $response = $this->_object->get('http://www.example.invalid/foo');

        foreach ($properties as $name => $value) {
            $this->assertEquals($value, $response->get($name));
        }
    }

    public function responseToProperties()
    {
        return array(
            // response, properties

            /*
             * COMMON ERRORS
             */
            // handle empty body
            array(
                '',
                array(
                    'type'  => 'link',
                    'title' => 'http://www.example.invalid/foo',
                    'url'   => 'http://www.example.invalid/foo',
                )
            ),
            // do not wrap
            array(
                '<head>
                    <title>Very Long Title Very Long Title Very Long Title Very Long Title Very Long Title </title>
                </head>',
                array(
                    'title' => 'Very Long Title Very Long Title Very Long Title Very Long Title Very Long Title',
                )
            ),
            // extract only text values, not markup
            array(
                '<head>
                    <h1>Ignore <span class="a_3_14"><font>Embedded</font> Markup</span></h1>
                </head>',
                array(
                    'title' => 'Ignore Embedded Markup',
                )
            ),

            /*
             * ENCODING
             */
            array(
                '<head>
                    <title>ČĆŽŠĐ čćžšđ</title>
                </head>',
                array(
                    'title' => 'ČĆŽŠĐ čćžšđ',
                )
            ),
            array(
                '<head>
                    <title>'.
                        // "ČĆŽŠĐ čćžšđ" in ISO-8859-2 charset
                        pack("H*", 'C8C6AEA9D020E8E6BEB9F0')
                    .'</title>
                </head>',
                array(
                    'title' => 'ČĆŽŠĐ čćžšđ',
                ),
                'text/html; charset=iso-8859-2'
            ),


            /*
             * URL
             */
            array(
                '<head>
                    <link rel="canonical" href="http://my.canonical.invalid/url" />
                </head>',
                array(
                    'url' => 'http://my.canonical.invalid/url',
                )
            ),
            array(
                '<head>
                    <link rel="canonical" href="/url" />
                </head>',
                array(
                    'url' => 'http://www.example.invalid/url',
                )
            ),

            /*
             * TYPE
             */
            array(
                '<head>
                    <meta property="og:type" content="video">
                </head>',
                array(
                    'type' => 'video',
                )
            ),

            /*
             * TITLE
             */
            array(
                '<head>
                    <meta property="og:title" content="My OG Title">
                </head>',
                array(
                    'title' => 'My OG Title',
                )
            ),
            array(
                '<head>
                    <title>My Meta Title</title>
                </head>',
                array(
                    'title' => 'My Meta Title',
                )
            ),
            array(
                '<body>
                    <h1>My H1 Title</h1>
                </body>',
                array(
                    'title' => 'My H1 Title',
                )
            ),
            array(
                '<head>
                    <title>My MetaTitle</title>
                    <meta property="og:title" content="My OG Title">
                </head>',
                array(
                    'title' => 'My OG Title',
                )
            ),

            /*
             * DESCRIPTION
             */
            array(
                '<head>
                    <meta property="og:description" content="My OG Description">
                </head>',
                array(
                    'description' => 'My OG Description',
                )
            ),
            array(
                '<head>
                    <meta name="description" content="My Meta Description">
                </head>',
                array(
                    'description' => 'My Meta Description',
                )
            ),
            array(
                '<body>
                    <p>My Paragraph Description</p>
                    <p>another paragraph, ignored</p>
                </body>',
                array(
                    'description' => 'My Paragraph Description',
                )
            ),
            array(
                '<head>
                    <meta property="og:description" content="My OG Description">
                    <meta name="description" content="My Meta Description">
                </head>',
                array(
                    'description' => 'My OG Description',
                )
            ),

            /*
             * PROVIDER NAME
             */
            array(
                '<head>
                    <meta property="og:site_name" content="My OG Site Name">
                </head>',
                array(
                    'provider_name' => 'My OG Site Name',
                )
            ),

            /*
             * IMAGE
             */
            array(
                '<head>
                    <meta property="og:image" content="http://example.invalid/og-image">
                    <meta property="og:image:type" content="image/jpeg">
                    <meta property="og:image:width" content="640">
                    <meta property="og:image:height" content="480">
                </head>',
                array(
                    'image'        => 'http://example.invalid/og-image',
                    'image_type'   => 'image/jpeg',
                    'image_width'  => '640',
                    'image_height' => '480',
                )
            ),
            array(
                '<head>
                    <link rel="image_src" href="http://example.invalid/legacy-fb-image" />
                </head>',
                array(
                    'image' => 'http://example.invalid/legacy-fb-image',
                )
            ),
            array(
                '<head>
                    <meta property="og:image" content="http://example.invalid/og-image">
                    <link rel="image_src" href="http://example.invalid/legacy-fb-image" />
                </head>',
                array(
                    'image' => 'http://example.invalid/og-image',
                )
            ),

            /*
             * VIDEO
             */
            array(
                '<head>
                    <meta property="og:video" content="http://example.invalid/og-video">
                    <meta property="og:video:type" content="application/x-shockwave-flash">
                    <meta property="og:video:width" content="640">
                    <meta property="og:video:height" content="480">
                </head>',
                array(
                    'video'        => 'http://example.invalid/og-video',
                    'video_type'   => 'application/x-shockwave-flash',
                    'video_width'  => '640',
                    'video_height' => '480',
                )
            ),
        );
    }

    /**
     * @param string $body
     */
    protected function _defineResponse($body, $type = 'text/html; charset=UTF-8')
    {
        $response   = $this->getMock('Zend_Http_Response', array('getHeader', 'getBody'), array(null, array()));
        $response
            ->expects($this->once())
            ->method('getHeader')
            ->with($this->equalTo('Content-Type'))
            ->will($this->returnValue($type));
        $response
            ->expects($this->once())
            ->method('getBody')
            ->will($this->returnValue($body));
        $httpClient = $this->getMock('Zend_Http_Client', array('request'));
        $httpClient
            ->expects($this->once())
            ->method('request')
            ->will($this->returnValue($response));

        $this->_object->setHttpClient($httpClient);
    }
}
