// 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/browser/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"
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 {
void 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 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 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 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 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());
}
} // namespace
TEST(BookmarkHTMLReaderTest, Firefox2BookmarkFileImport) {
base::FilePath path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
path = path.AppendASCII("bookmark_html_reader");
path = 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(BookmarkHTMLReaderTest, EpiphanyBookmarkFileImport) {
base::FilePath path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
path = path.AppendASCII("bookmark_html_reader");
path = 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(BookmarkHTMLReaderTest, CancellationCallback) {
base::FilePath path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
path = path.AppendASCII("bookmark_html_reader");
// Use a file for testing that has multiple bookmarks.
path = 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(BookmarkHTMLReaderTest, ValidURLCallback) {
base::FilePath path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
path = path.AppendASCII("bookmark_html_reader");
// Use a file for testing that has multiple bookmarks.
path = 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