]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - tests/bookmark/BookmarkFileServiceTest.php
Merge pull request #1698 from ArthurHoaro/feature/plugins-search-filter
[github/shaarli/Shaarli.git] / tests / bookmark / BookmarkFileServiceTest.php
CommitLineData
e26e2060
A
1<?php
2/**
3 * Link datastore tests
4 */
5
6namespace Shaarli\Bookmark;
7
8use DateTime;
fd1ddad9 9use malkusch\lock\mutex\NoMutex;
e26e2060
A
10use ReferenceLinkDB;
11use ReflectionClass;
12use Shaarli;
13use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
14use Shaarli\Config\ConfigManager;
a39acb25 15use Shaarli\Formatter\BookmarkMarkdownFormatter;
e26e2060 16use Shaarli\History;
bcba6bd3 17use Shaarli\Plugin\PluginManager;
a5a9cf23 18use Shaarli\TestCase;
e26e2060
A
19
20/**
21 * Unitary tests for LegacyLinkDBTest
22 */
23class BookmarkFileServiceTest extends TestCase
24{
25 // datastore to test write operations
26 protected static $testDatastore = 'sandbox/datastore.php';
27
28 protected static $testConf = 'sandbox/config';
29
30 protected static $testUpdates = 'sandbox/updates.txt';
31
32 /**
33 * @var ConfigManager instance.
34 */
35 protected $conf;
36
37 /**
38 * @var History instance.
39 */
40 protected $history;
41
42 /**
43 * @var ReferenceLinkDB instance.
44 */
45 protected $refDB = null;
46
47 /**
48 * @var BookmarkFileService public LinkDB instance.
49 */
50 protected $publicLinkDB = null;
51
52 /**
53 * @var BookmarkFileService private LinkDB instance.
54 */
55 protected $privateLinkDB = null;
56
fd1ddad9
A
57 /** @var NoMutex */
58 protected $mutex;
59
bcba6bd3
A
60 /** @var PluginManager */
61 protected $pluginManager;
62
e26e2060
A
63 /**
64 * Instantiates public and private LinkDBs with test data
65 *
66 * The reference datastore contains public and private bookmarks that
67 * will be used to test LinkDB's methods:
68 * - access filtering (public/private),
69 * - link searches:
70 * - by day,
71 * - by tag,
72 * - by text,
73 * - etc.
74 *
75 * Resets test data for each test
76 */
8f60e120 77 protected function setUp(): void
e26e2060 78 {
fd1ddad9
A
79 $this->mutex = new NoMutex();
80
e26e2060
A
81 if (file_exists(self::$testDatastore)) {
82 unlink(self::$testDatastore);
83 }
84
85 if (file_exists(self::$testConf .'.json.php')) {
86 unlink(self::$testConf .'.json.php');
87 }
88
89 if (file_exists(self::$testUpdates)) {
90 unlink(self::$testUpdates);
91 }
92
93 copy('tests/utils/config/configJson.json.php', self::$testConf .'.json.php');
94 $this->conf = new ConfigManager(self::$testConf);
95 $this->conf->set('resource.datastore', self::$testDatastore);
96 $this->conf->set('resource.updates', self::$testUpdates);
97 $this->refDB = new \ReferenceLinkDB();
98 $this->refDB->write(self::$testDatastore);
99 $this->history = new History('sandbox/history.php');
bcba6bd3
A
100 $this->pluginManager = new PluginManager($this->conf);
101 $this->publicLinkDB = new BookmarkFileService(
102 $this->conf,
103 $this->pluginManager,
104 $this->history,
105 $this->mutex,
106 false
107 );
108 $this->privateLinkDB = new BookmarkFileService(
109 $this->conf,
110 $this->pluginManager,
111 $this->history,
112 $this->mutex,
113 true
114 );
e26e2060
A
115 }
116
117 /**
118 * Test migrate() method with a legacy datastore.
119 */
120 public function testDatabaseMigration()
121 {
122 if (!defined('SHAARLI_VERSION')) {
123 define('SHAARLI_VERSION', 'dev');
124 }
125
126 $this->refDB = new \ReferenceLinkDB(true);
127 $this->refDB->write(self::$testDatastore);
128 $db = self::getMethod('migrate');
129 $db->invokeArgs($this->privateLinkDB, []);
130
bcba6bd3
A
131 $db = new \FakeBookmarkService(
132 $this->conf,
133 $this->pluginManager,
134 $this->history,
135 $this->mutex,
136 true
137 );
e26e2060
A
138 $this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks());
139 $this->assertEquals($this->refDB->countLinks(), $db->count());
140 }
141
142 /**
143 * Test get() method for a defined and saved bookmark
144 */
145 public function testGetDefinedSaved()
146 {
147 $bookmark = $this->privateLinkDB->get(42);
148 $this->assertEquals(42, $bookmark->getId());
149 $this->assertEquals('Note: I have a big ID but an old date', $bookmark->getTitle());
150 }
151
152 /**
153 * Test get() method for a defined and not saved bookmark
154 */
155 public function testGetDefinedNotSaved()
156 {
157 $bookmark = new Bookmark();
158 $this->privateLinkDB->add($bookmark);
159 $createdBookmark = $this->privateLinkDB->get(43);
160 $this->assertEquals(43, $createdBookmark->getId());
161 $this->assertEmpty($createdBookmark->getDescription());
162 }
163
164 /**
165 * Test get() method for an undefined bookmark
e26e2060
A
166 */
167 public function testGetUndefined()
168 {
b1baca99
A
169 $this->expectException(\Shaarli\Bookmark\Exception\BookmarkNotFoundException::class);
170
e26e2060
A
171 $this->privateLinkDB->get(666);
172 }
173
174 /**
175 * Test add() method for a bookmark fully built
176 */
177 public function testAddFull()
178 {
179 $bookmark = new Bookmark();
180 $bookmark->setUrl($url = 'https://domain.tld/index.php');
181 $bookmark->setShortUrl('abc');
182 $bookmark->setTitle($title = 'This a brand new bookmark');
183 $bookmark->setDescription($desc = 'It should be created and written');
184 $bookmark->setTags($tags = ['tag1', 'tagssss']);
185 $bookmark->setThumbnail($thumb = 'http://thumb.tld/dle.png');
186 $bookmark->setPrivate(true);
187 $bookmark->setSticky(true);
188 $bookmark->setCreated($created = DateTime::createFromFormat('Ymd_His', '20190518_140354'));
189 $bookmark->setUpdated($updated = DateTime::createFromFormat('Ymd_His', '20190518_150354'));
190
191 $this->privateLinkDB->add($bookmark);
192 $bookmark = $this->privateLinkDB->get(43);
193 $this->assertEquals(43, $bookmark->getId());
194 $this->assertEquals($url, $bookmark->getUrl());
195 $this->assertEquals('abc', $bookmark->getShortUrl());
196 $this->assertEquals($title, $bookmark->getTitle());
197 $this->assertEquals($desc, $bookmark->getDescription());
198 $this->assertEquals($tags, $bookmark->getTags());
199 $this->assertEquals($thumb, $bookmark->getThumbnail());
200 $this->assertTrue($bookmark->isPrivate());
201 $this->assertTrue($bookmark->isSticky());
202 $this->assertEquals($created, $bookmark->getCreated());
203 $this->assertEquals($updated, $bookmark->getUpdated());
204
205 // reload from file
bcba6bd3
A
206 $this->privateLinkDB = new \FakeBookmarkService(
207 $this->conf,
208 $this->pluginManager,
209 $this->history,
210 $this->mutex,
211 true
212 );
e26e2060
A
213
214 $bookmark = $this->privateLinkDB->get(43);
215 $this->assertEquals(43, $bookmark->getId());
216 $this->assertEquals($url, $bookmark->getUrl());
217 $this->assertEquals('abc', $bookmark->getShortUrl());
218 $this->assertEquals($title, $bookmark->getTitle());
219 $this->assertEquals($desc, $bookmark->getDescription());
220 $this->assertEquals($tags, $bookmark->getTags());
221 $this->assertEquals($thumb, $bookmark->getThumbnail());
222 $this->assertTrue($bookmark->isPrivate());
223 $this->assertTrue($bookmark->isSticky());
224 $this->assertEquals($created, $bookmark->getCreated());
225 $this->assertEquals($updated, $bookmark->getUpdated());
226 }
227
228 /**
229 * Test add() method for a bookmark without any field set
230 */
231 public function testAddMinimal()
232 {
233 $bookmark = new Bookmark();
234 $this->privateLinkDB->add($bookmark);
235
236 $bookmark = $this->privateLinkDB->get(43);
237 $this->assertEquals(43, $bookmark->getId());
301c7ab1 238 $this->assertRegExp('#/shaare/[\w\-]{6}#', $bookmark->getUrl());
e26e2060
A
239 $this->assertRegExp('/[\w\-]{6}/', $bookmark->getShortUrl());
240 $this->assertEquals($bookmark->getUrl(), $bookmark->getTitle());
241 $this->assertEmpty($bookmark->getDescription());
242 $this->assertEmpty($bookmark->getTags());
243 $this->assertEmpty($bookmark->getThumbnail());
244 $this->assertFalse($bookmark->isPrivate());
245 $this->assertFalse($bookmark->isSticky());
246 $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getCreated());
247 $this->assertNull($bookmark->getUpdated());
248
249 // reload from file
bcba6bd3
A
250 $this->privateLinkDB = new BookmarkFileService(
251 $this->conf,
252 $this->pluginManager,
253 $this->history,
254 $this->mutex,
255 true
256 );
e26e2060
A
257
258 $bookmark = $this->privateLinkDB->get(43);
259 $this->assertEquals(43, $bookmark->getId());
301c7ab1 260 $this->assertRegExp('#/shaare/[\w\-]{6}#', $bookmark->getUrl());
e26e2060
A
261 $this->assertRegExp('/[\w\-]{6}/', $bookmark->getShortUrl());
262 $this->assertEquals($bookmark->getUrl(), $bookmark->getTitle());
263 $this->assertEmpty($bookmark->getDescription());
264 $this->assertEmpty($bookmark->getTags());
265 $this->assertEmpty($bookmark->getThumbnail());
266 $this->assertFalse($bookmark->isPrivate());
267 $this->assertFalse($bookmark->isSticky());
268 $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getCreated());
269 $this->assertNull($bookmark->getUpdated());
270 }
271
272 /**
273 * Test add() method for a bookmark without any field set and without writing the data store
e26e2060
A
274 */
275 public function testAddMinimalNoWrite()
276 {
b1baca99
A
277 $this->expectException(\Shaarli\Bookmark\Exception\BookmarkNotFoundException::class);
278
e26e2060 279 $bookmark = new Bookmark();
b1baca99 280 $this->privateLinkDB->add($bookmark, false);
e26e2060
A
281
282 $bookmark = $this->privateLinkDB->get(43);
283 $this->assertEquals(43, $bookmark->getId());
284
285 // reload from file
bcba6bd3
A
286 $this->privateLinkDB = new BookmarkFileService(
287 $this->conf,
288 $this->pluginManager,
289 $this->history,
290 $this->mutex,
291 true
292 );
e26e2060
A
293
294 $this->privateLinkDB->get(43);
295 }
296
297 /**
298 * Test add() method while logged out
e26e2060
A
299 */
300 public function testAddLoggedOut()
301 {
b1baca99
A
302 $this->expectException(\Exception::class);
303 $this->expectExceptionMessage('You\'re not authorized to alter the datastore');
304
e26e2060
A
305 $this->publicLinkDB->add(new Bookmark());
306 }
307
e26e2060
A
308 /**
309 * Test add() method with a Bookmark already containing an ID
e26e2060
A
310 */
311 public function testAddWithId()
312 {
b1baca99
A
313 $this->expectException(\Exception::class);
314 $this->expectExceptionMessage('This bookmarks already exists');
315
e26e2060
A
316 $bookmark = new Bookmark();
317 $bookmark->setId(43);
318 $this->privateLinkDB->add($bookmark);
319 }
320
321 /**
322 * Test set() method for a bookmark fully built
323 */
324 public function testSetFull()
325 {
326 $bookmark = $this->privateLinkDB->get(42);
327 $bookmark->setUrl($url = 'https://domain.tld/index.php');
328 $bookmark->setShortUrl('abc');
329 $bookmark->setTitle($title = 'This a brand new bookmark');
330 $bookmark->setDescription($desc = 'It should be created and written');
331 $bookmark->setTags($tags = ['tag1', 'tagssss']);
332 $bookmark->setThumbnail($thumb = 'http://thumb.tld/dle.png');
333 $bookmark->setPrivate(true);
334 $bookmark->setSticky(true);
335 $bookmark->setCreated($created = DateTime::createFromFormat('Ymd_His', '20190518_140354'));
336 $bookmark->setUpdated($updated = DateTime::createFromFormat('Ymd_His', '20190518_150354'));
337
338 $this->privateLinkDB->set($bookmark);
339 $bookmark = $this->privateLinkDB->get(42);
340 $this->assertEquals(42, $bookmark->getId());
341 $this->assertEquals($url, $bookmark->getUrl());
342 $this->assertEquals('abc', $bookmark->getShortUrl());
343 $this->assertEquals($title, $bookmark->getTitle());
344 $this->assertEquals($desc, $bookmark->getDescription());
345 $this->assertEquals($tags, $bookmark->getTags());
346 $this->assertEquals($thumb, $bookmark->getThumbnail());
347 $this->assertTrue($bookmark->isPrivate());
348 $this->assertTrue($bookmark->isSticky());
349 $this->assertEquals($created, $bookmark->getCreated());
350 $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated());
351
352 // reload from file
bcba6bd3
A
353 $this->privateLinkDB = new BookmarkFileService(
354 $this->conf,
355 $this->pluginManager,
356 $this->history,
357 $this->mutex,
358 true
359 );
e26e2060
A
360
361 $bookmark = $this->privateLinkDB->get(42);
362 $this->assertEquals(42, $bookmark->getId());
363 $this->assertEquals($url, $bookmark->getUrl());
364 $this->assertEquals('abc', $bookmark->getShortUrl());
365 $this->assertEquals($title, $bookmark->getTitle());
366 $this->assertEquals($desc, $bookmark->getDescription());
367 $this->assertEquals($tags, $bookmark->getTags());
368 $this->assertEquals($thumb, $bookmark->getThumbnail());
369 $this->assertTrue($bookmark->isPrivate());
370 $this->assertTrue($bookmark->isSticky());
371 $this->assertEquals($created, $bookmark->getCreated());
372 $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated());
373 }
374
375 /**
376 * Test set() method for a bookmark without any field set
377 */
378 public function testSetMinimal()
379 {
380 $bookmark = $this->privateLinkDB->get(42);
381 $this->privateLinkDB->set($bookmark);
382
383 $bookmark = $this->privateLinkDB->get(42);
384 $this->assertEquals(42, $bookmark->getId());
f7f08cee 385 $this->assertEquals('/shaare/WDWyig', $bookmark->getUrl());
e26e2060
A
386 $this->assertEquals('1eYJ1Q', $bookmark->getShortUrl());
387 $this->assertEquals('Note: I have a big ID but an old date', $bookmark->getTitle());
388 $this->assertEquals('Used to test bookmarks reordering.', $bookmark->getDescription());
389 $this->assertEquals(['ut'], $bookmark->getTags());
390 $this->assertFalse($bookmark->getThumbnail());
391 $this->assertFalse($bookmark->isPrivate());
392 $this->assertFalse($bookmark->isSticky());
393 $this->assertEquals(
394 DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, '20100310_101010'),
395 $bookmark->getCreated()
396 );
397 $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated());
398
399 // reload from file
bcba6bd3
A
400 $this->privateLinkDB = new BookmarkFileService(
401 $this->conf,
402 $this->pluginManager,
403 $this->history,
404 $this->mutex,
405 true
406 );
e26e2060
A
407
408 $bookmark = $this->privateLinkDB->get(42);
409 $this->assertEquals(42, $bookmark->getId());
f7f08cee 410 $this->assertEquals('/shaare/WDWyig', $bookmark->getUrl());
e26e2060
A
411 $this->assertEquals('1eYJ1Q', $bookmark->getShortUrl());
412 $this->assertEquals('Note: I have a big ID but an old date', $bookmark->getTitle());
413 $this->assertEquals('Used to test bookmarks reordering.', $bookmark->getDescription());
414 $this->assertEquals(['ut'], $bookmark->getTags());
415 $this->assertFalse($bookmark->getThumbnail());
416 $this->assertFalse($bookmark->isPrivate());
417 $this->assertFalse($bookmark->isSticky());
418 $this->assertEquals(
419 DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, '20100310_101010'),
420 $bookmark->getCreated()
421 );
422 $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated());
423 }
424
425 /**
426 * Test set() method for a bookmark without any field set and without writing the data store
427 */
428 public function testSetMinimalNoWrite()
429 {
430 $bookmark = $this->privateLinkDB->get(42);
431 $bookmark->setTitle($title = 'hi!');
432 $this->privateLinkDB->set($bookmark, false);
433
434 $bookmark = $this->privateLinkDB->get(42);
435 $this->assertEquals(42, $bookmark->getId());
436 $this->assertEquals($title, $bookmark->getTitle());
437
438 // reload from file
bcba6bd3
A
439 $this->privateLinkDB = new BookmarkFileService(
440 $this->conf,
441 $this->pluginManager,
442 $this->history,
443 $this->mutex,
444 true
445 );
e26e2060
A
446
447 $bookmark = $this->privateLinkDB->get(42);
448 $this->assertEquals(42, $bookmark->getId());
449 $this->assertEquals('Note: I have a big ID but an old date', $bookmark->getTitle());
450 }
451
452 /**
453 * Test set() method while logged out
e26e2060
A
454 */
455 public function testSetLoggedOut()
456 {
b1baca99
A
457 $this->expectException(\Exception::class);
458 $this->expectExceptionMessage('You\'re not authorized to alter the datastore');
459
e26e2060
A
460 $this->publicLinkDB->set(new Bookmark());
461 }
462
e26e2060
A
463 /**
464 * Test set() method with a Bookmark without an ID defined.
e26e2060
A
465 */
466 public function testSetWithoutId()
467 {
b1baca99
A
468 $this->expectException(\Shaarli\Bookmark\Exception\BookmarkNotFoundException::class);
469
e26e2060
A
470 $bookmark = new Bookmark();
471 $this->privateLinkDB->set($bookmark);
472 }
473
474 /**
475 * Test set() method with a Bookmark with an unknow ID
e26e2060
A
476 */
477 public function testSetWithUnknownId()
478 {
b1baca99
A
479 $this->expectException(\Shaarli\Bookmark\Exception\BookmarkNotFoundException::class);
480
e26e2060
A
481 $bookmark = new Bookmark();
482 $bookmark->setId(666);
483 $this->privateLinkDB->set($bookmark);
484 }
485
486 /**
487 * Test addOrSet() method with a new ID
488 */
489 public function testAddOrSetNew()
490 {
491 $bookmark = new Bookmark();
492 $this->privateLinkDB->addOrSet($bookmark);
493
494 $bookmark = $this->privateLinkDB->get(43);
495 $this->assertEquals(43, $bookmark->getId());
496
497 // reload from file
bcba6bd3
A
498 $this->privateLinkDB = new BookmarkFileService(
499 $this->conf,
500 $this->pluginManager,
501 $this->history,
502 $this->mutex,
503 true
504 );
e26e2060
A
505
506 $bookmark = $this->privateLinkDB->get(43);
507 $this->assertEquals(43, $bookmark->getId());
508 }
509
510 /**
511 * Test addOrSet() method with an existing ID
512 */
513 public function testAddOrSetExisting()
514 {
515 $bookmark = $this->privateLinkDB->get(42);
516 $bookmark->setTitle($title = 'hi!');
517 $this->privateLinkDB->addOrSet($bookmark);
518
519 $bookmark = $this->privateLinkDB->get(42);
520 $this->assertEquals(42, $bookmark->getId());
521 $this->assertEquals($title, $bookmark->getTitle());
522
523 // reload from file
bcba6bd3
A
524 $this->privateLinkDB = new BookmarkFileService(
525 $this->conf,
526 $this->pluginManager,
527 $this->history,
528 $this->mutex,
529 true
530 );
e26e2060
A
531
532 $bookmark = $this->privateLinkDB->get(42);
533 $this->assertEquals(42, $bookmark->getId());
534 $this->assertEquals($title, $bookmark->getTitle());
535 }
536
537 /**
538 * Test addOrSet() method while logged out
e26e2060
A
539 */
540 public function testAddOrSetLoggedOut()
541 {
b1baca99
A
542 $this->expectException(\Exception::class);
543 $this->expectExceptionMessage('You\'re not authorized to alter the datastore');
544
e26e2060
A
545 $this->publicLinkDB->addOrSet(new Bookmark());
546 }
547
e26e2060
A
548 /**
549 * Test addOrSet() method for a bookmark without any field set and without writing the data store
550 */
551 public function testAddOrSetMinimalNoWrite()
552 {
553 $bookmark = $this->privateLinkDB->get(42);
554 $bookmark->setTitle($title = 'hi!');
555 $this->privateLinkDB->addOrSet($bookmark, false);
556
557 $bookmark = $this->privateLinkDB->get(42);
558 $this->assertEquals(42, $bookmark->getId());
559 $this->assertEquals($title, $bookmark->getTitle());
560
561 // reload from file
bcba6bd3
A
562 $this->privateLinkDB = new BookmarkFileService(
563 $this->conf,
564 $this->pluginManager,
565 $this->history,
566 $this->mutex,
567 true
568 );
e26e2060
A
569
570 $bookmark = $this->privateLinkDB->get(42);
571 $this->assertEquals(42, $bookmark->getId());
572 $this->assertEquals('Note: I have a big ID but an old date', $bookmark->getTitle());
573 }
574
575 /**
576 * Test remove() method with an existing Bookmark
e26e2060
A
577 */
578 public function testRemoveExisting()
579 {
b1baca99
A
580 $this->expectException(\Shaarli\Bookmark\Exception\BookmarkNotFoundException::class);
581
e26e2060
A
582 $bookmark = $this->privateLinkDB->get(42);
583 $this->privateLinkDB->remove($bookmark);
584
585 $exception = null;
586 try {
587 $this->privateLinkDB->get(42);
588 } catch (BookmarkNotFoundException $e) {
589 $exception = $e;
590 }
591 $this->assertInstanceOf(BookmarkNotFoundException::class, $exception);
592
593 // reload from file
bcba6bd3
A
594 $this->privateLinkDB = new BookmarkFileService(
595 $this->conf,
596 $this->pluginManager,
597 $this->history,
598 $this->mutex,
599 true
600 );
e26e2060
A
601
602 $this->privateLinkDB->get(42);
603 }
604
605 /**
606 * Test remove() method while logged out
e26e2060
A
607 */
608 public function testRemoveLoggedOut()
609 {
b1baca99
A
610 $this->expectException(\Exception::class);
611 $this->expectExceptionMessage('You\'re not authorized to alter the datastore');
612
e26e2060
A
613 $bookmark = $this->privateLinkDB->get(42);
614 $this->publicLinkDB->remove($bookmark);
615 }
616
e26e2060
A
617 /**
618 * Test remove() method with a Bookmark with an unknown ID
e26e2060
A
619 */
620 public function testRemoveWithUnknownId()
621 {
b1baca99
A
622 $this->expectException(\Shaarli\Bookmark\Exception\BookmarkNotFoundException::class);
623
e26e2060
A
624 $bookmark = new Bookmark();
625 $bookmark->setId(666);
626 $this->privateLinkDB->remove($bookmark);
627 }
628
629 /**
630 * Test exists() method
631 */
632 public function testExists()
633 {
634 $this->assertTrue($this->privateLinkDB->exists(42)); // public
635 $this->assertTrue($this->privateLinkDB->exists(6)); // private
636
637 $this->assertTrue($this->privateLinkDB->exists(42, BookmarkFilter::$ALL));
638 $this->assertTrue($this->privateLinkDB->exists(6, BookmarkFilter::$ALL));
639
640 $this->assertTrue($this->privateLinkDB->exists(42, BookmarkFilter::$PUBLIC));
641 $this->assertFalse($this->privateLinkDB->exists(6, BookmarkFilter::$PUBLIC));
642
643 $this->assertFalse($this->privateLinkDB->exists(42, BookmarkFilter::$PRIVATE));
644 $this->assertTrue($this->privateLinkDB->exists(6, BookmarkFilter::$PRIVATE));
645
646 $this->assertTrue($this->publicLinkDB->exists(42));
647 $this->assertFalse($this->publicLinkDB->exists(6));
648
649 $this->assertTrue($this->publicLinkDB->exists(42, BookmarkFilter::$PUBLIC));
650 $this->assertFalse($this->publicLinkDB->exists(6, BookmarkFilter::$PUBLIC));
651
652 $this->assertFalse($this->publicLinkDB->exists(42, BookmarkFilter::$PRIVATE));
653 $this->assertTrue($this->publicLinkDB->exists(6, BookmarkFilter::$PRIVATE));
654 }
655
656 /**
657 * Test initialize() method
658 */
659 public function testInitialize()
660 {
661 $dbSize = $this->privateLinkDB->count();
662 $this->privateLinkDB->initialize();
da7acb98
A
663 $this->assertEquals($dbSize + 3, $this->privateLinkDB->count());
664 $this->assertStringStartsWith(
665 'Shaarli will automatically pick up the thumbnail for links to a variety of websites.',
666 $this->privateLinkDB->get(43)->getDescription()
e26e2060 667 );
da7acb98
A
668 $this->assertStringStartsWith(
669 'Adding a shaare without entering a URL creates a text-only "note" post such as this one.',
670 $this->privateLinkDB->get(44)->getDescription()
671 );
672 $this->assertStringStartsWith(
673 'Welcome to Shaarli!',
674 $this->privateLinkDB->get(45)->getDescription()
e26e2060
A
675 );
676 }
677
678 /*
679 * The following tests have been taken from the legacy LinkDB test and adapted
680 * to make sure that nothing have been broken in the migration process.
681 * They mostly cover search/filters. Some of them might be redundant with the previous ones.
682 */
e26e2060
A
683 /**
684 * Attempt to instantiate a LinkDB whereas the datastore is not writable
e26e2060
A
685 */
686 public function testConstructDatastoreNotWriteable()
687 {
f447edb7 688 $this->expectException(\Shaarli\Bookmark\Exception\NotWritableDataStoreException::class);
b1baca99
A
689 $this->expectExceptionMessageRegExp('#Couldn\'t load data from the data store file "null".*#');
690
e26e2060
A
691 $conf = new ConfigManager('tests/utils/config/configJson');
692 $conf->set('resource.datastore', 'null/store.db');
bcba6bd3 693 new BookmarkFileService($conf, $this->pluginManager, $this->history, $this->mutex, true);
e26e2060
A
694 }
695
696 /**
697 * The DB doesn't exist, ensure it is created with an empty datastore
698 */
699 public function testCheckDBNewLoggedIn()
700 {
701 unlink(self::$testDatastore);
702 $this->assertFileNotExists(self::$testDatastore);
bcba6bd3 703 new BookmarkFileService($this->conf, $this->pluginManager, $this->history, $this->mutex, true);
e26e2060
A
704 $this->assertFileExists(self::$testDatastore);
705
706 // ensure the correct data has been written
707 $this->assertGreaterThan(0, filesize(self::$testDatastore));
708 }
709
710 /**
711 * The DB doesn't exist, but not logged in, ensure it initialized, but the file is not written
712 */
713 public function testCheckDBNewLoggedOut()
714 {
715 unlink(self::$testDatastore);
716 $this->assertFileNotExists(self::$testDatastore);
bcba6bd3 717 $db = new \FakeBookmarkService($this->conf, $this->pluginManager, $this->history, $this->mutex, false);
e26e2060
A
718 $this->assertFileNotExists(self::$testDatastore);
719 $this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks());
720 $this->assertCount(0, $db->getBookmarks());
721 }
722
723 /**
724 * Load public bookmarks from the DB
725 */
726 public function testReadPublicDB()
727 {
728 $this->assertEquals(
729 $this->refDB->countPublicLinks(),
730 $this->publicLinkDB->count()
731 );
732 }
733
734 /**
735 * Load public and private bookmarks from the DB
736 */
737 public function testReadPrivateDB()
738 {
739 $this->assertEquals(
740 $this->refDB->countLinks(),
741 $this->privateLinkDB->count()
742 );
743 }
744
745 /**
746 * Save the bookmarks to the DB
747 */
748 public function testSave()
749 {
bcba6bd3 750 $testDB = new BookmarkFileService($this->conf, $this->pluginManager, $this->history, $this->mutex, true);
e26e2060
A
751 $dbSize = $testDB->count();
752
753 $bookmark = new Bookmark();
754 $testDB->add($bookmark);
755
bcba6bd3 756 $testDB = new BookmarkFileService($this->conf, $this->pluginManager, $this->history, $this->mutex, true);
e26e2060
A
757 $this->assertEquals($dbSize + 1, $testDB->count());
758 }
759
760 /**
761 * Count existing bookmarks - public bookmarks hidden
762 */
763 public function testCountHiddenPublic()
764 {
765 $this->conf->set('privacy.hide_public_links', true);
bcba6bd3 766 $linkDB = new BookmarkFileService($this->conf, $this->pluginManager, $this->history, $this->mutex, false);
e26e2060
A
767
768 $this->assertEquals(0, $linkDB->count());
769 }
770
e26e2060
A
771 /**
772 * The URL corresponds to an existing entry in the DB
773 */
774 public function testGetKnownLinkFromURL()
775 {
776 $link = $this->publicLinkDB->findByUrl('http://mediagoblin.org/');
777
778 $this->assertNotEquals(false, $link);
a5a9cf23 779 $this->assertContainsPolyfill(
e26e2060
A
780 'A free software media publishing platform',
781 $link->getDescription()
782 );
783 }
784
785 /**
786 * The URL is not in the DB
787 */
788 public function testGetUnknownLinkFromURL()
789 {
790 $this->assertEquals(
791 false,
792 $this->publicLinkDB->findByUrl('http://dev.null')
793 );
794 }
795
796 /**
797 * Lists all tags
798 */
799 public function testAllTags()
800 {
801 $this->assertEquals(
802 [
803 'web' => 3,
804 'cartoon' => 2,
805 'gnu' => 2,
806 'dev' => 1,
807 'samba' => 1,
808 'media' => 1,
809 'software' => 1,
810 'stallman' => 1,
811 'free' => 1,
812 '-exclude' => 1,
813 'hashtag' => 2,
814 // The DB contains a link with `sTuff` and another one with `stuff` tag.
815 // They need to be grouped with the first case found - order by date DESC: `sTuff`.
816 'sTuff' => 2,
817 'ut' => 1,
f1a148ab
A
818 'assurance' => 1,
819 'coding-style' => 1,
820 'quality' => 1,
821 'standards' => 1,
e26e2060
A
822 ],
823 $this->publicLinkDB->bookmarksCountPerTag()
824 );
825
826 $this->assertEquals(
827 [
828 'web' => 4,
829 'cartoon' => 3,
830 'gnu' => 2,
831 'dev' => 2,
832 'samba' => 1,
833 'media' => 1,
834 'software' => 1,
835 'stallman' => 1,
836 'free' => 1,
837 'html' => 1,
838 'w3c' => 1,
839 'css' => 1,
840 'Mercurial' => 1,
841 'sTuff' => 2,
842 '-exclude' => 1,
843 '.hidden' => 1,
844 'hashtag' => 2,
845 'tag1' => 1,
846 'tag2' => 1,
847 'tag3' => 1,
848 'tag4' => 1,
849 'ut' => 1,
f1a148ab
A
850 'assurance' => 1,
851 'coding-style' => 1,
852 'quality' => 1,
853 'standards' => 1,
e26e2060
A
854 ],
855 $this->privateLinkDB->bookmarksCountPerTag()
856 );
857 $this->assertEquals(
858 [
e26e2060
A
859 'cartoon' => 2,
860 'gnu' => 1,
861 'dev' => 1,
862 'samba' => 1,
863 'media' => 1,
864 'html' => 1,
865 'w3c' => 1,
866 'css' => 1,
867 'Mercurial' => 1,
868 '.hidden' => 1,
869 'hashtag' => 1,
870 ],
871 $this->privateLinkDB->bookmarksCountPerTag(['web'])
872 );
873 $this->assertEquals(
874 [
e26e2060
A
875 'html' => 1,
876 'w3c' => 1,
877 'css' => 1,
878 'Mercurial' => 1,
879 ],
880 $this->privateLinkDB->bookmarksCountPerTag(['web'], 'private')
881 );
882 }
883
884 /**
885 * Test filter with string.
886 */
887 public function testFilterString()
888 {
889 $tags = 'dev cartoon';
890 $request = ['searchtags' => $tags];
891 $this->assertEquals(
892 2,
9b8c0a45 893 count($this->privateLinkDB->search($request, null, true)->getBookmarks())
e26e2060
A
894 );
895 }
896
897 /**
898 * Test filter with array.
899 */
900 public function testFilterArray()
901 {
902 $tags = ['dev', 'cartoon'];
903 $request = ['searchtags' => $tags];
904 $this->assertEquals(
905 2,
9b8c0a45 906 count($this->privateLinkDB->search($request, null, true)->getBookmarks())
e26e2060
A
907 );
908 }
909
910 /**
911 * Test hidden tags feature:
912 * tags starting with a dot '.' are only visible when logged in.
913 */
914 public function testHiddenTags()
915 {
916 $tags = '.hidden';
917 $request = ['searchtags' => $tags];
918 $this->assertEquals(
919 1,
9b8c0a45 920 count($this->privateLinkDB->search($request, 'all', true)->getBookmarks())
e26e2060
A
921 );
922
923 $this->assertEquals(
924 0,
9b8c0a45 925 count($this->publicLinkDB->search($request, 'public', true)->getBookmarks())
e26e2060
A
926 );
927 }
928
929 /**
930 * Test filterHash() with a valid smallhash.
931 */
932 public function testFilterHashValid()
933 {
934 $request = smallHash('20150310_114651');
1a8ac737
A
935 $this->assertSame(
936 $request,
937 $this->publicLinkDB->findByHash($request)->getShortUrl()
e26e2060
A
938 );
939 $request = smallHash('20150310_114633' . 8);
1a8ac737
A
940 $this->assertSame(
941 $request,
942 $this->publicLinkDB->findByHash($request)->getShortUrl()
e26e2060
A
943 );
944 }
945
946 /**
947 * Test filterHash() with an invalid smallhash.
e26e2060
A
948 */
949 public function testFilterHashInValid1()
950 {
1a8ac737
A
951 $this->expectException(BookmarkNotFoundException::class);
952
e26e2060
A
953 $request = 'blabla';
954 $this->publicLinkDB->findByHash($request);
955 }
956
957 /**
958 * Test filterHash() with an empty smallhash.
e26e2060
A
959 */
960 public function testFilterHashInValid()
961 {
1a8ac737
A
962 $this->expectException(BookmarkNotFoundException::class);
963
e26e2060
A
964 $this->publicLinkDB->findByHash('');
965 }
966
9c04921a
A
967 /**
968 * Test filterHash() on a private bookmark while logged out.
969 */
970 public function testFilterHashPrivateWhileLoggedOut()
971 {
156061d4
A
972 $this->expectException(BookmarkNotFoundException::class);
973 $this->expectExceptionMessage('The link you are trying to reach does not exist or has been deleted');
9c04921a
A
974
975 $hash = smallHash('20141125_084734' . 6);
976
977 $this->publicLinkDB->findByHash($hash);
978 }
979
980 /**
981 * Test filterHash() with private key.
982 */
983 public function testFilterHashWithPrivateKey()
984 {
985 $hash = smallHash('20141125_084734' . 6);
986 $privateKey = 'this is usually auto generated';
987
988 $bookmark = $this->privateLinkDB->findByHash($hash);
989 $bookmark->addAdditionalContentEntry('private_key', $privateKey);
990 $this->privateLinkDB->save();
991
bcba6bd3
A
992 $this->privateLinkDB = new BookmarkFileService(
993 $this->conf,
994 $this->pluginManager,
995 $this->history,
996 $this->mutex,
997 false
998 );
9c04921a
A
999 $bookmark = $this->privateLinkDB->findByHash($hash, $privateKey);
1000
1001 static::assertSame(6, $bookmark->getId());
1002 }
1003
e26e2060
A
1004 /**
1005 * Test linksCountPerTag all tags without filter.
1006 * Equal occurrences should be sorted alphabetically.
1007 */
1008 public function testCountLinkPerTagAllNoFilter()
1009 {
1010 $expected = [
1011 'web' => 4,
1012 'cartoon' => 3,
1013 'dev' => 2,
1014 'gnu' => 2,
1015 'hashtag' => 2,
1016 'sTuff' => 2,
1017 '-exclude' => 1,
1018 '.hidden' => 1,
1019 'Mercurial' => 1,
1020 'css' => 1,
1021 'free' => 1,
1022 'html' => 1,
1023 'media' => 1,
1024 'samba' => 1,
1025 'software' => 1,
1026 'stallman' => 1,
1027 'tag1' => 1,
1028 'tag2' => 1,
1029 'tag3' => 1,
1030 'tag4' => 1,
1031 'ut' => 1,
1032 'w3c' => 1,
f1a148ab
A
1033 'assurance' => 1,
1034 'coding-style' => 1,
1035 'quality' => 1,
1036 'standards' => 1,
e26e2060
A
1037 ];
1038 $tags = $this->privateLinkDB->bookmarksCountPerTag();
1039
1040 $this->assertEquals($expected, $tags, var_export($tags, true));
1041 }
1042
1043 /**
1044 * Test linksCountPerTag all tags with filter.
1045 * Equal occurrences should be sorted alphabetically.
1046 */
1047 public function testCountLinkPerTagAllWithFilter()
1048 {
1049 $expected = [
e26e2060
A
1050 'hashtag' => 2,
1051 '-exclude' => 1,
1052 '.hidden' => 1,
1053 'free' => 1,
1054 'media' => 1,
1055 'software' => 1,
1056 'stallman' => 1,
1057 'stuff' => 1,
1058 'web' => 1,
1059 ];
1060 $tags = $this->privateLinkDB->bookmarksCountPerTag(['gnu']);
1061
1062 $this->assertEquals($expected, $tags, var_export($tags, true));
1063 }
1064
1065 /**
1066 * Test linksCountPerTag public tags with filter.
1067 * Equal occurrences should be sorted alphabetically.
1068 */
1069 public function testCountLinkPerTagPublicWithFilter()
1070 {
1071 $expected = [
e26e2060
A
1072 'hashtag' => 2,
1073 '-exclude' => 1,
1074 '.hidden' => 1,
1075 'free' => 1,
1076 'media' => 1,
1077 'software' => 1,
1078 'stallman' => 1,
1079 'stuff' => 1,
1080 'web' => 1,
1081 ];
1082 $tags = $this->privateLinkDB->bookmarksCountPerTag(['gnu'], 'public');
1083
1084 $this->assertEquals($expected, $tags, var_export($tags, true));
1085 }
1086
1087 /**
1088 * Test linksCountPerTag public tags with filter.
1089 * Equal occurrences should be sorted alphabetically.
1090 */
1091 public function testCountLinkPerTagPrivateWithFilter()
1092 {
1093 $expected = [
1094 'cartoon' => 1,
e26e2060
A
1095 'tag1' => 1,
1096 'tag2' => 1,
1097 'tag3' => 1,
1098 'tag4' => 1,
1099 ];
1100 $tags = $this->privateLinkDB->bookmarksCountPerTag(['dev'], 'private');
1101
1102 $this->assertEquals($expected, $tags, var_export($tags, true));
1103 }
1104
a39acb25
A
1105 /**
1106 * Test linksCountPerTag public tags with filter.
1107 * Equal occurrences should be sorted alphabetically.
1108 */
1109 public function testCountTagsNoMarkdown()
1110 {
1111 $expected = [
1112 'cartoon' => 3,
1113 'dev' => 2,
1114 'tag1' => 1,
1115 'tag2' => 1,
1116 'tag3' => 1,
1117 'tag4' => 1,
1118 'web' => 4,
1119 'gnu' => 2,
1120 'hashtag' => 2,
1121 'sTuff' => 2,
1122 '-exclude' => 1,
1123 '.hidden' => 1,
1124 'Mercurial' => 1,
1125 'css' => 1,
1126 'free' => 1,
1127 'html' => 1,
1128 'media' => 1,
1129 'newTagToCount' => 1,
1130 'samba' => 1,
1131 'software' => 1,
1132 'stallman' => 1,
1133 'ut' => 1,
1134 'w3c' => 1,
f1a148ab
A
1135 'assurance' => 1,
1136 'coding-style' => 1,
1137 'quality' => 1,
1138 'standards' => 1,
a39acb25
A
1139 ];
1140 $bookmark = new Bookmark();
1141 $bookmark->setTags(['newTagToCount', BookmarkMarkdownFormatter::NO_MD_TAG]);
1142 $this->privateLinkDB->add($bookmark);
1143
1144 $tags = $this->privateLinkDB->bookmarksCountPerTag();
1145
1146 $this->assertEquals($expected, $tags, var_export($tags, true));
1147 }
1148
27ddfec3 1149 /**
36e6d88d 1150 * Test find by dates in the middle of the datastore (sorted by dates) with a single bookmark as a result.
27ddfec3 1151 */
36e6d88d 1152 public function testFilterByDateMidTimePeriodSingleBookmark(): void
27ddfec3 1153 {
36e6d88d
A
1154 $bookmarks = $this->privateLinkDB->findByDate(
1155 DateTime::createFromFormat('Ymd_His', '20121206_150000'),
1156 DateTime::createFromFormat('Ymd_His', '20121206_160000'),
1157 $before,
1158 $after
1159 );
27ddfec3 1160
36e6d88d
A
1161 static::assertCount(1, $bookmarks);
1162
1163 static::assertSame(9, $bookmarks[0]->getId());
1164 static::assertEquals(DateTime::createFromFormat('Ymd_His', '20121206_142300'), $before);
1165 static::assertEquals(DateTime::createFromFormat('Ymd_His', '20121206_172539'), $after);
27ddfec3
A
1166 }
1167
1168 /**
36e6d88d 1169 * Test find by dates in the middle of the datastore (sorted by dates) with a multiple bookmarks as a result.
27ddfec3 1170 */
36e6d88d 1171 public function testFilterByDateMidTimePeriodMultipleBookmarks(): void
27ddfec3 1172 {
36e6d88d
A
1173 $bookmarks = $this->privateLinkDB->findByDate(
1174 DateTime::createFromFormat('Ymd_His', '20121206_150000'),
1175 DateTime::createFromFormat('Ymd_His', '20121206_180000'),
1176 $before,
1177 $after
1178 );
27ddfec3 1179
36e6d88d
A
1180 static::assertCount(2, $bookmarks);
1181
1182 static::assertSame(1, $bookmarks[0]->getId());
1183 static::assertSame(9, $bookmarks[1]->getId());
1184 static::assertEquals(DateTime::createFromFormat('Ymd_His', '20121206_142300'), $before);
1185 static::assertEquals(DateTime::createFromFormat('Ymd_His', '20121206_182539'), $after);
1186 }
1187
1188 /**
1189 * Test find by dates at the end of the datastore (sorted by dates).
1190 */
1191 public function testFilterByDateLastTimePeriod(): void
1192 {
1193 $after = new DateTime();
1194 $bookmarks = $this->privateLinkDB->findByDate(
1195 DateTime::createFromFormat('Ymd_His', '20150310_114640'),
1196 DateTime::createFromFormat('Ymd_His', '20450101_010101'),
1197 $before,
1198 $after
1199 );
1200
1201 static::assertCount(1, $bookmarks);
1202
1203 static::assertSame(41, $bookmarks[0]->getId());
1204 static::assertEquals(DateTime::createFromFormat('Ymd_His', '20150310_114633'), $before);
1205 static::assertNull($after);
1206 }
1207
1208 /**
1209 * Test find by dates at the beginning of the datastore (sorted by dates).
1210 */
1211 public function testFilterByDateFirstTimePeriod(): void
1212 {
1213 $before = new DateTime();
1214 $bookmarks = $this->privateLinkDB->findByDate(
1215 DateTime::createFromFormat('Ymd_His', '20000101_101010'),
1216 DateTime::createFromFormat('Ymd_His', '20100309_110000'),
1217 $before,
1218 $after
1219 );
1220
1221 static::assertCount(1, $bookmarks);
1222
1223 static::assertSame(11, $bookmarks[0]->getId());
1224 static::assertNull($before);
1225 static::assertEquals(DateTime::createFromFormat('Ymd_His', '20100310_101010'), $after);
1226 }
1227
1228 /**
1229 * Test getLatest with a sticky bookmark: it should be ignored and return the latest by creation date instead.
1230 */
1231 public function testGetLatestWithSticky(): void
1232 {
1233 $bookmark = $this->publicLinkDB->getLatest();
1234
1235 static::assertSame(41, $bookmark->getId());
1236 }
1237
1238 /**
1239 * Test getLatest with a sticky bookmark: it should be ignored and return the latest by creation date instead.
1240 */
1241 public function testGetLatestEmptyDatastore(): void
1242 {
1243 unlink($this->conf->get('resource.datastore'));
bcba6bd3
A
1244 $this->publicLinkDB = new BookmarkFileService(
1245 $this->conf,
1246 $this->pluginManager,
1247 $this->history,
1248 $this->mutex,
1249 false
1250 );
36e6d88d
A
1251
1252 $bookmark = $this->publicLinkDB->getLatest();
1253
1254 static::assertNull($bookmark);
27ddfec3
A
1255 }
1256
e26e2060
A
1257 /**
1258 * Allows to test LinkDB's private methods
1259 *
1260 * @see
1261 * https://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html
1262 * http://stackoverflow.com/a/2798203
1263 */
1264 protected static function getMethod($name)
1265 {
1266 $class = new ReflectionClass('Shaarli\Bookmark\BookmarkFileService');
1267 $method = $class->getMethod($name);
1268 $method->setAccessible(true);
1269 return $method;
1270 }
1271}