aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/bookmark
diff options
context:
space:
mode:
Diffstat (limited to 'tests/bookmark')
-rw-r--r--tests/bookmark/BookmarkArrayTest.php236
-rw-r--r--tests/bookmark/BookmarkFileServiceTest.php1111
-rw-r--r--tests/bookmark/BookmarkFilterTest.php (renamed from tests/bookmark/LinkFilterTest.php)161
-rw-r--r--tests/bookmark/BookmarkInitializerTest.php150
-rw-r--r--tests/bookmark/BookmarkTest.php388
-rw-r--r--tests/bookmark/LinkDBTest.php622
-rw-r--r--tests/bookmark/LinkUtilsTest.php48
7 files changed, 2000 insertions, 716 deletions
diff --git a/tests/bookmark/BookmarkArrayTest.php b/tests/bookmark/BookmarkArrayTest.php
new file mode 100644
index 00000000..ebed9bfc
--- /dev/null
+++ b/tests/bookmark/BookmarkArrayTest.php
@@ -0,0 +1,236 @@
1<?php
2
3namespace Shaarli\Bookmark;
4
5use Shaarli\TestCase;
6
7/**
8 * Class BookmarkArrayTest
9 */
10class BookmarkArrayTest extends TestCase
11{
12 /**
13 * Test the constructor and make sure that the instance is properly initialized
14 */
15 public function testArrayConstructorEmpty()
16 {
17 $array = new BookmarkArray();
18 $this->assertTrue(is_iterable($array));
19 $this->assertEmpty($array);
20 }
21
22 /**
23 * Test adding entries to the array, specifying the key offset or not.
24 */
25 public function testArrayAccessAddEntries()
26 {
27 $array = new BookmarkArray();
28 $bookmark = new Bookmark();
29 $bookmark->setId(11)->validate();
30 $array[] = $bookmark;
31 $this->assertCount(1, $array);
32 $this->assertTrue(isset($array[11]));
33 $this->assertNull($array[0]);
34 $this->assertEquals($bookmark, $array[11]);
35
36 $bookmark = new Bookmark();
37 $bookmark->setId(14)->validate();
38 $array[14] = $bookmark;
39 $this->assertCount(2, $array);
40 $this->assertTrue(isset($array[14]));
41 $this->assertNull($array[0]);
42 $this->assertEquals($bookmark, $array[14]);
43 }
44
45 /**
46 * Test adding a bad entry: wrong type
47 */
48 public function testArrayAccessAddBadEntryInstance()
49 {
50 $this->expectException(\Shaarli\Bookmark\Exception\InvalidBookmarkException::class);
51
52 $array = new BookmarkArray();
53 $array[] = 'nope';
54 }
55
56 /**
57 * Test adding a bad entry: no id
58 */
59 public function testArrayAccessAddBadEntryNoId()
60 {
61 $this->expectException(\Shaarli\Bookmark\Exception\InvalidBookmarkException::class);
62
63 $array = new BookmarkArray();
64 $bookmark = new Bookmark();
65 $array[] = $bookmark;
66 }
67
68 /**
69 * Test adding a bad entry: no url
70 */
71 public function testArrayAccessAddBadEntryNoUrl()
72 {
73 $this->expectException(\Shaarli\Bookmark\Exception\InvalidBookmarkException::class);
74
75 $array = new BookmarkArray();
76 $bookmark = (new Bookmark())->setId(11);
77 $array[] = $bookmark;
78 }
79
80 /**
81 * Test adding a bad entry: invalid offset
82 */
83 public function testArrayAccessAddBadEntryOffset()
84 {
85 $this->expectException(\Shaarli\Bookmark\Exception\InvalidBookmarkException::class);
86
87 $array = new BookmarkArray();
88 $bookmark = (new Bookmark())->setId(11);
89 $bookmark->validate();
90 $array['nope'] = $bookmark;
91 }
92
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
108 */
109 public function testArrayAccessAddBadEntryIdOffset()
110 {
111 $this->expectException(\Shaarli\Bookmark\Exception\InvalidBookmarkException::class);
112
113 $array = new BookmarkArray();
114 $bookmark = (new Bookmark())->setId(11);
115 $bookmark->validate();
116 $array[14] = $bookmark;
117 }
118
119 /**
120 * Test update entries through array access.
121 */
122 public function testArrayAccessUpdateEntries()
123 {
124 $array = new BookmarkArray();
125 $bookmark = new Bookmark();
126 $bookmark->setId(11)->validate();
127 $bookmark->setTitle('old');
128 $array[] = $bookmark;
129 $bookmark = new Bookmark();
130 $bookmark->setId(11)->validate();
131 $bookmark->setTitle('test');
132 $array[] = $bookmark;
133 $this->assertCount(1, $array);
134 $this->assertEquals('test', $array[11]->getTitle());
135
136 $bookmark = new Bookmark();
137 $bookmark->setId(11)->validate();
138 $bookmark->setTitle('test2');
139 $array[11] = $bookmark;
140 $this->assertCount(1, $array);
141 $this->assertEquals('test2', $array[11]->getTitle());
142 }
143
144 /**
145 * Test delete entries through array access.
146 */
147 public function testArrayAccessDeleteEntries()
148 {
149 $array = new BookmarkArray();
150 $bookmark11 = new Bookmark();
151 $bookmark11->setId(11)->validate();
152 $array[] = $bookmark11;
153 $bookmark14 = new Bookmark();
154 $bookmark14->setId(14)->validate();
155 $array[] = $bookmark14;
156 $bookmark23 = new Bookmark();
157 $bookmark23->setId(23)->validate();
158 $array[] = $bookmark23;
159 $bookmark0 = new Bookmark();
160 $bookmark0->setId(0)->validate();
161 $array[] = $bookmark0;
162 $this->assertCount(4, $array);
163
164 unset($array[14]);
165 $this->assertCount(3, $array);
166 $this->assertEquals($bookmark11, $array[11]);
167 $this->assertEquals($bookmark23, $array[23]);
168 $this->assertEquals($bookmark0, $array[0]);
169
170 unset($array[23]);
171 $this->assertCount(2, $array);
172 $this->assertEquals($bookmark11, $array[11]);
173 $this->assertEquals($bookmark0, $array[0]);
174
175 unset($array[11]);
176 $this->assertCount(1, $array);
177 $this->assertEquals($bookmark0, $array[0]);
178
179 unset($array[0]);
180 $this->assertCount(0, $array);
181 }
182
183 /**
184 * Test iterating through array access.
185 */
186 public function testArrayAccessIterate()
187 {
188 $array = new BookmarkArray();
189 $bookmark11 = new Bookmark();
190 $bookmark11->setId(11)->validate();
191 $array[] = $bookmark11;
192 $bookmark14 = new Bookmark();
193 $bookmark14->setId(14)->validate();
194 $array[] = $bookmark14;
195 $bookmark23 = new Bookmark();
196 $bookmark23->setId(23)->validate();
197 $array[] = $bookmark23;
198 $this->assertCount(3, $array);
199
200 foreach ($array as $id => $bookmark) {
201 $this->assertEquals(${'bookmark'. $id}, $bookmark);
202 }
203 }
204
205 /**
206 * Test reordering the array.
207 */
208 public function testReorder()
209 {
210 $refDB = new \ReferenceLinkDB();
211 $refDB->write('sandbox/datastore.php');
212
213
214 $bookmarks = $refDB->getLinks();
215 $bookmarks->reorder('ASC');
216 $this->assertInstanceOf(BookmarkArray::class, $bookmarks);
217
218 $stickyIds = [11, 10];
219 $standardIds = [42, 4, 9, 1, 0, 7, 6, 8, 41];
220 $linkIds = array_merge($stickyIds, $standardIds);
221 $cpt = 0;
222 foreach ($bookmarks as $key => $value) {
223 $this->assertEquals($linkIds[$cpt++], $key);
224 }
225
226 $bookmarks = $refDB->getLinks();
227 $bookmarks->reorder('DESC');
228 $this->assertInstanceOf(BookmarkArray::class, $bookmarks);
229
230 $linkIds = array_merge(array_reverse($stickyIds), array_reverse($standardIds));
231 $cpt = 0;
232 foreach ($bookmarks as $key => $value) {
233 $this->assertEquals($linkIds[$cpt++], $key);
234 }
235 }
236}
diff --git a/tests/bookmark/BookmarkFileServiceTest.php b/tests/bookmark/BookmarkFileServiceTest.php
new file mode 100644
index 00000000..c399822b
--- /dev/null
+++ b/tests/bookmark/BookmarkFileServiceTest.php
@@ -0,0 +1,1111 @@
1<?php
2/**
3 * Link datastore tests
4 */
5
6namespace Shaarli\Bookmark;
7
8use DateTime;
9use ReferenceLinkDB;
10use ReflectionClass;
11use Shaarli;
12use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
13use Shaarli\Config\ConfigManager;
14use Shaarli\Formatter\BookmarkMarkdownFormatter;
15use Shaarli\History;
16use Shaarli\TestCase;
17
18/**
19 * Unitary tests for LegacyLinkDBTest
20 */
21class BookmarkFileServiceTest extends TestCase
22{
23 // datastore to test write operations
24 protected static $testDatastore = 'sandbox/datastore.php';
25
26 protected static $testConf = 'sandbox/config';
27
28 protected static $testUpdates = 'sandbox/updates.txt';
29
30 /**
31 * @var ConfigManager instance.
32 */
33 protected $conf;
34
35 /**
36 * @var History instance.
37 */
38 protected $history;
39
40 /**
41 * @var ReferenceLinkDB instance.
42 */
43 protected $refDB = null;
44
45 /**
46 * @var BookmarkFileService public LinkDB instance.
47 */
48 protected $publicLinkDB = null;
49
50 /**
51 * @var BookmarkFileService private LinkDB instance.
52 */
53 protected $privateLinkDB = null;
54
55 /**
56 * Instantiates public and private LinkDBs with test data
57 *
58 * The reference datastore contains public and private bookmarks that
59 * will be used to test LinkDB's methods:
60 * - access filtering (public/private),
61 * - link searches:
62 * - by day,
63 * - by tag,
64 * - by text,
65 * - etc.
66 *
67 * Resets test data for each test
68 */
69 protected function setUp(): void
70 {
71 if (file_exists(self::$testDatastore)) {
72 unlink(self::$testDatastore);
73 }
74
75 if (file_exists(self::$testConf .'.json.php')) {
76 unlink(self::$testConf .'.json.php');
77 }
78
79 if (file_exists(self::$testUpdates)) {
80 unlink(self::$testUpdates);
81 }
82
83 copy('tests/utils/config/configJson.json.php', self::$testConf .'.json.php');
84 $this->conf = new ConfigManager(self::$testConf);
85 $this->conf->set('resource.datastore', self::$testDatastore);
86 $this->conf->set('resource.updates', self::$testUpdates);
87 $this->refDB = new \ReferenceLinkDB();
88 $this->refDB->write(self::$testDatastore);
89 $this->history = new History('sandbox/history.php');
90 $this->publicLinkDB = new BookmarkFileService($this->conf, $this->history, false);
91 $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true);
92 }
93
94 /**
95 * Test migrate() method with a legacy datastore.
96 */
97 public function testDatabaseMigration()
98 {
99 if (!defined('SHAARLI_VERSION')) {
100 define('SHAARLI_VERSION', 'dev');
101 }
102
103 $this->refDB = new \ReferenceLinkDB(true);
104 $this->refDB->write(self::$testDatastore);
105 $db = self::getMethod('migrate');
106 $db->invokeArgs($this->privateLinkDB, []);
107
108 $db = new \FakeBookmarkService($this->conf, $this->history, true);
109 $this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks());
110 $this->assertEquals($this->refDB->countLinks(), $db->count());
111 }
112
113 /**
114 * Test get() method for a defined and saved bookmark
115 */
116 public function testGetDefinedSaved()
117 {
118 $bookmark = $this->privateLinkDB->get(42);
119 $this->assertEquals(42, $bookmark->getId());
120 $this->assertEquals('Note: I have a big ID but an old date', $bookmark->getTitle());
121 }
122
123 /**
124 * Test get() method for a defined and not saved bookmark
125 */
126 public function testGetDefinedNotSaved()
127 {
128 $bookmark = new Bookmark();
129 $this->privateLinkDB->add($bookmark);
130 $createdBookmark = $this->privateLinkDB->get(43);
131 $this->assertEquals(43, $createdBookmark->getId());
132 $this->assertEmpty($createdBookmark->getDescription());
133 }
134
135 /**
136 * Test get() method for an undefined bookmark
137 */
138 public function testGetUndefined()
139 {
140 $this->expectException(\Shaarli\Bookmark\Exception\BookmarkNotFoundException::class);
141
142 $this->privateLinkDB->get(666);
143 }
144
145 /**
146 * Test add() method for a bookmark fully built
147 */
148 public function testAddFull()
149 {
150 $bookmark = new Bookmark();
151 $bookmark->setUrl($url = 'https://domain.tld/index.php');
152 $bookmark->setShortUrl('abc');
153 $bookmark->setTitle($title = 'This a brand new bookmark');
154 $bookmark->setDescription($desc = 'It should be created and written');
155 $bookmark->setTags($tags = ['tag1', 'tagssss']);
156 $bookmark->setThumbnail($thumb = 'http://thumb.tld/dle.png');
157 $bookmark->setPrivate(true);
158 $bookmark->setSticky(true);
159 $bookmark->setCreated($created = DateTime::createFromFormat('Ymd_His', '20190518_140354'));
160 $bookmark->setUpdated($updated = DateTime::createFromFormat('Ymd_His', '20190518_150354'));
161
162 $this->privateLinkDB->add($bookmark);
163 $bookmark = $this->privateLinkDB->get(43);
164 $this->assertEquals(43, $bookmark->getId());
165 $this->assertEquals($url, $bookmark->getUrl());
166 $this->assertEquals('abc', $bookmark->getShortUrl());
167 $this->assertEquals($title, $bookmark->getTitle());
168 $this->assertEquals($desc, $bookmark->getDescription());
169 $this->assertEquals($tags, $bookmark->getTags());
170 $this->assertEquals($thumb, $bookmark->getThumbnail());
171 $this->assertTrue($bookmark->isPrivate());
172 $this->assertTrue($bookmark->isSticky());
173 $this->assertEquals($created, $bookmark->getCreated());
174 $this->assertEquals($updated, $bookmark->getUpdated());
175
176 // reload from file
177 $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true);
178
179 $bookmark = $this->privateLinkDB->get(43);
180 $this->assertEquals(43, $bookmark->getId());
181 $this->assertEquals($url, $bookmark->getUrl());
182 $this->assertEquals('abc', $bookmark->getShortUrl());
183 $this->assertEquals($title, $bookmark->getTitle());
184 $this->assertEquals($desc, $bookmark->getDescription());
185 $this->assertEquals($tags, $bookmark->getTags());
186 $this->assertEquals($thumb, $bookmark->getThumbnail());
187 $this->assertTrue($bookmark->isPrivate());
188 $this->assertTrue($bookmark->isSticky());
189 $this->assertEquals($created, $bookmark->getCreated());
190 $this->assertEquals($updated, $bookmark->getUpdated());
191 }
192
193 /**
194 * Test add() method for a bookmark without any field set
195 */
196 public function testAddMinimal()
197 {
198 $bookmark = new Bookmark();
199 $this->privateLinkDB->add($bookmark);
200
201 $bookmark = $this->privateLinkDB->get(43);
202 $this->assertEquals(43, $bookmark->getId());
203 $this->assertRegExp('#/shaare/[\w\-]{6}#', $bookmark->getUrl());
204 $this->assertRegExp('/[\w\-]{6}/', $bookmark->getShortUrl());
205 $this->assertEquals($bookmark->getUrl(), $bookmark->getTitle());
206 $this->assertEmpty($bookmark->getDescription());
207 $this->assertEmpty($bookmark->getTags());
208 $this->assertEmpty($bookmark->getThumbnail());
209 $this->assertFalse($bookmark->isPrivate());
210 $this->assertFalse($bookmark->isSticky());
211 $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getCreated());
212 $this->assertNull($bookmark->getUpdated());
213
214 // reload from file
215 $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true);
216
217 $bookmark = $this->privateLinkDB->get(43);
218 $this->assertEquals(43, $bookmark->getId());
219 $this->assertRegExp('#/shaare/[\w\-]{6}#', $bookmark->getUrl());
220 $this->assertRegExp('/[\w\-]{6}/', $bookmark->getShortUrl());
221 $this->assertEquals($bookmark->getUrl(), $bookmark->getTitle());
222 $this->assertEmpty($bookmark->getDescription());
223 $this->assertEmpty($bookmark->getTags());
224 $this->assertEmpty($bookmark->getThumbnail());
225 $this->assertFalse($bookmark->isPrivate());
226 $this->assertFalse($bookmark->isSticky());
227 $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getCreated());
228 $this->assertNull($bookmark->getUpdated());
229 }
230
231 /**
232 * Test add() method for a bookmark without any field set and without writing the data store
233 */
234 public function testAddMinimalNoWrite()
235 {
236 $this->expectException(\Shaarli\Bookmark\Exception\BookmarkNotFoundException::class);
237
238 $bookmark = new Bookmark();
239 $this->privateLinkDB->add($bookmark, false);
240
241 $bookmark = $this->privateLinkDB->get(43);
242 $this->assertEquals(43, $bookmark->getId());
243
244 // reload from file
245 $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true);
246
247 $this->privateLinkDB->get(43);
248 }
249
250 /**
251 * Test add() method while logged out
252 */
253 public function testAddLoggedOut()
254 {
255 $this->expectException(\Exception::class);
256 $this->expectExceptionMessage('You\'re not authorized to alter the datastore');
257
258 $this->publicLinkDB->add(new Bookmark());
259 }
260
261 /**
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
274 */
275 public function testAddWithId()
276 {
277 $this->expectException(\Exception::class);
278 $this->expectExceptionMessage('This bookmarks already exists');
279
280 $bookmark = new Bookmark();
281 $bookmark->setId(43);
282 $this->privateLinkDB->add($bookmark);
283 }
284
285 /**
286 * Test set() method for a bookmark fully built
287 */
288 public function testSetFull()
289 {
290 $bookmark = $this->privateLinkDB->get(42);
291 $bookmark->setUrl($url = 'https://domain.tld/index.php');
292 $bookmark->setShortUrl('abc');
293 $bookmark->setTitle($title = 'This a brand new bookmark');
294 $bookmark->setDescription($desc = 'It should be created and written');
295 $bookmark->setTags($tags = ['tag1', 'tagssss']);
296 $bookmark->setThumbnail($thumb = 'http://thumb.tld/dle.png');
297 $bookmark->setPrivate(true);
298 $bookmark->setSticky(true);
299 $bookmark->setCreated($created = DateTime::createFromFormat('Ymd_His', '20190518_140354'));
300 $bookmark->setUpdated($updated = DateTime::createFromFormat('Ymd_His', '20190518_150354'));
301
302 $this->privateLinkDB->set($bookmark);
303 $bookmark = $this->privateLinkDB->get(42);
304 $this->assertEquals(42, $bookmark->getId());
305 $this->assertEquals($url, $bookmark->getUrl());
306 $this->assertEquals('abc', $bookmark->getShortUrl());
307 $this->assertEquals($title, $bookmark->getTitle());
308 $this->assertEquals($desc, $bookmark->getDescription());
309 $this->assertEquals($tags, $bookmark->getTags());
310 $this->assertEquals($thumb, $bookmark->getThumbnail());
311 $this->assertTrue($bookmark->isPrivate());
312 $this->assertTrue($bookmark->isSticky());
313 $this->assertEquals($created, $bookmark->getCreated());
314 $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated());
315
316 // reload from file
317 $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true);
318
319 $bookmark = $this->privateLinkDB->get(42);
320 $this->assertEquals(42, $bookmark->getId());
321 $this->assertEquals($url, $bookmark->getUrl());
322 $this->assertEquals('abc', $bookmark->getShortUrl());
323 $this->assertEquals($title, $bookmark->getTitle());
324 $this->assertEquals($desc, $bookmark->getDescription());
325 $this->assertEquals($tags, $bookmark->getTags());
326 $this->assertEquals($thumb, $bookmark->getThumbnail());
327 $this->assertTrue($bookmark->isPrivate());
328 $this->assertTrue($bookmark->isSticky());
329 $this->assertEquals($created, $bookmark->getCreated());
330 $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated());
331 }
332
333 /**
334 * Test set() method for a bookmark without any field set
335 */
336 public function testSetMinimal()
337 {
338 $bookmark = $this->privateLinkDB->get(42);
339 $this->privateLinkDB->set($bookmark);
340
341 $bookmark = $this->privateLinkDB->get(42);
342 $this->assertEquals(42, $bookmark->getId());
343 $this->assertEquals('/shaare/WDWyig', $bookmark->getUrl());
344 $this->assertEquals('1eYJ1Q', $bookmark->getShortUrl());
345 $this->assertEquals('Note: I have a big ID but an old date', $bookmark->getTitle());
346 $this->assertEquals('Used to test bookmarks reordering.', $bookmark->getDescription());
347 $this->assertEquals(['ut'], $bookmark->getTags());
348 $this->assertFalse($bookmark->getThumbnail());
349 $this->assertFalse($bookmark->isPrivate());
350 $this->assertFalse($bookmark->isSticky());
351 $this->assertEquals(
352 DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, '20100310_101010'),
353 $bookmark->getCreated()
354 );
355 $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated());
356
357 // reload from file
358 $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true);
359
360 $bookmark = $this->privateLinkDB->get(42);
361 $this->assertEquals(42, $bookmark->getId());
362 $this->assertEquals('/shaare/WDWyig', $bookmark->getUrl());
363 $this->assertEquals('1eYJ1Q', $bookmark->getShortUrl());
364 $this->assertEquals('Note: I have a big ID but an old date', $bookmark->getTitle());
365 $this->assertEquals('Used to test bookmarks reordering.', $bookmark->getDescription());
366 $this->assertEquals(['ut'], $bookmark->getTags());
367 $this->assertFalse($bookmark->getThumbnail());
368 $this->assertFalse($bookmark->isPrivate());
369 $this->assertFalse($bookmark->isSticky());
370 $this->assertEquals(
371 DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, '20100310_101010'),
372 $bookmark->getCreated()
373 );
374 $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated());
375 }
376
377 /**
378 * Test set() method for a bookmark without any field set and without writing the data store
379 */
380 public function testSetMinimalNoWrite()
381 {
382 $bookmark = $this->privateLinkDB->get(42);
383 $bookmark->setTitle($title = 'hi!');
384 $this->privateLinkDB->set($bookmark, false);
385
386 $bookmark = $this->privateLinkDB->get(42);
387 $this->assertEquals(42, $bookmark->getId());
388 $this->assertEquals($title, $bookmark->getTitle());
389
390 // reload from file
391 $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true);
392
393 $bookmark = $this->privateLinkDB->get(42);
394 $this->assertEquals(42, $bookmark->getId());
395 $this->assertEquals('Note: I have a big ID but an old date', $bookmark->getTitle());
396 }
397
398 /**
399 * Test set() method while logged out
400 */
401 public function testSetLoggedOut()
402 {
403 $this->expectException(\Exception::class);
404 $this->expectExceptionMessage('You\'re not authorized to alter the datastore');
405
406 $this->publicLinkDB->set(new Bookmark());
407 }
408
409 /**
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.
422 */
423 public function testSetWithoutId()
424 {
425 $this->expectException(\Shaarli\Bookmark\Exception\BookmarkNotFoundException::class);
426
427 $bookmark = new Bookmark();
428 $this->privateLinkDB->set($bookmark);
429 }
430
431 /**
432 * Test set() method with a Bookmark with an unknow ID
433 */
434 public function testSetWithUnknownId()
435 {
436 $this->expectException(\Shaarli\Bookmark\Exception\BookmarkNotFoundException::class);
437
438 $bookmark = new Bookmark();
439 $bookmark->setId(666);
440 $this->privateLinkDB->set($bookmark);
441 }
442
443 /**
444 * Test addOrSet() method with a new ID
445 */
446 public function testAddOrSetNew()
447 {
448 $bookmark = new Bookmark();
449 $this->privateLinkDB->addOrSet($bookmark);
450
451 $bookmark = $this->privateLinkDB->get(43);
452 $this->assertEquals(43, $bookmark->getId());
453
454 // reload from file
455 $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true);
456
457 $bookmark = $this->privateLinkDB->get(43);
458 $this->assertEquals(43, $bookmark->getId());
459 }
460
461 /**
462 * Test addOrSet() method with an existing ID
463 */
464 public function testAddOrSetExisting()
465 {
466 $bookmark = $this->privateLinkDB->get(42);
467 $bookmark->setTitle($title = 'hi!');
468 $this->privateLinkDB->addOrSet($bookmark);
469
470 $bookmark = $this->privateLinkDB->get(42);
471 $this->assertEquals(42, $bookmark->getId());
472 $this->assertEquals($title, $bookmark->getTitle());
473
474 // reload from file
475 $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true);
476
477 $bookmark = $this->privateLinkDB->get(42);
478 $this->assertEquals(42, $bookmark->getId());
479 $this->assertEquals($title, $bookmark->getTitle());
480 }
481
482 /**
483 * Test addOrSet() method while logged out
484 */
485 public function testAddOrSetLoggedOut()
486 {
487 $this->expectException(\Exception::class);
488 $this->expectExceptionMessage('You\'re not authorized to alter the datastore');
489
490 $this->publicLinkDB->addOrSet(new Bookmark());
491 }
492
493 /**
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
506 */
507 public function testAddOrSetMinimalNoWrite()
508 {
509 $bookmark = $this->privateLinkDB->get(42);
510 $bookmark->setTitle($title = 'hi!');
511 $this->privateLinkDB->addOrSet($bookmark, false);
512
513 $bookmark = $this->privateLinkDB->get(42);
514 $this->assertEquals(42, $bookmark->getId());
515 $this->assertEquals($title, $bookmark->getTitle());
516
517 // reload from file
518 $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true);
519
520 $bookmark = $this->privateLinkDB->get(42);
521 $this->assertEquals(42, $bookmark->getId());
522 $this->assertEquals('Note: I have a big ID but an old date', $bookmark->getTitle());
523 }
524
525 /**
526 * Test remove() method with an existing Bookmark
527 */
528 public function testRemoveExisting()
529 {
530 $this->expectException(\Shaarli\Bookmark\Exception\BookmarkNotFoundException::class);
531
532 $bookmark = $this->privateLinkDB->get(42);
533 $this->privateLinkDB->remove($bookmark);
534
535 $exception = null;
536 try {
537 $this->privateLinkDB->get(42);
538 } catch (BookmarkNotFoundException $e) {
539 $exception = $e;
540 }
541 $this->assertInstanceOf(BookmarkNotFoundException::class, $exception);
542
543 // reload from file
544 $this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, true);
545
546 $this->privateLinkDB->get(42);
547 }
548
549 /**
550 * Test remove() method while logged out
551 */
552 public function testRemoveLoggedOut()
553 {
554 $this->expectException(\Exception::class);
555 $this->expectExceptionMessage('You\'re not authorized to alter the datastore');
556
557 $bookmark = $this->privateLinkDB->get(42);
558 $this->publicLinkDB->remove($bookmark);
559 }
560
561 /**
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
574 */
575 public function testRemoveWithUnknownId()
576 {
577 $this->expectException(\Shaarli\Bookmark\Exception\BookmarkNotFoundException::class);
578
579 $bookmark = new Bookmark();
580 $bookmark->setId(666);
581 $this->privateLinkDB->remove($bookmark);
582 }
583
584 /**
585 * Test exists() method
586 */
587 public function testExists()
588 {
589 $this->assertTrue($this->privateLinkDB->exists(42)); // public
590 $this->assertTrue($this->privateLinkDB->exists(6)); // private
591
592 $this->assertTrue($this->privateLinkDB->exists(42, BookmarkFilter::$ALL));
593 $this->assertTrue($this->privateLinkDB->exists(6, BookmarkFilter::$ALL));
594
595 $this->assertTrue($this->privateLinkDB->exists(42, BookmarkFilter::$PUBLIC));
596 $this->assertFalse($this->privateLinkDB->exists(6, BookmarkFilter::$PUBLIC));
597
598 $this->assertFalse($this->privateLinkDB->exists(42, BookmarkFilter::$PRIVATE));
599 $this->assertTrue($this->privateLinkDB->exists(6, BookmarkFilter::$PRIVATE));
600
601 $this->assertTrue($this->publicLinkDB->exists(42));
602 $this->assertFalse($this->publicLinkDB->exists(6));
603
604 $this->assertTrue($this->publicLinkDB->exists(42, BookmarkFilter::$PUBLIC));
605 $this->assertFalse($this->publicLinkDB->exists(6, BookmarkFilter::$PUBLIC));
606
607 $this->assertFalse($this->publicLinkDB->exists(42, BookmarkFilter::$PRIVATE));
608 $this->assertTrue($this->publicLinkDB->exists(6, BookmarkFilter::$PRIVATE));
609 }
610
611 /**
612 * Test initialize() method
613 */
614 public function testInitialize()
615 {
616 $dbSize = $this->privateLinkDB->count();
617 $this->privateLinkDB->initialize();
618 $this->assertEquals($dbSize + 3, $this->privateLinkDB->count());
619 $this->assertStringStartsWith(
620 'Shaarli will automatically pick up the thumbnail for links to a variety of websites.',
621 $this->privateLinkDB->get(43)->getDescription()
622 );
623 $this->assertStringStartsWith(
624 'Adding a shaare without entering a URL creates a text-only "note" post such as this one.',
625 $this->privateLinkDB->get(44)->getDescription()
626 );
627 $this->assertStringStartsWith(
628 'Welcome to Shaarli!',
629 $this->privateLinkDB->get(45)->getDescription()
630 );
631 }
632
633 /*
634 * The following tests have been taken from the legacy LinkDB test and adapted
635 * to make sure that nothing have been broken in the migration process.
636 * They mostly cover search/filters. Some of them might be redundant with the previous ones.
637 */
638 /**
639 * Attempt to instantiate a LinkDB whereas the datastore is not writable
640 */
641 public function testConstructDatastoreNotWriteable()
642 {
643 $this->expectException(\Shaarli\Bookmark\Exception\NotWritableDataStoreException::class);
644 $this->expectExceptionMessageRegExp('#Couldn\'t load data from the data store file "null".*#');
645
646 $conf = new ConfigManager('tests/utils/config/configJson');
647 $conf->set('resource.datastore', 'null/store.db');
648 new BookmarkFileService($conf, $this->history, true);
649 }
650
651 /**
652 * The DB doesn't exist, ensure it is created with an empty datastore
653 */
654 public function testCheckDBNewLoggedIn()
655 {
656 unlink(self::$testDatastore);
657 $this->assertFileNotExists(self::$testDatastore);
658 new BookmarkFileService($this->conf, $this->history, true);
659 $this->assertFileExists(self::$testDatastore);
660
661 // ensure the correct data has been written
662 $this->assertGreaterThan(0, filesize(self::$testDatastore));
663 }
664
665 /**
666 * The DB doesn't exist, but not logged in, ensure it initialized, but the file is not written
667 */
668 public function testCheckDBNewLoggedOut()
669 {
670 unlink(self::$testDatastore);
671 $this->assertFileNotExists(self::$testDatastore);
672 $db = new \FakeBookmarkService($this->conf, $this->history, false);
673 $this->assertFileNotExists(self::$testDatastore);
674 $this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks());
675 $this->assertCount(0, $db->getBookmarks());
676 }
677
678 /**
679 * Load public bookmarks from the DB
680 */
681 public function testReadPublicDB()
682 {
683 $this->assertEquals(
684 $this->refDB->countPublicLinks(),
685 $this->publicLinkDB->count()
686 );
687 }
688
689 /**
690 * Load public and private bookmarks from the DB
691 */
692 public function testReadPrivateDB()
693 {
694 $this->assertEquals(
695 $this->refDB->countLinks(),
696 $this->privateLinkDB->count()
697 );
698 }
699
700 /**
701 * Save the bookmarks to the DB
702 */
703 public function testSave()
704 {
705 $testDB = new BookmarkFileService($this->conf, $this->history, true);
706 $dbSize = $testDB->count();
707
708 $bookmark = new Bookmark();
709 $testDB->add($bookmark);
710
711 $testDB = new BookmarkFileService($this->conf, $this->history, true);
712 $this->assertEquals($dbSize + 1, $testDB->count());
713 }
714
715 /**
716 * Count existing bookmarks - public bookmarks hidden
717 */
718 public function testCountHiddenPublic()
719 {
720 $this->conf->set('privacy.hide_public_links', true);
721 $linkDB = new BookmarkFileService($this->conf, $this->history, false);
722
723 $this->assertEquals(0, $linkDB->count());
724 }
725
726 /**
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
744 */
745 public function testGetKnownLinkFromURL()
746 {
747 $link = $this->publicLinkDB->findByUrl('http://mediagoblin.org/');
748
749 $this->assertNotEquals(false, $link);
750 $this->assertContainsPolyfill(
751 'A free software media publishing platform',
752 $link->getDescription()
753 );
754 }
755
756 /**
757 * The URL is not in the DB
758 */
759 public function testGetUnknownLinkFromURL()
760 {
761 $this->assertEquals(
762 false,
763 $this->publicLinkDB->findByUrl('http://dev.null')
764 );
765 }
766
767 /**
768 * Lists all tags
769 */
770 public function testAllTags()
771 {
772 $this->assertEquals(
773 [
774 'web' => 3,
775 'cartoon' => 2,
776 'gnu' => 2,
777 'dev' => 1,
778 'samba' => 1,
779 'media' => 1,
780 'software' => 1,
781 'stallman' => 1,
782 'free' => 1,
783 '-exclude' => 1,
784 'hashtag' => 2,
785 // The DB contains a link with `sTuff` and another one with `stuff` tag.
786 // They need to be grouped with the first case found - order by date DESC: `sTuff`.
787 'sTuff' => 2,
788 'ut' => 1,
789 ],
790 $this->publicLinkDB->bookmarksCountPerTag()
791 );
792
793 $this->assertEquals(
794 [
795 'web' => 4,
796 'cartoon' => 3,
797 'gnu' => 2,
798 'dev' => 2,
799 'samba' => 1,
800 'media' => 1,
801 'software' => 1,
802 'stallman' => 1,
803 'free' => 1,
804 'html' => 1,
805 'w3c' => 1,
806 'css' => 1,
807 'Mercurial' => 1,
808 'sTuff' => 2,
809 '-exclude' => 1,
810 '.hidden' => 1,
811 'hashtag' => 2,
812 'tag1' => 1,
813 'tag2' => 1,
814 'tag3' => 1,
815 'tag4' => 1,
816 'ut' => 1,
817 ],
818 $this->privateLinkDB->bookmarksCountPerTag()
819 );
820 $this->assertEquals(
821 [
822 'cartoon' => 2,
823 'gnu' => 1,
824 'dev' => 1,
825 'samba' => 1,
826 'media' => 1,
827 'html' => 1,
828 'w3c' => 1,
829 'css' => 1,
830 'Mercurial' => 1,
831 '.hidden' => 1,
832 'hashtag' => 1,
833 ],
834 $this->privateLinkDB->bookmarksCountPerTag(['web'])
835 );
836 $this->assertEquals(
837 [
838 'html' => 1,
839 'w3c' => 1,
840 'css' => 1,
841 'Mercurial' => 1,
842 ],
843 $this->privateLinkDB->bookmarksCountPerTag(['web'], 'private')
844 );
845 }
846
847 /**
848 * Test filter with string.
849 */
850 public function testFilterString()
851 {
852 $tags = 'dev cartoon';
853 $request = ['searchtags' => $tags];
854 $this->assertEquals(
855 2,
856 count($this->privateLinkDB->search($request, null, true))
857 );
858 }
859
860 /**
861 * Test filter with array.
862 */
863 public function testFilterArray()
864 {
865 $tags = ['dev', 'cartoon'];
866 $request = ['searchtags' => $tags];
867 $this->assertEquals(
868 2,
869 count($this->privateLinkDB->search($request, null, true))
870 );
871 }
872
873 /**
874 * Test hidden tags feature:
875 * tags starting with a dot '.' are only visible when logged in.
876 */
877 public function testHiddenTags()
878 {
879 $tags = '.hidden';
880 $request = ['searchtags' => $tags];
881 $this->assertEquals(
882 1,
883 count($this->privateLinkDB->search($request, 'all', true))
884 );
885
886 $this->assertEquals(
887 0,
888 count($this->publicLinkDB->search($request, 'public', true))
889 );
890 }
891
892 /**
893 * Test filterHash() with a valid smallhash.
894 */
895 public function testFilterHashValid()
896 {
897 $request = smallHash('20150310_114651');
898 $this->assertSame(
899 $request,
900 $this->publicLinkDB->findByHash($request)->getShortUrl()
901 );
902 $request = smallHash('20150310_114633' . 8);
903 $this->assertSame(
904 $request,
905 $this->publicLinkDB->findByHash($request)->getShortUrl()
906 );
907 }
908
909 /**
910 * Test filterHash() with an invalid smallhash.
911 */
912 public function testFilterHashInValid1()
913 {
914 $this->expectException(BookmarkNotFoundException::class);
915
916 $request = 'blabla';
917 $this->publicLinkDB->findByHash($request);
918 }
919
920 /**
921 * Test filterHash() with an empty smallhash.
922 */
923 public function testFilterHashInValid()
924 {
925 $this->expectException(BookmarkNotFoundException::class);
926
927 $this->publicLinkDB->findByHash('');
928 }
929
930 /**
931 * Test linksCountPerTag all tags without filter.
932 * Equal occurrences should be sorted alphabetically.
933 */
934 public function testCountLinkPerTagAllNoFilter()
935 {
936 $expected = [
937 'web' => 4,
938 'cartoon' => 3,
939 'dev' => 2,
940 'gnu' => 2,
941 'hashtag' => 2,
942 'sTuff' => 2,
943 '-exclude' => 1,
944 '.hidden' => 1,
945 'Mercurial' => 1,
946 'css' => 1,
947 'free' => 1,
948 'html' => 1,
949 'media' => 1,
950 'samba' => 1,
951 'software' => 1,
952 'stallman' => 1,
953 'tag1' => 1,
954 'tag2' => 1,
955 'tag3' => 1,
956 'tag4' => 1,
957 'ut' => 1,
958 'w3c' => 1,
959 ];
960 $tags = $this->privateLinkDB->bookmarksCountPerTag();
961
962 $this->assertEquals($expected, $tags, var_export($tags, true));
963 }
964
965 /**
966 * Test linksCountPerTag all tags with filter.
967 * Equal occurrences should be sorted alphabetically.
968 */
969 public function testCountLinkPerTagAllWithFilter()
970 {
971 $expected = [
972 'hashtag' => 2,
973 '-exclude' => 1,
974 '.hidden' => 1,
975 'free' => 1,
976 'media' => 1,
977 'software' => 1,
978 'stallman' => 1,
979 'stuff' => 1,
980 'web' => 1,
981 ];
982 $tags = $this->privateLinkDB->bookmarksCountPerTag(['gnu']);
983
984 $this->assertEquals($expected, $tags, var_export($tags, true));
985 }
986
987 /**
988 * Test linksCountPerTag public tags with filter.
989 * Equal occurrences should be sorted alphabetically.
990 */
991 public function testCountLinkPerTagPublicWithFilter()
992 {
993 $expected = [
994 'hashtag' => 2,
995 '-exclude' => 1,
996 '.hidden' => 1,
997 'free' => 1,
998 'media' => 1,
999 'software' => 1,
1000 'stallman' => 1,
1001 'stuff' => 1,
1002 'web' => 1,
1003 ];
1004 $tags = $this->privateLinkDB->bookmarksCountPerTag(['gnu'], 'public');
1005
1006 $this->assertEquals($expected, $tags, var_export($tags, true));
1007 }
1008
1009 /**
1010 * Test linksCountPerTag public tags with filter.
1011 * Equal occurrences should be sorted alphabetically.
1012 */
1013 public function testCountLinkPerTagPrivateWithFilter()
1014 {
1015 $expected = [
1016 'cartoon' => 1,
1017 'tag1' => 1,
1018 'tag2' => 1,
1019 'tag3' => 1,
1020 'tag4' => 1,
1021 ];
1022 $tags = $this->privateLinkDB->bookmarksCountPerTag(['dev'], 'private');
1023
1024 $this->assertEquals($expected, $tags, var_export($tags, true));
1025 }
1026
1027 /**
1028 * Test linksCountPerTag public tags with filter.
1029 * Equal occurrences should be sorted alphabetically.
1030 */
1031 public function testCountTagsNoMarkdown()
1032 {
1033 $expected = [
1034 'cartoon' => 3,
1035 'dev' => 2,
1036 'tag1' => 1,
1037 'tag2' => 1,
1038 'tag3' => 1,
1039 'tag4' => 1,
1040 'web' => 4,
1041 'gnu' => 2,
1042 'hashtag' => 2,
1043 'sTuff' => 2,
1044 '-exclude' => 1,
1045 '.hidden' => 1,
1046 'Mercurial' => 1,
1047 'css' => 1,
1048 'free' => 1,
1049 'html' => 1,
1050 'media' => 1,
1051 'newTagToCount' => 1,
1052 'samba' => 1,
1053 'software' => 1,
1054 'stallman' => 1,
1055 'ut' => 1,
1056 'w3c' => 1,
1057 ];
1058 $bookmark = new Bookmark();
1059 $bookmark->setTags(['newTagToCount', BookmarkMarkdownFormatter::NO_MD_TAG]);
1060 $this->privateLinkDB->add($bookmark);
1061
1062 $tags = $this->privateLinkDB->bookmarksCountPerTag();
1063
1064 $this->assertEquals($expected, $tags, var_export($tags, true));
1065 }
1066
1067 /**
1068 * Test filterDay while logged in
1069 */
1070 public function testFilterDayLoggedIn(): void
1071 {
1072 $bookmarks = $this->privateLinkDB->filterDay('20121206');
1073 $expectedIds = [4, 9, 1, 0];
1074
1075 static::assertCount(4, $bookmarks);
1076 foreach ($bookmarks as $bookmark) {
1077 $i = ($i ?? -1) + 1;
1078 static::assertSame($expectedIds[$i], $bookmark->getId());
1079 }
1080 }
1081
1082 /**
1083 * Test filterDay while logged out
1084 */
1085 public function testFilterDayLoggedOut(): void
1086 {
1087 $bookmarks = $this->publicLinkDB->filterDay('20121206');
1088 $expectedIds = [4, 9, 1];
1089
1090 static::assertCount(3, $bookmarks);
1091 foreach ($bookmarks as $bookmark) {
1092 $i = ($i ?? -1) + 1;
1093 static::assertSame($expectedIds[$i], $bookmark->getId());
1094 }
1095 }
1096
1097 /**
1098 * Allows to test LinkDB's private methods
1099 *
1100 * @see
1101 * https://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html
1102 * http://stackoverflow.com/a/2798203
1103 */
1104 protected static function getMethod($name)
1105 {
1106 $class = new ReflectionClass('Shaarli\Bookmark\BookmarkFileService');
1107 $method = $class->getMethod($name);
1108 $method->setAccessible(true);
1109 return $method;
1110 }
1111}
diff --git a/tests/bookmark/LinkFilterTest.php b/tests/bookmark/BookmarkFilterTest.php
index 808f8122..48c7f824 100644
--- a/tests/bookmark/LinkFilterTest.php
+++ b/tests/bookmark/BookmarkFilterTest.php
@@ -4,18 +4,21 @@ namespace Shaarli\Bookmark;
4 4
5use Exception; 5use Exception;
6use ReferenceLinkDB; 6use ReferenceLinkDB;
7use Shaarli\Config\ConfigManager;
8use Shaarli\History;
9use Shaarli\TestCase;
7 10
8/** 11/**
9 * Class LinkFilterTest. 12 * Class BookmarkFilterTest.
10 */ 13 */
11class LinkFilterTest extends \PHPUnit\Framework\TestCase 14class BookmarkFilterTest extends TestCase
12{ 15{
13 /** 16 /**
14 * @var string Test datastore path. 17 * @var string Test datastore path.
15 */ 18 */
16 protected static $testDatastore = 'sandbox/datastore.php'; 19 protected static $testDatastore = 'sandbox/datastore.php';
17 /** 20 /**
18 * @var LinkFilter instance. 21 * @var BookmarkFilter instance.
19 */ 22 */
20 protected static $linkFilter; 23 protected static $linkFilter;
21 24
@@ -25,19 +28,22 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
25 protected static $refDB; 28 protected static $refDB;
26 29
27 /** 30 /**
28 * @var LinkDB instance 31 * @var BookmarkFileService instance
29 */ 32 */
30 protected static $linkDB; 33 protected static $bookmarkService;
31 34
32 /** 35 /**
33 * Instantiate linkFilter with ReferenceLinkDB data. 36 * Instantiate linkFilter with ReferenceLinkDB data.
34 */ 37 */
35 public static function setUpBeforeClass() 38 public static function setUpBeforeClass(): void
36 { 39 {
37 self::$refDB = new ReferenceLinkDB(); 40 $conf = new ConfigManager('tests/utils/config/configJson');
41 $conf->set('resource.datastore', self::$testDatastore);
42 self::$refDB = new \ReferenceLinkDB();
38 self::$refDB->write(self::$testDatastore); 43 self::$refDB->write(self::$testDatastore);
39 self::$linkDB = new LinkDB(self::$testDatastore, true, false); 44 $history = new History('sandbox/history.php');
40 self::$linkFilter = new LinkFilter(self::$linkDB); 45 self::$bookmarkService = new \FakeBookmarkService($conf, $history, true);
46 self::$linkFilter = new BookmarkFilter(self::$bookmarkService->getBookmarks());
41 } 47 }
42 48
43 /** 49 /**
@@ -74,14 +80,14 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
74 80
75 $this->assertEquals( 81 $this->assertEquals(
76 ReferenceLinkDB::$NB_LINKS_TOTAL, 82 ReferenceLinkDB::$NB_LINKS_TOTAL,
77 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, '')) 83 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, ''))
78 ); 84 );
79 85
80 $this->assertEquals( 86 $this->assertEquals(
81 self::$refDB->countUntaggedLinks(), 87 self::$refDB->countUntaggedLinks(),
82 count( 88 count(
83 self::$linkFilter->filter( 89 self::$linkFilter->filter(
84 LinkFilter::$FILTER_TAG, 90 BookmarkFilter::$FILTER_TAG,
85 /*$request=*/ 91 /*$request=*/
86 '', 92 '',
87 /*$casesensitive=*/ 93 /*$casesensitive=*/
@@ -96,89 +102,100 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
96 102
97 $this->assertEquals( 103 $this->assertEquals(
98 ReferenceLinkDB::$NB_LINKS_TOTAL, 104 ReferenceLinkDB::$NB_LINKS_TOTAL,
99 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '')) 105 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, ''))
100 ); 106 );
101 } 107 }
102 108
103 /** 109 /**
104 * Filter links using a tag 110 * Filter bookmarks using a tag
105 */ 111 */
106 public function testFilterOneTag() 112 public function testFilterOneTag()
107 { 113 {
108 $this->assertEquals( 114 $this->assertEquals(
109 4, 115 4,
110 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false)) 116 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'web', false))
111 ); 117 );
112 118
113 $this->assertEquals( 119 $this->assertEquals(
114 4, 120 4,
115 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'all')) 121 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'web', false, 'all'))
116 ); 122 );
117 123
118 $this->assertEquals( 124 $this->assertEquals(
119 4, 125 4,
120 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'default-blabla')) 126 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'web', false, 'default-blabla'))
121 ); 127 );
122 128
123 // Private only. 129 // Private only.
124 $this->assertEquals( 130 $this->assertEquals(
125 1, 131 1,
126 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'private')) 132 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'web', false, 'private'))
127 ); 133 );
128 134
129 // Public only. 135 // Public only.
130 $this->assertEquals( 136 $this->assertEquals(
131 3, 137 3,
132 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'public')) 138 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'web', false, 'public'))
133 ); 139 );
134 } 140 }
135 141
136 /** 142 /**
137 * Filter links using a tag - case-sensitive 143 * Filter bookmarks using a tag - case-sensitive
138 */ 144 */
139 public function testFilterCaseSensitiveTag() 145 public function testFilterCaseSensitiveTag()
140 { 146 {
141 $this->assertEquals( 147 $this->assertEquals(
142 0, 148 0,
143 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'mercurial', true)) 149 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'mercurial', true))
144 ); 150 );
145 151
146 $this->assertEquals( 152 $this->assertEquals(
147 1, 153 1,
148 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'Mercurial', true)) 154 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'Mercurial', true))
149 ); 155 );
150 } 156 }
151 157
152 /** 158 /**
153 * Filter links using a tag combination 159 * Filter bookmarks using a tag combination
154 */ 160 */
155 public function testFilterMultipleTags() 161 public function testFilterMultipleTags()
156 { 162 {
157 $this->assertEquals( 163 $this->assertEquals(
158 2, 164 2,
159 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'dev cartoon', false)) 165 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'dev cartoon', false))
160 ); 166 );
161 } 167 }
162 168
163 /** 169 /**
164 * Filter links using a non-existent tag 170 * Filter bookmarks using a non-existent tag
165 */ 171 */
166 public function testFilterUnknownTag() 172 public function testFilterUnknownTag()
167 { 173 {
168 $this->assertEquals( 174 $this->assertEquals(
169 0, 175 0,
170 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'null', false)) 176 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'null', false))
171 ); 177 );
172 } 178 }
173 179
174 /** 180 /**
175 * Return links for a given day 181 * Return bookmarks for a given day
176 */ 182 */
177 public function testFilterDay() 183 public function testFilterDay()
178 { 184 {
179 $this->assertEquals( 185 $this->assertEquals(
180 4, 186 4,
181 count(self::$linkFilter->filter(LinkFilter::$FILTER_DAY, '20121206')) 187 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_DAY, '20121206'))
188 );
189 }
190
191 /**
192 * Return bookmarks for a given day
193 */
194 public function testFilterDayRestrictedVisibility(): void
195 {
196 $this->assertEquals(
197 3,
198 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_DAY, '20121206', false, BookmarkFilter::$PUBLIC))
182 ); 199 );
183 } 200 }
184 201
@@ -189,28 +206,30 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
189 { 206 {
190 $this->assertEquals( 207 $this->assertEquals(
191 0, 208 0,
192 count(self::$linkFilter->filter(LinkFilter::$FILTER_DAY, '19700101')) 209 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_DAY, '19700101'))
193 ); 210 );
194 } 211 }
195 212
196 /** 213 /**
197 * Use an invalid date format 214 * Use an invalid date format
198 * @expectedException Exception
199 * @expectedExceptionMessageRegExp /Invalid date format/
200 */ 215 */
201 public function testFilterInvalidDayWithChars() 216 public function testFilterInvalidDayWithChars()
202 { 217 {
203 self::$linkFilter->filter(LinkFilter::$FILTER_DAY, 'Rainy day, dream away'); 218 $this->expectException(\Exception::class);
219 $this->expectExceptionMessageRegExp('/Invalid date format/');
220
221 self::$linkFilter->filter(BookmarkFilter::$FILTER_DAY, 'Rainy day, dream away');
204 } 222 }
205 223
206 /** 224 /**
207 * Use an invalid date format 225 * Use an invalid date format
208 * @expectedException Exception
209 * @expectedExceptionMessageRegExp /Invalid date format/
210 */ 226 */
211 public function testFilterInvalidDayDigits() 227 public function testFilterInvalidDayDigits()
212 { 228 {
213 self::$linkFilter->filter(LinkFilter::$FILTER_DAY, '20'); 229 $this->expectException(\Exception::class);
230 $this->expectExceptionMessageRegExp('/Invalid date format/');
231
232 self::$linkFilter->filter(BookmarkFilter::$FILTER_DAY, '20');
214 } 233 }
215 234
216 /** 235 /**
@@ -218,7 +237,7 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
218 */ 237 */
219 public function testFilterSmallHash() 238 public function testFilterSmallHash()
220 { 239 {
221 $links = self::$linkFilter->filter(LinkFilter::$FILTER_HASH, 'IuWvgA'); 240 $links = self::$linkFilter->filter(BookmarkFilter::$FILTER_HASH, 'IuWvgA');
222 241
223 $this->assertEquals( 242 $this->assertEquals(
224 1, 243 1,
@@ -227,18 +246,18 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
227 246
228 $this->assertEquals( 247 $this->assertEquals(
229 'MediaGoblin', 248 'MediaGoblin',
230 $links[7]['title'] 249 $links[7]->getTitle()
231 ); 250 );
232 } 251 }
233 252
234 /** 253 /**
235 * No link for this hash 254 * No link for this hash
236 *
237 * @expectedException \Shaarli\Bookmark\Exception\LinkNotFoundException
238 */ 255 */
239 public function testFilterUnknownSmallHash() 256 public function testFilterUnknownSmallHash()
240 { 257 {
241 self::$linkFilter->filter(LinkFilter::$FILTER_HASH, 'Iblaah'); 258 $this->expectException(\Shaarli\Bookmark\Exception\BookmarkNotFoundException::class);
259
260 self::$linkFilter->filter(BookmarkFilter::$FILTER_HASH, 'Iblaah');
242 } 261 }
243 262
244 /** 263 /**
@@ -248,7 +267,7 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
248 { 267 {
249 $this->assertEquals( 268 $this->assertEquals(
250 0, 269 0,
251 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'azertyuiop')) 270 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'azertyuiop'))
252 ); 271 );
253 } 272 }
254 273
@@ -259,12 +278,12 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
259 { 278 {
260 $this->assertEquals( 279 $this->assertEquals(
261 2, 280 2,
262 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'ars.userfriendly.org')) 281 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'ars.userfriendly.org'))
263 ); 282 );
264 283
265 $this->assertEquals( 284 $this->assertEquals(
266 2, 285 2,
267 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'ars org')) 286 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'ars org'))
268 ); 287 );
269 } 288 }
270 289
@@ -276,21 +295,21 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
276 // use miscellaneous cases 295 // use miscellaneous cases
277 $this->assertEquals( 296 $this->assertEquals(
278 2, 297 2,
279 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'userfriendly -')) 298 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'userfriendly -'))
280 ); 299 );
281 $this->assertEquals( 300 $this->assertEquals(
282 2, 301 2,
283 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'UserFriendly -')) 302 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'UserFriendly -'))
284 ); 303 );
285 $this->assertEquals( 304 $this->assertEquals(
286 2, 305 2,
287 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'uSeRFrIendlY -')) 306 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'uSeRFrIendlY -'))
288 ); 307 );
289 308
290 // use miscellaneous case and offset 309 // use miscellaneous case and offset
291 $this->assertEquals( 310 $this->assertEquals(
292 2, 311 2,
293 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'RFrIendL')) 312 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'RFrIendL'))
294 ); 313 );
295 } 314 }
296 315
@@ -301,17 +320,17 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
301 { 320 {
302 $this->assertEquals( 321 $this->assertEquals(
303 1, 322 1,
304 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'publishing media')) 323 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'publishing media'))
305 ); 324 );
306 325
307 $this->assertEquals( 326 $this->assertEquals(
308 1, 327 1,
309 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'mercurial w3c')) 328 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'mercurial w3c'))
310 ); 329 );
311 330
312 $this->assertEquals( 331 $this->assertEquals(
313 3, 332 3,
314 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '"free software"')) 333 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, '"free software"'))
315 ); 334 );
316 } 335 }
317 336
@@ -322,29 +341,29 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
322 { 341 {
323 $this->assertEquals( 342 $this->assertEquals(
324 6, 343 6,
325 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web')) 344 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'web'))
326 ); 345 );
327 346
328 $this->assertEquals( 347 $this->assertEquals(
329 6, 348 6,
330 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', 'all')) 349 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'web', 'all'))
331 ); 350 );
332 351
333 $this->assertEquals( 352 $this->assertEquals(
334 6, 353 6,
335 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', 'bla')) 354 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'web', 'bla'))
336 ); 355 );
337 356
338 // Private only. 357 // Private only.
339 $this->assertEquals( 358 $this->assertEquals(
340 1, 359 1,
341 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', false, 'private')) 360 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'web', false, 'private'))
342 ); 361 );
343 362
344 // Public only. 363 // Public only.
345 $this->assertEquals( 364 $this->assertEquals(
346 5, 365 5,
347 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', false, 'public')) 366 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'web', false, 'public'))
348 ); 367 );
349 } 368 }
350 369
@@ -355,7 +374,7 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
355 { 374 {
356 $this->assertEquals( 375 $this->assertEquals(
357 3, 376 3,
358 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'free software')) 377 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'free software'))
359 ); 378 );
360 } 379 }
361 380
@@ -366,12 +385,12 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
366 { 385 {
367 $this->assertEquals( 386 $this->assertEquals(
368 1, 387 1,
369 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'free -gnu')) 388 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'free -gnu'))
370 ); 389 );
371 390
372 $this->assertEquals( 391 $this->assertEquals(
373 ReferenceLinkDB::$NB_LINKS_TOTAL - 1, 392 ReferenceLinkDB::$NB_LINKS_TOTAL - 1,
374 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '-revolution')) 393 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, '-revolution'))
375 ); 394 );
376 } 395 }
377 396
@@ -383,7 +402,7 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
383 $this->assertEquals( 402 $this->assertEquals(
384 2, 403 2,
385 count(self::$linkFilter->filter( 404 count(self::$linkFilter->filter(
386 LinkFilter::$FILTER_TEXT, 405 BookmarkFilter::$FILTER_TEXT,
387 '"Free Software " stallman "read this" @website stuff' 406 '"Free Software " stallman "read this" @website stuff'
388 )) 407 ))
389 ); 408 );
@@ -391,7 +410,7 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
391 $this->assertEquals( 410 $this->assertEquals(
392 1, 411 1,
393 count(self::$linkFilter->filter( 412 count(self::$linkFilter->filter(
394 LinkFilter::$FILTER_TEXT, 413 BookmarkFilter::$FILTER_TEXT,
395 '"free software " stallman "read this" -beard @website stuff' 414 '"free software " stallman "read this" -beard @website stuff'
396 )) 415 ))
397 ); 416 );
@@ -405,7 +424,7 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
405 $this->assertEquals( 424 $this->assertEquals(
406 0, 425 0,
407 count(self::$linkFilter->filter( 426 count(self::$linkFilter->filter(
408 LinkFilter::$FILTER_TEXT, 427 BookmarkFilter::$FILTER_TEXT,
409 '"designer naming"' 428 '"designer naming"'
410 )) 429 ))
411 ); 430 );
@@ -413,7 +432,7 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
413 $this->assertEquals( 432 $this->assertEquals(
414 0, 433 0,
415 count(self::$linkFilter->filter( 434 count(self::$linkFilter->filter(
416 LinkFilter::$FILTER_TEXT, 435 BookmarkFilter::$FILTER_TEXT,
417 '"designernaming"' 436 '"designernaming"'
418 )) 437 ))
419 ); 438 );
@@ -426,12 +445,12 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
426 { 445 {
427 $this->assertEquals( 446 $this->assertEquals(
428 1, 447 1,
429 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'gnu -free')) 448 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'gnu -free'))
430 ); 449 );
431 450
432 $this->assertEquals( 451 $this->assertEquals(
433 ReferenceLinkDB::$NB_LINKS_TOTAL - 1, 452 ReferenceLinkDB::$NB_LINKS_TOTAL - 1,
434 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, '-free')) 453 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, '-free'))
435 ); 454 );
436 } 455 }
437 456
@@ -445,42 +464,42 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
445 $this->assertEquals( 464 $this->assertEquals(
446 1, 465 1,
447 count(self::$linkFilter->filter( 466 count(self::$linkFilter->filter(
448 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT, 467 BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT,
449 array($tags, $terms) 468 array($tags, $terms)
450 )) 469 ))
451 ); 470 );
452 $this->assertEquals( 471 $this->assertEquals(
453 2, 472 2,
454 count(self::$linkFilter->filter( 473 count(self::$linkFilter->filter(
455 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT, 474 BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT,
456 array('', $terms) 475 array('', $terms)
457 )) 476 ))
458 ); 477 );
459 $this->assertEquals( 478 $this->assertEquals(
460 1, 479 1,
461 count(self::$linkFilter->filter( 480 count(self::$linkFilter->filter(
462 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT, 481 BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT,
463 array(false, 'PSR-2') 482 array(false, 'PSR-2')
464 )) 483 ))
465 ); 484 );
466 $this->assertEquals( 485 $this->assertEquals(
467 1, 486 1,
468 count(self::$linkFilter->filter( 487 count(self::$linkFilter->filter(
469 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT, 488 BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT,
470 array($tags, '') 489 array($tags, '')
471 )) 490 ))
472 ); 491 );
473 $this->assertEquals( 492 $this->assertEquals(
474 ReferenceLinkDB::$NB_LINKS_TOTAL, 493 ReferenceLinkDB::$NB_LINKS_TOTAL,
475 count(self::$linkFilter->filter( 494 count(self::$linkFilter->filter(
476 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT, 495 BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT,
477 '' 496 ''
478 )) 497 ))
479 ); 498 );
480 } 499 }
481 500
482 /** 501 /**
483 * Filter links by #hashtag. 502 * Filter bookmarks by #hashtag.
484 */ 503 */
485 public function testFilterByHashtag() 504 public function testFilterByHashtag()
486 { 505 {
@@ -488,7 +507,7 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
488 $this->assertEquals( 507 $this->assertEquals(
489 3, 508 3,
490 count(self::$linkFilter->filter( 509 count(self::$linkFilter->filter(
491 LinkFilter::$FILTER_TAG, 510 BookmarkFilter::$FILTER_TAG,
492 $hashtag 511 $hashtag
493 )) 512 ))
494 ); 513 );
@@ -497,7 +516,7 @@ class LinkFilterTest extends \PHPUnit\Framework\TestCase
497 $this->assertEquals( 516 $this->assertEquals(
498 1, 517 1,
499 count(self::$linkFilter->filter( 518 count(self::$linkFilter->filter(
500 LinkFilter::$FILTER_TAG, 519 BookmarkFilter::$FILTER_TAG,
501 $hashtag, 520 $hashtag,
502 false, 521 false,
503 'private' 522 'private'
diff --git a/tests/bookmark/BookmarkInitializerTest.php b/tests/bookmark/BookmarkInitializerTest.php
new file mode 100644
index 00000000..25704004
--- /dev/null
+++ b/tests/bookmark/BookmarkInitializerTest.php
@@ -0,0 +1,150 @@
1<?php
2
3namespace Shaarli\Bookmark;
4
5use Shaarli\Config\ConfigManager;
6use Shaarli\History;
7use Shaarli\TestCase;
8
9/**
10 * Class BookmarkInitializerTest
11 * @package Shaarli\Bookmark
12 */
13class BookmarkInitializerTest extends TestCase
14{
15 /** @var string Path of test data store */
16 protected static $testDatastore = 'sandbox/datastore.php';
17
18 /** @var string Path of test config file */
19 protected static $testConf = 'sandbox/config';
20
21 /**
22 * @var ConfigManager instance.
23 */
24 protected $conf;
25
26 /**
27 * @var History instance.
28 */
29 protected $history;
30
31 /** @var BookmarkServiceInterface instance */
32 protected $bookmarkService;
33
34 /** @var BookmarkInitializer instance */
35 protected $initializer;
36
37 /**
38 * Initialize an empty BookmarkFileService
39 */
40 public function setUp(): void
41 {
42 if (file_exists(self::$testDatastore)) {
43 unlink(self::$testDatastore);
44 }
45
46 copy('tests/utils/config/configJson.json.php', self::$testConf .'.json.php');
47 $this->conf = new ConfigManager(self::$testConf);
48 $this->conf->set('resource.datastore', self::$testDatastore);
49 $this->history = new History('sandbox/history.php');
50 $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true);
51
52 $this->initializer = new BookmarkInitializer($this->bookmarkService);
53 }
54
55 /**
56 * Test initialize() with a data store containing bookmarks.
57 */
58 public function testInitializeNotEmptyDataStore(): void
59 {
60 $refDB = new \ReferenceLinkDB();
61 $refDB->write(self::$testDatastore);
62 $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true);
63 $this->initializer = new BookmarkInitializer($this->bookmarkService);
64
65 $this->initializer->initialize();
66
67 $this->assertEquals($refDB->countLinks() + 3, $this->bookmarkService->count());
68
69 $bookmark = $this->bookmarkService->get(43);
70 $this->assertStringStartsWith(
71 'Shaarli will automatically pick up the thumbnail for links to a variety of websites.',
72 $bookmark->getDescription()
73 );
74 $this->assertTrue($bookmark->isPrivate());
75
76 $bookmark = $this->bookmarkService->get(44);
77 $this->assertStringStartsWith(
78 'Adding a shaare without entering a URL creates a text-only "note" post such as this one.',
79 $bookmark->getDescription()
80 );
81 $this->assertTrue($bookmark->isPrivate());
82
83 $bookmark = $this->bookmarkService->get(45);
84 $this->assertStringStartsWith(
85 'Welcome to Shaarli!',
86 $bookmark->getDescription()
87 );
88 $this->assertFalse($bookmark->isPrivate());
89
90 $this->bookmarkService->save();
91
92 // Reload from file
93 $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true);
94 $this->assertEquals($refDB->countLinks() + 3, $this->bookmarkService->count());
95
96 $bookmark = $this->bookmarkService->get(43);
97 $this->assertStringStartsWith(
98 'Shaarli will automatically pick up the thumbnail for links to a variety of websites.',
99 $bookmark->getDescription()
100 );
101 $this->assertTrue($bookmark->isPrivate());
102
103 $bookmark = $this->bookmarkService->get(44);
104 $this->assertStringStartsWith(
105 'Adding a shaare without entering a URL creates a text-only "note" post such as this one.',
106 $bookmark->getDescription()
107 );
108 $this->assertTrue($bookmark->isPrivate());
109
110 $bookmark = $this->bookmarkService->get(45);
111 $this->assertStringStartsWith(
112 'Welcome to Shaarli!',
113 $bookmark->getDescription()
114 );
115 $this->assertFalse($bookmark->isPrivate());
116 }
117
118 /**
119 * Test initialize() with an a non existent datastore file .
120 */
121 public function testInitializeNonExistentDataStore(): void
122 {
123 $this->conf->set('resource.datastore', static::$testDatastore . '_empty');
124 $this->bookmarkService = new BookmarkFileService($this->conf, $this->history, true);
125
126 $this->initializer->initialize();
127
128 $this->assertEquals(3, $this->bookmarkService->count());
129 $bookmark = $this->bookmarkService->get(0);
130 $this->assertStringStartsWith(
131 'Shaarli will automatically pick up the thumbnail for links to a variety of websites.',
132 $bookmark->getDescription()
133 );
134 $this->assertTrue($bookmark->isPrivate());
135
136 $bookmark = $this->bookmarkService->get(1);
137 $this->assertStringStartsWith(
138 'Adding a shaare without entering a URL creates a text-only "note" post such as this one.',
139 $bookmark->getDescription()
140 );
141 $this->assertTrue($bookmark->isPrivate());
142
143 $bookmark = $this->bookmarkService->get(2);
144 $this->assertStringStartsWith(
145 'Welcome to Shaarli!',
146 $bookmark->getDescription()
147 );
148 $this->assertFalse($bookmark->isPrivate());
149 }
150}
diff --git a/tests/bookmark/BookmarkTest.php b/tests/bookmark/BookmarkTest.php
new file mode 100644
index 00000000..afec2440
--- /dev/null
+++ b/tests/bookmark/BookmarkTest.php
@@ -0,0 +1,388 @@
1<?php
2
3namespace Shaarli\Bookmark;
4
5use Shaarli\Bookmark\Exception\InvalidBookmarkException;
6use Shaarli\TestCase;
7
8/**
9 * Class BookmarkTest
10 */
11class BookmarkTest extends TestCase
12{
13 /**
14 * Test fromArray() with a link with full data
15 */
16 public function testFromArrayFull()
17 {
18 $data = [
19 'id' => 1,
20 'shorturl' => 'abc',
21 'url' => 'https://domain.tld/oof.html?param=value#anchor',
22 'title' => 'This is an array link',
23 'description' => 'HTML desc<br><p>hi!</p>',
24 'thumbnail' => 'https://domain.tld/pic.png',
25 'sticky' => true,
26 'created' => new \DateTime('-1 minute'),
27 'tags' => ['tag1', 'tag2', 'chair'],
28 'updated' => new \DateTime(),
29 'private' => true,
30 ];
31
32 $bookmark = (new Bookmark())->fromArray($data);
33 $this->assertEquals($data['id'], $bookmark->getId());
34 $this->assertEquals($data['shorturl'], $bookmark->getShortUrl());
35 $this->assertEquals($data['url'], $bookmark->getUrl());
36 $this->assertEquals($data['title'], $bookmark->getTitle());
37 $this->assertEquals($data['description'], $bookmark->getDescription());
38 $this->assertEquals($data['thumbnail'], $bookmark->getThumbnail());
39 $this->assertEquals($data['sticky'], $bookmark->isSticky());
40 $this->assertEquals($data['created'], $bookmark->getCreated());
41 $this->assertEquals($data['tags'], $bookmark->getTags());
42 $this->assertEquals('tag1 tag2 chair', $bookmark->getTagsString());
43 $this->assertEquals($data['updated'], $bookmark->getUpdated());
44 $this->assertEquals($data['private'], $bookmark->isPrivate());
45 $this->assertFalse($bookmark->isNote());
46 }
47
48 /**
49 * Test fromArray() with a link with minimal data.
50 * Note that I use null values everywhere but this should not happen in the real world.
51 */
52 public function testFromArrayMinimal()
53 {
54 $data = [
55 'id' => null,
56 'shorturl' => null,
57 'url' => null,
58 'title' => null,
59 'description' => null,
60 'created' => null,
61 'tags' => null,
62 'private' => null,
63 ];
64
65 $bookmark = (new Bookmark())->fromArray($data);
66 $this->assertNull($bookmark->getId());
67 $this->assertNull($bookmark->getShortUrl());
68 $this->assertNull($bookmark->getUrl());
69 $this->assertNull($bookmark->getTitle());
70 $this->assertEquals('', $bookmark->getDescription());
71 $this->assertNull($bookmark->getCreated());
72 $this->assertEquals([], $bookmark->getTags());
73 $this->assertEquals('', $bookmark->getTagsString());
74 $this->assertNull($bookmark->getUpdated());
75 $this->assertFalse($bookmark->getThumbnail());
76 $this->assertFalse($bookmark->isSticky());
77 $this->assertFalse($bookmark->isPrivate());
78 $this->assertTrue($bookmark->isNote());
79 }
80
81 /**
82 * Test validate() with a valid minimal bookmark
83 */
84 public function testValidateValidFullBookmark()
85 {
86 $bookmark = new Bookmark();
87 $bookmark->setId(2);
88 $bookmark->setShortUrl('abc');
89 $bookmark->setCreated($date = \DateTime::createFromFormat('Ymd_His', '20190514_200102'));
90 $bookmark->setUpdated($dateUp = \DateTime::createFromFormat('Ymd_His', '20190514_210203'));
91 $bookmark->setUrl($url = 'https://domain.tld/oof.html?param=value#anchor');
92 $bookmark->setTitle($title = 'This is an array link');
93 $bookmark->setDescription($desc = 'HTML desc<br><p>hi!</p>');
94 $bookmark->setTags($tags = ['tag1', 'tag2', 'chair']);
95 $bookmark->setThumbnail($thumb = 'https://domain.tld/pic.png');
96 $bookmark->setPrivate(true);
97 $bookmark->validate();
98
99 $this->assertEquals(2, $bookmark->getId());
100 $this->assertEquals('abc', $bookmark->getShortUrl());
101 $this->assertEquals($date, $bookmark->getCreated());
102 $this->assertEquals($dateUp, $bookmark->getUpdated());
103 $this->assertEquals($url, $bookmark->getUrl());
104 $this->assertEquals($title, $bookmark->getTitle());
105 $this->assertEquals($desc, $bookmark->getDescription());
106 $this->assertEquals($tags, $bookmark->getTags());
107 $this->assertEquals(implode(' ', $tags), $bookmark->getTagsString());
108 $this->assertEquals($thumb, $bookmark->getThumbnail());
109 $this->assertTrue($bookmark->isPrivate());
110 $this->assertFalse($bookmark->isNote());
111 }
112
113 /**
114 * Test validate() with a valid minimal bookmark
115 */
116 public function testValidateValidMinimalBookmark()
117 {
118 $bookmark = new Bookmark();
119 $bookmark->setId(1);
120 $bookmark->setShortUrl('abc');
121 $bookmark->setCreated($date = \DateTime::createFromFormat('Ymd_His', '20190514_200102'));
122 $bookmark->validate();
123
124 $this->assertEquals(1, $bookmark->getId());
125 $this->assertEquals('abc', $bookmark->getShortUrl());
126 $this->assertEquals($date, $bookmark->getCreated());
127 $this->assertEquals('/shaare/abc', $bookmark->getUrl());
128 $this->assertEquals('/shaare/abc', $bookmark->getTitle());
129 $this->assertEquals('', $bookmark->getDescription());
130 $this->assertEquals([], $bookmark->getTags());
131 $this->assertEquals('', $bookmark->getTagsString());
132 $this->assertFalse($bookmark->getThumbnail());
133 $this->assertFalse($bookmark->isPrivate());
134 $this->assertTrue($bookmark->isNote());
135 $this->assertNull($bookmark->getUpdated());
136 }
137
138 /**
139 * Test validate() with a a bookmark without ID.
140 */
141 public function testValidateNotValidNoId()
142 {
143 $bookmark = new Bookmark();
144 $bookmark->setShortUrl('abc');
145 $bookmark->setCreated(\DateTime::createFromFormat('Ymd_His', '20190514_200102'));
146 $exception = null;
147 try {
148 $bookmark->validate();
149 } catch (InvalidBookmarkException $e) {
150 $exception = $e;
151 }
152 $this->assertNotNull($exception);
153 $this->assertContainsPolyfill('- ID: '. PHP_EOL, $exception->getMessage());
154 }
155
156 /**
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.
177 */
178 public function testValidateNotValidNoShortUrl()
179 {
180 $bookmark = new Bookmark();
181 $bookmark->setId(1);
182 $bookmark->setCreated(\DateTime::createFromFormat('Ymd_His', '20190514_200102'));
183 $bookmark->setShortUrl(null);
184 $exception = null;
185 try {
186 $bookmark->validate();
187 } catch (InvalidBookmarkException $e) {
188 $exception = $e;
189 }
190 $this->assertNotNull($exception);
191 $this->assertContainsPolyfill('- ShortUrl: '. PHP_EOL, $exception->getMessage());
192 }
193
194 /**
195 * Test validate() with a a bookmark without created datetime.
196 */
197 public function testValidateNotValidNoCreated()
198 {
199 $bookmark = new Bookmark();
200 $bookmark->setId(1);
201 $bookmark->setShortUrl('abc');
202 $bookmark->setCreated(null);
203 $exception = null;
204 try {
205 $bookmark->validate();
206 } catch (InvalidBookmarkException $e) {
207 $exception = $e;
208 }
209 $this->assertNotNull($exception);
210 $this->assertContainsPolyfill('- Created: '. PHP_EOL, $exception->getMessage());
211 }
212
213 /**
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.
234 */
235 public function testSetIdEmptyGeneratedFields()
236 {
237 $bookmark = new Bookmark();
238 $bookmark->setId(2);
239
240 $this->assertEquals(2, $bookmark->getId());
241 $this->assertRegExp('/[\w\-]{6}/', $bookmark->getShortUrl());
242 $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getCreated());
243 }
244
245 /**
246 * Test setId() and with generated fields already set.
247 */
248 public function testSetIdSetGeneratedFields()
249 {
250 $bookmark = new Bookmark();
251 $bookmark->setShortUrl('abc');
252 $bookmark->setCreated($date = \DateTime::createFromFormat('Ymd_His', '20190514_200102'));
253 $bookmark->setId(2);
254
255 $this->assertEquals(2, $bookmark->getId());
256 $this->assertEquals('abc', $bookmark->getShortUrl());
257 $this->assertEquals($date, $bookmark->getCreated());
258 }
259
260 /**
261 * Test setUrl() and make sure it accepts custom protocols
262 */
263 public function testGetUrlWithValidProtocols()
264 {
265 $bookmark = new Bookmark();
266 $bookmark->setUrl($url = 'myprotocol://helloworld', ['myprotocol']);
267 $this->assertEquals($url, $bookmark->getUrl());
268
269 $bookmark->setUrl($url = 'https://helloworld.tld', ['myprotocol']);
270 $this->assertEquals($url, $bookmark->getUrl());
271 }
272
273 /**
274 * Test setUrl() and make sure it accepts custom protocols
275 */
276 public function testGetUrlWithNotValidProtocols()
277 {
278 $bookmark = new Bookmark();
279 $bookmark->setUrl('myprotocol://helloworld', []);
280 $this->assertEquals('http://helloworld', $bookmark->getUrl());
281
282 $bookmark->setUrl($url = 'https://helloworld.tld', []);
283 $this->assertEquals($url, $bookmark->getUrl());
284 }
285
286 /**
287 * Test setTagsString() with exotic data
288 */
289 public function testSetTagsString()
290 {
291 $bookmark = new Bookmark();
292
293 $str = 'tag1 tag2 tag3.tag3-2, tag4 , -tag5 ';
294 $bookmark->setTagsString($str);
295 $this->assertEquals(
296 [
297 'tag1',
298 'tag2',
299 'tag3.tag3-2',
300 'tag4',
301 'tag5',
302 ],
303 $bookmark->getTags()
304 );
305 }
306
307 /**
308 * Test setTags() with exotic data
309 */
310 public function testSetTags()
311 {
312 $bookmark = new Bookmark();
313
314 $array = [
315 'tag1 ',
316 ' tag2',
317 'tag3.tag3-2,',
318 ', tag4',
319 ', ',
320 '-tag5 ',
321 ];
322 $bookmark->setTags($array);
323 $this->assertEquals(
324 [
325 'tag1',
326 'tag2',
327 'tag3.tag3-2',
328 'tag4',
329 'tag5',
330 ],
331 $bookmark->getTags()
332 );
333 }
334
335 /**
336 * Test renameTag()
337 */
338 public function testRenameTag()
339 {
340 $bookmark = new Bookmark();
341 $bookmark->setTags(['tag1', 'tag2', 'chair']);
342 $bookmark->renameTag('chair', 'table');
343 $this->assertEquals(['tag1', 'tag2', 'table'], $bookmark->getTags());
344 $bookmark->renameTag('tag1', 'tag42');
345 $this->assertEquals(['tag42', 'tag2', 'table'], $bookmark->getTags());
346 $bookmark->renameTag('tag42', 'tag43');
347 $this->assertEquals(['tag43', 'tag2', 'table'], $bookmark->getTags());
348 $bookmark->renameTag('table', 'desk');
349 $this->assertEquals(['tag43', 'tag2', 'desk'], $bookmark->getTags());
350 }
351
352 /**
353 * Test renameTag() with a tag that is not present in the bookmark
354 */
355 public function testRenameTagNotExists()
356 {
357 $bookmark = new Bookmark();
358 $bookmark->setTags(['tag1', 'tag2', 'chair']);
359 $bookmark->renameTag('nope', 'table');
360 $this->assertEquals(['tag1', 'tag2', 'chair'], $bookmark->getTags());
361 }
362
363 /**
364 * Test deleteTag()
365 */
366 public function testDeleteTag()
367 {
368 $bookmark = new Bookmark();
369 $bookmark->setTags(['tag1', 'tag2', 'chair']);
370 $bookmark->deleteTag('chair');
371 $this->assertEquals(['tag1', 'tag2'], $bookmark->getTags());
372 $bookmark->deleteTag('tag1');
373 $this->assertEquals(['tag2'], $bookmark->getTags());
374 $bookmark->deleteTag('tag2');
375 $this->assertEquals([], $bookmark->getTags());
376 }
377
378 /**
379 * Test deleteTag() with a tag that is not present in the bookmark
380 */
381 public function testDeleteTagNotExists()
382 {
383 $bookmark = new Bookmark();
384 $bookmark->setTags(['tag1', 'tag2', 'chair']);
385 $bookmark->deleteTag('nope');
386 $this->assertEquals(['tag1', 'tag2', 'chair'], $bookmark->getTags());
387 }
388}
diff --git a/tests/bookmark/LinkDBTest.php b/tests/bookmark/LinkDBTest.php
deleted file mode 100644
index 2990a6b5..00000000
--- a/tests/bookmark/LinkDBTest.php
+++ /dev/null
@@ -1,622 +0,0 @@
1<?php
2/**
3 * Link datastore tests
4 */
5
6namespace Shaarli\Bookmark;
7
8use DateTime;
9use ReferenceLinkDB;
10use ReflectionClass;
11use Shaarli;
12
13require_once 'application/feed/Cache.php';
14require_once 'application/Utils.php';
15require_once 'tests/utils/ReferenceLinkDB.php';
16
17
18/**
19 * Unitary tests for LinkDB
20 */
21class LinkDBTest extends \PHPUnit\Framework\TestCase
22{
23 // datastore to test write operations
24 protected static $testDatastore = 'sandbox/datastore.php';
25
26 /**
27 * @var ReferenceLinkDB instance.
28 */
29 protected static $refDB = null;
30
31 /**
32 * @var LinkDB public LinkDB instance.
33 */
34 protected static $publicLinkDB = null;
35
36 /**
37 * @var LinkDB private LinkDB instance.
38 */
39 protected static $privateLinkDB = null;
40
41 /**
42 * Instantiates public and private LinkDBs with test data
43 *
44 * The reference datastore contains public and private links that
45 * will be used to test LinkDB's methods:
46 * - access filtering (public/private),
47 * - link searches:
48 * - by day,
49 * - by tag,
50 * - by text,
51 * - etc.
52 */
53 public static function setUpBeforeClass()
54 {
55 self::$refDB = new ReferenceLinkDB();
56 self::$refDB->write(self::$testDatastore);
57
58 self::$publicLinkDB = new LinkDB(self::$testDatastore, false, false);
59 self::$privateLinkDB = new LinkDB(self::$testDatastore, true, false);
60 }
61
62 /**
63 * Resets test data for each test
64 */
65 protected function setUp()
66 {
67 if (file_exists(self::$testDatastore)) {
68 unlink(self::$testDatastore);
69 }
70 }
71
72 /**
73 * Allows to test LinkDB's private methods
74 *
75 * @see
76 * https://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html
77 * http://stackoverflow.com/a/2798203
78 */
79 protected static function getMethod($name)
80 {
81 $class = new ReflectionClass('Shaarli\Bookmark\LinkDB');
82 $method = $class->getMethod($name);
83 $method->setAccessible(true);
84 return $method;
85 }
86
87 /**
88 * Instantiate LinkDB objects - logged in user
89 */
90 public function testConstructLoggedIn()
91 {
92 new LinkDB(self::$testDatastore, true, false);
93 $this->assertFileExists(self::$testDatastore);
94 }
95
96 /**
97 * Instantiate LinkDB objects - logged out or public instance
98 */
99 public function testConstructLoggedOut()
100 {
101 new LinkDB(self::$testDatastore, false, false);
102 $this->assertFileExists(self::$testDatastore);
103 }
104
105 /**
106 * Attempt to instantiate a LinkDB whereas the datastore is not writable
107 *
108 * @expectedException Shaarli\Exceptions\IOException
109 * @expectedExceptionMessageRegExp /Error accessing "null"/
110 */
111 public function testConstructDatastoreNotWriteable()
112 {
113 new LinkDB('null/store.db', false, false);
114 }
115
116 /**
117 * The DB doesn't exist, ensure it is created with dummy content
118 */
119 public function testCheckDBNew()
120 {
121 $linkDB = new LinkDB(self::$testDatastore, false, false);
122 unlink(self::$testDatastore);
123 $this->assertFileNotExists(self::$testDatastore);
124
125 $checkDB = self::getMethod('check');
126 $checkDB->invokeArgs($linkDB, array());
127 $this->assertFileExists(self::$testDatastore);
128
129 // ensure the correct data has been written
130 $this->assertGreaterThan(0, filesize(self::$testDatastore));
131 }
132
133 /**
134 * The DB exists, don't do anything
135 */
136 public function testCheckDBLoad()
137 {
138 $linkDB = new LinkDB(self::$testDatastore, false, false);
139 $datastoreSize = filesize(self::$testDatastore);
140 $this->assertGreaterThan(0, $datastoreSize);
141
142 $checkDB = self::getMethod('check');
143 $checkDB->invokeArgs($linkDB, array());
144
145 // ensure the datastore is left unmodified
146 $this->assertEquals(
147 $datastoreSize,
148 filesize(self::$testDatastore)
149 );
150 }
151
152 /**
153 * Load an empty DB
154 */
155 public function testReadEmptyDB()
156 {
157 file_put_contents(self::$testDatastore, '<?php /* S7QysKquBQA= */ ?>');
158 $emptyDB = new LinkDB(self::$testDatastore, false, false);
159 $this->assertEquals(0, sizeof($emptyDB));
160 $this->assertEquals(0, count($emptyDB));
161 }
162
163 /**
164 * Load public links from the DB
165 */
166 public function testReadPublicDB()
167 {
168 $this->assertEquals(
169 self::$refDB->countPublicLinks(),
170 sizeof(self::$publicLinkDB)
171 );
172 }
173
174 /**
175 * Load public and private links from the DB
176 */
177 public function testReadPrivateDB()
178 {
179 $this->assertEquals(
180 self::$refDB->countLinks(),
181 sizeof(self::$privateLinkDB)
182 );
183 }
184
185 /**
186 * Save the links to the DB
187 */
188 public function testSave()
189 {
190 $testDB = new LinkDB(self::$testDatastore, true, false);
191 $dbSize = sizeof($testDB);
192
193 $link = array(
194 'id' => 42,
195 'title' => 'an additional link',
196 'url' => 'http://dum.my',
197 'description' => 'One more',
198 'private' => 0,
199 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150518_190000'),
200 'tags' => 'unit test'
201 );
202 $testDB[$link['id']] = $link;
203 $testDB->save('tests');
204
205 $testDB = new LinkDB(self::$testDatastore, true, false);
206 $this->assertEquals($dbSize + 1, sizeof($testDB));
207 }
208
209 /**
210 * Count existing links
211 */
212 public function testCount()
213 {
214 $this->assertEquals(
215 self::$refDB->countPublicLinks(),
216 self::$publicLinkDB->count()
217 );
218 $this->assertEquals(
219 self::$refDB->countLinks(),
220 self::$privateLinkDB->count()
221 );
222 }
223
224 /**
225 * Count existing links - public links hidden
226 */
227 public function testCountHiddenPublic()
228 {
229 $linkDB = new LinkDB(self::$testDatastore, false, true);
230
231 $this->assertEquals(
232 0,
233 $linkDB->count()
234 );
235 $this->assertEquals(
236 0,
237 $linkDB->count()
238 );
239 }
240
241 /**
242 * List the days for which links have been posted
243 */
244 public function testDays()
245 {
246 $this->assertEquals(
247 array('20100309', '20100310', '20121206', '20121207', '20130614', '20150310'),
248 self::$publicLinkDB->days()
249 );
250
251 $this->assertEquals(
252 array('20100309', '20100310', '20121206', '20121207', '20130614', '20141125', '20150310'),
253 self::$privateLinkDB->days()
254 );
255 }
256
257 /**
258 * The URL corresponds to an existing entry in the DB
259 */
260 public function testGetKnownLinkFromURL()
261 {
262 $link = self::$publicLinkDB->getLinkFromUrl('http://mediagoblin.org/');
263
264 $this->assertNotEquals(false, $link);
265 $this->assertContains(
266 'A free software media publishing platform',
267 $link['description']
268 );
269 }
270
271 /**
272 * The URL is not in the DB
273 */
274 public function testGetUnknownLinkFromURL()
275 {
276 $this->assertEquals(
277 false,
278 self::$publicLinkDB->getLinkFromUrl('http://dev.null')
279 );
280 }
281
282 /**
283 * Lists all tags
284 */
285 public function testAllTags()
286 {
287 $this->assertEquals(
288 array(
289 'web' => 3,
290 'cartoon' => 2,
291 'gnu' => 2,
292 'dev' => 1,
293 'samba' => 1,
294 'media' => 1,
295 'software' => 1,
296 'stallman' => 1,
297 'free' => 1,
298 '-exclude' => 1,
299 'hashtag' => 2,
300 // The DB contains a link with `sTuff` and another one with `stuff` tag.
301 // They need to be grouped with the first case found - order by date DESC: `sTuff`.
302 'sTuff' => 2,
303 'ut' => 1,
304 ),
305 self::$publicLinkDB->linksCountPerTag()
306 );
307
308 $this->assertEquals(
309 array(
310 'web' => 4,
311 'cartoon' => 3,
312 'gnu' => 2,
313 'dev' => 2,
314 'samba' => 1,
315 'media' => 1,
316 'software' => 1,
317 'stallman' => 1,
318 'free' => 1,
319 'html' => 1,
320 'w3c' => 1,
321 'css' => 1,
322 'Mercurial' => 1,
323 'sTuff' => 2,
324 '-exclude' => 1,
325 '.hidden' => 1,
326 'hashtag' => 2,
327 'tag1' => 1,
328 'tag2' => 1,
329 'tag3' => 1,
330 'tag4' => 1,
331 'ut' => 1,
332 ),
333 self::$privateLinkDB->linksCountPerTag()
334 );
335 $this->assertEquals(
336 array(
337 'web' => 4,
338 'cartoon' => 2,
339 'gnu' => 1,
340 'dev' => 1,
341 'samba' => 1,
342 'media' => 1,
343 'html' => 1,
344 'w3c' => 1,
345 'css' => 1,
346 'Mercurial' => 1,
347 '.hidden' => 1,
348 'hashtag' => 1,
349 ),
350 self::$privateLinkDB->linksCountPerTag(['web'])
351 );
352 $this->assertEquals(
353 array(
354 'web' => 1,
355 'html' => 1,
356 'w3c' => 1,
357 'css' => 1,
358 'Mercurial' => 1,
359 ),
360 self::$privateLinkDB->linksCountPerTag(['web'], 'private')
361 );
362 }
363
364 /**
365 * Test filter with string.
366 */
367 public function testFilterString()
368 {
369 $tags = 'dev cartoon';
370 $request = array('searchtags' => $tags);
371 $this->assertEquals(
372 2,
373 count(self::$privateLinkDB->filterSearch($request, true, false))
374 );
375 }
376
377 /**
378 * Test filter with string.
379 */
380 public function testFilterArray()
381 {
382 $tags = array('dev', 'cartoon');
383 $request = array('searchtags' => $tags);
384 $this->assertEquals(
385 2,
386 count(self::$privateLinkDB->filterSearch($request, true, false))
387 );
388 }
389
390 /**
391 * Test hidden tags feature:
392 * tags starting with a dot '.' are only visible when logged in.
393 */
394 public function testHiddenTags()
395 {
396 $tags = '.hidden';
397 $request = array('searchtags' => $tags);
398 $this->assertEquals(
399 1,
400 count(self::$privateLinkDB->filterSearch($request, true, false))
401 );
402
403 $this->assertEquals(
404 0,
405 count(self::$publicLinkDB->filterSearch($request, true, false))
406 );
407 }
408
409 /**
410 * Test filterHash() with a valid smallhash.
411 */
412 public function testFilterHashValid()
413 {
414 $request = smallHash('20150310_114651');
415 $this->assertEquals(
416 1,
417 count(self::$publicLinkDB->filterHash($request))
418 );
419 $request = smallHash('20150310_114633' . 8);
420 $this->assertEquals(
421 1,
422 count(self::$publicLinkDB->filterHash($request))
423 );
424 }
425
426 /**
427 * Test filterHash() with an invalid smallhash.
428 *
429 * @expectedException \Shaarli\Bookmark\Exception\LinkNotFoundException
430 */
431 public function testFilterHashInValid1()
432 {
433 $request = 'blabla';
434 self::$publicLinkDB->filterHash($request);
435 }
436
437 /**
438 * Test filterHash() with an empty smallhash.
439 *
440 * @expectedException \Shaarli\Bookmark\Exception\LinkNotFoundException
441 */
442 public function testFilterHashInValid()
443 {
444 self::$publicLinkDB->filterHash('');
445 }
446
447 /**
448 * Test reorder with asc/desc parameter.
449 */
450 public function testReorderLinksDesc()
451 {
452 self::$privateLinkDB->reorder('ASC');
453 $stickyIds = [11, 10];
454 $standardIds = [42, 4, 9, 1, 0, 7, 6, 8, 41];
455 $linkIds = array_merge($stickyIds, $standardIds);
456 $cpt = 0;
457 foreach (self::$privateLinkDB as $key => $value) {
458 $this->assertEquals($linkIds[$cpt++], $key);
459 }
460 self::$privateLinkDB->reorder('DESC');
461 $linkIds = array_merge(array_reverse($stickyIds), array_reverse($standardIds));
462 $cpt = 0;
463 foreach (self::$privateLinkDB as $key => $value) {
464 $this->assertEquals($linkIds[$cpt++], $key);
465 }
466 }
467
468 /**
469 * Test rename tag with a valid value present in multiple links
470 */
471 public function testRenameTagMultiple()
472 {
473 self::$refDB->write(self::$testDatastore);
474 $linkDB = new LinkDB(self::$testDatastore, true, false);
475
476 $res = $linkDB->renameTag('cartoon', 'Taz');
477 $this->assertEquals(3, count($res));
478 $this->assertContains(' Taz ', $linkDB[4]['tags']);
479 $this->assertContains(' Taz ', $linkDB[1]['tags']);
480 $this->assertContains(' Taz ', $linkDB[0]['tags']);
481 }
482
483 /**
484 * Test rename tag with a valid value
485 */
486 public function testRenameTagCaseSensitive()
487 {
488 self::$refDB->write(self::$testDatastore);
489 $linkDB = new LinkDB(self::$testDatastore, true, false);
490
491 $res = $linkDB->renameTag('sTuff', 'Taz');
492 $this->assertEquals(1, count($res));
493 $this->assertEquals('Taz', $linkDB[41]['tags']);
494 }
495
496 /**
497 * Test rename tag with invalid values
498 */
499 public function testRenameTagInvalid()
500 {
501 $linkDB = new LinkDB(self::$testDatastore, false, false);
502
503 $this->assertFalse($linkDB->renameTag('', 'test'));
504 $this->assertFalse($linkDB->renameTag('', ''));
505 // tag non existent
506 $this->assertEquals([], $linkDB->renameTag('test', ''));
507 $this->assertEquals([], $linkDB->renameTag('test', 'retest'));
508 }
509
510 /**
511 * Test delete tag with a valid value
512 */
513 public function testDeleteTag()
514 {
515 self::$refDB->write(self::$testDatastore);
516 $linkDB = new LinkDB(self::$testDatastore, true, false);
517
518 $res = $linkDB->renameTag('cartoon', null);
519 $this->assertEquals(3, count($res));
520 $this->assertNotContains('cartoon', $linkDB[4]['tags']);
521 }
522
523 /**
524 * Test linksCountPerTag all tags without filter.
525 * Equal occurrences should be sorted alphabetically.
526 */
527 public function testCountLinkPerTagAllNoFilter()
528 {
529 $expected = [
530 'web' => 4,
531 'cartoon' => 3,
532 'dev' => 2,
533 'gnu' => 2,
534 'hashtag' => 2,
535 'sTuff' => 2,
536 '-exclude' => 1,
537 '.hidden' => 1,
538 'Mercurial' => 1,
539 'css' => 1,
540 'free' => 1,
541 'html' => 1,
542 'media' => 1,
543 'samba' => 1,
544 'software' => 1,
545 'stallman' => 1,
546 'tag1' => 1,
547 'tag2' => 1,
548 'tag3' => 1,
549 'tag4' => 1,
550 'ut' => 1,
551 'w3c' => 1,
552 ];
553 $tags = self::$privateLinkDB->linksCountPerTag();
554
555 $this->assertEquals($expected, $tags, var_export($tags, true));
556 }
557
558 /**
559 * Test linksCountPerTag all tags with filter.
560 * Equal occurrences should be sorted alphabetically.
561 */
562 public function testCountLinkPerTagAllWithFilter()
563 {
564 $expected = [
565 'gnu' => 2,
566 'hashtag' => 2,
567 '-exclude' => 1,
568 '.hidden' => 1,
569 'free' => 1,
570 'media' => 1,
571 'software' => 1,
572 'stallman' => 1,
573 'stuff' => 1,
574 'web' => 1,
575 ];
576 $tags = self::$privateLinkDB->linksCountPerTag(['gnu']);
577
578 $this->assertEquals($expected, $tags, var_export($tags, true));
579 }
580
581 /**
582 * Test linksCountPerTag public tags with filter.
583 * Equal occurrences should be sorted alphabetically.
584 */
585 public function testCountLinkPerTagPublicWithFilter()
586 {
587 $expected = [
588 'gnu' => 2,
589 'hashtag' => 2,
590 '-exclude' => 1,
591 '.hidden' => 1,
592 'free' => 1,
593 'media' => 1,
594 'software' => 1,
595 'stallman' => 1,
596 'stuff' => 1,
597 'web' => 1,
598 ];
599 $tags = self::$privateLinkDB->linksCountPerTag(['gnu'], 'public');
600
601 $this->assertEquals($expected, $tags, var_export($tags, true));
602 }
603
604 /**
605 * Test linksCountPerTag public tags with filter.
606 * Equal occurrences should be sorted alphabetically.
607 */
608 public function testCountLinkPerTagPrivateWithFilter()
609 {
610 $expected = [
611 'cartoon' => 1,
612 'dev' => 1,
613 'tag1' => 1,
614 'tag2' => 1,
615 'tag3' => 1,
616 'tag4' => 1,
617 ];
618 $tags = self::$privateLinkDB->linksCountPerTag(['dev'], 'private');
619
620 $this->assertEquals($expected, $tags, var_export($tags, true));
621 }
622}
diff --git a/tests/bookmark/LinkUtilsTest.php b/tests/bookmark/LinkUtilsTest.php
index 78cb8f2a..ef00b92f 100644
--- a/tests/bookmark/LinkUtilsTest.php
+++ b/tests/bookmark/LinkUtilsTest.php
@@ -2,9 +2,7 @@
2 2
3namespace Shaarli\Bookmark; 3namespace Shaarli\Bookmark;
4 4
5use PHPUnit\Framework\TestCase; 5use Shaarli\TestCase;
6use ReferenceLinkDB;
7use Shaarli\Config\ConfigManager;
8 6
9require_once 'tests/utils/CurlUtils.php'; 7require_once 'tests/utils/CurlUtils.php';
10 8
@@ -45,6 +43,19 @@ class LinkUtilsTest extends TestCase
45 } 43 }
46 44
47 /** 45 /**
46 * Test headers_extract_charset() when the charset is found with odd quotes.
47 */
48 public function testHeadersExtractExistentCharsetWithQuotes()
49 {
50 $charset = 'x-MacCroatian';
51 $headers = 'text/html; charset="' . $charset . '"otherstuff="test"';
52 $this->assertEquals(strtolower($charset), header_extract_charset($headers));
53
54 $headers = 'text/html; charset=\'' . $charset . '\'otherstuff="test"';
55 $this->assertEquals(strtolower($charset), header_extract_charset($headers));
56 }
57
58 /**
48 * Test headers_extract_charset() when the charset is not found. 59 * Test headers_extract_charset() when the charset is not found.
49 */ 60 */
50 public function testHeadersExtractNonExistentCharset() 61 public function testHeadersExtractNonExistentCharset()
@@ -389,15 +400,6 @@ class LinkUtilsTest extends TestCase
389 } 400 }
390 401
391 /** 402 /**
392 * Test count_private.
393 */
394 public function testCountPrivateLinks()
395 {
396 $refDB = new ReferenceLinkDB();
397 $this->assertEquals($refDB->countPrivateLinks(), count_private($refDB->getLinks()));
398 }
399
400 /**
401 * Test text2clickable. 403 * Test text2clickable.
402 */ 404 */
403 public function testText2clickable() 405 public function testText2clickable()
@@ -448,13 +450,13 @@ class LinkUtilsTest extends TestCase
448 カタカナ #カタカナ」カタカナ\n'; 450 カタカナ #カタカナ」カタカナ\n';
449 $autolinkedDescription = hashtag_autolink($rawDescription, $index); 451 $autolinkedDescription = hashtag_autolink($rawDescription, $index);
450 452
451 $this->assertContains($this->getHashtagLink('hashtag', $index), $autolinkedDescription); 453 $this->assertContainsPolyfill($this->getHashtagLink('hashtag', $index), $autolinkedDescription);
452 $this->assertNotContains(' #hashtag', $autolinkedDescription); 454 $this->assertNotContainsPolyfill(' #hashtag', $autolinkedDescription);
453 $this->assertNotContains('>#nothashtag', $autolinkedDescription); 455 $this->assertNotContainsPolyfill('>#nothashtag', $autolinkedDescription);
454 $this->assertContains($this->getHashtagLink('ашок', $index), $autolinkedDescription); 456 $this->assertContainsPolyfill($this->getHashtagLink('ашок', $index), $autolinkedDescription);
455 $this->assertContains($this->getHashtagLink('カタカナ', $index), $autolinkedDescription); 457 $this->assertContainsPolyfill($this->getHashtagLink('カタカナ', $index), $autolinkedDescription);
456 $this->assertContains($this->getHashtagLink('hashtag_hashtag', $index), $autolinkedDescription); 458 $this->assertContainsPolyfill($this->getHashtagLink('hashtag_hashtag', $index), $autolinkedDescription);
457 $this->assertNotContains($this->getHashtagLink('hashtag-nothashtag', $index), $autolinkedDescription); 459 $this->assertNotContainsPolyfill($this->getHashtagLink('hashtag-nothashtag', $index), $autolinkedDescription);
458 } 460 }
459 461
460 /** 462 /**
@@ -465,9 +467,9 @@ class LinkUtilsTest extends TestCase
465 $rawDescription = 'blabla #hashtag x#nothashtag'; 467 $rawDescription = 'blabla #hashtag x#nothashtag';
466 $autolinkedDescription = hashtag_autolink($rawDescription); 468 $autolinkedDescription = hashtag_autolink($rawDescription);
467 469
468 $this->assertContains($this->getHashtagLink('hashtag'), $autolinkedDescription); 470 $this->assertContainsPolyfill($this->getHashtagLink('hashtag'), $autolinkedDescription);
469 $this->assertNotContains(' #hashtag', $autolinkedDescription); 471 $this->assertNotContainsPolyfill(' #hashtag', $autolinkedDescription);
470 $this->assertNotContains('>#nothashtag', $autolinkedDescription); 472 $this->assertNotContainsPolyfill('>#nothashtag', $autolinkedDescription);
471 } 473 }
472 474
473 /** 475 /**
@@ -500,7 +502,7 @@ class LinkUtilsTest extends TestCase
500 */ 502 */
501 private function getHashtagLink($hashtag, $index = '') 503 private function getHashtagLink($hashtag, $index = '')
502 { 504 {
503 $hashtagLink = '<a href="' . $index . '?addtag=$1" title="Hashtag $1">#$1</a>'; 505 $hashtagLink = '<a href="' . $index . './add-tag/$1" title="Hashtag $1">#$1</a>';
504 return str_replace('$1', $hashtag, $hashtagLink); 506 return str_replace('$1', $hashtag, $hashtagLink);
505 } 507 }
506} 508}