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