]> git.immae.eu Git - github/shaarli/Shaarli.git/blob - tests/bookmark/BookmarkFilterTest.php
91e139c20e283ad59982001ce04064fcfcccaa41
[github/shaarli/Shaarli.git] / tests / bookmark / BookmarkFilterTest.php
1 <?php
2
3 namespace Shaarli\Bookmark;
4
5 use Exception;
6 use PHPUnit\Framework\TestCase;
7 use ReferenceLinkDB;
8 use Shaarli\Config\ConfigManager;
9 use Shaarli\History;
10
11 /**
12 * Class BookmarkFilterTest.
13 */
14 class BookmarkFilterTest extends TestCase
15 {
16 /**
17 * @var string Test datastore path.
18 */
19 protected static $testDatastore = 'sandbox/datastore.php';
20 /**
21 * @var BookmarkFilter instance.
22 */
23 protected static $linkFilter;
24
25 /**
26 * @var ReferenceLinkDB instance
27 */
28 protected static $refDB;
29
30 /**
31 * @var BookmarkFileService instance
32 */
33 protected static $bookmarkService;
34
35 /**
36 * Instantiate linkFilter with ReferenceLinkDB data.
37 */
38 public static function setUpBeforeClass(): void
39 {
40 $conf = new ConfigManager('tests/utils/config/configJson');
41 $conf->set('resource.datastore', self::$testDatastore);
42 self::$refDB = new \ReferenceLinkDB();
43 self::$refDB->write(self::$testDatastore);
44 $history = new History('sandbox/history.php');
45 self::$bookmarkService = new \FakeBookmarkService($conf, $history, true);
46 self::$linkFilter = new BookmarkFilter(self::$bookmarkService->getBookmarks());
47 }
48
49 /**
50 * Blank filter.
51 */
52 public function testFilter()
53 {
54 $this->assertEquals(
55 self::$refDB->countLinks(),
56 count(self::$linkFilter->filter('', ''))
57 );
58
59 $this->assertEquals(
60 self::$refDB->countLinks(),
61 count(self::$linkFilter->filter('', '', 'all'))
62 );
63
64 $this->assertEquals(
65 self::$refDB->countLinks(),
66 count(self::$linkFilter->filter('', '', 'randomstr'))
67 );
68
69 // Private only.
70 $this->assertEquals(
71 self::$refDB->countPrivateLinks(),
72 count(self::$linkFilter->filter('', '', false, 'private'))
73 );
74
75 // Public only.
76 $this->assertEquals(
77 self::$refDB->countPublicLinks(),
78 count(self::$linkFilter->filter('', '', false, 'public'))
79 );
80
81 $this->assertEquals(
82 ReferenceLinkDB::$NB_LINKS_TOTAL,
83 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, ''))
84 );
85
86 $this->assertEquals(
87 self::$refDB->countUntaggedLinks(),
88 count(
89 self::$linkFilter->filter(
90 BookmarkFilter::$FILTER_TAG,
91 /*$request=*/
92 '',
93 /*$casesensitive=*/
94 false,
95 /*$visibility=*/
96 'all',
97 /*$untaggedonly=*/
98 true
99 )
100 )
101 );
102
103 $this->assertEquals(
104 ReferenceLinkDB::$NB_LINKS_TOTAL,
105 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, ''))
106 );
107 }
108
109 /**
110 * Filter bookmarks using a tag
111 */
112 public function testFilterOneTag()
113 {
114 $this->assertEquals(
115 4,
116 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'web', false))
117 );
118
119 $this->assertEquals(
120 4,
121 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'web', false, 'all'))
122 );
123
124 $this->assertEquals(
125 4,
126 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'web', false, 'default-blabla'))
127 );
128
129 // Private only.
130 $this->assertEquals(
131 1,
132 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'web', false, 'private'))
133 );
134
135 // Public only.
136 $this->assertEquals(
137 3,
138 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'web', false, 'public'))
139 );
140 }
141
142 /**
143 * Filter bookmarks using a tag - case-sensitive
144 */
145 public function testFilterCaseSensitiveTag()
146 {
147 $this->assertEquals(
148 0,
149 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'mercurial', true))
150 );
151
152 $this->assertEquals(
153 1,
154 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'Mercurial', true))
155 );
156 }
157
158 /**
159 * Filter bookmarks using a tag combination
160 */
161 public function testFilterMultipleTags()
162 {
163 $this->assertEquals(
164 2,
165 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'dev cartoon', false))
166 );
167 }
168
169 /**
170 * Filter bookmarks using a non-existent tag
171 */
172 public function testFilterUnknownTag()
173 {
174 $this->assertEquals(
175 0,
176 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'null', false))
177 );
178 }
179
180 /**
181 * Return bookmarks for a given day
182 */
183 public function testFilterDay()
184 {
185 $this->assertEquals(
186 4,
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))
199 );
200 }
201
202 /**
203 * 404 - day not found
204 */
205 public function testFilterUnknownDay()
206 {
207 $this->assertEquals(
208 0,
209 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_DAY, '19700101'))
210 );
211 }
212
213 /**
214 * Use an invalid date format
215 * @expectedException Exception
216 * @expectedExceptionMessageRegExp /Invalid date format/
217 */
218 public function testFilterInvalidDayWithChars()
219 {
220 self::$linkFilter->filter(BookmarkFilter::$FILTER_DAY, 'Rainy day, dream away');
221 }
222
223 /**
224 * Use an invalid date format
225 * @expectedException Exception
226 * @expectedExceptionMessageRegExp /Invalid date format/
227 */
228 public function testFilterInvalidDayDigits()
229 {
230 self::$linkFilter->filter(BookmarkFilter::$FILTER_DAY, '20');
231 }
232
233 /**
234 * Retrieve a link entry with its hash
235 */
236 public function testFilterSmallHash()
237 {
238 $links = self::$linkFilter->filter(BookmarkFilter::$FILTER_HASH, 'IuWvgA');
239
240 $this->assertEquals(
241 1,
242 count($links)
243 );
244
245 $this->assertEquals(
246 'MediaGoblin',
247 $links[7]->getTitle()
248 );
249 }
250
251 /**
252 * No link for this hash
253 *
254 * @expectedException \Shaarli\Bookmark\Exception\BookmarkNotFoundException
255 */
256 public function testFilterUnknownSmallHash()
257 {
258 self::$linkFilter->filter(BookmarkFilter::$FILTER_HASH, 'Iblaah');
259 }
260
261 /**
262 * Full-text search - no result found.
263 */
264 public function testFilterFullTextNoResult()
265 {
266 $this->assertEquals(
267 0,
268 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'azertyuiop'))
269 );
270 }
271
272 /**
273 * Full-text search - result from a link's URL
274 */
275 public function testFilterFullTextURL()
276 {
277 $this->assertEquals(
278 2,
279 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'ars.userfriendly.org'))
280 );
281
282 $this->assertEquals(
283 2,
284 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'ars org'))
285 );
286 }
287
288 /**
289 * Full-text search - result from a link's title only
290 */
291 public function testFilterFullTextTitle()
292 {
293 // use miscellaneous cases
294 $this->assertEquals(
295 2,
296 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'userfriendly -'))
297 );
298 $this->assertEquals(
299 2,
300 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'UserFriendly -'))
301 );
302 $this->assertEquals(
303 2,
304 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'uSeRFrIendlY -'))
305 );
306
307 // use miscellaneous case and offset
308 $this->assertEquals(
309 2,
310 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'RFrIendL'))
311 );
312 }
313
314 /**
315 * Full-text search - result from the link's description only
316 */
317 public function testFilterFullTextDescription()
318 {
319 $this->assertEquals(
320 1,
321 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'publishing media'))
322 );
323
324 $this->assertEquals(
325 1,
326 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'mercurial w3c'))
327 );
328
329 $this->assertEquals(
330 3,
331 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, '"free software"'))
332 );
333 }
334
335 /**
336 * Full-text search - result from the link's tags only
337 */
338 public function testFilterFullTextTags()
339 {
340 $this->assertEquals(
341 6,
342 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'web'))
343 );
344
345 $this->assertEquals(
346 6,
347 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'web', 'all'))
348 );
349
350 $this->assertEquals(
351 6,
352 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'web', 'bla'))
353 );
354
355 // Private only.
356 $this->assertEquals(
357 1,
358 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'web', false, 'private'))
359 );
360
361 // Public only.
362 $this->assertEquals(
363 5,
364 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'web', false, 'public'))
365 );
366 }
367
368 /**
369 * Full-text search - result set from mixed sources
370 */
371 public function testFilterFullTextMixed()
372 {
373 $this->assertEquals(
374 3,
375 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'free software'))
376 );
377 }
378
379 /**
380 * Full-text search - test exclusion with '-'.
381 */
382 public function testExcludeSearch()
383 {
384 $this->assertEquals(
385 1,
386 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, 'free -gnu'))
387 );
388
389 $this->assertEquals(
390 ReferenceLinkDB::$NB_LINKS_TOTAL - 1,
391 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TEXT, '-revolution'))
392 );
393 }
394
395 /**
396 * Full-text search - test AND, exact terms and exclusion combined, across fields.
397 */
398 public function testMultiSearch()
399 {
400 $this->assertEquals(
401 2,
402 count(self::$linkFilter->filter(
403 BookmarkFilter::$FILTER_TEXT,
404 '"Free Software " stallman "read this" @website stuff'
405 ))
406 );
407
408 $this->assertEquals(
409 1,
410 count(self::$linkFilter->filter(
411 BookmarkFilter::$FILTER_TEXT,
412 '"free software " stallman "read this" -beard @website stuff'
413 ))
414 );
415 }
416
417 /**
418 * Full-text search - make sure that exact search won't work across fields.
419 */
420 public function testSearchExactTermMultiFieldsKo()
421 {
422 $this->assertEquals(
423 0,
424 count(self::$linkFilter->filter(
425 BookmarkFilter::$FILTER_TEXT,
426 '"designer naming"'
427 ))
428 );
429
430 $this->assertEquals(
431 0,
432 count(self::$linkFilter->filter(
433 BookmarkFilter::$FILTER_TEXT,
434 '"designernaming"'
435 ))
436 );
437 }
438
439 /**
440 * Tag search with exclusion.
441 */
442 public function testTagFilterWithExclusion()
443 {
444 $this->assertEquals(
445 1,
446 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, 'gnu -free'))
447 );
448
449 $this->assertEquals(
450 ReferenceLinkDB::$NB_LINKS_TOTAL - 1,
451 count(self::$linkFilter->filter(BookmarkFilter::$FILTER_TAG, '-free'))
452 );
453 }
454
455 /**
456 * Test crossed search (terms + tags).
457 */
458 public function testFilterCrossedSearch()
459 {
460 $terms = '"Free Software " stallman "read this" @website stuff';
461 $tags = 'free';
462 $this->assertEquals(
463 1,
464 count(self::$linkFilter->filter(
465 BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT,
466 array($tags, $terms)
467 ))
468 );
469 $this->assertEquals(
470 2,
471 count(self::$linkFilter->filter(
472 BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT,
473 array('', $terms)
474 ))
475 );
476 $this->assertEquals(
477 1,
478 count(self::$linkFilter->filter(
479 BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT,
480 array(false, 'PSR-2')
481 ))
482 );
483 $this->assertEquals(
484 1,
485 count(self::$linkFilter->filter(
486 BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT,
487 array($tags, '')
488 ))
489 );
490 $this->assertEquals(
491 ReferenceLinkDB::$NB_LINKS_TOTAL,
492 count(self::$linkFilter->filter(
493 BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT,
494 ''
495 ))
496 );
497 }
498
499 /**
500 * Filter bookmarks by #hashtag.
501 */
502 public function testFilterByHashtag()
503 {
504 $hashtag = 'hashtag';
505 $this->assertEquals(
506 3,
507 count(self::$linkFilter->filter(
508 BookmarkFilter::$FILTER_TAG,
509 $hashtag
510 ))
511 );
512
513 $hashtag = 'private';
514 $this->assertEquals(
515 1,
516 count(self::$linkFilter->filter(
517 BookmarkFilter::$FILTER_TAG,
518 $hashtag,
519 false,
520 'private'
521 ))
522 );
523 }
524 }