]> git.immae.eu Git - github/shaarli/Shaarli.git/blob - tests/LinkDBTest.php
Merge remote-tracking branch 'ArthurHoaro/default-links'
[github/shaarli/Shaarli.git] / tests / LinkDBTest.php
1 <?php
2 /**
3 * Link datastore tests
4 */
5
6 require_once 'application/LinkDB.php';
7 require_once 'application/Utils.php';
8 require_once 'tests/utils/ReferenceLinkDB.php';
9
10
11 /**
12 * Unitary tests for LinkDB
13 */
14 class LinkDBTest extends PHPUnit_Framework_TestCase
15 {
16 // datastore to test write operations
17 protected static $testDatastore = 'tests/datastore.php';
18 protected static $dummyDatastoreFilesize = 759;
19 protected static $refDB = null;
20 protected static $publicLinkDB = null;
21 protected static $privateLinkDB = null;
22
23 /**
24 * Instantiates public and private LinkDBs with test data
25 *
26 * The reference datastore contains public and private links that
27 * will be used to test LinkDB's methods:
28 * - access filtering (public/private),
29 * - link searches:
30 * - by day,
31 * - by tag,
32 * - by text,
33 * - etc.
34 */
35 public static function setUpBeforeClass()
36 {
37 self::$refDB = new ReferenceLinkDB();
38 self::$refDB->write(self::$testDatastore);
39
40 self::$publicLinkDB = new LinkDB(self::$testDatastore, false, false);
41 self::$privateLinkDB = new LinkDB(self::$testDatastore, true, false);
42 }
43
44 /**
45 * Resets test data for each test
46 */
47 protected function setUp()
48 {
49 if (file_exists(self::$testDatastore)) {
50 unlink(self::$testDatastore);
51 }
52 }
53
54 /**
55 * Allows to test LinkDB's private methods
56 *
57 * @see
58 * https://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html
59 * http://stackoverflow.com/a/2798203
60 */
61 protected static function getMethod($name)
62 {
63 $class = new ReflectionClass('LinkDB');
64 $method = $class->getMethod($name);
65 $method->setAccessible(true);
66 return $method;
67 }
68
69 /**
70 * Instantiate LinkDB objects - logged in user
71 */
72 public function testConstructLoggedIn()
73 {
74 new LinkDB(self::$testDatastore, true, false);
75 $this->assertFileExists(self::$testDatastore);
76 }
77
78 /**
79 * Instantiate LinkDB objects - logged out or public instance
80 */
81 public function testConstructLoggedOut()
82 {
83 new LinkDB(self::$testDatastore, false, false);
84 $this->assertFileExists(self::$testDatastore);
85 }
86
87 /**
88 * Attempt to instantiate a LinkDB whereas the datastore is not writable
89 *
90 * @expectedException PHPUnit_Framework_Error_Warning
91 * @expectedExceptionMessageRegExp /failed to open stream: No such file or directory/
92 */
93 public function testConstructDatastoreNotWriteable()
94 {
95 new LinkDB('null/store.db', false, false);
96 }
97
98 /**
99 * The DB doesn't exist, ensure it is created with dummy content
100 */
101 public function testCheckDBNew()
102 {
103 $linkDB = new LinkDB(self::$testDatastore, false, false);
104 unlink(self::$testDatastore);
105 $this->assertFileNotExists(self::$testDatastore);
106
107 $checkDB = self::getMethod('checkDB');
108 $checkDB->invokeArgs($linkDB, array());
109 $this->assertFileExists(self::$testDatastore);
110
111 // ensure the correct data has been written
112 $this->assertEquals(
113 self::$dummyDatastoreFilesize,
114 filesize(self::$testDatastore)
115 );
116 }
117
118 /**
119 * The DB exists, don't do anything
120 */
121 public function testCheckDBLoad()
122 {
123 $linkDB = new LinkDB(self::$testDatastore, false, false);
124 $this->assertEquals(
125 self::$dummyDatastoreFilesize,
126 filesize(self::$testDatastore)
127 );
128
129 $checkDB = self::getMethod('checkDB');
130 $checkDB->invokeArgs($linkDB, array());
131
132 // ensure the datastore is left unmodified
133 $this->assertEquals(
134 self::$dummyDatastoreFilesize,
135 filesize(self::$testDatastore)
136 );
137 }
138
139 /**
140 * Load an empty DB
141 */
142 public function testReadEmptyDB()
143 {
144 file_put_contents(self::$testDatastore, '<?php /* S7QysKquBQA= */ ?>');
145 $emptyDB = new LinkDB(self::$testDatastore, false, false);
146 $this->assertEquals(0, sizeof($emptyDB));
147 $this->assertEquals(0, count($emptyDB));
148 }
149
150 /**
151 * Load public links from the DB
152 */
153 public function testReadPublicDB()
154 {
155 $this->assertEquals(
156 self::$refDB->countPublicLinks(),
157 sizeof(self::$publicLinkDB)
158 );
159 }
160
161 /**
162 * Load public and private links from the DB
163 */
164 public function testReadPrivateDB()
165 {
166 $this->assertEquals(
167 self::$refDB->countLinks(),
168 sizeof(self::$privateLinkDB)
169 );
170 }
171
172 /**
173 * Save the links to the DB
174 */
175 public function testSaveDB()
176 {
177 $testDB = new LinkDB(self::$testDatastore, true, false);
178 $dbSize = sizeof($testDB);
179
180 $link = array(
181 'title'=>'an additional link',
182 'url'=>'http://dum.my',
183 'description'=>'One more',
184 'private'=>0,
185 'linkdate'=>'20150518_190000',
186 'tags'=>'unit test'
187 );
188 $testDB[$link['linkdate']] = $link;
189
190 // TODO: move PageCache to a proper class/file
191 function invalidateCaches() {}
192
193 $testDB->savedb();
194
195 $testDB = new LinkDB(self::$testDatastore, true, false);
196 $this->assertEquals($dbSize + 1, sizeof($testDB));
197 }
198
199 /**
200 * Count existing links
201 */
202 public function testCount()
203 {
204 $this->assertEquals(
205 self::$refDB->countPublicLinks(),
206 self::$publicLinkDB->count()
207 );
208 $this->assertEquals(
209 self::$refDB->countLinks(),
210 self::$privateLinkDB->count()
211 );
212 }
213
214 /**
215 * Count existing links - public links hidden
216 */
217 public function testCountHiddenPublic()
218 {
219 $linkDB = new LinkDB(self::$testDatastore, false, true);
220
221 $this->assertEquals(
222 0,
223 $linkDB->count()
224 );
225 $this->assertEquals(
226 0,
227 $linkDB->count()
228 );
229 }
230
231 /**
232 * List the days for which links have been posted
233 */
234 public function testDays()
235 {
236 $this->assertEquals(
237 ['20121206', '20130614', '20150310'],
238 self::$publicLinkDB->days()
239 );
240
241 $this->assertEquals(
242 ['20121206', '20130614', '20141125', '20150310'],
243 self::$privateLinkDB->days()
244 );
245 }
246
247 /**
248 * The URL corresponds to an existing entry in the DB
249 */
250 public function testGetKnownLinkFromURL()
251 {
252 $link = self::$publicLinkDB->getLinkFromUrl('http://mediagoblin.org/');
253
254 $this->assertNotEquals(false, $link);
255 $this->assertEquals(
256 'A free software media publishing platform',
257 $link['description']
258 );
259 }
260
261 /**
262 * The URL is not in the DB
263 */
264 public function testGetUnknownLinkFromURL()
265 {
266 $this->assertEquals(
267 false,
268 self::$publicLinkDB->getLinkFromUrl('http://dev.null')
269 );
270 }
271
272 /**
273 * Lists all tags
274 */
275 public function testAllTags()
276 {
277 $this->assertEquals(
278 [
279 'web' => 3,
280 'cartoon' => 2,
281 'gnu' => 2,
282 'dev' => 1,
283 'samba' => 1,
284 'media' => 1,
285 'software' => 1,
286 'stallman' => 1,
287 'free' => 1
288 ],
289 self::$publicLinkDB->allTags()
290 );
291
292 $this->assertEquals(
293 [
294 'web' => 4,
295 'cartoon' => 3,
296 'gnu' => 2,
297 'dev' => 2,
298 'samba' => 1,
299 'media' => 1,
300 'software' => 1,
301 'stallman' => 1,
302 'free' => 1,
303 'html' => 1,
304 'w3c' => 1,
305 'css' => 1,
306 'Mercurial' => 1
307 ],
308 self::$privateLinkDB->allTags()
309 );
310 }
311
312 /**
313 * Filter links using a tag
314 */
315 public function testFilterOneTag()
316 {
317 $this->assertEquals(
318 3,
319 sizeof(self::$publicLinkDB->filterTags('web', false))
320 );
321
322 $this->assertEquals(
323 4,
324 sizeof(self::$privateLinkDB->filterTags('web', false))
325 );
326 }
327
328 /**
329 * Filter links using a tag - case-sensitive
330 */
331 public function testFilterCaseSensitiveTag()
332 {
333 $this->assertEquals(
334 0,
335 sizeof(self::$privateLinkDB->filterTags('mercurial', true))
336 );
337
338 $this->assertEquals(
339 1,
340 sizeof(self::$privateLinkDB->filterTags('Mercurial', true))
341 );
342 }
343
344 /**
345 * Filter links using a tag combination
346 */
347 public function testFilterMultipleTags()
348 {
349 $this->assertEquals(
350 1,
351 sizeof(self::$publicLinkDB->filterTags('dev cartoon', false))
352 );
353
354 $this->assertEquals(
355 2,
356 sizeof(self::$privateLinkDB->filterTags('dev cartoon', false))
357 );
358 }
359
360 /**
361 * Filter links using a non-existent tag
362 */
363 public function testFilterUnknownTag()
364 {
365 $this->assertEquals(
366 0,
367 sizeof(self::$publicLinkDB->filterTags('null', false))
368 );
369 }
370
371 /**
372 * Return links for a given day
373 */
374 public function testFilterDay()
375 {
376 $this->assertEquals(
377 2,
378 sizeof(self::$publicLinkDB->filterDay('20121206'))
379 );
380
381 $this->assertEquals(
382 3,
383 sizeof(self::$privateLinkDB->filterDay('20121206'))
384 );
385 }
386
387 /**
388 * 404 - day not found
389 */
390 public function testFilterUnknownDay()
391 {
392 $this->assertEquals(
393 0,
394 sizeof(self::$publicLinkDB->filterDay('19700101'))
395 );
396
397 $this->assertEquals(
398 0,
399 sizeof(self::$privateLinkDB->filterDay('19700101'))
400 );
401 }
402
403 /**
404 * Use an invalid date format
405 */
406 public function testFilterInvalidDay()
407 {
408 $this->assertEquals(
409 0,
410 sizeof(self::$privateLinkDB->filterDay('Rainy day, dream away'))
411 );
412
413 // TODO: check input format
414 $this->assertEquals(
415 6,
416 sizeof(self::$privateLinkDB->filterDay('20'))
417 );
418 }
419
420 /**
421 * Retrieve a link entry with its hash
422 */
423 public function testFilterSmallHash()
424 {
425 $links = self::$privateLinkDB->filterSmallHash('IuWvgA');
426
427 $this->assertEquals(
428 1,
429 sizeof($links)
430 );
431
432 $this->assertEquals(
433 'MediaGoblin',
434 $links['20130614_184135']['title']
435 );
436
437 }
438
439 /**
440 * No link for this hash
441 */
442 public function testFilterUnknownSmallHash()
443 {
444 $this->assertEquals(
445 0,
446 sizeof(self::$privateLinkDB->filterSmallHash('Iblaah'))
447 );
448 }
449
450 /**
451 * Full-text search - result from a link's URL
452 */
453 public function testFilterFullTextURL()
454 {
455 $this->assertEquals(
456 2,
457 sizeof(self::$publicLinkDB->filterFullText('ars.userfriendly.org'))
458 );
459 }
460
461 /**
462 * Full-text search - result from a link's title only
463 */
464 public function testFilterFullTextTitle()
465 {
466 // use miscellaneous cases
467 $this->assertEquals(
468 2,
469 sizeof(self::$publicLinkDB->filterFullText('userfriendly -'))
470 );
471 $this->assertEquals(
472 2,
473 sizeof(self::$publicLinkDB->filterFullText('UserFriendly -'))
474 );
475 $this->assertEquals(
476 2,
477 sizeof(self::$publicLinkDB->filterFullText('uSeRFrIendlY -'))
478 );
479
480 // use miscellaneous case and offset
481 $this->assertEquals(
482 2,
483 sizeof(self::$publicLinkDB->filterFullText('RFrIendL'))
484 );
485 }
486
487 /**
488 * Full-text search - result from the link's description only
489 */
490 public function testFilterFullTextDescription()
491 {
492 $this->assertEquals(
493 1,
494 sizeof(self::$publicLinkDB->filterFullText('media publishing'))
495 );
496 }
497
498 /**
499 * Full-text search - result from the link's tags only
500 */
501 public function testFilterFullTextTags()
502 {
503 $this->assertEquals(
504 2,
505 sizeof(self::$publicLinkDB->filterFullText('gnu'))
506 );
507 }
508
509 /**
510 * Full-text search - result set from mixed sources
511 */
512 public function testFilterFullTextMixed()
513 {
514 $this->assertEquals(
515 2,
516 sizeof(self::$publicLinkDB->filterFullText('free software'))
517 );
518 }
519 }
520 ?>