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