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