]> git.immae.eu Git - github/shaarli/Shaarli.git/blobdiff - tests/bookmark/LinkUtilsTest.php
Merge branch 'v0.11' into stable
[github/shaarli/Shaarli.git] / tests / bookmark / LinkUtilsTest.php
similarity index 50%
rename from tests/LinkUtilsTest.php
rename to tests/bookmark/LinkUtilsTest.php
index 5407159a04c37ed9908aa7fcb063c576b4fd8475..78cb8f2abda69c07b26e9bfe54d7c508eec5ec40 100644 (file)
@@ -1,11 +1,17 @@
 <?php
 
-require_once 'application/LinkUtils.php';
+namespace Shaarli\Bookmark;
+
+use PHPUnit\Framework\TestCase;
+use ReferenceLinkDB;
+use Shaarli\Config\ConfigManager;
+
+require_once 'tests/utils/CurlUtils.php';
 
 /**
-* Class LinkUtilsTest.
-*/
-class LinkUtilsTest extends PHPUnit_Framework_TestCase
+ * Class LinkUtilsTest.
+ */
+class LinkUtilsTest extends TestCase
 {
     /**
      * Test html_extract_title() when the title is found.
@@ -13,9 +19,9 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
     public function testHtmlExtractExistentTitle()
     {
         $title = 'Read me please.';
-        $html = '<html><meta>stuff</meta><title>'. $title .'</title></html>';
+        $html = '<html><meta>stuff</meta><title>' . $title . '</title></html>';
         $this->assertEquals($title, html_extract_title($html));
-        $html = '<html><title>'. $title .'</title>blabla<title>another</title></html>';
+        $html = '<html><title>' . $title . '</title>blabla<title>another</title></html>';
         $this->assertEquals($title, html_extract_title($html));
     }
 
@@ -34,7 +40,7 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
     public function testHeadersExtractExistentCharset()
     {
         $charset = 'x-MacCroatian';
-        $headers = 'text/html; charset='. $charset;
+        $headers = 'text/html; charset=' . $charset;
         $this->assertEquals(strtolower($charset), header_extract_charset($headers));
     }
 
@@ -56,7 +62,7 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
     public function testHtmlExtractExistentCharset()
     {
         $charset = 'x-MacCroatian';
-        $html = '<html><meta>stuff2</meta><meta charset="'. $charset .'"/></html>';
+        $html = '<html><meta>stuff2</meta><meta charset="' . $charset . '"/></html>';
         $this->assertEquals(strtolower($charset), html_extract_charset($html));
     }
 
@@ -71,12 +77,57 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
         $this->assertFalse(html_extract_charset($html));
     }
 
+    /**
+     * Test html_extract_tag() when the tag <meta name= is found.
+     */
+    public function testHtmlExtractExistentNameTag()
+    {
+        $description = 'Bob and Alice share cookies.';
+        $html = '<html><meta>stuff2</meta><meta name="description" content="' . $description . '"/></html>';
+        $this->assertEquals($description, html_extract_tag('description', $html));
+    }
+
+    /**
+     * Test html_extract_tag() when the tag <meta name= is not found.
+     */
+    public function testHtmlExtractNonExistentNameTag()
+    {
+        $html = '<html><meta>stuff2</meta><meta name="image" content="img"/></html>';
+        $this->assertFalse(html_extract_tag('description', $html));
+    }
+
+    /**
+     * Test html_extract_tag() when the tag <meta property="og: is found.
+     */
+    public function testHtmlExtractExistentOgTag()
+    {
+        $description = 'Bob and Alice share cookies.';
+        $html = '<html><meta>stuff2</meta><meta property="og:description" content="' . $description . '"/></html>';
+        $this->assertEquals($description, html_extract_tag('description', $html));
+    }
+
+    /**
+     * Test html_extract_tag() when the tag <meta property="og: is not found.
+     */
+    public function testHtmlExtractNonExistentOgTag()
+    {
+        $html = '<html><meta>stuff2</meta><meta name="image" content="img"/></html>';
+        $this->assertFalse(html_extract_tag('description', $html));
+    }
+
     /**
      * Test the download callback with valid value
      */
     public function testCurlDownloadCallbackOk()
     {
-        $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_ok');
+        $callback = get_curl_download_callback(
+            $charset,
+            $title,
+            $desc,
+            $keywords,
+            false,
+            'ut_curl_getinfo_ok'
+        );
         $data = [
             'HTTP/1.1 200 OK',
             'Server: GitHub.com',
@@ -84,9 +135,11 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
             'Content-Type: text/html; charset=utf-8',
             'Status: 200 OK',
             'end' => 'th=device-width">'
-            .'<title>Refactoring · GitHub</title>'
-            .'<link rel="search" type="application/opensea',
-            '<title>ignored</title>',
+                . '<title>Refactoring · GitHub</title>'
+                . '<link rel="search" type="application/opensea',
+            '<title>ignored</title>'
+                . '<meta name="description" content="desc" />'
+                . '<meta name="keywords" content="key1,key2" />',
         ];
         foreach ($data as $key => $line) {
             $ignore = null;
@@ -98,6 +151,8 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
         }
         $this->assertEquals('utf-8', $charset);
         $this->assertEquals('Refactoring · GitHub', $title);
+        $this->assertEmpty($desc);
+        $this->assertEmpty($keywords);
     }
 
     /**
@@ -105,13 +160,22 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
      */
     public function testCurlDownloadCallbackOkNoCharset()
     {
-        $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_no_charset');
+        $callback = get_curl_download_callback(
+            $charset,
+            $title,
+            $desc,
+            $keywords,
+            false,
+            'ut_curl_getinfo_no_charset'
+        );
         $data = [
             'HTTP/1.1 200 OK',
             'end' => 'th=device-width">'
-            .'<title>Refactoring · GitHub</title>'
-            .'<link rel="search" type="application/opensea',
-            '<title>ignored</title>',
+                . '<title>Refactoring · GitHub</title>'
+                . '<link rel="search" type="application/opensea',
+            '<title>ignored</title>'
+            . '<meta name="description" content="desc" />'
+            . '<meta name="keywords" content="key1,key2" />',
         ];
         foreach ($data as $key => $line) {
             $ignore = null;
@@ -119,6 +183,8 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
         }
         $this->assertEmpty($charset);
         $this->assertEquals('Refactoring · GitHub', $title);
+        $this->assertEmpty($desc);
+        $this->assertEmpty($keywords);
     }
 
     /**
@@ -126,14 +192,23 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
      */
     public function testCurlDownloadCallbackOkHtmlCharset()
     {
-        $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_no_charset');
+        $callback = get_curl_download_callback(
+            $charset,
+            $title,
+            $desc,
+            $keywords,
+            false,
+            'ut_curl_getinfo_no_charset'
+        );
         $data = [
             'HTTP/1.1 200 OK',
             '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />',
             'end' => 'th=device-width">'
-            .'<title>Refactoring · GitHub</title>'
-            .'<link rel="search" type="application/opensea',
-            '<title>ignored</title>',
+                . '<title>Refactoring · GitHub</title>'
+                . '<link rel="search" type="application/opensea',
+            '<title>ignored</title>'
+            . '<meta name="description" content="desc" />'
+            . '<meta name="keywords" content="key1,key2" />',
         ];
         foreach ($data as $key => $line) {
             $ignore = null;
@@ -145,6 +220,8 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
         }
         $this->assertEquals('utf-8', $charset);
         $this->assertEquals('Refactoring · GitHub', $title);
+        $this->assertEmpty($desc);
+        $this->assertEmpty($keywords);
     }
 
     /**
@@ -152,7 +229,14 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
      */
     public function testCurlDownloadCallbackOkNoTitle()
     {
-        $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_ok');
+        $callback = get_curl_download_callback(
+            $charset,
+            $title,
+            $desc,
+            $keywords,
+            false,
+            'ut_curl_getinfo_ok'
+        );
         $data = [
             'HTTP/1.1 200 OK',
             'end' => 'th=device-width">Refactoring · GitHub<link rel="search" type="application/opensea',
@@ -164,6 +248,8 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
         }
         $this->assertEquals('utf-8', $charset);
         $this->assertEmpty($title);
+        $this->assertEmpty($desc);
+        $this->assertEmpty($keywords);
     }
 
     /**
@@ -171,7 +257,14 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
      */
     public function testCurlDownloadCallbackInvalidContentType()
     {
-        $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_ct_ko');
+        $callback = get_curl_download_callback(
+            $charset,
+            $title,
+            $desc,
+            $keywords,
+            false,
+            'ut_curl_getinfo_ct_ko'
+        );
         $ignore = null;
         $this->assertFalse($callback($ignore, ''));
         $this->assertEmpty($charset);
@@ -183,7 +276,14 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
      */
     public function testCurlDownloadCallbackInvalidResponseCode()
     {
-        $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_rc_ko');
+        $callback = $callback = get_curl_download_callback(
+            $charset,
+            $title,
+            $desc,
+            $keywords,
+            false,
+            'ut_curl_getinfo_rc_ko'
+        );
         $ignore = null;
         $this->assertFalse($callback($ignore, ''));
         $this->assertEmpty($charset);
@@ -195,13 +295,99 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
      */
     public function testCurlDownloadCallbackInvalidContentTypeAndResponseCode()
     {
-        $callback = get_curl_download_callback($charset, $title, 'ut_curl_getinfo_rs_ct_ko');
+        $callback = $callback = get_curl_download_callback(
+            $charset,
+            $title,
+            $desc,
+            $keywords,
+            false,
+            'ut_curl_getinfo_rs_ct_ko'
+        );
         $ignore = null;
         $this->assertFalse($callback($ignore, ''));
         $this->assertEmpty($charset);
         $this->assertEmpty($title);
     }
 
+    /**
+     * Test the download callback with valid value, and retrieve_description option enabled.
+     */
+    public function testCurlDownloadCallbackOkWithDesc()
+    {
+        $callback = get_curl_download_callback(
+            $charset,
+            $title,
+            $desc,
+            $keywords,
+            true,
+            'ut_curl_getinfo_ok'
+        );
+        $data = [
+            'HTTP/1.1 200 OK',
+            'Server: GitHub.com',
+            'Date: Sat, 28 Oct 2017 12:01:33 GMT',
+            'Content-Type: text/html; charset=utf-8',
+            'Status: 200 OK',
+            'th=device-width">'
+                . '<title>Refactoring · GitHub</title>'
+                . '<link rel="search" type="application/opensea',
+            'end' => '<title>ignored</title>'
+            . '<meta name="description" content="link desc" />'
+            . '<meta name="keywords" content="key1,key2" />',
+        ];
+        foreach ($data as $key => $line) {
+            $ignore = null;
+            $expected = $key !== 'end' ? strlen($line) : false;
+            $this->assertEquals($expected, $callback($ignore, $line));
+            if ($expected === false) {
+                break;
+            }
+        }
+        $this->assertEquals('utf-8', $charset);
+        $this->assertEquals('Refactoring · GitHub', $title);
+        $this->assertEquals('link desc', $desc);
+        $this->assertEquals('key1 key2', $keywords);
+    }
+
+    /**
+     * Test the download callback with valid value, and retrieve_description option enabled,
+     * but no desc or keyword defined in the page.
+     */
+    public function testCurlDownloadCallbackOkWithDescNotFound()
+    {
+        $callback = get_curl_download_callback(
+            $charset,
+            $title,
+            $desc,
+            $keywords,
+            true,
+            'ut_curl_getinfo_ok'
+        );
+        $data = [
+            'HTTP/1.1 200 OK',
+            'Server: GitHub.com',
+            'Date: Sat, 28 Oct 2017 12:01:33 GMT',
+            'Content-Type: text/html; charset=utf-8',
+            'Status: 200 OK',
+            'th=device-width">'
+                . '<title>Refactoring · GitHub</title>'
+                . '<link rel="search" type="application/opensea',
+            'end' => '<title>ignored</title>',
+        ];
+        foreach ($data as $key => $line) {
+            $ignore = null;
+            $expected = $key !== 'end' ? strlen($line) : false;
+            $this->assertEquals($expected, $callback($ignore, $line));
+            if ($expected === false) {
+                break;
+            }
+        }
+        $this->assertEquals('utf-8', $charset);
+        $this->assertEquals('Refactoring · GitHub', $title);
+        $this->assertEmpty($desc);
+        $this->assertEmpty($keywords);
+    }
+
     /**
      * Test count_private.
      */
@@ -212,56 +398,27 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test text2clickable without a redirector being set.
+     * Test text2clickable.
      */
-    public function testText2clickableWithoutRedirector()
+    public function testText2clickable()
     {
         $text = 'stuff http://hello.there/is=someone#here otherstuff';
         $expectedText = 'stuff <a href="http://hello.there/is=someone#here">'
-            .'http://hello.there/is=someone#here</a> otherstuff';
-        $processedText = text2clickable($text, '');
+            . 'http://hello.there/is=someone#here</a> otherstuff';
+        $processedText = text2clickable($text);
         $this->assertEquals($expectedText, $processedText);
 
         $text = 'stuff http://hello.there/is=someone#here(please) otherstuff';
         $expectedText = 'stuff <a href="http://hello.there/is=someone#here(please)">'
-            .'http://hello.there/is=someone#here(please)</a> otherstuff';
-        $processedText = text2clickable($text, '');
+            . 'http://hello.there/is=someone#here(please)</a> otherstuff';
+        $processedText = text2clickable($text);
         $this->assertEquals($expectedText, $processedText);
 
+        $text = 'stuff http://hello.there/is=someone#here(please)&no otherstuff';
         $text = 'stuff http://hello.there/is=someone#here(please)&no otherstuff';
         $expectedText = 'stuff <a href="http://hello.there/is=someone#here(please)&no">'
-            .'http://hello.there/is=someone#here(please)&no</a> otherstuff';
-        $processedText = text2clickable($text, '');
-        $this->assertEquals($expectedText, $processedText);
-    }
-
-    /**
-     * Test text2clickable with a redirector set.
-     */
-    public function testText2clickableWithRedirector()
-    {
-        $text = 'stuff http://hello.there/is=someone#here otherstuff';
-        $redirector = 'http://redirector.to';
-        $expectedText = 'stuff <a href="'.
-            $redirector .
-            urlencode('http://hello.there/is=someone#here') .
-            '">http://hello.there/is=someone#here</a> otherstuff';
-        $processedText = text2clickable($text, $redirector);
-        $this->assertEquals($expectedText, $processedText);
-    }
-
-    /**
-     * Test text2clickable a redirector set and without URL encode.
-     */
-    public function testText2clickableWithRedirectorDontEncode()
-    {
-        $text = 'stuff http://hello.there/?is=someone&or=something#here otherstuff';
-        $redirector = 'http://redirector.to';
-        $expectedText = 'stuff <a href="'.
-            $redirector .
-            'http://hello.there/?is=someone&or=something#here' .
-            '">http://hello.there/?is=someone&or=something#here</a> otherstuff';
-        $processedText = text2clickable($text, $redirector, false);
+            . 'http://hello.there/is=someone#here(please)&no</a> otherstuff';
+        $processedText = text2clickable($text);
         $this->assertEquals($expectedText, $processedText);
     }
 
@@ -270,8 +427,8 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
      */
     public function testSpace2nbsp()
     {
-        $text = '  Are you   thrilled  by flags   ?'. PHP_EOL .' Really?';
-        $expectedText = '&nbsp; Are you &nbsp; thrilled &nbsp;by flags &nbsp; ?'. PHP_EOL .'&nbsp;Really?';
+        $text = '  Are you   thrilled  by flags   ?' . PHP_EOL . ' Really?';
+        $expectedText = '&nbsp; Are you &nbsp; thrilled &nbsp;by flags &nbsp; ?' . PHP_EOL . '&nbsp;Really?';
         $processedText = space2nbsp($text);
         $this->assertEquals($expectedText, $processedText);
     }
@@ -313,109 +470,37 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
         $this->assertNotContains('>#nothashtag', $autolinkedDescription);
     }
 
+    /**
+     * Test is_note with note URLs.
+     */
+    public function testIsNote()
+    {
+        $this->assertTrue(is_note('?'));
+        $this->assertTrue(is_note('?abcDEf'));
+        $this->assertTrue(is_note('?_abcDEf#123'));
+    }
+
+    /**
+     * Test is_note with non note URLs.
+     */
+    public function testIsNotNote()
+    {
+        $this->assertFalse(is_note(''));
+        $this->assertFalse(is_note('nope'));
+        $this->assertFalse(is_note('https://github.com/shaarli/Shaarli/?hi'));
+    }
+
     /**
      * Util function to build an hashtag link.
      *
      * @param string $hashtag Hashtag name.
-     * @param string $index   Index URL.
+     * @param string $index Index URL.
      *
      * @return string HTML hashtag link.
      */
     private function getHashtagLink($hashtag, $index = '')
     {
-        $hashtagLink = '<a href="'. $index .'?addtag=$1" title="Hashtag $1">#$1</a>';
+        $hashtagLink = '<a href="' . $index . '?addtag=$1" title="Hashtag $1">#$1</a>';
         return str_replace('$1', $hashtag, $hashtagLink);
     }
 }
-
-// old style mock: PHPUnit doesn't allow function mock
-
-/**
- * Returns code 200 or html content type.
- *
- * @param resource $ch   cURL resource
- * @param int      $type cURL info type
- *
- * @return int|string 200 or 'text/html'
- */
-function ut_curl_getinfo_ok($ch, $type)
-{
-    switch ($type) {
-        case CURLINFO_RESPONSE_CODE:
-            return 200;
-        case CURLINFO_CONTENT_TYPE:
-            return 'text/html; charset=utf-8';
-    }
-}
-
-/**
- * Returns code 200 or html content type without charset.
- *
- * @param resource $ch   cURL resource
- * @param int      $type cURL info type
- *
- * @return int|string 200 or 'text/html'
- */
-function ut_curl_getinfo_no_charset($ch, $type)
-{
-    switch ($type) {
-        case CURLINFO_RESPONSE_CODE:
-            return 200;
-        case CURLINFO_CONTENT_TYPE:
-            return 'text/html';
-    }
-}
-
-/**
- * Invalid response code.
- *
- * @param resource $ch   cURL resource
- * @param int      $type cURL info type
- *
- * @return int|string 404 or 'text/html'
- */
-function ut_curl_getinfo_rc_ko($ch, $type)
-{
-    switch ($type) {
-        case CURLINFO_RESPONSE_CODE:
-            return 404;
-        case CURLINFO_CONTENT_TYPE:
-            return 'text/html; charset=utf-8';
-    }
-}
-
-/**
- * Invalid content type.
- *
- * @param resource $ch   cURL resource
- * @param int      $type cURL info type
- *
- * @return int|string 200 or 'text/plain'
- */
-function ut_curl_getinfo_ct_ko($ch, $type)
-{
-    switch ($type) {
-        case CURLINFO_RESPONSE_CODE:
-            return 200;
-        case CURLINFO_CONTENT_TYPE:
-            return 'text/plain';
-    }
-}
-
-/**
- * Invalid response code and content type.
- *
- * @param resource $ch   cURL resource
- * @param int      $type cURL info type
- *
- * @return int|string 404 or 'text/plain'
- */
-function ut_curl_getinfo_rs_ct_ko($ch, $type)
-{
-    switch ($type) {
-        case CURLINFO_RESPONSE_CODE:
-            return 404;
-        case CURLINFO_CONTENT_TYPE:
-            return 'text/plain';
-    }
-}