]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - tests/NetscapeBookmarkUtils/BookmarkImportTest.php
Unit Test for the new ID system
[github/shaarli/Shaarli.git] / tests / NetscapeBookmarkUtils / BookmarkImportTest.php
CommitLineData
a973afea
V
1<?php
2
3require_once 'application/NetscapeBookmarkUtils.php';
4
5
6/**
7 * Utility function to load a file's metadata in a $_FILES-like array
8 *
9 * @param string $filename Basename of the file
10 *
11 * @return array A $_FILES-like array
12 */
13function file2array($filename)
14{
15 return array(
16 'filetoupload' => array(
17 'name' => $filename,
18 'tmp_name' => __DIR__ . '/input/' . $filename,
19 'size' => filesize(__DIR__ . '/input/' . $filename)
20 )
21 );
22}
23
24
25/**
26 * Netscape bookmark import
27 */
28class BookmarkImportTest extends PHPUnit_Framework_TestCase
29{
30 /**
31 * @var string datastore to test write operations
32 */
33 protected static $testDatastore = 'sandbox/datastore.php';
34
35 /**
36 * @var LinkDB private LinkDB instance
37 */
38 protected $linkDb = null;
39
40 /**
41 * @var string Dummy page cache
42 */
43 protected $pagecache = 'tests';
44
c3dfd899
A
45 /**
46 * @var string Save the current timezone.
47 */
48 protected static $defaultTimeZone;
49
50 public static function setUpBeforeClass()
51 {
52 self::$defaultTimeZone = date_default_timezone_get();
53 // Timezone without DST for test consistency
54 date_default_timezone_set('Africa/Nairobi');
55 }
56
a973afea
V
57 /**
58 * Resets test data before each test
59 */
60 protected function setUp()
61 {
62 if (file_exists(self::$testDatastore)) {
63 unlink(self::$testDatastore);
64 }
65 // start with an empty datastore
66 file_put_contents(self::$testDatastore, '<?php /* S7QysKquBQA= */ ?>');
67 $this->linkDb = new LinkDB(self::$testDatastore, true, false);
68 }
69
c3dfd899
A
70 public static function tearDownAfterClass()
71 {
72 date_default_timezone_set(self::$defaultTimeZone);
73 }
74
a973afea
V
75 /**
76 * Attempt to import bookmarks from an empty file
77 */
78 public function testImportEmptyData()
79 {
80 $files = file2array('empty.htm');
81 $this->assertEquals(
82 'File empty.htm (0 bytes) has an unknown file format.'
83 .' Nothing was imported.',
84 NetscapeBookmarkUtils::import(NULL, $files, NULL, NULL)
85 );
86 $this->assertEquals(0, count($this->linkDb));
87 }
88
89 /**
90 * Attempt to import bookmarks from a file with no Doctype
91 */
92 public function testImportNoDoctype()
93 {
94 $files = file2array('no_doctype.htm');
95 $this->assertEquals(
96 'File no_doctype.htm (350 bytes) has an unknown file format. Nothing was imported.',
97 NetscapeBookmarkUtils::import(NULL, $files, NULL, NULL)
98 );
99 $this->assertEquals(0, count($this->linkDb));
100 }
101
f4ad7bde
V
102 /**
103 * Ensure IE dumps are supported
104 */
105 public function testImportInternetExplorerEncoding()
106 {
107 $files = file2array('internet_explorer_encoding.htm');
108 $this->assertEquals(
109 'File internet_explorer_encoding.htm (356 bytes) was successfully processed:'
110 .' 1 links imported, 0 links overwritten, 0 links skipped.',
111 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->pagecache)
112 );
113 $this->assertEquals(1, count($this->linkDb));
114 $this->assertEquals(0, count_private($this->linkDb));
115
116 $this->assertEquals(
117 array(
c3dfd899
A
118 'id' => 0,
119 'created' => DateTime::createFromFormat('Ymd_His', '20160618_203944'),
f4ad7bde
V
120 'title' => 'Hg Init a Mercurial tutorial by Joel Spolsky',
121 'url' => 'http://hginit.com/',
122 'description' => '',
123 'private' => 0,
c3dfd899
A
124 'tags' => '',
125 'shorturl' => 'La37cg',
f4ad7bde
V
126 ),
127 $this->linkDb->getLinkFromUrl('http://hginit.com/')
128 );
129 }
130
a973afea
V
131 /**
132 * Import bookmarks nested in a folder hierarchy
133 */
134 public function testImportNested()
135 {
136 $files = file2array('netscape_nested.htm');
137 $this->assertEquals(
138 'File netscape_nested.htm (1337 bytes) was successfully processed:'
139 .' 8 links imported, 0 links overwritten, 0 links skipped.',
140 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->pagecache)
141 );
142 $this->assertEquals(8, count($this->linkDb));
143 $this->assertEquals(2, count_private($this->linkDb));
144
145 $this->assertEquals(
146 array(
c3dfd899
A
147 'id' => 0,
148 'created' => DateTime::createFromFormat('Ymd_His', '20160225_235541'),
a973afea
V
149 'title' => 'Nested 1',
150 'url' => 'http://nest.ed/1',
151 'description' => '',
152 'private' => 0,
c3dfd899
A
153 'tags' => 'tag1 tag2',
154 'shorturl' => 'KyDNKA',
a973afea
V
155 ),
156 $this->linkDb->getLinkFromUrl('http://nest.ed/1')
157 );
158 $this->assertEquals(
159 array(
c3dfd899
A
160 'id' => 1,
161 'created' => DateTime::createFromFormat('Ymd_His', '20160225_235542'),
a973afea
V
162 'title' => 'Nested 1-1',
163 'url' => 'http://nest.ed/1-1',
164 'description' => '',
165 'private' => 0,
c3dfd899
A
166 'tags' => 'folder1 tag1 tag2',
167 'shorturl' => 'T2LnXg',
a973afea
V
168 ),
169 $this->linkDb->getLinkFromUrl('http://nest.ed/1-1')
170 );
171 $this->assertEquals(
172 array(
c3dfd899
A
173 'id' => 2,
174 'created' => DateTime::createFromFormat('Ymd_His', '20160225_235547'),
a973afea
V
175 'title' => 'Nested 1-2',
176 'url' => 'http://nest.ed/1-2',
177 'description' => '',
178 'private' => 0,
c3dfd899
A
179 'tags' => 'folder1 tag3 tag4',
180 'shorturl' => '46SZxA',
a973afea
V
181 ),
182 $this->linkDb->getLinkFromUrl('http://nest.ed/1-2')
183 );
184 $this->assertEquals(
185 array(
c3dfd899
A
186 'id' => 3,
187 'created' => DateTime::createFromFormat('Ymd_His', '20160202_202222'),
a973afea
V
188 'title' => 'Nested 2-1',
189 'url' => 'http://nest.ed/2-1',
190 'description' => 'First link of the second section',
191 'private' => 1,
c3dfd899
A
192 'tags' => 'folder2',
193 'shorturl' => '4UHOSw',
a973afea
V
194 ),
195 $this->linkDb->getLinkFromUrl('http://nest.ed/2-1')
196 );
197 $this->assertEquals(
198 array(
c3dfd899
A
199 'id' => 4,
200 'created' => DateTime::createFromFormat('Ymd_His', '20160119_230227'),
a973afea
V
201 'title' => 'Nested 2-2',
202 'url' => 'http://nest.ed/2-2',
203 'description' => 'Second link of the second section',
204 'private' => 1,
c3dfd899
A
205 'tags' => 'folder2',
206 'shorturl' => 'yfzwbw',
a973afea
V
207 ),
208 $this->linkDb->getLinkFromUrl('http://nest.ed/2-2')
209 );
210 $this->assertEquals(
211 array(
c3dfd899
A
212 'id' => 5,
213 'created' => DateTime::createFromFormat('Ymd_His', '20160202_202222'),
a973afea
V
214 'title' => 'Nested 3-1',
215 'url' => 'http://nest.ed/3-1',
216 'description' => '',
217 'private' => 0,
c3dfd899
A
218 'tags' => 'folder3 folder3-1 tag3',
219 'shorturl' => 'UwxIUQ',
a973afea
V
220 ),
221 $this->linkDb->getLinkFromUrl('http://nest.ed/3-1')
222 );
223 $this->assertEquals(
224 array(
c3dfd899
A
225 'id' => 6,
226 'created' => DateTime::createFromFormat('Ymd_His', '20160119_230227'),
a973afea
V
227 'title' => 'Nested 3-2',
228 'url' => 'http://nest.ed/3-2',
229 'description' => '',
230 'private' => 0,
c3dfd899
A
231 'tags' => 'folder3 folder3-1',
232 'shorturl' => 'p8dyZg',
a973afea
V
233 ),
234 $this->linkDb->getLinkFromUrl('http://nest.ed/3-2')
235 );
236 $this->assertEquals(
237 array(
c3dfd899
A
238 'id' => 7,
239 'created' => DateTime::createFromFormat('Ymd_His', '20160229_111541'),
a973afea
V
240 'title' => 'Nested 2',
241 'url' => 'http://nest.ed/2',
242 'description' => '',
243 'private' => 0,
c3dfd899
A
244 'tags' => 'tag4',
245 'shorturl' => 'Gt3Uug',
a973afea
V
246 ),
247 $this->linkDb->getLinkFromUrl('http://nest.ed/2')
248 );
249 }
250
251 /**
252 * Import bookmarks with the default privacy setting (reuse from file)
253 *
254 * The $_POST array is not set.
255 */
256 public function testImportDefaultPrivacyNoPost()
257 {
258 $files = file2array('netscape_basic.htm');
259 $this->assertEquals(
260 'File netscape_basic.htm (482 bytes) was successfully processed:'
261 .' 2 links imported, 0 links overwritten, 0 links skipped.',
262 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->pagecache)
263 );
c3dfd899 264
a973afea
V
265 $this->assertEquals(2, count($this->linkDb));
266 $this->assertEquals(1, count_private($this->linkDb));
267
268 $this->assertEquals(
269 array(
c3dfd899
A
270 'id' => 0,
271 // Old link - UTC+4 (note that TZ in the import file is ignored).
272 'created' => DateTime::createFromFormat('Ymd_His', '20001010_135536'),
a973afea
V
273 'title' => 'Secret stuff',
274 'url' => 'https://private.tld',
275 'description' => "Super-secret stuff you're not supposed to know about",
276 'private' => 1,
c3dfd899
A
277 'tags' => 'private secret',
278 'shorturl' => 'EokDtA',
a973afea
V
279 ),
280 $this->linkDb->getLinkFromUrl('https://private.tld')
281 );
282 $this->assertEquals(
283 array(
c3dfd899
A
284 'id' => 1,
285 'created' => DateTime::createFromFormat('Ymd_His', '20160225_235548'),
a973afea
V
286 'title' => 'Public stuff',
287 'url' => 'http://public.tld',
288 'description' => '',
289 'private' => 0,
c3dfd899
A
290 'tags' => 'public hello world',
291 'shorturl' => 'Er9ddA',
a973afea
V
292 ),
293 $this->linkDb->getLinkFromUrl('http://public.tld')
294 );
295 }
296
297 /**
298 * Import bookmarks with the default privacy setting (reuse from file)
299 */
300 public function testImportKeepPrivacy()
301 {
302 $post = array('privacy' => 'default');
303 $files = file2array('netscape_basic.htm');
304 $this->assertEquals(
305 'File netscape_basic.htm (482 bytes) was successfully processed:'
306 .' 2 links imported, 0 links overwritten, 0 links skipped.',
307 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
308 );
309 $this->assertEquals(2, count($this->linkDb));
310 $this->assertEquals(1, count_private($this->linkDb));
311
312 $this->assertEquals(
313 array(
c3dfd899
A
314 'id' => 0,
315 // Note that TZ in the import file is ignored.
316 'created' => DateTime::createFromFormat('Ymd_His', '20001010_135536'),
a973afea
V
317 'title' => 'Secret stuff',
318 'url' => 'https://private.tld',
319 'description' => "Super-secret stuff you're not supposed to know about",
320 'private' => 1,
c3dfd899
A
321 'tags' => 'private secret',
322 'shorturl' => 'EokDtA',
a973afea
V
323 ),
324 $this->linkDb->getLinkFromUrl('https://private.tld')
325 );
326 $this->assertEquals(
327 array(
c3dfd899
A
328 'id' => 1,
329 'created' => DateTime::createFromFormat('Ymd_His', '20160225_235548'),
a973afea
V
330 'title' => 'Public stuff',
331 'url' => 'http://public.tld',
332 'description' => '',
333 'private' => 0,
c3dfd899
A
334 'tags' => 'public hello world',
335 'shorturl' => 'Er9ddA',
a973afea
V
336 ),
337 $this->linkDb->getLinkFromUrl('http://public.tld')
338 );
339 }
340
341 /**
342 * Import links as public
343 */
344 public function testImportAsPublic()
345 {
346 $post = array('privacy' => 'public');
347 $files = file2array('netscape_basic.htm');
348 $this->assertEquals(
349 'File netscape_basic.htm (482 bytes) was successfully processed:'
350 .' 2 links imported, 0 links overwritten, 0 links skipped.',
351 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
352 );
353 $this->assertEquals(2, count($this->linkDb));
354 $this->assertEquals(0, count_private($this->linkDb));
355 $this->assertEquals(
356 0,
c3dfd899 357 $this->linkDb[0]['private']
a973afea
V
358 );
359 $this->assertEquals(
360 0,
c3dfd899 361 $this->linkDb[1]['private']
a973afea
V
362 );
363 }
364
365 /**
366 * Import links as private
367 */
368 public function testImportAsPrivate()
369 {
370 $post = array('privacy' => 'private');
371 $files = file2array('netscape_basic.htm');
372 $this->assertEquals(
373 'File netscape_basic.htm (482 bytes) was successfully processed:'
374 .' 2 links imported, 0 links overwritten, 0 links skipped.',
375 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
376 );
377 $this->assertEquals(2, count($this->linkDb));
378 $this->assertEquals(2, count_private($this->linkDb));
379 $this->assertEquals(
380 1,
c3dfd899 381 $this->linkDb['0']['private']
a973afea
V
382 );
383 $this->assertEquals(
384 1,
c3dfd899 385 $this->linkDb['1']['private']
a973afea
V
386 );
387 }
388
389 /**
390 * Overwrite private links so they become public
391 */
392 public function testOverwriteAsPublic()
393 {
394 $files = file2array('netscape_basic.htm');
395
396 // import links as private
397 $post = array('privacy' => 'private');
398 $this->assertEquals(
399 'File netscape_basic.htm (482 bytes) was successfully processed:'
400 .' 2 links imported, 0 links overwritten, 0 links skipped.',
401 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
402 );
403 $this->assertEquals(2, count($this->linkDb));
404 $this->assertEquals(2, count_private($this->linkDb));
405 $this->assertEquals(
406 1,
c3dfd899 407 $this->linkDb[0]['private']
a973afea
V
408 );
409 $this->assertEquals(
410 1,
c3dfd899 411 $this->linkDb[1]['private']
a973afea 412 );
a973afea
V
413 // re-import as public, enable overwriting
414 $post = array(
415 'privacy' => 'public',
416 'overwrite' => 'true'
417 );
418 $this->assertEquals(
419 'File netscape_basic.htm (482 bytes) was successfully processed:'
420 .' 2 links imported, 2 links overwritten, 0 links skipped.',
421 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
422 );
423 $this->assertEquals(2, count($this->linkDb));
424 $this->assertEquals(0, count_private($this->linkDb));
425 $this->assertEquals(
426 0,
c3dfd899 427 $this->linkDb[0]['private']
a973afea
V
428 );
429 $this->assertEquals(
430 0,
c3dfd899 431 $this->linkDb[1]['private']
a973afea
V
432 );
433 }
434
435 /**
436 * Overwrite public links so they become private
437 */
438 public function testOverwriteAsPrivate()
439 {
440 $files = file2array('netscape_basic.htm');
441
442 // import links as public
443 $post = array('privacy' => 'public');
444 $this->assertEquals(
445 'File netscape_basic.htm (482 bytes) was successfully processed:'
446 .' 2 links imported, 0 links overwritten, 0 links skipped.',
447 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
448 );
449 $this->assertEquals(2, count($this->linkDb));
450 $this->assertEquals(0, count_private($this->linkDb));
451 $this->assertEquals(
452 0,
c3dfd899 453 $this->linkDb['0']['private']
a973afea
V
454 );
455 $this->assertEquals(
456 0,
c3dfd899 457 $this->linkDb['1']['private']
a973afea
V
458 );
459
460 // re-import as private, enable overwriting
461 $post = array(
462 'privacy' => 'private',
463 'overwrite' => 'true'
464 );
465 $this->assertEquals(
466 'File netscape_basic.htm (482 bytes) was successfully processed:'
467 .' 2 links imported, 2 links overwritten, 0 links skipped.',
468 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
469 );
470 $this->assertEquals(2, count($this->linkDb));
471 $this->assertEquals(2, count_private($this->linkDb));
472 $this->assertEquals(
473 1,
c3dfd899 474 $this->linkDb['0']['private']
a973afea
V
475 );
476 $this->assertEquals(
477 1,
c3dfd899 478 $this->linkDb['1']['private']
a973afea
V
479 );
480 }
481
482 /**
483 * Attept to import the same links twice without enabling overwriting
484 */
485 public function testSkipOverwrite()
486 {
487 $post = array('privacy' => 'public');
488 $files = file2array('netscape_basic.htm');
489 $this->assertEquals(
490 'File netscape_basic.htm (482 bytes) was successfully processed:'
491 .' 2 links imported, 0 links overwritten, 0 links skipped.',
492 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
493 );
494 $this->assertEquals(2, count($this->linkDb));
495 $this->assertEquals(0, count_private($this->linkDb));
496
497 // re-import as private, DO NOT enable overwriting
498 $post = array('privacy' => 'private');
499 $this->assertEquals(
500 'File netscape_basic.htm (482 bytes) was successfully processed:'
501 .' 0 links imported, 0 links overwritten, 2 links skipped.',
502 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
503 );
504 $this->assertEquals(2, count($this->linkDb));
505 $this->assertEquals(0, count_private($this->linkDb));
506 }
507
508 /**
509 * Add user-specified tags to all imported bookmarks
510 */
511 public function testSetDefaultTags()
512 {
513 $post = array(
514 'privacy' => 'public',
515 'default_tags' => 'tag1,tag2 tag3'
516 );
517 $files = file2array('netscape_basic.htm');
518 $this->assertEquals(
519 'File netscape_basic.htm (482 bytes) was successfully processed:'
520 .' 2 links imported, 0 links overwritten, 0 links skipped.',
521 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
522 );
523 $this->assertEquals(2, count($this->linkDb));
524 $this->assertEquals(0, count_private($this->linkDb));
525 $this->assertEquals(
526 'tag1 tag2 tag3 private secret',
c3dfd899 527 $this->linkDb['0']['tags']
a973afea
V
528 );
529 $this->assertEquals(
530 'tag1 tag2 tag3 public hello world',
c3dfd899 531 $this->linkDb['1']['tags']
a973afea
V
532 );
533 }
534
535 /**
536 * The user-specified tags contain characters to be escaped
537 */
538 public function testSanitizeDefaultTags()
539 {
540 $post = array(
541 'privacy' => 'public',
542 'default_tags' => 'tag1&,tag2 "tag3"'
543 );
544 $files = file2array('netscape_basic.htm');
545 $this->assertEquals(
546 'File netscape_basic.htm (482 bytes) was successfully processed:'
547 .' 2 links imported, 0 links overwritten, 0 links skipped.',
548 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
549 );
550 $this->assertEquals(2, count($this->linkDb));
551 $this->assertEquals(0, count_private($this->linkDb));
552 $this->assertEquals(
553 'tag1&amp; tag2 &quot;tag3&quot; private secret',
c3dfd899 554 $this->linkDb['0']['tags']
a973afea
V
555 );
556 $this->assertEquals(
557 'tag1&amp; tag2 &quot;tag3&quot; public hello world',
c3dfd899 558 $this->linkDb['1']['tags']
a973afea
V
559 );
560 }
561
562 /**
c3dfd899 563 * Ensure each imported bookmark has a unique id
a973afea
V
564 *
565 * See https://github.com/shaarli/Shaarli/issues/351
566 */
567 public function testImportSameDate()
568 {
569 $files = file2array('same_date.htm');
570 $this->assertEquals(
571 'File same_date.htm (453 bytes) was successfully processed:'
572 .' 3 links imported, 0 links overwritten, 0 links skipped.',
573 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->pagecache)
574 );
575 $this->assertEquals(3, count($this->linkDb));
576 $this->assertEquals(0, count_private($this->linkDb));
577 $this->assertEquals(
c3dfd899
A
578 0,
579 $this->linkDb[0]['id']
a973afea
V
580 );
581 $this->assertEquals(
c3dfd899
A
582 1,
583 $this->linkDb[1]['id']
a973afea
V
584 );
585 $this->assertEquals(
c3dfd899
A
586 2,
587 $this->linkDb[2]['id']
a973afea
V
588 );
589 }
590}