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