From 349b0144011e25f2b1a727b1d28d49d55b3b2ebb Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Tue, 4 Dec 2018 00:13:42 +0100 Subject: namespacing: \Shaarli\Netscape\NetscapeBookmarkUtils Signed-off-by: VirtualTam --- tests/netscape/BookmarkImportTest.php | 657 ++++++++++++++++++++++++++++++++++ 1 file changed, 657 insertions(+) create mode 100644 tests/netscape/BookmarkImportTest.php (limited to 'tests/netscape/BookmarkImportTest.php') diff --git a/tests/netscape/BookmarkImportTest.php b/tests/netscape/BookmarkImportTest.php new file mode 100644 index 00000000..ccafc161 --- /dev/null +++ b/tests/netscape/BookmarkImportTest.php @@ -0,0 +1,657 @@ + array( + 'name' => $filename, + 'tmp_name' => __DIR__ . '/input/' . $filename, + 'size' => filesize(__DIR__ . '/input/' . $filename) + ) + ); +} + + +/** + * Netscape bookmark import + */ +class BookmarkImportTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var string datastore to test write operations + */ + protected static $testDatastore = 'sandbox/datastore.php'; + + /** + * @var string History file path + */ + protected static $historyFilePath = 'sandbox/history.php'; + + /** + * @var LinkDB private LinkDB instance + */ + protected $linkDb = null; + + /** + * @var string Dummy page cache + */ + protected $pagecache = 'tests'; + + /** + * @var ConfigManager instance. + */ + protected $conf; + + /** + * @var History instance. + */ + protected $history; + + /** + * @var string Save the current timezone. + */ + protected static $defaultTimeZone; + + public static function setUpBeforeClass() + { + self::$defaultTimeZone = date_default_timezone_get(); + // Timezone without DST for test consistency + date_default_timezone_set('Africa/Nairobi'); + } + + /** + * Resets test data before each test + */ + protected function setUp() + { + if (file_exists(self::$testDatastore)) { + unlink(self::$testDatastore); + } + // start with an empty datastore + file_put_contents(self::$testDatastore, ''); + $this->linkDb = new LinkDB(self::$testDatastore, true, false); + $this->conf = new ConfigManager('tests/utils/config/configJson'); + $this->conf->set('resource.page_cache', $this->pagecache); + $this->history = new History(self::$historyFilePath); + } + + /** + * Delete history file. + */ + public function tearDown() + { + @unlink(self::$historyFilePath); + } + + public static function tearDownAfterClass() + { + date_default_timezone_set(self::$defaultTimeZone); + } + + /** + * Attempt to import bookmarks from an empty file + */ + public function testImportEmptyData() + { + $files = file2array('empty.htm'); + $this->assertEquals( + 'File empty.htm (0 bytes) has an unknown file format.' + .' Nothing was imported.', + NetscapeBookmarkUtils::import(null, $files, null, $this->conf, $this->history) + ); + $this->assertEquals(0, count($this->linkDb)); + } + + /** + * Attempt to import bookmarks from a file with no Doctype + */ + public function testImportNoDoctype() + { + $files = file2array('no_doctype.htm'); + $this->assertEquals( + 'File no_doctype.htm (350 bytes) has an unknown file format. Nothing was imported.', + NetscapeBookmarkUtils::import(null, $files, null, $this->conf, $this->history) + ); + $this->assertEquals(0, count($this->linkDb)); + } + + /** + * Attempt to import bookmarks from a file with a lowercase Doctype + */ + public function testImportLowecaseDoctype() + { + $files = file2array('lowercase_doctype.htm'); + $this->assertStringMatchesFormat( + 'File lowercase_doctype.htm (386 bytes) was successfully processed in %d seconds:' + .' 2 links imported, 0 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import(null, $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(2, count($this->linkDb)); + } + + + /** + * Ensure IE dumps are supported + */ + public function testImportInternetExplorerEncoding() + { + $files = file2array('internet_explorer_encoding.htm'); + $this->assertStringMatchesFormat( + 'File internet_explorer_encoding.htm (356 bytes) was successfully processed in %d seconds:' + .' 1 links imported, 0 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(1, count($this->linkDb)); + $this->assertEquals(0, count_private($this->linkDb)); + + $this->assertEquals( + array( + 'id' => 0, + 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160618_203944'), + 'title' => 'Hg Init a Mercurial tutorial by Joel Spolsky', + 'url' => 'http://hginit.com/', + 'description' => '', + 'private' => 0, + 'tags' => '', + 'shorturl' => 'La37cg', + ), + $this->linkDb->getLinkFromUrl('http://hginit.com/') + ); + } + + /** + * Import bookmarks nested in a folder hierarchy + */ + public function testImportNested() + { + $files = file2array('netscape_nested.htm'); + $this->assertStringMatchesFormat( + 'File netscape_nested.htm (1337 bytes) was successfully processed in %d seconds:' + .' 8 links imported, 0 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(8, count($this->linkDb)); + $this->assertEquals(2, count_private($this->linkDb)); + + $this->assertEquals( + array( + 'id' => 0, + 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160225_235541'), + 'title' => 'Nested 1', + 'url' => 'http://nest.ed/1', + 'description' => '', + 'private' => 0, + 'tags' => 'tag1 tag2', + 'shorturl' => 'KyDNKA', + ), + $this->linkDb->getLinkFromUrl('http://nest.ed/1') + ); + $this->assertEquals( + array( + 'id' => 1, + 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160225_235542'), + 'title' => 'Nested 1-1', + 'url' => 'http://nest.ed/1-1', + 'description' => '', + 'private' => 0, + 'tags' => 'folder1 tag1 tag2', + 'shorturl' => 'T2LnXg', + ), + $this->linkDb->getLinkFromUrl('http://nest.ed/1-1') + ); + $this->assertEquals( + array( + 'id' => 2, + 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160225_235547'), + 'title' => 'Nested 1-2', + 'url' => 'http://nest.ed/1-2', + 'description' => '', + 'private' => 0, + 'tags' => 'folder1 tag3 tag4', + 'shorturl' => '46SZxA', + ), + $this->linkDb->getLinkFromUrl('http://nest.ed/1-2') + ); + $this->assertEquals( + array( + 'id' => 3, + 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160202_202222'), + 'title' => 'Nested 2-1', + 'url' => 'http://nest.ed/2-1', + 'description' => 'First link of the second section', + 'private' => 1, + 'tags' => 'folder2', + 'shorturl' => '4UHOSw', + ), + $this->linkDb->getLinkFromUrl('http://nest.ed/2-1') + ); + $this->assertEquals( + array( + 'id' => 4, + 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160119_230227'), + 'title' => 'Nested 2-2', + 'url' => 'http://nest.ed/2-2', + 'description' => 'Second link of the second section', + 'private' => 1, + 'tags' => 'folder2', + 'shorturl' => 'yfzwbw', + ), + $this->linkDb->getLinkFromUrl('http://nest.ed/2-2') + ); + $this->assertEquals( + array( + 'id' => 5, + 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160202_202222'), + 'title' => 'Nested 3-1', + 'url' => 'http://nest.ed/3-1', + 'description' => '', + 'private' => 0, + 'tags' => 'folder3 folder3-1 tag3', + 'shorturl' => 'UwxIUQ', + ), + $this->linkDb->getLinkFromUrl('http://nest.ed/3-1') + ); + $this->assertEquals( + array( + 'id' => 6, + 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160119_230227'), + 'title' => 'Nested 3-2', + 'url' => 'http://nest.ed/3-2', + 'description' => '', + 'private' => 0, + 'tags' => 'folder3 folder3-1', + 'shorturl' => 'p8dyZg', + ), + $this->linkDb->getLinkFromUrl('http://nest.ed/3-2') + ); + $this->assertEquals( + array( + 'id' => 7, + 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160229_111541'), + 'title' => 'Nested 2', + 'url' => 'http://nest.ed/2', + 'description' => '', + 'private' => 0, + 'tags' => 'tag4', + 'shorturl' => 'Gt3Uug', + ), + $this->linkDb->getLinkFromUrl('http://nest.ed/2') + ); + } + + /** + * Import bookmarks with the default privacy setting (reuse from file) + * + * The $_POST array is not set. + */ + public function testImportDefaultPrivacyNoPost() + { + $files = file2array('netscape_basic.htm'); + $this->assertStringMatchesFormat( + 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:' + .' 2 links imported, 0 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history) + ); + + $this->assertEquals(2, count($this->linkDb)); + $this->assertEquals(1, count_private($this->linkDb)); + + $this->assertEquals( + array( + 'id' => 0, + // Old link - UTC+4 (note that TZ in the import file is ignored). + 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20001010_135536'), + 'title' => 'Secret stuff', + 'url' => 'https://private.tld', + 'description' => "Super-secret stuff you're not supposed to know about", + 'private' => 1, + 'tags' => 'private secret', + 'shorturl' => 'EokDtA', + ), + $this->linkDb->getLinkFromUrl('https://private.tld') + ); + $this->assertEquals( + array( + 'id' => 1, + 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160225_235548'), + 'title' => 'Public stuff', + 'url' => 'http://public.tld', + 'description' => '', + 'private' => 0, + 'tags' => 'public hello world', + 'shorturl' => 'Er9ddA', + ), + $this->linkDb->getLinkFromUrl('http://public.tld') + ); + } + + /** + * Import bookmarks with the default privacy setting (reuse from file) + */ + public function testImportKeepPrivacy() + { + $post = array('privacy' => 'default'); + $files = file2array('netscape_basic.htm'); + $this->assertStringMatchesFormat( + 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:' + .' 2 links imported, 0 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(2, count($this->linkDb)); + $this->assertEquals(1, count_private($this->linkDb)); + + $this->assertEquals( + array( + 'id' => 0, + // Note that TZ in the import file is ignored. + 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20001010_135536'), + 'title' => 'Secret stuff', + 'url' => 'https://private.tld', + 'description' => "Super-secret stuff you're not supposed to know about", + 'private' => 1, + 'tags' => 'private secret', + 'shorturl' => 'EokDtA', + ), + $this->linkDb->getLinkFromUrl('https://private.tld') + ); + $this->assertEquals( + array( + 'id' => 1, + 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160225_235548'), + 'title' => 'Public stuff', + 'url' => 'http://public.tld', + 'description' => '', + 'private' => 0, + 'tags' => 'public hello world', + 'shorturl' => 'Er9ddA', + ), + $this->linkDb->getLinkFromUrl('http://public.tld') + ); + } + + /** + * Import links as public + */ + public function testImportAsPublic() + { + $post = array('privacy' => 'public'); + $files = file2array('netscape_basic.htm'); + $this->assertStringMatchesFormat( + 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:' + .' 2 links imported, 0 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(2, count($this->linkDb)); + $this->assertEquals(0, count_private($this->linkDb)); + $this->assertEquals( + 0, + $this->linkDb[0]['private'] + ); + $this->assertEquals( + 0, + $this->linkDb[1]['private'] + ); + } + + /** + * Import links as private + */ + public function testImportAsPrivate() + { + $post = array('privacy' => 'private'); + $files = file2array('netscape_basic.htm'); + $this->assertStringMatchesFormat( + 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:' + .' 2 links imported, 0 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(2, count($this->linkDb)); + $this->assertEquals(2, count_private($this->linkDb)); + $this->assertEquals( + 1, + $this->linkDb['0']['private'] + ); + $this->assertEquals( + 1, + $this->linkDb['1']['private'] + ); + } + + /** + * Overwrite private links so they become public + */ + public function testOverwriteAsPublic() + { + $files = file2array('netscape_basic.htm'); + + // import links as private + $post = array('privacy' => 'private'); + $this->assertStringMatchesFormat( + 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:' + .' 2 links imported, 0 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(2, count($this->linkDb)); + $this->assertEquals(2, count_private($this->linkDb)); + $this->assertEquals( + 1, + $this->linkDb[0]['private'] + ); + $this->assertEquals( + 1, + $this->linkDb[1]['private'] + ); + // re-import as public, enable overwriting + $post = array( + 'privacy' => 'public', + 'overwrite' => 'true' + ); + $this->assertStringMatchesFormat( + 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:' + .' 2 links imported, 2 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(2, count($this->linkDb)); + $this->assertEquals(0, count_private($this->linkDb)); + $this->assertEquals( + 0, + $this->linkDb[0]['private'] + ); + $this->assertEquals( + 0, + $this->linkDb[1]['private'] + ); + } + + /** + * Overwrite public links so they become private + */ + public function testOverwriteAsPrivate() + { + $files = file2array('netscape_basic.htm'); + + // import links as public + $post = array('privacy' => 'public'); + $this->assertStringMatchesFormat( + 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:' + .' 2 links imported, 0 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(2, count($this->linkDb)); + $this->assertEquals(0, count_private($this->linkDb)); + $this->assertEquals( + 0, + $this->linkDb['0']['private'] + ); + $this->assertEquals( + 0, + $this->linkDb['1']['private'] + ); + + // re-import as private, enable overwriting + $post = array( + 'privacy' => 'private', + 'overwrite' => 'true' + ); + $this->assertStringMatchesFormat( + 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:' + .' 2 links imported, 2 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(2, count($this->linkDb)); + $this->assertEquals(2, count_private($this->linkDb)); + $this->assertEquals( + 1, + $this->linkDb['0']['private'] + ); + $this->assertEquals( + 1, + $this->linkDb['1']['private'] + ); + } + + /** + * Attept to import the same links twice without enabling overwriting + */ + public function testSkipOverwrite() + { + $post = array('privacy' => 'public'); + $files = file2array('netscape_basic.htm'); + $this->assertStringMatchesFormat( + 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:' + .' 2 links imported, 0 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(2, count($this->linkDb)); + $this->assertEquals(0, count_private($this->linkDb)); + + // re-import as private, DO NOT enable overwriting + $post = array('privacy' => 'private'); + $this->assertStringMatchesFormat( + 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:' + .' 0 links imported, 0 links overwritten, 2 links skipped.', + NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(2, count($this->linkDb)); + $this->assertEquals(0, count_private($this->linkDb)); + } + + /** + * Add user-specified tags to all imported bookmarks + */ + public function testSetDefaultTags() + { + $post = array( + 'privacy' => 'public', + 'default_tags' => 'tag1,tag2 tag3' + ); + $files = file2array('netscape_basic.htm'); + $this->assertStringMatchesFormat( + 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:' + .' 2 links imported, 0 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(2, count($this->linkDb)); + $this->assertEquals(0, count_private($this->linkDb)); + $this->assertEquals( + 'tag1 tag2 tag3 private secret', + $this->linkDb['0']['tags'] + ); + $this->assertEquals( + 'tag1 tag2 tag3 public hello world', + $this->linkDb['1']['tags'] + ); + } + + /** + * The user-specified tags contain characters to be escaped + */ + public function testSanitizeDefaultTags() + { + $post = array( + 'privacy' => 'public', + 'default_tags' => 'tag1&,tag2 "tag3"' + ); + $files = file2array('netscape_basic.htm'); + $this->assertStringMatchesFormat( + 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:' + .' 2 links imported, 0 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(2, count($this->linkDb)); + $this->assertEquals(0, count_private($this->linkDb)); + $this->assertEquals( + 'tag1& tag2 "tag3" private secret', + $this->linkDb['0']['tags'] + ); + $this->assertEquals( + 'tag1& tag2 "tag3" public hello world', + $this->linkDb['1']['tags'] + ); + } + + /** + * Ensure each imported bookmark has a unique id + * + * See https://github.com/shaarli/Shaarli/issues/351 + */ + public function testImportSameDate() + { + $files = file2array('same_date.htm'); + $this->assertStringMatchesFormat( + 'File same_date.htm (453 bytes) was successfully processed in %d seconds:' + .' 3 links imported, 0 links overwritten, 0 links skipped.', + NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->conf, $this->history) + ); + $this->assertEquals(3, count($this->linkDb)); + $this->assertEquals(0, count_private($this->linkDb)); + $this->assertEquals( + 0, + $this->linkDb[0]['id'] + ); + $this->assertEquals( + 1, + $this->linkDb[1]['id'] + ); + $this->assertEquals( + 2, + $this->linkDb[2]['id'] + ); + } + + public function testImportCreateUpdateHistory() + { + $post = [ + 'privacy' => 'public', + 'overwrite' => 'true', + ]; + $files = file2array('netscape_basic.htm'); + NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history); + $history = $this->history->getHistory(); + $this->assertEquals(1, count($history)); + $this->assertEquals(History::IMPORT, $history[0]['event']); + $this->assertTrue(new DateTime('-5 seconds') < $history[0]['datetime']); + + // re-import as private, enable overwriting + NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history); + $history = $this->history->getHistory(); + $this->assertEquals(2, count($history)); + $this->assertEquals(History::IMPORT, $history[0]['event']); + $this->assertTrue(new DateTime('-5 seconds') < $history[0]['datetime']); + $this->assertEquals(History::IMPORT, $history[1]['event']); + $this->assertTrue(new DateTime('-5 seconds') < $history[1]['datetime']); + } +} -- cgit v1.2.3