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