// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/utility/importer/bookmark_html_reader.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback.h" #include "base/files/file_path.h" #include "base/path_service.h" #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/importer/imported_bookmark_entry.h" #include "testing/gtest/include/gtest/gtest.h" using base::ASCIIToUTF16; using base::UTF16ToWide; namespace bookmark_html_reader { TEST(BookmarkHTMLReaderTest, ParseTests) { bool result; // Tests charset. std::string charset; result = internal::ParseCharsetFromLine( "", &charset); EXPECT_TRUE(result); EXPECT_EQ("UTF-8", charset); // Escaped characters in name. base::string16 folder_name; bool is_toolbar_folder; base::Time folder_add_date; result = internal::ParseFolderNameFromLine( "

< >" " & " ' \\ /

", charset, &folder_name, &is_toolbar_folder, &folder_add_date); EXPECT_TRUE(result); EXPECT_EQ(ASCIIToUTF16("< > & \" ' \\ /"), folder_name); EXPECT_FALSE(is_toolbar_folder); EXPECT_TRUE(base::Time::FromTimeT(1207558707) == folder_add_date); // Empty name and toolbar folder attribute. result = internal::ParseFolderNameFromLine( "

", charset, &folder_name, &is_toolbar_folder, &folder_add_date); EXPECT_TRUE(result); EXPECT_EQ(base::string16(), folder_name); EXPECT_TRUE(is_toolbar_folder); // Unicode characters in title and shortcut. base::string16 title; GURL url, favicon; base::string16 shortcut; base::string16 post_data; base::Time add_date; result = internal::ParseBookmarkFromLine( "
\xE4\xB8\xAD\xE6\x96\x87", charset, &title, &url, &favicon, &shortcut, &add_date, &post_data); EXPECT_TRUE(result); EXPECT_EQ(L"\x4E2D\x6587", UTF16ToWide(title)); EXPECT_EQ("http://chinese.site.cn/path?query=1#ref", url.spec()); EXPECT_EQ(L"\x4E2D", UTF16ToWide(shortcut)); EXPECT_EQ(base::string16(), post_data); EXPECT_TRUE(base::Time() == add_date); // No shortcut, and url contains %22 ('"' character). result = internal::ParseBookmarkFromLine( "
%22\">name", charset, &title, &url, &favicon, &shortcut, &add_date, &post_data); EXPECT_TRUE(result); EXPECT_EQ(ASCIIToUTF16("name"), title); EXPECT_EQ("http://domain.com/?q=%22%3C%3E%22", url.spec()); EXPECT_EQ(base::string16(), shortcut); EXPECT_EQ(base::string16(), post_data); EXPECT_TRUE(base::Time() == add_date); result = internal::ParseBookmarkFromLine( "
name", charset, &title, &url, &favicon, &shortcut, &add_date, &post_data); EXPECT_TRUE(result); EXPECT_EQ(ASCIIToUTF16("name"), title); EXPECT_EQ("http://domain.com/?g=%22", url.spec()); EXPECT_EQ(base::string16(), shortcut); EXPECT_EQ(base::string16(), post_data); EXPECT_TRUE(base::Time() == add_date); // Creation date. result = internal::ParseBookmarkFromLine( "
name", charset, &title, &url, &favicon, &shortcut, &add_date, &post_data); EXPECT_TRUE(result); EXPECT_EQ(ASCIIToUTF16("name"), title); EXPECT_EQ(GURL("http://site/"), url); EXPECT_EQ(base::string16(), shortcut); EXPECT_EQ(base::string16(), post_data); EXPECT_TRUE(base::Time::FromTimeT(1121301154) == add_date); // Post-data result = internal::ParseBookmarkFromLine( "
Test Post keyword", charset, &title, &url, &favicon, &shortcut, &add_date, &post_data); EXPECT_TRUE(result); EXPECT_EQ(ASCIIToUTF16("Test Post keyword"), title); EXPECT_EQ("http://localhost:8080/test/hello.html", url.spec()); EXPECT_EQ(ASCIIToUTF16("post"), shortcut); EXPECT_EQ(ASCIIToUTF16("lname%3D%25s"), post_data); EXPECT_TRUE(base::Time::FromTimeT(1212447159) == add_date); // Invalid case. result = internal::ParseBookmarkFromLine( "
Google
", charset, &title, &url); EXPECT_TRUE(result); EXPECT_EQ(ASCIIToUTF16("Google"), title); EXPECT_EQ("http://www.google.com/", url.spec()); } namespace { class BookmarkHTMLReaderTestWithData : public testing::Test { public: virtual void SetUp() OVERRIDE; protected: void ExpectFirstFirefox2Bookmark(const ImportedBookmarkEntry& entry); void ExpectSecondFirefox2Bookmark(const ImportedBookmarkEntry& entry); void ExpectThirdFirefox2Bookmark(const ImportedBookmarkEntry& entry); void ExpectFirstEpiphanyBookmark(const ImportedBookmarkEntry& entry); void ExpectSecondEpiphanyBookmark(const ImportedBookmarkEntry& entry); void ExpectFirstFirefox23Bookmark(const ImportedBookmarkEntry& entry); void ExpectSecondFirefox23Bookmark(const ImportedBookmarkEntry& entry); void ExpectThirdFirefox23Bookmark(const ImportedBookmarkEntry& entry); base::FilePath test_data_path_; }; void BookmarkHTMLReaderTestWithData::SetUp() { ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_path_)); test_data_path_ = test_data_path_.AppendASCII("bookmark_html_reader"); } void BookmarkHTMLReaderTestWithData::ExpectFirstFirefox2Bookmark( const ImportedBookmarkEntry& entry) { EXPECT_EQ(ASCIIToUTF16("Empty"), entry.title); EXPECT_TRUE(entry.is_folder); EXPECT_EQ(base::Time::FromTimeT(1295938143), entry.creation_time); EXPECT_EQ(1U, entry.path.size()); if (entry.path.size() == 1) EXPECT_EQ(ASCIIToUTF16("Empty's Parent"), entry.path.front()); } void BookmarkHTMLReaderTestWithData::ExpectSecondFirefox2Bookmark( const ImportedBookmarkEntry& entry) { EXPECT_EQ(ASCIIToUTF16("[Tamura Yukari.com]"), entry.title); EXPECT_FALSE(entry.is_folder); EXPECT_EQ(base::Time::FromTimeT(1234567890), entry.creation_time); EXPECT_EQ(1U, entry.path.size()); if (entry.path.size() == 1) EXPECT_EQ(ASCIIToUTF16("Not Empty"), entry.path.front()); EXPECT_EQ("http://www.tamurayukari.com/", entry.url.spec()); } void BookmarkHTMLReaderTestWithData::ExpectThirdFirefox2Bookmark( const ImportedBookmarkEntry& entry) { EXPECT_EQ(ASCIIToUTF16("Google"), entry.title); EXPECT_FALSE(entry.is_folder); EXPECT_EQ(base::Time::FromTimeT(0000000000), entry.creation_time); EXPECT_EQ(1U, entry.path.size()); if (entry.path.size() == 1) EXPECT_EQ(ASCIIToUTF16("Not Empty But Default"), entry.path.front()); EXPECT_EQ("http://www.google.com/", entry.url.spec()); } void BookmarkHTMLReaderTestWithData::ExpectFirstEpiphanyBookmark( const ImportedBookmarkEntry& entry) { EXPECT_EQ(ASCIIToUTF16("[Tamura Yukari.com]"), entry.title); EXPECT_EQ("http://www.tamurayukari.com/", entry.url.spec()); EXPECT_EQ(0U, entry.path.size()); } void BookmarkHTMLReaderTestWithData::ExpectSecondEpiphanyBookmark( const ImportedBookmarkEntry& entry) { EXPECT_EQ(ASCIIToUTF16("Google"), entry.title); EXPECT_EQ("http://www.google.com/", entry.url.spec()); EXPECT_EQ(0U, entry.path.size()); } void BookmarkHTMLReaderTestWithData::ExpectFirstFirefox23Bookmark( const ImportedBookmarkEntry& entry) { EXPECT_EQ(ASCIIToUTF16("Google"), entry.title); EXPECT_FALSE(entry.is_folder); EXPECT_EQ(base::Time::FromTimeT(1376102167), entry.creation_time); EXPECT_EQ(0U, entry.path.size()); EXPECT_EQ("https://www.google.com/", entry.url.spec()); } void BookmarkHTMLReaderTestWithData::ExpectSecondFirefox23Bookmark( const ImportedBookmarkEntry& entry) { EXPECT_EQ(ASCIIToUTF16("Issues"), entry.title); EXPECT_FALSE(entry.is_folder); EXPECT_EQ(base::Time::FromTimeT(1376102304), entry.creation_time); EXPECT_EQ(1U, entry.path.size()); EXPECT_EQ(ASCIIToUTF16("Chromium"), entry.path.front()); EXPECT_EQ("https://code.google.com/p/chromium/issues/list", entry.url.spec()); } void BookmarkHTMLReaderTestWithData::ExpectThirdFirefox23Bookmark( const ImportedBookmarkEntry& entry) { EXPECT_EQ(ASCIIToUTF16("CodeSearch"), entry.title); EXPECT_FALSE(entry.is_folder); EXPECT_EQ(base::Time::FromTimeT(1376102224), entry.creation_time); EXPECT_EQ(1U, entry.path.size()); EXPECT_EQ(ASCIIToUTF16("Chromium"), entry.path.front()); EXPECT_EQ("http://code.google.com/p/chromium/codesearch", entry.url.spec()); } } // namespace TEST_F(BookmarkHTMLReaderTestWithData, Firefox2BookmarkFileImport) { base::FilePath path = test_data_path_.AppendASCII("firefox2.html"); std::vector bookmarks; ImportBookmarksFile(base::Callback(), base::Callback(), path, &bookmarks, NULL); ASSERT_EQ(3U, bookmarks.size()); ExpectFirstFirefox2Bookmark(bookmarks[0]); ExpectSecondFirefox2Bookmark(bookmarks[1]); ExpectThirdFirefox2Bookmark(bookmarks[2]); } TEST_F(BookmarkHTMLReaderTestWithData, BookmarkFileWithHrTagImport) { base::FilePath path = test_data_path_.AppendASCII("firefox23.html"); std::vector bookmarks; ImportBookmarksFile(base::Callback(), base::Callback(), path, &bookmarks, NULL); ASSERT_EQ(3U, bookmarks.size()); ExpectFirstFirefox23Bookmark(bookmarks[0]); ExpectSecondFirefox23Bookmark(bookmarks[1]); ExpectThirdFirefox23Bookmark(bookmarks[2]); } TEST_F(BookmarkHTMLReaderTestWithData, EpiphanyBookmarkFileImport) { base::FilePath path = test_data_path_.AppendASCII("epiphany.html"); std::vector bookmarks; ImportBookmarksFile(base::Callback(), base::Callback(), path, &bookmarks, NULL); ASSERT_EQ(2U, bookmarks.size()); ExpectFirstEpiphanyBookmark(bookmarks[0]); ExpectSecondEpiphanyBookmark(bookmarks[1]); } namespace { class CancelAfterFifteenCalls { int count; public: CancelAfterFifteenCalls() : count(0) { } bool ShouldCancel() { return ++count > 16; } }; } // namespace TEST_F(BookmarkHTMLReaderTestWithData, CancellationCallback) { // Use a file for testing that has multiple bookmarks. base::FilePath path = test_data_path_.AppendASCII("firefox2.html"); std::vector bookmarks; CancelAfterFifteenCalls cancel_fifteen; ImportBookmarksFile(base::Bind(&CancelAfterFifteenCalls::ShouldCancel, base::Unretained(&cancel_fifteen)), base::Callback(), path, &bookmarks, NULL); // The cancellation callback is checked before each line is read, so fifteen // lines are imported. The first fifteen lines of firefox2.html include only // one bookmark. ASSERT_EQ(1U, bookmarks.size()); ExpectFirstFirefox2Bookmark(bookmarks[0]); } namespace { bool IsURLValid(const GURL& url) { // No offense to whomever owns this domain... return !url.DomainIs("tamurayukari.com"); } } // namespace TEST_F(BookmarkHTMLReaderTestWithData, ValidURLCallback) { // Use a file for testing that has multiple bookmarks. base::FilePath path = test_data_path_.AppendASCII("firefox2.html"); std::vector bookmarks; ImportBookmarksFile(base::Callback(), base::Bind(&IsURLValid), path, &bookmarks, NULL); ASSERT_EQ(2U, bookmarks.size()); ExpectFirstFirefox2Bookmark(bookmarks[0]); ExpectThirdFirefox2Bookmark(bookmarks[1]); } } // namespace bookmark_html_reader