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