]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - tests/bookmark/LinkFilterTest.php
namespacing: \Shaarli\Bookmark\LinkFilter
[github/shaarli/Shaarli.git] / tests / bookmark / LinkFilterTest.php
CommitLineData
822bffce
A
1<?php
2
6696729b 3namespace Shaarli\Bookmark;
f24896b2 4
6696729b
V
5use Exception;
6use ReferenceLinkDB;
822bffce
A
7
8/**
9 * Class LinkFilterTest.
10 */
6696729b 11class LinkFilterTest extends \PHPUnit\Framework\TestCase
822bffce 12{
9ec0a611
A
13 /**
14 * @var string Test datastore path.
15 */
16 protected static $testDatastore = 'sandbox/datastore.php';
822bffce
A
17 /**
18 * @var LinkFilter instance.
19 */
20 protected static $linkFilter;
21
7f96d9ec
A
22 /**
23 * @var ReferenceLinkDB instance
24 */
25 protected static $refDB;
26
9ec0a611
A
27 /**
28 * @var LinkDB instance
29 */
30 protected static $linkDB;
31
822bffce 32 /**
6696729b 33 * Instantiate linkFilter with ReferenceLinkDB data.
822bffce
A
34 */
35 public static function setUpBeforeClass()
36 {
7f96d9ec 37 self::$refDB = new ReferenceLinkDB();
9ec0a611
A
38 self::$refDB->write(self::$testDatastore);
39 self::$linkDB = new LinkDB(self::$testDatastore, true, false);
40 self::$linkFilter = new LinkFilter(self::$linkDB);
822bffce
A
41 }
42
43 /**
44 * Blank filter.
45 */
46 public function testFilter()
47 {
48 $this->assertEquals(
7f96d9ec 49 self::$refDB->countLinks(),
822bffce
A
50 count(self::$linkFilter->filter('', ''))
51 );
52
7f96d9ec
A
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
822bffce
A
63 // Private only.
64 $this->assertEquals(
7f96d9ec
A
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'))
822bffce 73 );
c51fae92
A
74
75 $this->assertEquals(
89baf23d 76 ReferenceLinkDB::$NB_LINKS_TOTAL,
c51fae92
A
77 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, ''))
78 );
79
7d86f40b
A
80 $this->assertEquals(
81 self::$refDB->countUntaggedLinks(),
9d9f6d75
V
82 count(
83 self::$linkFilter->filter(
84 LinkFilter::$FILTER_TAG,
6696729b
V
85 /*$request=*/
86 '',
87 /*$casesensitive=*/
88 false,
89 /*$visibility=*/
90 'all',
91 /*$untaggedonly=*/
92 true
9d9f6d75
V
93 )
94 )
7d86f40b
A
95 );
96
c51fae92 97 $this->assertEquals(
89baf23d 98 ReferenceLinkDB::$NB_LINKS_TOTAL,
c51fae92
A
99 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, ''))
100 );
822bffce
A
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
7f96d9ec
A
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
822bffce
A
123 // Private only.
124 $this->assertEquals(
125 1,
7f96d9ec
A
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'))
822bffce
A
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(
7d86f40b 180 4,
822bffce
A
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',
c3dfd899 230 $links[7]['title']
822bffce
A
231 );
232 }
233
234 /**
235 * No link for this hash
528a6f8a 236 *
6696729b 237 * @expectedException \Shaarli\Bookmark\Exception\LinkNotFoundException
822bffce
A
238 */
239 public function testFilterUnknownSmallHash()
240 {
528a6f8a 241 self::$linkFilter->filter(LinkFilter::$FILTER_HASH, 'Iblaah');
822bffce
A
242 }
243
522b278b
A
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
822bffce
A
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 );
9d9f6d75 264
ebd8075a
FV
265 $this->assertEquals(
266 2,
267 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'ars org'))
268 );
822bffce
A
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,
ebd8075a
FV
304 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'publishing media'))
305 );
9d9f6d75 306
ebd8075a
FV
307 $this->assertEquals(
308 1,
309 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'mercurial w3c'))
822bffce 310 );
9d9f6d75 311
ebd8075a 312 $this->assertEquals(
bedd176a 313 3,
ebd8075a 314 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '"free software"'))
067c2dd8 315 );
822bffce
A
316 }
317
318 /**
319 * Full-text search - result from the link's tags only
320 */
321 public function testFilterFullTextTags()
322 {
323 $this->assertEquals(
7f96d9ec
A
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'))
822bffce
A
336 );
337
338 // Private only.
339 $this->assertEquals(
340 1,
7f96d9ec
A
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'))
822bffce
A
348 );
349 }
350
351 /**
352 * Full-text search - result set from mixed sources
353 */
354 public function testFilterFullTextMixed()
355 {
356 $this->assertEquals(
bedd176a 357 3,
822bffce
A
358 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'free software'))
359 );
360 }
21979ff1 361
bedd176a
A
362 /**
363 * Full-text search - test exclusion with '-'.
364 */
365 public function testExcludeSearch()
366 {
367 $this->assertEquals(
368 1,
522b278b 369 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'free -gnu'))
bedd176a
A
370 );
371
372 $this->assertEquals(
7d86f40b 373 ReferenceLinkDB::$NB_LINKS_TOTAL - 1,
522b278b 374 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '-revolution'))
bedd176a
A
375 );
376 }
377
378 /**
522b278b 379 * Full-text search - test AND, exact terms and exclusion combined, across fields.
bedd176a
A
380 */
381 public function testMultiSearch()
382 {
383 $this->assertEquals(
384 2,
522b278b
A
385 count(self::$linkFilter->filter(
386 LinkFilter::$FILTER_TEXT,
387 '"Free Software " stallman "read this" @website stuff'
388 ))
bedd176a
A
389 );
390
391 $this->assertEquals(
392 1,
522b278b
A
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 ))
bedd176a
A
419 );
420 }
421
21979ff1
A
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(
7d86f40b 433 ReferenceLinkDB::$NB_LINKS_TOTAL - 1,
21979ff1
A
434 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, '-free'))
435 );
436 }
c51fae92
A
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(
7d86f40b
A
460 1,
461 count(self::$linkFilter->filter(
462 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
463 array(false, 'PSR-2')
464 ))
465 );
466 $this->assertEquals(
c51fae92
A
467 1,
468 count(self::$linkFilter->filter(
469 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
470 array($tags, '')
471 ))
472 );
473 $this->assertEquals(
89baf23d 474 ReferenceLinkDB::$NB_LINKS_TOTAL,
c51fae92
A
475 count(self::$linkFilter->filter(
476 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
477 ''
478 ))
479 );
480 }
9ccca401
A
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,
7f96d9ec 503 'private'
9ccca401
A
504 ))
505 );
506 }
822bffce 507}