Commit 8a1ed343 authored by kszatan's avatar kszatan Committed by Commit bot

Fix Firefox bookmarks import.

Firefox abandoned usage of the moz_bookmarks_roots table since v. 30 and
removed the table in v. 31 in favor of storing relevant info in the
'guid' column of the moz_bookmarks table.

BUG=638977

Review-Url: https://codereview.chromium.org/2296633002
Cr-Commit-Position: refs/heads/master@{#436262}
parent a497ed33
......@@ -38,6 +38,10 @@
#define MAYBE_IMPORTER(x) x
#endif
// TODO(kszatan): Disabled all tests on old profiles. http://crbug.com/592239
#undef MAYBE_IMPORTER
#define MAYBE_IMPORTER(x) DISABLED_##x
namespace {
struct PasswordInfo {
......
// Copyright 2016 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/common/importer/mock_importer_bridge.h"
MockImporterBridge::MockImporterBridge() {}
MockImporterBridge::~MockImporterBridge() {}
// Copyright (c) 2016 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.
#ifndef CHROME_COMMON_IMPORTER_MOCK_IMPORTER_BRIDGE_H_
#define CHROME_COMMON_IMPORTER_MOCK_IMPORTER_BRIDGE_H_
#include <string>
#include <vector>
#include "chrome/common/importer/imported_bookmark_entry.h"
#include "chrome/common/importer/importer_autofill_form_data_entry.h"
#include "chrome/common/importer/importer_bridge.h"
#include "components/autofill/core/common/password_form.h"
#include "testing/gmock/include/gmock/gmock.h"
class MockImporterBridge : public ImporterBridge {
public:
MockImporterBridge();
MOCK_METHOD2(AddBookmarks,
void(const std::vector<ImportedBookmarkEntry>&,
const base::string16&));
MOCK_METHOD1(AddHomePage, void(const GURL&));
#if defined(OS_WIN)
MOCK_METHOD1(AddIE7PasswordInfo,
void(const importer::ImporterIE7PasswordInfo&));
#endif
MOCK_METHOD1(SetFavicons, void(const favicon_base::FaviconUsageDataList&));
MOCK_METHOD2(SetHistoryItems,
void(const std::vector<ImporterURLRow>&, importer::VisitSource));
MOCK_METHOD2(SetKeywords,
void(const std::vector<importer::SearchEngineInfo>&, bool));
MOCK_METHOD1(SetFirefoxSearchEnginesXMLData,
void(const std::vector<std::string>&));
MOCK_METHOD1(SetPasswordForm, void(const autofill::PasswordForm&));
MOCK_METHOD1(SetAutofillFormData,
void(const std::vector<ImporterAutofillFormDataEntry>&));
MOCK_METHOD0(NotifyStarted, void());
MOCK_METHOD1(NotifyItemStarted, void(importer::ImportItem));
MOCK_METHOD1(NotifyItemEnded, void(importer::ImportItem));
MOCK_METHOD0(NotifyEnded, void());
MOCK_METHOD1(GetLocalizedString, base::string16(int));
private:
~MockImporterBridge() override;
};
#endif // CHROME_COMMON_IMPORTER_MOCK_IMPORTER_BRIDGE_H_
......@@ -3694,6 +3694,8 @@ test("unit_tests") {
"../common/importer/firefox_importer_utils_unittest.cc",
# No service process (which also requires multiprocess lock).
"../common/importer/mock_importer_bridge.cc",
"../common/importer/mock_importer_bridge.h",
"../common/multi_process_lock_unittest.cc",
"../test/base/browser_with_test_window_test.cc",
"../test/base/browser_with_test_window_test.h",
......
......@@ -205,10 +205,9 @@ void FirefoxImporter::ImportBookmarks() {
return;
// Get the bookmark folders that we are interested in.
int toolbar_folder_id = -1;
int menu_folder_id = -1;
int unsorted_folder_id = -1;
LoadRootNodeID(&db, &toolbar_folder_id, &menu_folder_id, &unsorted_folder_id);
int toolbar_folder_id = LoadNodeIDByGUID(&db, "toolbar_____");
int menu_folder_id = LoadNodeIDByGUID(&db, "menu________");
int unsorted_folder_id = LoadNodeIDByGUID(&db, "unfiled_____");
// Load livemark IDs.
std::set<int> livemark_id;
......@@ -643,27 +642,18 @@ void FirefoxImporter::GetSearchEnginesXMLDataFromJSON(
}
}
void FirefoxImporter::LoadRootNodeID(sql::Connection* db,
int* toolbar_folder_id,
int* menu_folder_id,
int* unsorted_folder_id) {
static const char kToolbarFolderName[] = "toolbar";
static const char kMenuFolderName[] = "menu";
static const char kUnsortedFolderName[] = "unfiled";
const char query[] = "SELECT root_name, folder_id FROM moz_bookmarks_roots";
int FirefoxImporter::LoadNodeIDByGUID(sql::Connection* db,
const std::string& GUID) {
const char query[] =
"SELECT id "
"FROM moz_bookmarks "
"WHERE guid == ?";
sql::Statement s(db->GetUniqueStatement(query));
s.BindString(0, GUID);
while (s.Step()) {
std::string folder = s.ColumnString(0);
int id = s.ColumnInt(1);
if (folder == kToolbarFolderName)
*toolbar_folder_id = id;
else if (folder == kMenuFolderName)
*menu_folder_id = id;
else if (folder == kUnsortedFolderName)
*unsorted_folder_id = id;
}
if (!s.Step())
return -1;
return s.ColumnInt(0);
}
void FirefoxImporter::LoadLivemarkIDs(sql::Connection* db,
......
......@@ -16,6 +16,7 @@
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "build/build_config.h"
#include "chrome/utility/importer/importer.h"
......@@ -44,6 +45,7 @@ class FirefoxImporter : public Importer {
~FirefoxImporter() override;
FRIEND_TEST_ALL_PREFIXES(FirefoxImporterTest, ImportBookmarksV25);
void ImportBookmarks();
void ImportPasswords();
void ImportHistory();
......@@ -60,9 +62,9 @@ class FirefoxImporter : public Importer {
struct BookmarkItem;
using BookmarkList = std::vector<std::unique_ptr<BookmarkItem>>;
// Gets the specific IDs of bookmark root node from |db|.
void LoadRootNodeID(sql::Connection* db, int* toolbar_folder_id,
int* menu_folder_id, int* unsorted_folder_id);
// Gets the specific ID of bookmark node with given GUID from |db|.
// Returns -1 if not found.
int LoadNodeIDByGUID(sql::Connection* db, const std::string& GUID);
// Loads all livemark IDs from database |db|.
void LoadLivemarkIDs(sql::Connection* db, std::set<int>* livemark);
......
......@@ -8,8 +8,14 @@
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/importer/imported_bookmark_entry.h"
#include "chrome/common/importer/importer_data_types.h"
#include "chrome/common/importer/importer_url_row.h"
#include "chrome/common/importer/mock_importer_bridge.h"
#include "chrome/utility/importer/firefox_importer.h"
#include "chrome/utility/importer/firefox_importer_unittest_utils.h"
#include "chrome/utility/importer/nss_decryptor.h"
#include "components/favicon_base/favicon_usage_data.h"
#include "sql/connection.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -39,11 +45,13 @@ TEST(FirefoxImporterTest, MAYBE_NSS(Firefox3NSS3Decryptor)) {
ASSERT_TRUE(decryptor_proxy.Setup(nss_path));
ASSERT_TRUE(decryptor_proxy.DecryptorInit(nss_path, db_path));
EXPECT_EQ(base::ASCIIToUTF16("hello"),
EXPECT_EQ(
base::ASCIIToUTF16("hello"),
decryptor_proxy.Decrypt("MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECKa"
"jtRg4qFSHBAhv9luFkXgDJA=="));
// Test UTF-16 encoding.
EXPECT_EQ(base::WideToUTF16(L"\x4E2D"),
EXPECT_EQ(
base::WideToUTF16(L"\x4E2D"),
decryptor_proxy.Decrypt("MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECLW"
"qqiccfQHWBAie74hxnULxlw=="));
......@@ -115,3 +123,76 @@ TEST(FirefoxImporterTest, MAYBE_NSS(FirefoxNSSDecryptorDeduceAuthScheme)) {
EXPECT_EQ(autofill::PasswordForm::SCHEME_BASIC, forms[0].scheme);
EXPECT_EQ(autofill::PasswordForm::SCHEME_HTML, forms[1].scheme);
}
TEST(FirefoxImporterTest, ImportBookmarks) {
using ::testing::_;
base::FilePath places_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &places_path));
places_path =
places_path.AppendASCII("import").AppendASCII("firefox").AppendASCII(
"48.0.2");
scoped_refptr<FirefoxImporter> importer = new FirefoxImporter;
importer::SourceProfile profile;
profile.source_path = places_path;
scoped_refptr<MockImporterBridge> bridge = new MockImporterBridge;
std::vector<ImportedBookmarkEntry> bookmarks;
favicon_base::FaviconUsageDataList favicons;
EXPECT_CALL(*bridge, NotifyStarted());
EXPECT_CALL(*bridge, NotifyItemStarted(importer::FAVORITES));
EXPECT_CALL(*bridge, AddBookmarks(_, _))
.WillOnce(::testing::SaveArg<0>(&bookmarks));
EXPECT_CALL(*bridge, SetFavicons(_))
.WillOnce(::testing::SaveArg<0>(&favicons));
EXPECT_CALL(*bridge, NotifyItemEnded(importer::FAVORITES));
EXPECT_CALL(*bridge, NotifyEnded());
importer->StartImport(profile, importer::FAVORITES, bridge.get());
ASSERT_EQ(6u, bookmarks.size());
EXPECT_EQ("https://www.mozilla.org/en-US/firefox/central/",
bookmarks[0].url.spec());
EXPECT_EQ("https://www.mozilla.org/en-US/firefox/help/",
bookmarks[1].url.spec());
EXPECT_EQ("https://www.mozilla.org/en-US/firefox/customize/",
bookmarks[2].url.spec());
EXPECT_EQ("https://www.mozilla.org/en-US/contribute/",
bookmarks[3].url.spec());
EXPECT_EQ("https://www.mozilla.org/en-US/about/", bookmarks[4].url.spec());
EXPECT_EQ("https://www.google.com/", bookmarks[5].url.spec());
ASSERT_EQ(5u, favicons.size());
EXPECT_EQ("http://www.mozilla.org/2005/made-up-favicon/0-1473403921346",
favicons[0].favicon_url.spec());
EXPECT_EQ("http://www.mozilla.org/2005/made-up-favicon/1-1473403921347",
favicons[1].favicon_url.spec());
EXPECT_EQ("http://www.mozilla.org/2005/made-up-favicon/2-1473403921348",
favicons[2].favicon_url.spec());
EXPECT_EQ("http://www.mozilla.org/2005/made-up-favicon/3-1473403921349",
favicons[3].favicon_url.spec());
EXPECT_EQ("http://www.mozilla.org/2005/made-up-favicon/4-1473403921349",
favicons[4].favicon_url.spec());
}
TEST(FirefoxImporterTest, ImportHistorySchema) {
using ::testing::_;
base::FilePath places_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &places_path));
places_path =
places_path.AppendASCII("import").AppendASCII("firefox").AppendASCII(
"48.0.2");
scoped_refptr<FirefoxImporter> ff_importer = new FirefoxImporter;
importer::SourceProfile profile;
profile.source_path = places_path;
scoped_refptr<MockImporterBridge> bridge = new MockImporterBridge;
std::vector<ImporterURLRow> history;
EXPECT_CALL(*bridge, NotifyStarted());
EXPECT_CALL(*bridge, NotifyItemStarted(importer::HISTORY));
EXPECT_CALL(*bridge, SetHistoryItems(_, _))
.WillOnce(::testing::SaveArg<0>(&history));
EXPECT_CALL(*bridge, NotifyItemEnded(importer::HISTORY));
EXPECT_CALL(*bridge, NotifyEnded());
ff_importer->StartImport(profile, importer::HISTORY, bridge.get());
ASSERT_EQ(3u, history.size());
EXPECT_EQ("https://www.mozilla.org/en-US/firefox/48.0.2/firstrun/learnmore/",
history[0].url.spec());
EXPECT_EQ("https://www.mozilla.org/en-US/firefox/48.0.2/firstrun/",
history[1].url.spec());
EXPECT_EQ("http://google.com/", history[2].url.spec());
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment