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