]> git.immae.eu Git - github/shaarli/Shaarli.git/blob - tests/LinkDBTest.php
Support text search across link fields.
[github/shaarli/Shaarli.git] / tests / LinkDBTest.php
1 <?php
2 /**
3 * Link datastore tests
4 */
5
6 require_once 'application/Cache.php';
7 require_once 'application/FileUtils.php';
8 require_once 'application/LinkDB.php';
9 require_once 'application/Utils.php';
10 require_once 'tests/utils/ReferenceLinkDB.php';
11
12
13 /**
14 * Unitary tests for LinkDB
15 */
16 class LinkDBTest extends PHPUnit_Framework_TestCase
17 {
18 // datastore to test write operations
19 protected static $testDatastore = 'sandbox/datastore.php';
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();
39 self::$refDB->write(self::$testDatastore);
40
41 self::$publicLinkDB = new LinkDB(self::$testDatastore, false, false);
42 self::$privateLinkDB = new LinkDB(self::$testDatastore, true, false);
43 }
44
45 /**
46 * Resets test data for each test
47 */
48 protected function setUp()
49 {
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 {
75 new LinkDB(self::$testDatastore, true, false);
76 $this->assertFileExists(self::$testDatastore);
77 }
78
79 /**
80 * Instantiate LinkDB objects - logged out or public instance
81 */
82 public function testConstructLoggedOut()
83 {
84 new LinkDB(self::$testDatastore, false, false);
85 $this->assertFileExists(self::$testDatastore);
86 }
87
88 /**
89 * Attempt to instantiate a LinkDB whereas the datastore is not writable
90 *
91 * @expectedException IOException
92 * @expectedExceptionMessageRegExp /Error accessing null/
93 */
94 public function testConstructDatastoreNotWriteable()
95 {
96 new LinkDB('null/store.db', false, false);
97 }
98
99 /**
100 * The DB doesn't exist, ensure it is created with dummy content
101 */
102 public function testCheckDBNew()
103 {
104 $linkDB = new LinkDB(self::$testDatastore, false, false);
105 unlink(self::$testDatastore);
106 $this->assertFileNotExists(self::$testDatastore);
107
108 $checkDB = self::getMethod('_checkDB');
109 $checkDB->invokeArgs($linkDB, array());
110 $this->assertFileExists(self::$testDatastore);
111
112 // ensure the correct data has been written
113 $this->assertGreaterThan(0, filesize(self::$testDatastore));
114 }
115
116 /**
117 * The DB exists, don't do anything
118 */
119 public function testCheckDBLoad()
120 {
121 $linkDB = new LinkDB(self::$testDatastore, false, false);
122 $datastoreSize = filesize(self::$testDatastore);
123 $this->assertGreaterThan(0, $datastoreSize);
124
125 $checkDB = self::getMethod('_checkDB');
126 $checkDB->invokeArgs($linkDB, array());
127
128 // ensure the datastore is left unmodified
129 $this->assertEquals(
130 $datastoreSize,
131 filesize(self::$testDatastore)
132 );
133 }
134
135 /**
136 * Load an empty DB
137 */
138 public function testReadEmptyDB()
139 {
140 file_put_contents(self::$testDatastore, '<?php /* S7QysKquBQA= */ ?>');
141 $emptyDB = new LinkDB(self::$testDatastore, false, false);
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 {
173 $testDB = new LinkDB(self::$testDatastore, true, false);
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;
185 $testDB->savedb('tests');
186
187 $testDB = new LinkDB(self::$testDatastore, true, false);
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
206 /**
207 * Count existing links - public links hidden
208 */
209 public function testCountHiddenPublic()
210 {
211 $linkDB = new LinkDB(self::$testDatastore, false, true);
212
213 $this->assertEquals(
214 0,
215 $linkDB->count()
216 );
217 $this->assertEquals(
218 0,
219 $linkDB->count()
220 );
221 }
222
223 /**
224 * List the days for which links have been posted
225 */
226 public function testDays()
227 {
228 $this->assertEquals(
229 array('20121206', '20130614', '20150310'),
230 self::$publicLinkDB->days()
231 );
232
233 $this->assertEquals(
234 array('20121206', '20130614', '20141125', '20150310'),
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(
270 array(
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,
280 '-exclude' => 1,
281 'stuff' => 2,
282 ),
283 self::$publicLinkDB->allTags()
284 );
285
286 $this->assertEquals(
287 array(
288 'web' => 4,
289 'cartoon' => 3,
290 'gnu' => 2,
291 'dev' => 2,
292 'samba' => 1,
293 'media' => 1,
294 'software' => 1,
295 'stallman' => 1,
296 'free' => 1,
297 'html' => 1,
298 'w3c' => 1,
299 'css' => 1,
300 'Mercurial' => 1,
301 'stuff' => 2,
302 '-exclude' => 1,
303 '.hidden' => 1,
304 ),
305 self::$privateLinkDB->allTags()
306 );
307 }
308
309 /**
310 * Test real_url without redirector.
311 */
312 public function testLinkRealUrlWithoutRedirector()
313 {
314 $db = new LinkDB(self::$testDatastore, false, false);
315 foreach($db as $link) {
316 $this->assertEquals($link['url'], $link['real_url']);
317 }
318 }
319
320 /**
321 * Test real_url with redirector.
322 */
323 public function testLinkRealUrlWithRedirector()
324 {
325 $redirector = 'http://redirector.to?';
326 $db = new LinkDB(self::$testDatastore, false, false, $redirector);
327 foreach($db as $link) {
328 $this->assertStringStartsWith($redirector, $link['real_url']);
329 }
330 }
331
332 /**
333 * Test filter with string.
334 */
335 public function testFilterString()
336 {
337 $tags = 'dev cartoon';
338 $this->assertEquals(
339 2,
340 count(self::$privateLinkDB->filter(LinkFilter::$FILTER_TAG, $tags, true, false))
341 );
342 }
343
344 /**
345 * Test filter with string.
346 */
347 public function testFilterArray()
348 {
349 $tags = array('dev', 'cartoon');
350 $this->assertEquals(
351 2,
352 count(self::$privateLinkDB->filter(LinkFilter::$FILTER_TAG, $tags, true, false))
353 );
354 }
355
356 /**
357 * Test hidden tags feature:
358 * tags starting with a dot '.' are only visible when logged in.
359 */
360 public function testHiddenTags()
361 {
362 $tags = '.hidden';
363 $this->assertEquals(
364 1,
365 count(self::$privateLinkDB->filter(LinkFilter::$FILTER_TAG, $tags, true, false))
366 );
367
368 $this->assertEquals(
369 0,
370 count(self::$publicLinkDB->filter(LinkFilter::$FILTER_TAG, $tags, true, false))
371 );
372 }
373 }