diff options
Diffstat (limited to 'tests/bookmark')
-rw-r--r-- | tests/bookmark/BookmarkArrayTest.php | 13 | ||||
-rw-r--r-- | tests/bookmark/BookmarkFileServiceTest.php | 259 | ||||
-rw-r--r-- | tests/bookmark/BookmarkFilterTest.php | 46 | ||||
-rw-r--r-- | tests/bookmark/BookmarkInitializerTest.php | 13 | ||||
-rw-r--r-- | tests/bookmark/BookmarkTest.php | 107 | ||||
-rw-r--r-- | tests/bookmark/LinkUtilsTest.php | 446 |
6 files changed, 615 insertions, 269 deletions
diff --git a/tests/bookmark/BookmarkArrayTest.php b/tests/bookmark/BookmarkArrayTest.php index ebed9bfc..1953078c 100644 --- a/tests/bookmark/BookmarkArrayTest.php +++ b/tests/bookmark/BookmarkArrayTest.php | |||
@@ -91,19 +91,6 @@ class BookmarkArrayTest extends TestCase | |||
91 | } | 91 | } |
92 | 92 | ||
93 | /** | 93 | /** |
94 | * Test adding a bad entry: invalid ID type | ||
95 | */ | ||
96 | public function testArrayAccessAddBadEntryIdType() | ||
97 | { | ||
98 | $this->expectException(\Shaarli\Bookmark\Exception\InvalidBookmarkException::class); | ||
99 | |||
100 | $array = new BookmarkArray(); | ||
101 | $bookmark = (new Bookmark())->setId('nope'); | ||
102 | $bookmark->validate(); | ||
103 | $array[] = $bookmark; | ||
104 | } | ||
105 | |||
106 | /** | ||
107 | * Test adding a bad entry: ID/offset not consistent | 94 | * Test adding a bad entry: ID/offset not consistent |
108 | */ | 95 | */ |
109 | public function testArrayAccessAddBadEntryIdOffset() | 96 | public function testArrayAccessAddBadEntryIdOffset() |
diff --git a/tests/bookmark/BookmarkFileServiceTest.php b/tests/bookmark/BookmarkFileServiceTest.php index c399822b..f619aff3 100644 --- a/tests/bookmark/BookmarkFileServiceTest.php +++ b/tests/bookmark/BookmarkFileServiceTest.php | |||
@@ -6,6 +6,7 @@ | |||
6 | namespace Shaarli\Bookmark; | 6 | namespace Shaarli\Bookmark; |
7 | 7 | ||
8 | use DateTime; | 8 | use DateTime; |
9 | use malkusch\lock\mutex\NoMutex; | ||
9 | use ReferenceLinkDB; | 10 | use ReferenceLinkDB; |
10 | use ReflectionClass; | 11 | use ReflectionClass; |
11 | use Shaarli; | 12 | use Shaarli; |
@@ -52,6 +53,9 @@ class BookmarkFileServiceTest extends TestCase | |||
52 | */ | 53 | */ |
53 | protected $privateLinkDB = null; | 54 | protected $privateLinkDB = null; |
54 | 55 | ||
56 | /** @var NoMutex */ | ||
57 | protected $mutex; | ||
58 | |||
55 | /** | 59 | /** |
56 | * Instantiates public and private LinkDBs with test data | 60 | * Instantiates public and private LinkDBs with test data |
57 | * | 61 | * |
@@ -68,6 +72,8 @@ class BookmarkFileServiceTest extends TestCase | |||
68 | */ | 72 | */ |
69 | protected function setUp(): void | 73 | protected function setUp(): void |
70 | { | 74 | { |
75 | $this->mutex = new NoMutex(); | ||
76 | |||
71 | if (file_exists(self::$testDatastore)) { | 77 | if (file_exists(self::$testDatastore)) { |
72 | unlink(self::$testDatastore); | 78 | unlink(self::$testDatastore); |
73 | } | 79 | } |
@@ -87,8 +93,8 @@ class BookmarkFileServiceTest extends TestCase | |||
87 | $this->refDB = new \ReferenceLinkDB(); | 93 | $this->refDB = new \ReferenceLinkDB(); |
88 | $this->refDB->write(self::$testDatastore); | 94 | $this->refDB->write(self::$testDatastore); |
89 | $this->history = new History('sandbox/history.php'); | 95 | $this->history = new History('sandbox/history.php'); |
90 | $this->publicLinkDB = new BookmarkFileService($this->conf, $this->history, false); | 96 | $this->publicLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, false); |
91 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); | 97 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
92 | } | 98 | } |
93 | 99 | ||
94 | /** | 100 | /** |
@@ -105,7 +111,7 @@ class BookmarkFileServiceTest extends TestCase | |||
105 | $db = self::getMethod('migrate'); | 111 | $db = self::getMethod('migrate'); |
106 | $db->invokeArgs($this->privateLinkDB, []); | 112 | $db->invokeArgs($this->privateLinkDB, []); |
107 | 113 | ||
108 | $db = new \FakeBookmarkService($this->conf, $this->history, true); | 114 | $db = new \FakeBookmarkService($this->conf, $this->history, $this->mutex, true); |
109 | $this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks()); | 115 | $this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks()); |
110 | $this->assertEquals($this->refDB->countLinks(), $db->count()); | 116 | $this->assertEquals($this->refDB->countLinks(), $db->count()); |
111 | } | 117 | } |
@@ -174,7 +180,7 @@ class BookmarkFileServiceTest extends TestCase | |||
174 | $this->assertEquals($updated, $bookmark->getUpdated()); | 180 | $this->assertEquals($updated, $bookmark->getUpdated()); |
175 | 181 | ||
176 | // reload from file | 182 | // reload from file |
177 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); | 183 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
178 | 184 | ||
179 | $bookmark = $this->privateLinkDB->get(43); | 185 | $bookmark = $this->privateLinkDB->get(43); |
180 | $this->assertEquals(43, $bookmark->getId()); | 186 | $this->assertEquals(43, $bookmark->getId()); |
@@ -212,7 +218,7 @@ class BookmarkFileServiceTest extends TestCase | |||
212 | $this->assertNull($bookmark->getUpdated()); | 218 | $this->assertNull($bookmark->getUpdated()); |
213 | 219 | ||
214 | // reload from file | 220 | // reload from file |
215 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); | 221 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
216 | 222 | ||
217 | $bookmark = $this->privateLinkDB->get(43); | 223 | $bookmark = $this->privateLinkDB->get(43); |
218 | $this->assertEquals(43, $bookmark->getId()); | 224 | $this->assertEquals(43, $bookmark->getId()); |
@@ -242,7 +248,7 @@ class BookmarkFileServiceTest extends TestCase | |||
242 | $this->assertEquals(43, $bookmark->getId()); | 248 | $this->assertEquals(43, $bookmark->getId()); |
243 | 249 | ||
244 | // reload from file | 250 | // reload from file |
245 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); | 251 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
246 | 252 | ||
247 | $this->privateLinkDB->get(43); | 253 | $this->privateLinkDB->get(43); |
248 | } | 254 | } |
@@ -259,17 +265,6 @@ class BookmarkFileServiceTest extends TestCase | |||
259 | } | 265 | } |
260 | 266 | ||
261 | /** | 267 | /** |
262 | * Test add() method with an entry which is not a bookmark instance | ||
263 | */ | ||
264 | public function testAddNotABookmark() | ||
265 | { | ||
266 | $this->expectException(\Exception::class); | ||
267 | $this->expectExceptionMessage('Provided data is invalid'); | ||
268 | |||
269 | $this->privateLinkDB->add(['title' => 'hi!']); | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * Test add() method with a Bookmark already containing an ID | 268 | * Test add() method with a Bookmark already containing an ID |
274 | */ | 269 | */ |
275 | public function testAddWithId() | 270 | public function testAddWithId() |
@@ -314,7 +309,7 @@ class BookmarkFileServiceTest extends TestCase | |||
314 | $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated()); | 309 | $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated()); |
315 | 310 | ||
316 | // reload from file | 311 | // reload from file |
317 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); | 312 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
318 | 313 | ||
319 | $bookmark = $this->privateLinkDB->get(42); | 314 | $bookmark = $this->privateLinkDB->get(42); |
320 | $this->assertEquals(42, $bookmark->getId()); | 315 | $this->assertEquals(42, $bookmark->getId()); |
@@ -355,7 +350,7 @@ class BookmarkFileServiceTest extends TestCase | |||
355 | $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated()); | 350 | $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated()); |
356 | 351 | ||
357 | // reload from file | 352 | // reload from file |
358 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); | 353 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
359 | 354 | ||
360 | $bookmark = $this->privateLinkDB->get(42); | 355 | $bookmark = $this->privateLinkDB->get(42); |
361 | $this->assertEquals(42, $bookmark->getId()); | 356 | $this->assertEquals(42, $bookmark->getId()); |
@@ -388,7 +383,7 @@ class BookmarkFileServiceTest extends TestCase | |||
388 | $this->assertEquals($title, $bookmark->getTitle()); | 383 | $this->assertEquals($title, $bookmark->getTitle()); |
389 | 384 | ||
390 | // reload from file | 385 | // reload from file |
391 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); | 386 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
392 | 387 | ||
393 | $bookmark = $this->privateLinkDB->get(42); | 388 | $bookmark = $this->privateLinkDB->get(42); |
394 | $this->assertEquals(42, $bookmark->getId()); | 389 | $this->assertEquals(42, $bookmark->getId()); |
@@ -407,17 +402,6 @@ class BookmarkFileServiceTest extends TestCase | |||
407 | } | 402 | } |
408 | 403 | ||
409 | /** | 404 | /** |
410 | * Test set() method with an entry which is not a bookmark instance | ||
411 | */ | ||
412 | public function testSetNotABookmark() | ||
413 | { | ||
414 | $this->expectException(\Exception::class); | ||
415 | $this->expectExceptionMessage('Provided data is invalid'); | ||
416 | |||
417 | $this->privateLinkDB->set(['title' => 'hi!']); | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * Test set() method with a Bookmark without an ID defined. | 405 | * Test set() method with a Bookmark without an ID defined. |
422 | */ | 406 | */ |
423 | public function testSetWithoutId() | 407 | public function testSetWithoutId() |
@@ -452,7 +436,7 @@ class BookmarkFileServiceTest extends TestCase | |||
452 | $this->assertEquals(43, $bookmark->getId()); | 436 | $this->assertEquals(43, $bookmark->getId()); |
453 | 437 | ||
454 | // reload from file | 438 | // reload from file |
455 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); | 439 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
456 | 440 | ||
457 | $bookmark = $this->privateLinkDB->get(43); | 441 | $bookmark = $this->privateLinkDB->get(43); |
458 | $this->assertEquals(43, $bookmark->getId()); | 442 | $this->assertEquals(43, $bookmark->getId()); |
@@ -472,7 +456,7 @@ class BookmarkFileServiceTest extends TestCase | |||
472 | $this->assertEquals($title, $bookmark->getTitle()); | 456 | $this->assertEquals($title, $bookmark->getTitle()); |
473 | 457 | ||
474 | // reload from file | 458 | // reload from file |
475 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); | 459 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
476 | 460 | ||
477 | $bookmark = $this->privateLinkDB->get(42); | 461 | $bookmark = $this->privateLinkDB->get(42); |
478 | $this->assertEquals(42, $bookmark->getId()); | 462 | $this->assertEquals(42, $bookmark->getId()); |
@@ -491,17 +475,6 @@ class BookmarkFileServiceTest extends TestCase | |||
491 | } | 475 | } |
492 | 476 | ||
493 | /** | 477 | /** |
494 | * Test addOrSet() method with an entry which is not a bookmark instance | ||
495 | */ | ||
496 | public function testAddOrSetNotABookmark() | ||
497 | { | ||
498 | $this->expectException(\Exception::class); | ||
499 | $this->expectExceptionMessage('Provided data is invalid'); | ||
500 | |||
501 | $this->privateLinkDB->addOrSet(['title' => 'hi!']); | ||
502 | } | ||
503 | |||
504 | /** | ||
505 | * Test addOrSet() method for a bookmark without any field set and without writing the data store | 478 | * Test addOrSet() method for a bookmark without any field set and without writing the data store |
506 | */ | 479 | */ |
507 | public function testAddOrSetMinimalNoWrite() | 480 | public function testAddOrSetMinimalNoWrite() |
@@ -515,7 +488,7 @@ class BookmarkFileServiceTest extends TestCase | |||
515 | $this->assertEquals($title, $bookmark->getTitle()); | 488 | $this->assertEquals($title, $bookmark->getTitle()); |
516 | 489 | ||
517 | // reload from file | 490 | // reload from file |
518 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); | 491 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
519 | 492 | ||
520 | $bookmark = $this->privateLinkDB->get(42); | 493 | $bookmark = $this->privateLinkDB->get(42); |
521 | $this->assertEquals(42, $bookmark->getId()); | 494 | $this->assertEquals(42, $bookmark->getId()); |
@@ -541,7 +514,7 @@ class BookmarkFileServiceTest extends TestCase | |||
541 | $this->assertInstanceOf(BookmarkNotFoundException::class, $exception); | 514 | $this->assertInstanceOf(BookmarkNotFoundException::class, $exception); |
542 | 515 | ||
543 | // reload from file | 516 | // reload from file |
544 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true); | 517 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
545 | 518 | ||
546 | $this->privateLinkDB->get(42); | 519 | $this->privateLinkDB->get(42); |
547 | } | 520 | } |
@@ -559,17 +532,6 @@ class BookmarkFileServiceTest extends TestCase | |||
559 | } | 532 | } |
560 | 533 | ||
561 | /** | 534 | /** |
562 | * Test remove() method with an entry which is not a bookmark instance | ||
563 | */ | ||
564 | public function testRemoveNotABookmark() | ||
565 | { | ||
566 | $this->expectException(\Exception::class); | ||
567 | $this->expectExceptionMessage('Provided data is invalid'); | ||
568 | |||
569 | $this->privateLinkDB->remove(['title' => 'hi!']); | ||
570 | } | ||
571 | |||
572 | /** | ||
573 | * Test remove() method with a Bookmark with an unknown ID | 535 | * Test remove() method with a Bookmark with an unknown ID |
574 | */ | 536 | */ |
575 | public function testRemoveWithUnknownId() | 537 | public function testRemoveWithUnknownId() |
@@ -645,7 +607,7 @@ class BookmarkFileServiceTest extends TestCase | |||
645 | 607 | ||
646 | $conf = new ConfigManager('tests/utils/config/configJson'); | 608 | $conf = new ConfigManager('tests/utils/config/configJson'); |
647 | $conf->set('resource.datastore', 'null/store.db'); | 609 | $conf->set('resource.datastore', 'null/store.db'); |
648 | new BookmarkFileService($conf, $this->history, true); | 610 | new BookmarkFileService($conf, $this->history, $this->mutex, true); |
649 | } | 611 | } |
650 | 612 | ||
651 | /** | 613 | /** |
@@ -655,7 +617,7 @@ class BookmarkFileServiceTest extends TestCase | |||
655 | { | 617 | { |
656 | unlink(self::$testDatastore); | 618 | unlink(self::$testDatastore); |
657 | $this->assertFileNotExists(self::$testDatastore); | 619 | $this->assertFileNotExists(self::$testDatastore); |
658 | new BookmarkFileService($this->conf, $this->history, true); | 620 | new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
659 | $this->assertFileExists(self::$testDatastore); | 621 | $this->assertFileExists(self::$testDatastore); |
660 | 622 | ||
661 | // ensure the correct data has been written | 623 | // ensure the correct data has been written |
@@ -669,7 +631,7 @@ class BookmarkFileServiceTest extends TestCase | |||
669 | { | 631 | { |
670 | unlink(self::$testDatastore); | 632 | unlink(self::$testDatastore); |
671 | $this->assertFileNotExists(self::$testDatastore); | 633 | $this->assertFileNotExists(self::$testDatastore); |
672 | $db = new \FakeBookmarkService($this->conf, $this->history, false); | 634 | $db = new \FakeBookmarkService($this->conf, $this->history, $this->mutex, false); |
673 | $this->assertFileNotExists(self::$testDatastore); | 635 | $this->assertFileNotExists(self::$testDatastore); |
674 | $this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks()); | 636 | $this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks()); |
675 | $this->assertCount(0, $db->getBookmarks()); | 637 | $this->assertCount(0, $db->getBookmarks()); |
@@ -702,13 +664,13 @@ class BookmarkFileServiceTest extends TestCase | |||
702 | */ | 664 | */ |
703 | public function testSave() | 665 | public function testSave() |
704 | { | 666 | { |
705 | $testDB = new BookmarkFileService($this->conf, $this->history, true); | 667 | $testDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
706 | $dbSize = $testDB->count(); | 668 | $dbSize = $testDB->count(); |
707 | 669 | ||
708 | $bookmark = new Bookmark(); | 670 | $bookmark = new Bookmark(); |
709 | $testDB->add($bookmark); | 671 | $testDB->add($bookmark); |
710 | 672 | ||
711 | $testDB = new BookmarkFileService($this->conf, $this->history, true); | 673 | $testDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
712 | $this->assertEquals($dbSize + 1, $testDB->count()); | 674 | $this->assertEquals($dbSize + 1, $testDB->count()); |
713 | } | 675 | } |
714 | 676 | ||
@@ -718,28 +680,12 @@ class BookmarkFileServiceTest extends TestCase | |||
718 | public function testCountHiddenPublic() | 680 | public function testCountHiddenPublic() |
719 | { | 681 | { |
720 | $this->conf->set('privacy.hide_public_links', true); | 682 | $this->conf->set('privacy.hide_public_links', true); |
721 | $linkDB = new BookmarkFileService($this->conf, $this->history, false); | 683 | $linkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, false); |
722 | 684 | ||
723 | $this->assertEquals(0, $linkDB->count()); | 685 | $this->assertEquals(0, $linkDB->count()); |
724 | } | 686 | } |
725 | 687 | ||
726 | /** | 688 | /** |
727 | * List the days for which bookmarks have been posted | ||
728 | */ | ||
729 | public function testDays() | ||
730 | { | ||
731 | $this->assertEquals( | ||
732 | ['20100309', '20100310', '20121206', '20121207', '20130614', '20150310'], | ||
733 | $this->publicLinkDB->days() | ||
734 | ); | ||
735 | |||
736 | $this->assertEquals( | ||
737 | ['20100309', '20100310', '20121206', '20121207', '20130614', '20141125', '20150310'], | ||
738 | $this->privateLinkDB->days() | ||
739 | ); | ||
740 | } | ||
741 | |||
742 | /** | ||
743 | * The URL corresponds to an existing entry in the DB | 689 | * The URL corresponds to an existing entry in the DB |
744 | */ | 690 | */ |
745 | public function testGetKnownLinkFromURL() | 691 | public function testGetKnownLinkFromURL() |
@@ -786,6 +732,10 @@ class BookmarkFileServiceTest extends TestCase | |||
786 | // They need to be grouped with the first case found - order by date DESC: `sTuff`. | 732 | // They need to be grouped with the first case found - order by date DESC: `sTuff`. |
787 | 'sTuff' => 2, | 733 | 'sTuff' => 2, |
788 | 'ut' => 1, | 734 | 'ut' => 1, |
735 | 'assurance' => 1, | ||
736 | 'coding-style' => 1, | ||
737 | 'quality' => 1, | ||
738 | 'standards' => 1, | ||
789 | ], | 739 | ], |
790 | $this->publicLinkDB->bookmarksCountPerTag() | 740 | $this->publicLinkDB->bookmarksCountPerTag() |
791 | ); | 741 | ); |
@@ -814,6 +764,10 @@ class BookmarkFileServiceTest extends TestCase | |||
814 | 'tag3' => 1, | 764 | 'tag3' => 1, |
815 | 'tag4' => 1, | 765 | 'tag4' => 1, |
816 | 'ut' => 1, | 766 | 'ut' => 1, |
767 | 'assurance' => 1, | ||
768 | 'coding-style' => 1, | ||
769 | 'quality' => 1, | ||
770 | 'standards' => 1, | ||
817 | ], | 771 | ], |
818 | $this->privateLinkDB->bookmarksCountPerTag() | 772 | $this->privateLinkDB->bookmarksCountPerTag() |
819 | ); | 773 | ); |
@@ -928,6 +882,37 @@ class BookmarkFileServiceTest extends TestCase | |||
928 | } | 882 | } |
929 | 883 | ||
930 | /** | 884 | /** |
885 | * Test filterHash() on a private bookmark while logged out. | ||
886 | */ | ||
887 | public function testFilterHashPrivateWhileLoggedOut() | ||
888 | { | ||
889 | $this->expectException(BookmarkNotFoundException::class); | ||
890 | $this->expectExceptionMessage('The link you are trying to reach does not exist or has been deleted'); | ||
891 | |||
892 | $hash = smallHash('20141125_084734' . 6); | ||
893 | |||
894 | $this->publicLinkDB->findByHash($hash); | ||
895 | } | ||
896 | |||
897 | /** | ||
898 | * Test filterHash() with private key. | ||
899 | */ | ||
900 | public function testFilterHashWithPrivateKey() | ||
901 | { | ||
902 | $hash = smallHash('20141125_084734' . 6); | ||
903 | $privateKey = 'this is usually auto generated'; | ||
904 | |||
905 | $bookmark = $this->privateLinkDB->findByHash($hash); | ||
906 | $bookmark->addAdditionalContentEntry('private_key', $privateKey); | ||
907 | $this->privateLinkDB->save(); | ||
908 | |||
909 | $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, false); | ||
910 | $bookmark = $this->privateLinkDB->findByHash($hash, $privateKey); | ||
911 | |||
912 | static::assertSame(6, $bookmark->getId()); | ||
913 | } | ||
914 | |||
915 | /** | ||
931 | * Test linksCountPerTag all tags without filter. | 916 | * Test linksCountPerTag all tags without filter. |
932 | * Equal occurrences should be sorted alphabetically. | 917 | * Equal occurrences should be sorted alphabetically. |
933 | */ | 918 | */ |
@@ -956,6 +941,10 @@ class BookmarkFileServiceTest extends TestCase | |||
956 | 'tag4' => 1, | 941 | 'tag4' => 1, |
957 | 'ut' => 1, | 942 | 'ut' => 1, |
958 | 'w3c' => 1, | 943 | 'w3c' => 1, |
944 | 'assurance' => 1, | ||
945 | 'coding-style' => 1, | ||
946 | 'quality' => 1, | ||
947 | 'standards' => 1, | ||
959 | ]; | 948 | ]; |
960 | $tags = $this->privateLinkDB->bookmarksCountPerTag(); | 949 | $tags = $this->privateLinkDB->bookmarksCountPerTag(); |
961 | 950 | ||
@@ -1054,6 +1043,10 @@ class BookmarkFileServiceTest extends TestCase | |||
1054 | 'stallman' => 1, | 1043 | 'stallman' => 1, |
1055 | 'ut' => 1, | 1044 | 'ut' => 1, |
1056 | 'w3c' => 1, | 1045 | 'w3c' => 1, |
1046 | 'assurance' => 1, | ||
1047 | 'coding-style' => 1, | ||
1048 | 'quality' => 1, | ||
1049 | 'standards' => 1, | ||
1057 | ]; | 1050 | ]; |
1058 | $bookmark = new Bookmark(); | 1051 | $bookmark = new Bookmark(); |
1059 | $bookmark->setTags(['newTagToCount', BookmarkMarkdownFormatter::NO_MD_TAG]); | 1052 | $bookmark->setTags(['newTagToCount', BookmarkMarkdownFormatter::NO_MD_TAG]); |
@@ -1065,33 +1058,105 @@ class BookmarkFileServiceTest extends TestCase | |||
1065 | } | 1058 | } |
1066 | 1059 | ||
1067 | /** | 1060 | /** |
1068 | * Test filterDay while logged in | 1061 | * Test find by dates in the middle of the datastore (sorted by dates) with a single bookmark as a result. |
1069 | */ | 1062 | */ |
1070 | public function testFilterDayLoggedIn(): void | 1063 | public function testFilterByDateMidTimePeriodSingleBookmark(): void |
1071 | { | 1064 | { |
1072 | $bookmarks = $this->privateLinkDB->filterDay('20121206'); | 1065 | $bookmarks = $this->privateLinkDB->findByDate( |
1073 | $expectedIds = [4, 9, 1, 0]; | 1066 | DateTime::createFromFormat('Ymd_His', '20121206_150000'), |
1067 | DateTime::createFromFormat('Ymd_His', '20121206_160000'), | ||
1068 | $before, | ||
1069 | $after | ||
1070 | ); | ||
1074 | 1071 | ||
1075 | static::assertCount(4, $bookmarks); | 1072 | static::assertCount(1, $bookmarks); |
1076 | foreach ($bookmarks as $bookmark) { | 1073 | |
1077 | $i = ($i ?? -1) + 1; | 1074 | static::assertSame(9, $bookmarks[0]->getId()); |
1078 | static::assertSame($expectedIds[$i], $bookmark->getId()); | 1075 | static::assertEquals(DateTime::createFromFormat('Ymd_His', '20121206_142300'), $before); |
1079 | } | 1076 | static::assertEquals(DateTime::createFromFormat('Ymd_His', '20121206_172539'), $after); |
1080 | } | 1077 | } |
1081 | 1078 | ||
1082 | /** | 1079 | /** |
1083 | * Test filterDay while logged out | 1080 | * Test find by dates in the middle of the datastore (sorted by dates) with a multiple bookmarks as a result. |
1084 | */ | 1081 | */ |
1085 | public function testFilterDayLoggedOut(): void | 1082 | public function testFilterByDateMidTimePeriodMultipleBookmarks(): void |
1086 | { | 1083 | { |
1087 | $bookmarks = $this->publicLinkDB->filterDay('20121206'); | 1084 | $bookmarks = $this->privateLinkDB->findByDate( |
1088 | $expectedIds = [4, 9, 1]; | 1085 | DateTime::createFromFormat('Ymd_His', '20121206_150000'), |
1086 | DateTime::createFromFormat('Ymd_His', '20121206_180000'), | ||
1087 | $before, | ||
1088 | $after | ||
1089 | ); | ||
1089 | 1090 | ||
1090 | static::assertCount(3, $bookmarks); | 1091 | static::assertCount(2, $bookmarks); |
1091 | foreach ($bookmarks as $bookmark) { | 1092 | |
1092 | $i = ($i ?? -1) + 1; | 1093 | static::assertSame(1, $bookmarks[0]->getId()); |
1093 | static::assertSame($expectedIds[$i], $bookmark->getId()); | 1094 | static::assertSame(9, $bookmarks[1]->getId()); |
1094 | } | 1095 | static::assertEquals(DateTime::createFromFormat('Ymd_His', '20121206_142300'), $before); |
1096 | static::assertEquals(DateTime::createFromFormat('Ymd_His', '20121206_182539'), $after); | ||
1097 | } | ||
1098 | |||
1099 | /** | ||
1100 | * Test find by dates at the end of the datastore (sorted by dates). | ||
1101 | */ | ||
1102 | public function testFilterByDateLastTimePeriod(): void | ||
1103 | { | ||
1104 | $after = new DateTime(); | ||
1105 | $bookmarks = $this->privateLinkDB->findByDate( | ||
1106 | DateTime::createFromFormat('Ymd_His', '20150310_114640'), | ||
1107 | DateTime::createFromFormat('Ymd_His', '20450101_010101'), | ||
1108 | $before, | ||
1109 | $after | ||
1110 | ); | ||
1111 | |||
1112 | static::assertCount(1, $bookmarks); | ||
1113 | |||
1114 | static::assertSame(41, $bookmarks[0]->getId()); | ||
1115 | static::assertEquals(DateTime::createFromFormat('Ymd_His', '20150310_114633'), $before); | ||
1116 | static::assertNull($after); | ||
1117 | } | ||
1118 | |||
1119 | /** | ||
1120 | * Test find by dates at the beginning of the datastore (sorted by dates). | ||
1121 | */ | ||
1122 | public function testFilterByDateFirstTimePeriod(): void | ||
1123 | { | ||
1124 | $before = new DateTime(); | ||
1125 | $bookmarks = $this->privateLinkDB->findByDate( | ||
1126 | DateTime::createFromFormat('Ymd_His', '20000101_101010'), | ||
1127 | DateTime::createFromFormat('Ymd_His', '20100309_110000'), | ||
1128 | $before, | ||
1129 | $after | ||
1130 | ); | ||
1131 | |||
1132 | static::assertCount(1, $bookmarks); | ||
1133 | |||
1134 | static::assertSame(11, $bookmarks[0]->getId()); | ||
1135 | static::assertNull($before); | ||
1136 | static::assertEquals(DateTime::createFromFormat('Ymd_His', '20100310_101010'), $after); | ||
1137 | } | ||
1138 | |||
1139 | /** | ||
1140 | * Test getLatest with a sticky bookmark: it should be ignored and return the latest by creation date instead. | ||
1141 | */ | ||
1142 | public function testGetLatestWithSticky(): void | ||
1143 | { | ||
1144 | $bookmark = $this->publicLinkDB->getLatest(); | ||
1145 | |||
1146 | static::assertSame(41, $bookmark->getId()); | ||
1147 | } | ||
1148 | |||
1149 | /** | ||
1150 | * Test getLatest with a sticky bookmark: it should be ignored and return the latest by creation date instead. | ||
1151 | */ | ||
1152 | public function testGetLatestEmptyDatastore(): void | ||
1153 | { | ||
1154 | unlink($this->conf->get('resource.datastore')); | ||
1155 | $this->publicLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, false); | ||
1156 | |||
1157 | $bookmark = $this->publicLinkDB->getLatest(); | ||
1158 | |||
1159 | static::assertNull($bookmark); | ||
1095 | } | 1160 | } |
1096 | 1161 | ||
1097 | /** | 1162 | /** |
diff --git a/tests/bookmark/BookmarkFilterTest.php b/tests/bookmark/BookmarkFilterTest.php index 48c7f824..835674f2 100644 --- a/tests/bookmark/BookmarkFilterTest.php +++ b/tests/bookmark/BookmarkFilterTest.php | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | namespace Shaarli\Bookmark; | 3 | namespace Shaarli\Bookmark; |
4 | 4 | ||
5 | use Exception; | 5 | use malkusch\lock\mutex\NoMutex; |
6 | use ReferenceLinkDB; | 6 | use ReferenceLinkDB; |
7 | use Shaarli\Config\ConfigManager; | 7 | use Shaarli\Config\ConfigManager; |
8 | use Shaarli\History; | 8 | use Shaarli\History; |
@@ -37,13 +37,14 @@ class BookmarkFilterTest extends TestCase | |||
37 | */ | 37 | */ |
38 | public static function setUpBeforeClass(): void | 38 | public static function setUpBeforeClass(): void |
39 | { | 39 | { |
40 | $mutex = new NoMutex(); | ||
40 | $conf = new ConfigManager('tests/utils/config/configJson'); | 41 | $conf = new ConfigManager('tests/utils/config/configJson'); |
41 | $conf->set('resource.datastore', self::$testDatastore); | 42 | $conf->set('resource.datastore', self::$testDatastore); |
42 | self::$refDB = new \ReferenceLinkDB(); | 43 | self::$refDB = new \ReferenceLinkDB(); |
43 | self::$refDB->write(self::$testDatastore); | 44 | self::$refDB->write(self::$testDatastore); |
44 | $history = new History('sandbox/history.php'); | 45 | $history = new History('sandbox/history.php'); |
45 | self::$bookmarkService = new \FakeBookmarkService($conf, $history, true); | 46 | self::$bookmarkService = new \FakeBookmarkService($conf, $history, $mutex, true); |
46 | self::$linkFilter = new BookmarkFilter(self::$bookmarkService->getBookmarks()); | 47 | self::$linkFilter = new BookmarkFilter(self::$bookmarkService->getBookmarks(), $conf); |
47 | } | 48 | } |
48 | 49 | ||
49 | /** | 50 | /** |
@@ -523,4 +524,43 @@ class BookmarkFilterTest extends TestCase | |||
523 | )) | 524 | )) |
524 | ); | 525 | ); |
525 | } | 526 | } |
527 | |||
528 | /** | ||
529 | * Test search result highlights in every field of bookmark reference #9. | ||
530 | */ | ||
531 | public function testFullTextSearchHighlight(): void | ||
532 | { | ||
533 | $bookmarks = self::$linkFilter->filter( | ||
534 | BookmarkFilter::$FILTER_TEXT, | ||
535 | '"psr-2" coding guide http fig "psr-2/" "This guide" basic standard. coding-style quality assurance' | ||
536 | ); | ||
537 | |||
538 | static::assertCount(1, $bookmarks); | ||
539 | static::assertArrayHasKey(9, $bookmarks); | ||
540 | |||
541 | $bookmark = $bookmarks[9]; | ||
542 | $expectedHighlights = [ | ||
543 | 'title' => [ | ||
544 | ['start' => 0, 'end' => 5], // "psr-2" | ||
545 | ['start' => 7, 'end' => 13], // coding | ||
546 | ['start' => 20, 'end' => 25], // guide | ||
547 | ], | ||
548 | 'description' => [ | ||
549 | ['start' => 0, 'end' => 10], // "This guide" | ||
550 | ['start' => 45, 'end' => 50], // basic | ||
551 | ['start' => 58, 'end' => 67], // standard. | ||
552 | ], | ||
553 | 'url' => [ | ||
554 | ['start' => 0, 'end' => 4], // http | ||
555 | ['start' => 15, 'end' => 18], // fig | ||
556 | ['start' => 27, 'end' => 33], // "psr-2/" | ||
557 | ], | ||
558 | 'tags' => [ | ||
559 | ['start' => 0, 'end' => 12], // coding-style | ||
560 | ['start' => 23, 'end' => 30], // quality | ||
561 | ['start' => 31, 'end' => 40], // assurance | ||
562 | ], | ||
563 | ]; | ||
564 | static::assertSame($expectedHighlights, $bookmark->getAdditionalContentEntry('search_highlight')); | ||
565 | } | ||
526 | } | 566 | } |
diff --git a/tests/bookmark/BookmarkInitializerTest.php b/tests/bookmark/BookmarkInitializerTest.php index 25704004..0c8420ce 100644 --- a/tests/bookmark/BookmarkInitializerTest.php +++ b/tests/bookmark/BookmarkInitializerTest.php | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | namespace Shaarli\Bookmark; | 3 | namespace Shaarli\Bookmark; |
4 | 4 | ||
5 | use malkusch\lock\mutex\NoMutex; | ||
5 | use Shaarli\Config\ConfigManager; | 6 | use Shaarli\Config\ConfigManager; |
6 | use Shaarli\History; | 7 | use Shaarli\History; |
7 | use Shaarli\TestCase; | 8 | use Shaarli\TestCase; |
@@ -34,11 +35,15 @@ class BookmarkInitializerTest extends TestCase | |||
34 | /** @var BookmarkInitializer instance */ | 35 | /** @var BookmarkInitializer instance */ |
35 | protected $initializer; | 36 | protected $initializer; |
36 | 37 | ||
38 | /** @var NoMutex */ | ||
39 | protected $mutex; | ||
40 | |||
37 | /** | 41 | /** |
38 | * Initialize an empty BookmarkFileService | 42 | * Initialize an empty BookmarkFileService |
39 | */ | 43 | */ |
40 | public function setUp(): void | 44 | public function setUp(): void |
41 | { | 45 | { |
46 | $this->mutex = new NoMutex(); | ||
42 | if (file_exists(self::$testDatastore)) { | 47 | if (file_exists(self::$testDatastore)) { |
43 | unlink(self::$testDatastore); | 48 | unlink(self::$testDatastore); |
44 | } | 49 | } |
@@ -47,7 +52,7 @@ class BookmarkInitializerTest extends TestCase | |||
47 | $this->conf = new ConfigManager(self::$testConf); | 52 | $this->conf = new ConfigManager(self::$testConf); |
48 | $this->conf->set('resource.datastore', self::$testDatastore); | 53 | $this->conf->set('resource.datastore', self::$testDatastore); |
49 | $this->history = new History('sandbox/history.php'); | 54 | $this->history = new History('sandbox/history.php'); |
50 | $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); | 55 | $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
51 | 56 | ||
52 | $this->initializer = new BookmarkInitializer($this->bookmarkService); | 57 | $this->initializer = new BookmarkInitializer($this->bookmarkService); |
53 | } | 58 | } |
@@ -59,7 +64,7 @@ class BookmarkInitializerTest extends TestCase | |||
59 | { | 64 | { |
60 | $refDB = new \ReferenceLinkDB(); | 65 | $refDB = new \ReferenceLinkDB(); |
61 | $refDB->write(self::$testDatastore); | 66 | $refDB->write(self::$testDatastore); |
62 | $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); | 67 | $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
63 | $this->initializer = new BookmarkInitializer($this->bookmarkService); | 68 | $this->initializer = new BookmarkInitializer($this->bookmarkService); |
64 | 69 | ||
65 | $this->initializer->initialize(); | 70 | $this->initializer->initialize(); |
@@ -90,7 +95,7 @@ class BookmarkInitializerTest extends TestCase | |||
90 | $this->bookmarkService->save(); | 95 | $this->bookmarkService->save(); |
91 | 96 | ||
92 | // Reload from file | 97 | // Reload from file |
93 | $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); | 98 | $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
94 | $this->assertEquals($refDB->countLinks() + 3, $this->bookmarkService->count()); | 99 | $this->assertEquals($refDB->countLinks() + 3, $this->bookmarkService->count()); |
95 | 100 | ||
96 | $bookmark = $this->bookmarkService->get(43); | 101 | $bookmark = $this->bookmarkService->get(43); |
@@ -121,7 +126,7 @@ class BookmarkInitializerTest extends TestCase | |||
121 | public function testInitializeNonExistentDataStore(): void | 126 | public function testInitializeNonExistentDataStore(): void |
122 | { | 127 | { |
123 | $this->conf->set('resource.datastore', static::$testDatastore . '_empty'); | 128 | $this->conf->set('resource.datastore', static::$testDatastore . '_empty'); |
124 | $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true); | 129 | $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); |
125 | 130 | ||
126 | $this->initializer->initialize(); | 131 | $this->initializer->initialize(); |
127 | 132 | ||
diff --git a/tests/bookmark/BookmarkTest.php b/tests/bookmark/BookmarkTest.php index afec2440..cb91b26b 100644 --- a/tests/bookmark/BookmarkTest.php +++ b/tests/bookmark/BookmarkTest.php | |||
@@ -79,6 +79,23 @@ class BookmarkTest extends TestCase | |||
79 | } | 79 | } |
80 | 80 | ||
81 | /** | 81 | /** |
82 | * Test fromArray() with a link with a custom tags separator | ||
83 | */ | ||
84 | public function testFromArrayCustomTagsSeparator() | ||
85 | { | ||
86 | $data = [ | ||
87 | 'id' => 1, | ||
88 | 'tags' => ['tag1', 'tag2', 'chair'], | ||
89 | ]; | ||
90 | |||
91 | $bookmark = (new Bookmark())->fromArray($data, '@'); | ||
92 | $this->assertEquals($data['id'], $bookmark->getId()); | ||
93 | $this->assertEquals($data['tags'], $bookmark->getTags()); | ||
94 | $this->assertEquals('tag1@tag2@chair', $bookmark->getTagsString('@')); | ||
95 | } | ||
96 | |||
97 | |||
98 | /** | ||
82 | * Test validate() with a valid minimal bookmark | 99 | * Test validate() with a valid minimal bookmark |
83 | */ | 100 | */ |
84 | public function testValidateValidFullBookmark() | 101 | public function testValidateValidFullBookmark() |
@@ -154,25 +171,6 @@ class BookmarkTest extends TestCase | |||
154 | } | 171 | } |
155 | 172 | ||
156 | /** | 173 | /** |
157 | * Test validate() with a a bookmark with a non integer ID. | ||
158 | */ | ||
159 | public function testValidateNotValidStringId() | ||
160 | { | ||
161 | $bookmark = new Bookmark(); | ||
162 | $bookmark->setId('str'); | ||
163 | $bookmark->setShortUrl('abc'); | ||
164 | $bookmark->setCreated(\DateTime::createFromFormat('Ymd_His', '20190514_200102')); | ||
165 | $exception = null; | ||
166 | try { | ||
167 | $bookmark->validate(); | ||
168 | } catch (InvalidBookmarkException $e) { | ||
169 | $exception = $e; | ||
170 | } | ||
171 | $this->assertNotNull($exception); | ||
172 | $this->assertContainsPolyfill('- ID: str'. PHP_EOL, $exception->getMessage()); | ||
173 | } | ||
174 | |||
175 | /** | ||
176 | * Test validate() with a a bookmark without short url. | 174 | * Test validate() with a a bookmark without short url. |
177 | */ | 175 | */ |
178 | public function testValidateNotValidNoShortUrl() | 176 | public function testValidateNotValidNoShortUrl() |
@@ -211,25 +209,6 @@ class BookmarkTest extends TestCase | |||
211 | } | 209 | } |
212 | 210 | ||
213 | /** | 211 | /** |
214 | * Test validate() with a a bookmark with a bad created datetime. | ||
215 | */ | ||
216 | public function testValidateNotValidBadCreated() | ||
217 | { | ||
218 | $bookmark = new Bookmark(); | ||
219 | $bookmark->setId(1); | ||
220 | $bookmark->setShortUrl('abc'); | ||
221 | $bookmark->setCreated('hi!'); | ||
222 | $exception = null; | ||
223 | try { | ||
224 | $bookmark->validate(); | ||
225 | } catch (InvalidBookmarkException $e) { | ||
226 | $exception = $e; | ||
227 | } | ||
228 | $this->assertNotNull($exception); | ||
229 | $this->assertContainsPolyfill('- Created: Not a DateTime object'. PHP_EOL, $exception->getMessage()); | ||
230 | } | ||
231 | |||
232 | /** | ||
233 | * Test setId() and make sure that default fields are generated. | 212 | * Test setId() and make sure that default fields are generated. |
234 | */ | 213 | */ |
235 | public function testSetIdEmptyGeneratedFields() | 214 | public function testSetIdEmptyGeneratedFields() |
@@ -290,7 +269,7 @@ class BookmarkTest extends TestCase | |||
290 | { | 269 | { |
291 | $bookmark = new Bookmark(); | 270 | $bookmark = new Bookmark(); |
292 | 271 | ||
293 | $str = 'tag1 tag2 tag3.tag3-2, tag4 , -tag5 '; | 272 | $str = 'tag1 tag2 tag3.tag3-2 tag4 -tag5 '; |
294 | $bookmark->setTagsString($str); | 273 | $bookmark->setTagsString($str); |
295 | $this->assertEquals( | 274 | $this->assertEquals( |
296 | [ | 275 | [ |
@@ -314,9 +293,9 @@ class BookmarkTest extends TestCase | |||
314 | $array = [ | 293 | $array = [ |
315 | 'tag1 ', | 294 | 'tag1 ', |
316 | ' tag2', | 295 | ' tag2', |
317 | 'tag3.tag3-2,', | 296 | 'tag3.tag3-2', |
318 | ', tag4', | 297 | ' tag4', |
319 | ', ', | 298 | ' ', |
320 | '-tag5 ', | 299 | '-tag5 ', |
321 | ]; | 300 | ]; |
322 | $bookmark->setTags($array); | 301 | $bookmark->setTags($array); |
@@ -385,4 +364,48 @@ class BookmarkTest extends TestCase | |||
385 | $bookmark->deleteTag('nope'); | 364 | $bookmark->deleteTag('nope'); |
386 | $this->assertEquals(['tag1', 'tag2', 'chair'], $bookmark->getTags()); | 365 | $this->assertEquals(['tag1', 'tag2', 'chair'], $bookmark->getTags()); |
387 | } | 366 | } |
367 | |||
368 | /** | ||
369 | * Test shouldUpdateThumbnail() with bookmarks needing an update. | ||
370 | */ | ||
371 | public function testShouldUpdateThumbnail(): void | ||
372 | { | ||
373 | $bookmark = (new Bookmark())->setUrl('http://domain.tld/with-image'); | ||
374 | |||
375 | static::assertTrue($bookmark->shouldUpdateThumbnail()); | ||
376 | |||
377 | $bookmark = (new Bookmark()) | ||
378 | ->setUrl('http://domain.tld/with-image') | ||
379 | ->setThumbnail('unknown file') | ||
380 | ; | ||
381 | |||
382 | static::assertTrue($bookmark->shouldUpdateThumbnail()); | ||
383 | } | ||
384 | |||
385 | /** | ||
386 | * Test shouldUpdateThumbnail() with bookmarks that should not update. | ||
387 | */ | ||
388 | public function testShouldNotUpdateThumbnail(): void | ||
389 | { | ||
390 | $bookmark = (new Bookmark()); | ||
391 | |||
392 | static::assertFalse($bookmark->shouldUpdateThumbnail()); | ||
393 | |||
394 | $bookmark = (new Bookmark()) | ||
395 | ->setUrl('ftp://domain.tld/other-protocol', ['ftp']) | ||
396 | ; | ||
397 | |||
398 | static::assertFalse($bookmark->shouldUpdateThumbnail()); | ||
399 | |||
400 | $bookmark = (new Bookmark()) | ||
401 | ->setUrl('http://domain.tld/with-image') | ||
402 | ->setThumbnail(__FILE__) | ||
403 | ; | ||
404 | |||
405 | static::assertFalse($bookmark->shouldUpdateThumbnail()); | ||
406 | |||
407 | $bookmark = (new Bookmark())->setUrl('/shaare/abcdef'); | ||
408 | |||
409 | static::assertFalse($bookmark->shouldUpdateThumbnail()); | ||
410 | } | ||
388 | } | 411 | } |
diff --git a/tests/bookmark/LinkUtilsTest.php b/tests/bookmark/LinkUtilsTest.php index ef00b92f..ddab4e3c 100644 --- a/tests/bookmark/LinkUtilsTest.php +++ b/tests/bookmark/LinkUtilsTest.php | |||
@@ -94,8 +94,108 @@ class LinkUtilsTest extends TestCase | |||
94 | public function testHtmlExtractExistentNameTag() | 94 | public function testHtmlExtractExistentNameTag() |
95 | { | 95 | { |
96 | $description = 'Bob and Alice share cookies.'; | 96 | $description = 'Bob and Alice share cookies.'; |
97 | |||
98 | // Simple one line | ||
97 | $html = '<html><meta>stuff2</meta><meta name="description" content="' . $description . '"/></html>'; | 99 | $html = '<html><meta>stuff2</meta><meta name="description" content="' . $description . '"/></html>'; |
98 | $this->assertEquals($description, html_extract_tag('description', $html)); | 100 | $this->assertEquals($description, html_extract_tag('description', $html)); |
101 | |||
102 | // Simple OpenGraph | ||
103 | $html = '<meta property="og:description" content="' . $description . '">'; | ||
104 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
105 | |||
106 | // Simple reversed OpenGraph | ||
107 | $html = '<meta content="' . $description . '" property="og:description">'; | ||
108 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
109 | |||
110 | // ItemProp OpenGraph | ||
111 | $html = '<meta itemprop="og:description" content="' . $description . '">'; | ||
112 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
113 | |||
114 | // OpenGraph without quotes | ||
115 | $html = '<meta property=og:description content="' . $description . '">'; | ||
116 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
117 | |||
118 | // OpenGraph reversed without quotes | ||
119 | $html = '<meta content="' . $description . '" property=og:description>'; | ||
120 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
121 | |||
122 | // OpenGraph with noise | ||
123 | $html = '<meta tag1="content1" property="og:description" tag2="content2" content="' . | ||
124 | $description . '" tag3="content3">'; | ||
125 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
126 | |||
127 | // OpenGraph reversed with noise | ||
128 | $html = '<meta tag1="content1" content="' . $description . '" ' . | ||
129 | 'tag3="content3" tag2="content2" property="og:description">'; | ||
130 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
131 | |||
132 | // OpenGraph multiple properties start | ||
133 | $html = '<meta property="unrelated og:description" content="' . $description . '">'; | ||
134 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
135 | |||
136 | // OpenGraph multiple properties end | ||
137 | $html = '<meta property="og:description unrelated" content="' . $description . '">'; | ||
138 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
139 | |||
140 | // OpenGraph multiple properties both end | ||
141 | $html = '<meta property="og:unrelated1 og:description og:unrelated2" content="' . $description . '">'; | ||
142 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
143 | |||
144 | // OpenGraph multiple properties both end with noise | ||
145 | $html = '<meta tag1="content1" property="og:unrelated1 og:description og:unrelated2" '. | ||
146 | 'tag2="content2" content="' . $description . '" tag3="content3">'; | ||
147 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
148 | |||
149 | // OpenGraph reversed multiple properties start | ||
150 | $html = '<meta content="' . $description . '" property="unrelated og:description">'; | ||
151 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
152 | |||
153 | // OpenGraph reversed multiple properties end | ||
154 | $html = '<meta content="' . $description . '" property="og:description unrelated">'; | ||
155 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
156 | |||
157 | // OpenGraph reversed multiple properties both end | ||
158 | $html = '<meta content="' . $description . '" property="og:unrelated1 og:description og:unrelated2">'; | ||
159 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
160 | |||
161 | // OpenGraph reversed multiple properties both end with noise | ||
162 | $html = '<meta tag1="content1" content="' . $description . '" tag2="content2" '. | ||
163 | 'property="og:unrelated1 og:description og:unrelated2" tag3="content3">'; | ||
164 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
165 | |||
166 | // Suggestion from #1375 | ||
167 | $html = '<meta property="og:description" name="description" content="' . $description . '">'; | ||
168 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * Test html_extract_tag() with double quoted content containing single quote, and the opposite. | ||
173 | */ | ||
174 | public function testHtmlExtractExistentNameTagWithMixedQuotes(): void | ||
175 | { | ||
176 | $description = 'Bob and Alice share M&M\'s.'; | ||
177 | |||
178 | $html = '<meta property="og:description" content="' . $description . '">'; | ||
179 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
180 | |||
181 | $html = '<meta tag1="content1" property="og:unrelated1 og:description og:unrelated2" '. | ||
182 | 'tag2="content2" content="' . $description . '" tag3="content3">'; | ||
183 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
184 | |||
185 | $html = '<meta property="og:description" name="description" content="' . $description . '">'; | ||
186 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
187 | |||
188 | $description = 'Bob and Alice share "cookies".'; | ||
189 | |||
190 | $html = '<meta property="og:description" content=\'' . $description . '\'>'; | ||
191 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
192 | |||
193 | $html = '<meta tag1="content1" property="og:unrelated1 og:description og:unrelated2" '. | ||
194 | 'tag2="content2" content=\'' . $description . '\' tag3="content3">'; | ||
195 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
196 | |||
197 | $html = '<meta property="og:description" name="description" content=\'' . $description . '\'>'; | ||
198 | $this->assertEquals($description, html_extract_tag('description', $html)); | ||
99 | } | 199 | } |
100 | 200 | ||
101 | /** | 201 | /** |
@@ -105,6 +205,25 @@ class LinkUtilsTest extends TestCase | |||
105 | { | 205 | { |
106 | $html = '<html><meta>stuff2</meta><meta name="image" content="img"/></html>'; | 206 | $html = '<html><meta>stuff2</meta><meta name="image" content="img"/></html>'; |
107 | $this->assertFalse(html_extract_tag('description', $html)); | 207 | $this->assertFalse(html_extract_tag('description', $html)); |
208 | |||
209 | // Partial meta tag | ||
210 | $html = '<meta content="Brief description">'; | ||
211 | $this->assertFalse(html_extract_tag('description', $html)); | ||
212 | |||
213 | $html = '<meta property="og:description">'; | ||
214 | $this->assertFalse(html_extract_tag('description', $html)); | ||
215 | |||
216 | $html = '<meta tag1="content1" property="og:description">'; | ||
217 | $this->assertFalse(html_extract_tag('description', $html)); | ||
218 | |||
219 | $html = '<meta property="og:description" tag1="content1">'; | ||
220 | $this->assertFalse(html_extract_tag('description', $html)); | ||
221 | |||
222 | $html = '<meta tag1="content1" content="Brief description">'; | ||
223 | $this->assertFalse(html_extract_tag('description', $html)); | ||
224 | |||
225 | $html = '<meta content="Brief description" tag1="content1">'; | ||
226 | $this->assertFalse(html_extract_tag('description', $html)); | ||
108 | } | 227 | } |
109 | 228 | ||
110 | /** | 229 | /** |
@@ -127,60 +246,93 @@ class LinkUtilsTest extends TestCase | |||
127 | } | 246 | } |
128 | 247 | ||
129 | /** | 248 | /** |
249 | * Test the header callback with valid value | ||
250 | */ | ||
251 | public function testCurlHeaderCallbackOk(): void | ||
252 | { | ||
253 | $callback = get_curl_header_callback($charset, 'ut_curl_getinfo_ok'); | ||
254 | $data = [ | ||
255 | 'HTTP/1.1 200 OK', | ||
256 | 'Server: GitHub.com', | ||
257 | 'Date: Sat, 28 Oct 2017 12:01:33 GMT', | ||
258 | 'Content-Type: text/html; charset=utf-8', | ||
259 | 'Status: 200 OK', | ||
260 | ]; | ||
261 | |||
262 | foreach ($data as $chunk) { | ||
263 | static::assertIsInt($callback(null, $chunk)); | ||
264 | } | ||
265 | |||
266 | static::assertSame('utf-8', $charset); | ||
267 | } | ||
268 | |||
269 | /** | ||
130 | * Test the download callback with valid value | 270 | * Test the download callback with valid value |
131 | */ | 271 | */ |
132 | public function testCurlDownloadCallbackOk() | 272 | public function testCurlDownloadCallbackOk(): void |
133 | { | 273 | { |
274 | $charset = 'utf-8'; | ||
134 | $callback = get_curl_download_callback( | 275 | $callback = get_curl_download_callback( |
135 | $charset, | 276 | $charset, |
136 | $title, | 277 | $title, |
137 | $desc, | 278 | $desc, |
138 | $keywords, | 279 | $keywords, |
139 | false, | 280 | false, |
140 | 'ut_curl_getinfo_ok' | 281 | ' ' |
141 | ); | 282 | ); |
283 | |||
142 | $data = [ | 284 | $data = [ |
143 | 'HTTP/1.1 200 OK', | 285 | 'th=device-width">' |
144 | 'Server: GitHub.com', | ||
145 | 'Date: Sat, 28 Oct 2017 12:01:33 GMT', | ||
146 | 'Content-Type: text/html; charset=utf-8', | ||
147 | 'Status: 200 OK', | ||
148 | 'end' => 'th=device-width">' | ||
149 | . '<title>Refactoring · GitHub</title>' | 286 | . '<title>Refactoring · GitHub</title>' |
150 | . '<link rel="search" type="application/opensea', | 287 | . '<link rel="search" type="application/opensea', |
151 | '<title>ignored</title>' | 288 | '<title>ignored</title>' |
152 | . '<meta name="description" content="desc" />' | 289 | . '<meta name="description" content="desc" />' |
153 | . '<meta name="keywords" content="key1,key2" />', | 290 | . '<meta name="keywords" content="key1,key2" />', |
154 | ]; | 291 | ]; |
155 | foreach ($data as $key => $line) { | 292 | |
156 | $ignore = null; | 293 | foreach ($data as $chunk) { |
157 | $expected = $key !== 'end' ? strlen($line) : false; | 294 | static::assertSame(strlen($chunk), $callback(null, $chunk)); |
158 | $this->assertEquals($expected, $callback($ignore, $line)); | ||
159 | if ($expected === false) { | ||
160 | break; | ||
161 | } | ||
162 | } | 295 | } |
163 | $this->assertEquals('utf-8', $charset); | 296 | |
164 | $this->assertEquals('Refactoring · GitHub', $title); | 297 | static::assertSame('utf-8', $charset); |
165 | $this->assertEmpty($desc); | 298 | static::assertSame('Refactoring · GitHub', $title); |
166 | $this->assertEmpty($keywords); | 299 | static::assertEmpty($desc); |
300 | static::assertEmpty($keywords); | ||
301 | } | ||
302 | |||
303 | /** | ||
304 | * Test the header callback with valid value | ||
305 | */ | ||
306 | public function testCurlHeaderCallbackNoCharset(): void | ||
307 | { | ||
308 | $callback = get_curl_header_callback($charset, 'ut_curl_getinfo_no_charset'); | ||
309 | $data = [ | ||
310 | 'HTTP/1.1 200 OK', | ||
311 | ]; | ||
312 | |||
313 | foreach ($data as $chunk) { | ||
314 | static::assertSame(strlen($chunk), $callback(null, $chunk)); | ||
315 | } | ||
316 | |||
317 | static::assertFalse($charset); | ||
167 | } | 318 | } |
168 | 319 | ||
169 | /** | 320 | /** |
170 | * Test the download callback with valid values and no charset | 321 | * Test the download callback with valid values and no charset |
171 | */ | 322 | */ |
172 | public function testCurlDownloadCallbackOkNoCharset() | 323 | public function testCurlDownloadCallbackOkNoCharset(): void |
173 | { | 324 | { |
325 | $charset = null; | ||
174 | $callback = get_curl_download_callback( | 326 | $callback = get_curl_download_callback( |
175 | $charset, | 327 | $charset, |
176 | $title, | 328 | $title, |
177 | $desc, | 329 | $desc, |
178 | $keywords, | 330 | $keywords, |
179 | false, | 331 | false, |
180 | 'ut_curl_getinfo_no_charset' | 332 | ' ' |
181 | ); | 333 | ); |
334 | |||
182 | $data = [ | 335 | $data = [ |
183 | 'HTTP/1.1 200 OK', | ||
184 | 'end' => 'th=device-width">' | 336 | 'end' => 'th=device-width">' |
185 | . '<title>Refactoring · GitHub</title>' | 337 | . '<title>Refactoring · GitHub</title>' |
186 | . '<link rel="search" type="application/opensea', | 338 | . '<link rel="search" type="application/opensea', |
@@ -188,10 +340,11 @@ class LinkUtilsTest extends TestCase | |||
188 | . '<meta name="description" content="desc" />' | 340 | . '<meta name="description" content="desc" />' |
189 | . '<meta name="keywords" content="key1,key2" />', | 341 | . '<meta name="keywords" content="key1,key2" />', |
190 | ]; | 342 | ]; |
191 | foreach ($data as $key => $line) { | 343 | |
192 | $ignore = null; | 344 | foreach ($data as $chunk) { |
193 | $this->assertEquals(strlen($line), $callback($ignore, $line)); | 345 | static::assertSame(strlen($chunk), $callback(null, $chunk)); |
194 | } | 346 | } |
347 | |||
195 | $this->assertEmpty($charset); | 348 | $this->assertEmpty($charset); |
196 | $this->assertEquals('Refactoring · GitHub', $title); | 349 | $this->assertEquals('Refactoring · GitHub', $title); |
197 | $this->assertEmpty($desc); | 350 | $this->assertEmpty($desc); |
@@ -201,18 +354,19 @@ class LinkUtilsTest extends TestCase | |||
201 | /** | 354 | /** |
202 | * Test the download callback with valid values and no charset | 355 | * Test the download callback with valid values and no charset |
203 | */ | 356 | */ |
204 | public function testCurlDownloadCallbackOkHtmlCharset() | 357 | public function testCurlDownloadCallbackOkHtmlCharset(): void |
205 | { | 358 | { |
359 | $charset = null; | ||
206 | $callback = get_curl_download_callback( | 360 | $callback = get_curl_download_callback( |
207 | $charset, | 361 | $charset, |
208 | $title, | 362 | $title, |
209 | $desc, | 363 | $desc, |
210 | $keywords, | 364 | $keywords, |
211 | false, | 365 | false, |
212 | 'ut_curl_getinfo_no_charset' | 366 | ' ' |
213 | ); | 367 | ); |
368 | |||
214 | $data = [ | 369 | $data = [ |
215 | 'HTTP/1.1 200 OK', | ||
216 | '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />', | 370 | '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />', |
217 | 'end' => 'th=device-width">' | 371 | 'end' => 'th=device-width">' |
218 | . '<title>Refactoring · GitHub</title>' | 372 | . '<title>Refactoring · GitHub</title>' |
@@ -221,14 +375,10 @@ class LinkUtilsTest extends TestCase | |||
221 | . '<meta name="description" content="desc" />' | 375 | . '<meta name="description" content="desc" />' |
222 | . '<meta name="keywords" content="key1,key2" />', | 376 | . '<meta name="keywords" content="key1,key2" />', |
223 | ]; | 377 | ]; |
224 | foreach ($data as $key => $line) { | 378 | foreach ($data as $chunk) { |
225 | $ignore = null; | 379 | static::assertSame(strlen($chunk), $callback(null, $chunk)); |
226 | $expected = $key !== 'end' ? strlen($line) : false; | ||
227 | $this->assertEquals($expected, $callback($ignore, $line)); | ||
228 | if ($expected === false) { | ||
229 | break; | ||
230 | } | ||
231 | } | 380 | } |
381 | |||
232 | $this->assertEquals('utf-8', $charset); | 382 | $this->assertEquals('utf-8', $charset); |
233 | $this->assertEquals('Refactoring · GitHub', $title); | 383 | $this->assertEquals('Refactoring · GitHub', $title); |
234 | $this->assertEmpty($desc); | 384 | $this->assertEmpty($desc); |
@@ -238,25 +388,27 @@ class LinkUtilsTest extends TestCase | |||
238 | /** | 388 | /** |
239 | * Test the download callback with valid values and no title | 389 | * Test the download callback with valid values and no title |
240 | */ | 390 | */ |
241 | public function testCurlDownloadCallbackOkNoTitle() | 391 | public function testCurlDownloadCallbackOkNoTitle(): void |
242 | { | 392 | { |
393 | $charset = 'utf-8'; | ||
243 | $callback = get_curl_download_callback( | 394 | $callback = get_curl_download_callback( |
244 | $charset, | 395 | $charset, |
245 | $title, | 396 | $title, |
246 | $desc, | 397 | $desc, |
247 | $keywords, | 398 | $keywords, |
248 | false, | 399 | false, |
249 | 'ut_curl_getinfo_ok' | 400 | ' ' |
250 | ); | 401 | ); |
402 | |||
251 | $data = [ | 403 | $data = [ |
252 | 'HTTP/1.1 200 OK', | ||
253 | 'end' => 'th=device-width">Refactoring · GitHub<link rel="search" type="application/opensea', | 404 | 'end' => 'th=device-width">Refactoring · GitHub<link rel="search" type="application/opensea', |
254 | 'ignored', | 405 | 'ignored', |
255 | ]; | 406 | ]; |
256 | foreach ($data as $key => $line) { | 407 | |
257 | $ignore = null; | 408 | foreach ($data as $chunk) { |
258 | $this->assertEquals(strlen($line), $callback($ignore, $line)); | 409 | static::assertSame(strlen($chunk), $callback(null, $chunk)); |
259 | } | 410 | } |
411 | |||
260 | $this->assertEquals('utf-8', $charset); | 412 | $this->assertEquals('utf-8', $charset); |
261 | $this->assertEmpty($title); | 413 | $this->assertEmpty($title); |
262 | $this->assertEmpty($desc); | 414 | $this->assertEmpty($desc); |
@@ -264,81 +416,56 @@ class LinkUtilsTest extends TestCase | |||
264 | } | 416 | } |
265 | 417 | ||
266 | /** | 418 | /** |
267 | * Test the download callback with an invalid content type. | 419 | * Test the header callback with an invalid content type. |
268 | */ | 420 | */ |
269 | public function testCurlDownloadCallbackInvalidContentType() | 421 | public function testCurlHeaderCallbackInvalidContentType(): void |
270 | { | 422 | { |
271 | $callback = get_curl_download_callback( | 423 | $callback = get_curl_header_callback($charset, 'ut_curl_getinfo_ct_ko'); |
272 | $charset, | 424 | $data = [ |
273 | $title, | 425 | 'HTTP/1.1 200 OK', |
274 | $desc, | 426 | ]; |
275 | $keywords, | 427 | |
276 | false, | 428 | static::assertFalse($callback(null, $data[0])); |
277 | 'ut_curl_getinfo_ct_ko' | 429 | static::assertNull($charset); |
278 | ); | ||
279 | $ignore = null; | ||
280 | $this->assertFalse($callback($ignore, '')); | ||
281 | $this->assertEmpty($charset); | ||
282 | $this->assertEmpty($title); | ||
283 | } | 430 | } |
284 | 431 | ||
285 | /** | 432 | /** |
286 | * Test the download callback with an invalid response code. | 433 | * Test the header callback with an invalid response code. |
287 | */ | 434 | */ |
288 | public function testCurlDownloadCallbackInvalidResponseCode() | 435 | public function testCurlHeaderCallbackInvalidResponseCode(): void |
289 | { | 436 | { |
290 | $callback = $callback = get_curl_download_callback( | 437 | $callback = get_curl_header_callback($charset, 'ut_curl_getinfo_rc_ko'); |
291 | $charset, | 438 | |
292 | $title, | 439 | static::assertFalse($callback(null, '')); |
293 | $desc, | 440 | static::assertNull($charset); |
294 | $keywords, | ||
295 | false, | ||
296 | 'ut_curl_getinfo_rc_ko' | ||
297 | ); | ||
298 | $ignore = null; | ||
299 | $this->assertFalse($callback($ignore, '')); | ||
300 | $this->assertEmpty($charset); | ||
301 | $this->assertEmpty($title); | ||
302 | } | 441 | } |
303 | 442 | ||
304 | /** | 443 | /** |
305 | * Test the download callback with an invalid content type and response code. | 444 | * Test the header callback with an invalid content type and response code. |
306 | */ | 445 | */ |
307 | public function testCurlDownloadCallbackInvalidContentTypeAndResponseCode() | 446 | public function testCurlHeaderCallbackInvalidContentTypeAndResponseCode(): void |
308 | { | 447 | { |
309 | $callback = $callback = get_curl_download_callback( | 448 | $callback = get_curl_header_callback($charset, 'ut_curl_getinfo_rs_ct_ko'); |
310 | $charset, | 449 | |
311 | $title, | 450 | static::assertFalse($callback(null, '')); |
312 | $desc, | 451 | static::assertNull($charset); |
313 | $keywords, | ||
314 | false, | ||
315 | 'ut_curl_getinfo_rs_ct_ko' | ||
316 | ); | ||
317 | $ignore = null; | ||
318 | $this->assertFalse($callback($ignore, '')); | ||
319 | $this->assertEmpty($charset); | ||
320 | $this->assertEmpty($title); | ||
321 | } | 452 | } |
322 | 453 | ||
323 | /** | 454 | /** |
324 | * Test the download callback with valid value, and retrieve_description option enabled. | 455 | * Test the download callback with valid value, and retrieve_description option enabled. |
325 | */ | 456 | */ |
326 | public function testCurlDownloadCallbackOkWithDesc() | 457 | public function testCurlDownloadCallbackOkWithDesc(): void |
327 | { | 458 | { |
459 | $charset = 'utf-8'; | ||
328 | $callback = get_curl_download_callback( | 460 | $callback = get_curl_download_callback( |
329 | $charset, | 461 | $charset, |
330 | $title, | 462 | $title, |
331 | $desc, | 463 | $desc, |
332 | $keywords, | 464 | $keywords, |
333 | true, | 465 | true, |
334 | 'ut_curl_getinfo_ok' | 466 | ' ' |
335 | ); | 467 | ); |
336 | $data = [ | 468 | $data = [ |
337 | 'HTTP/1.1 200 OK', | ||
338 | 'Server: GitHub.com', | ||
339 | 'Date: Sat, 28 Oct 2017 12:01:33 GMT', | ||
340 | 'Content-Type: text/html; charset=utf-8', | ||
341 | 'Status: 200 OK', | ||
342 | 'th=device-width">' | 469 | 'th=device-width">' |
343 | . '<title>Refactoring · GitHub</title>' | 470 | . '<title>Refactoring · GitHub</title>' |
344 | . '<link rel="search" type="application/opensea', | 471 | . '<link rel="search" type="application/opensea', |
@@ -346,14 +473,11 @@ class LinkUtilsTest extends TestCase | |||
346 | . '<meta name="description" content="link desc" />' | 473 | . '<meta name="description" content="link desc" />' |
347 | . '<meta name="keywords" content="key1,key2" />', | 474 | . '<meta name="keywords" content="key1,key2" />', |
348 | ]; | 475 | ]; |
349 | foreach ($data as $key => $line) { | 476 | |
350 | $ignore = null; | 477 | foreach ($data as $chunk) { |
351 | $expected = $key !== 'end' ? strlen($line) : false; | 478 | static::assertSame(strlen($chunk), $callback(null, $chunk)); |
352 | $this->assertEquals($expected, $callback($ignore, $line)); | ||
353 | if ($expected === false) { | ||
354 | break; | ||
355 | } | ||
356 | } | 479 | } |
480 | |||
357 | $this->assertEquals('utf-8', $charset); | 481 | $this->assertEquals('utf-8', $charset); |
358 | $this->assertEquals('Refactoring · GitHub', $title); | 482 | $this->assertEquals('Refactoring · GitHub', $title); |
359 | $this->assertEquals('link desc', $desc); | 483 | $this->assertEquals('link desc', $desc); |
@@ -364,8 +488,9 @@ class LinkUtilsTest extends TestCase | |||
364 | * Test the download callback with valid value, and retrieve_description option enabled, | 488 | * Test the download callback with valid value, and retrieve_description option enabled, |
365 | * but no desc or keyword defined in the page. | 489 | * but no desc or keyword defined in the page. |
366 | */ | 490 | */ |
367 | public function testCurlDownloadCallbackOkWithDescNotFound() | 491 | public function testCurlDownloadCallbackOkWithDescNotFound(): void |
368 | { | 492 | { |
493 | $charset = 'utf-8'; | ||
369 | $callback = get_curl_download_callback( | 494 | $callback = get_curl_download_callback( |
370 | $charset, | 495 | $charset, |
371 | $title, | 496 | $title, |
@@ -375,24 +500,16 @@ class LinkUtilsTest extends TestCase | |||
375 | 'ut_curl_getinfo_ok' | 500 | 'ut_curl_getinfo_ok' |
376 | ); | 501 | ); |
377 | $data = [ | 502 | $data = [ |
378 | 'HTTP/1.1 200 OK', | ||
379 | 'Server: GitHub.com', | ||
380 | 'Date: Sat, 28 Oct 2017 12:01:33 GMT', | ||
381 | 'Content-Type: text/html; charset=utf-8', | ||
382 | 'Status: 200 OK', | ||
383 | 'th=device-width">' | 503 | 'th=device-width">' |
384 | . '<title>Refactoring · GitHub</title>' | 504 | . '<title>Refactoring · GitHub</title>' |
385 | . '<link rel="search" type="application/opensea', | 505 | . '<link rel="search" type="application/opensea', |
386 | 'end' => '<title>ignored</title>', | 506 | 'end' => '<title>ignored</title>', |
387 | ]; | 507 | ]; |
388 | foreach ($data as $key => $line) { | 508 | |
389 | $ignore = null; | 509 | foreach ($data as $chunk) { |
390 | $expected = $key !== 'end' ? strlen($line) : false; | 510 | static::assertSame(strlen($chunk), $callback(null, $chunk)); |
391 | $this->assertEquals($expected, $callback($ignore, $line)); | ||
392 | if ($expected === false) { | ||
393 | break; | ||
394 | } | ||
395 | } | 511 | } |
512 | |||
396 | $this->assertEquals('utf-8', $charset); | 513 | $this->assertEquals('utf-8', $charset); |
397 | $this->assertEquals('Refactoring · GitHub', $title); | 514 | $this->assertEquals('Refactoring · GitHub', $title); |
398 | $this->assertEmpty($desc); | 515 | $this->assertEmpty($desc); |
@@ -493,6 +610,115 @@ class LinkUtilsTest extends TestCase | |||
493 | } | 610 | } |
494 | 611 | ||
495 | /** | 612 | /** |
613 | * Test tags_str2array with whitespace separator. | ||
614 | */ | ||
615 | public function testTagsStr2ArrayWithSpaceSeparator(): void | ||
616 | { | ||
617 | $separator = ' '; | ||
618 | |||
619 | static::assertSame(['tag1', 'tag2', 'tag3'], tags_str2array('tag1 tag2 tag3', $separator)); | ||
620 | static::assertSame(['tag1', 'tag2', 'tag3'], tags_str2array('tag1 tag2 tag3', $separator)); | ||
621 | static::assertSame(['tag1', 'tag2', 'tag3'], tags_str2array(' tag1 tag2 tag3 ', $separator)); | ||
622 | static::assertSame(['tag1@', 'tag2,', '.tag3'], tags_str2array(' tag1@ tag2, .tag3 ', $separator)); | ||
623 | static::assertSame([], tags_str2array('', $separator)); | ||
624 | static::assertSame([], tags_str2array(' ', $separator)); | ||
625 | static::assertSame([], tags_str2array(null, $separator)); | ||
626 | } | ||
627 | |||
628 | /** | ||
629 | * Test tags_str2array with @ separator. | ||
630 | */ | ||
631 | public function testTagsStr2ArrayWithCharSeparator(): void | ||
632 | { | ||
633 | $separator = '@'; | ||
634 | |||
635 | static::assertSame(['tag1', 'tag2', 'tag3'], tags_str2array('tag1@tag2@tag3', $separator)); | ||
636 | static::assertSame(['tag1', 'tag2', 'tag3'], tags_str2array('tag1@@@@tag2@@@@tag3', $separator)); | ||
637 | static::assertSame(['tag1', 'tag2', 'tag3'], tags_str2array('@@@tag1@@@tag2@@@@tag3@@', $separator)); | ||
638 | static::assertSame( | ||
639 | ['tag1#', 'tag2, and other', '.tag3'], | ||
640 | tags_str2array('@@@ tag1# @@@ tag2, and other @@@@.tag3@@', $separator) | ||
641 | ); | ||
642 | static::assertSame([], tags_str2array('', $separator)); | ||
643 | static::assertSame([], tags_str2array(' ', $separator)); | ||
644 | static::assertSame([], tags_str2array(null, $separator)); | ||
645 | } | ||
646 | |||
647 | /** | ||
648 | * Test tags_array2str with ' ' separator. | ||
649 | */ | ||
650 | public function testTagsArray2StrWithSpaceSeparator(): void | ||
651 | { | ||
652 | $separator = ' '; | ||
653 | |||
654 | static::assertSame('tag1 tag2 tag3', tags_array2str(['tag1', 'tag2', 'tag3'], $separator)); | ||
655 | static::assertSame('tag1, tag2@ tag3', tags_array2str(['tag1,', 'tag2@', 'tag3'], $separator)); | ||
656 | static::assertSame('tag1 tag2 tag3', tags_array2str([' tag1 ', 'tag2', 'tag3 '], $separator)); | ||
657 | static::assertSame('tag1 tag2 tag3', tags_array2str([' tag1 ', ' ', 'tag2', ' ', 'tag3 '], $separator)); | ||
658 | static::assertSame('tag1', tags_array2str([' tag1 '], $separator)); | ||
659 | static::assertSame('', tags_array2str([' '], $separator)); | ||
660 | static::assertSame('', tags_array2str([], $separator)); | ||
661 | static::assertSame('', tags_array2str(null, $separator)); | ||
662 | } | ||
663 | |||
664 | /** | ||
665 | * Test tags_array2str with @ separator. | ||
666 | */ | ||
667 | public function testTagsArray2StrWithCharSeparator(): void | ||
668 | { | ||
669 | $separator = '@'; | ||
670 | |||
671 | static::assertSame('tag1@tag2@tag3', tags_array2str(['tag1', 'tag2', 'tag3'], $separator)); | ||
672 | static::assertSame('tag1,@tag2@tag3', tags_array2str(['tag1,', 'tag2@', 'tag3'], $separator)); | ||
673 | static::assertSame( | ||
674 | 'tag1@tag2, and other@tag3', | ||
675 | tags_array2str(['@@@@ tag1@@@', ' @tag2, and other @', 'tag3@@@@'], $separator) | ||
676 | ); | ||
677 | static::assertSame('tag1@tag2@tag3', tags_array2str(['@@@tag1@@@', '@', 'tag2', '@@@', 'tag3@@@'], $separator)); | ||
678 | static::assertSame('tag1', tags_array2str(['@@@@tag1@@@@'], $separator)); | ||
679 | static::assertSame('', tags_array2str(['@@@'], $separator)); | ||
680 | static::assertSame('', tags_array2str([], $separator)); | ||
681 | static::assertSame('', tags_array2str(null, $separator)); | ||
682 | } | ||
683 | |||
684 | /** | ||
685 | * Test tags_array2str with @ separator. | ||
686 | */ | ||
687 | public function testTagsFilterWithSpaceSeparator(): void | ||
688 | { | ||
689 | $separator = ' '; | ||
690 | |||
691 | static::assertSame(['tag1', 'tag2', 'tag3'], tags_filter(['tag1', 'tag2', 'tag3'], $separator)); | ||
692 | static::assertSame(['tag1,', 'tag2@', 'tag3'], tags_filter(['tag1,', 'tag2@', 'tag3'], $separator)); | ||
693 | static::assertSame(['tag1', 'tag2', 'tag3'], tags_filter([' tag1 ', 'tag2', 'tag3 '], $separator)); | ||
694 | static::assertSame(['tag1', 'tag2', 'tag3'], tags_filter([' tag1 ', ' ', 'tag2', ' ', 'tag3 '], $separator)); | ||
695 | static::assertSame(['tag1'], tags_filter([' tag1 '], $separator)); | ||
696 | static::assertSame([], tags_filter([' '], $separator)); | ||
697 | static::assertSame([], tags_filter([], $separator)); | ||
698 | static::assertSame([], tags_filter(null, $separator)); | ||
699 | } | ||
700 | |||
701 | /** | ||
702 | * Test tags_array2str with @ separator. | ||
703 | */ | ||
704 | public function testTagsArrayFilterWithSpaceSeparator(): void | ||
705 | { | ||
706 | $separator = '@'; | ||
707 | |||
708 | static::assertSame(['tag1', 'tag2', 'tag3'], tags_filter(['tag1', 'tag2', 'tag3'], $separator)); | ||
709 | static::assertSame(['tag1,', 'tag2#', 'tag3'], tags_filter(['tag1,', 'tag2#', 'tag3'], $separator)); | ||
710 | static::assertSame( | ||
711 | ['tag1', 'tag2, and other', 'tag3'], | ||
712 | tags_filter(['@@@@ tag1@@@', ' @tag2, and other @', 'tag3@@@@'], $separator) | ||
713 | ); | ||
714 | static::assertSame(['tag1', 'tag2', 'tag3'], tags_filter(['@@@tag1@@@', '@', 'tag2', '@@@', 'tag3@@@'], $separator)); | ||
715 | static::assertSame(['tag1'], tags_filter(['@@@@tag1@@@@'], $separator)); | ||
716 | static::assertSame([], tags_filter(['@@@'], $separator)); | ||
717 | static::assertSame([], tags_filter([], $separator)); | ||
718 | static::assertSame([], tags_filter(null, $separator)); | ||
719 | } | ||
720 | |||
721 | /** | ||
496 | * Util function to build an hashtag link. | 722 | * Util function to build an hashtag link. |
497 | * | 723 | * |
498 | * @param string $hashtag Hashtag name. | 724 | * @param string $hashtag Hashtag name. |