// Copyright (c) 2011 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 <vector>
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/memory/scoped_temp_dir.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/history/starred_url_database.h"
#include "chrome/common/chrome_paths.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace history {
class StarredURLDatabaseTest : public testing::Test,
public StarredURLDatabase {
public:
StarredURLDatabaseTest() {
}
void AddPage(const GURL& url) {
URLRow row(url);
row.set_visit_count(1);
EXPECT_TRUE(AddURL(row));
}
void CompareEntryByID(const StarredEntry& entry) {
DCHECK(entry.id != 0);
StarredEntry db_value;
EXPECT_TRUE(GetStarredEntry(entry.id, &db_value));
EXPECT_EQ(entry.id, db_value.id);
EXPECT_TRUE(entry.title == db_value.title);
EXPECT_EQ(entry.date_added.ToTimeT(), db_value.date_added.ToTimeT());
EXPECT_EQ(entry.folder_id, db_value.folder_id);
EXPECT_EQ(entry.parent_folder_id, db_value.parent_folder_id);
EXPECT_EQ(entry.visual_order, db_value.visual_order);
EXPECT_EQ(entry.type, db_value.type);
EXPECT_EQ(entry.url_id, db_value.url_id);
if (entry.type == StarredEntry::URL)
EXPECT_TRUE(entry.url == db_value.url);
}
int GetStarredEntryCount() {
DCHECK(db_.is_open());
std::vector<StarredEntry> entries;
GetAllStarredEntries(&entries);
return static_cast<int>(entries.size());
}
StarID CreateStarredEntry(StarredEntry* entry) {
return StarredURLDatabase::CreateStarredEntry(entry);
}
bool GetStarredEntry(StarID star_id, StarredEntry* entry) {
return StarredURLDatabase::GetStarredEntry(star_id, entry);
}
bool EnsureStarredIntegrity() {
return StarredURLDatabase::EnsureStarredIntegrity();
}
private:
// Test setup.
void SetUp() {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
db_file_ = temp_dir_.path().AppendASCII("VisitTest.db");
file_util::Delete(db_file_, false);
// Copy db file over that contains starred table.
FilePath old_history_path;
PathService::Get(chrome::DIR_TEST_DATA, &old_history_path);
old_history_path = old_history_path.AppendASCII("bookmarks");
old_history_path = old_history_path.Append(
FILE_PATH_LITERAL("History_with_empty_starred"));
file_util::CopyFile(old_history_path, db_file_);
EXPECT_TRUE(db_.Open(db_file_));
// Initialize the tables for this test.
CreateURLTable(false);
CreateMainURLIndex();
EnsureStarredIntegrity();
}
void TearDown() {
db_.Close();
}
// Provided for URL/StarredURLDatabase.
virtual sql::Connection& GetDB() {
return db_;
}
ScopedTempDir temp_dir_;
FilePath db_file_;
sql::Connection db_;
};
//-----------------------------------------------------------------------------
TEST_F(StarredURLDatabaseTest, FixOrphanedFolder) {
const int initial_count = GetStarredEntryCount();
// Create a folder that isn't parented to the other/bookmark folders.
StarredEntry g_entry;
g_entry.type = StarredEntry::USER_FOLDER;
g_entry.parent_folder_id = 100;
g_entry.visual_order = 10;
g_entry.folder_id = 100;
CreateStarredEntry(&g_entry);
ASSERT_TRUE(EnsureStarredIntegrity());
// Make sure no new entries were added.
ASSERT_EQ(initial_count + 1, GetStarredEntryCount());
// Make sure the folder was moved to the bookmark bar folder.
ASSERT_TRUE(GetStarredEntry(g_entry.id, &g_entry));
ASSERT_EQ(HistoryService::kBookmarkBarID, g_entry.parent_folder_id);
ASSERT_EQ(0, g_entry.visual_order);
}
TEST_F(StarredURLDatabaseTest, FixOrphanedBookmarks) {
const int initial_count = GetStarredEntryCount();
// Create two bookmarks that aren't in a random folder no on the bookmark bar.
StarredEntry entry1;
entry1.parent_folder_id = 100;
entry1.visual_order = 10;
entry1.url = GURL("http://google.com/1");
CreateStarredEntry(&entry1);
StarredEntry entry2;
entry2.parent_folder_id = 101;
entry2.visual_order = 20;
entry2.url = GURL("http://google.com/2");
CreateStarredEntry(&entry2);
ASSERT_TRUE(EnsureStarredIntegrity());
// Make sure no new entries were added.
ASSERT_EQ(initial_count + 2, GetStarredEntryCount());
// Make sure the entries were moved to the bookmark bar and the visual order
// order was updated appropriately.
ASSERT_TRUE(GetStarredEntry(entry1.id, &entry1));
ASSERT_EQ(HistoryService::kBookmarkBarID, entry1.parent_folder_id);
ASSERT_TRUE(GetStarredEntry(entry2.id, &entry2));
ASSERT_EQ(HistoryService::kBookmarkBarID, entry2.parent_folder_id);
ASSERT_TRUE((entry1.visual_order == 0 && entry2.visual_order == 1) ||
(entry1.visual_order == 1 && entry2.visual_order == 0));
}
TEST_F(StarredURLDatabaseTest, FixFolderCycleDepth0) {
const int initial_count = GetStarredEntryCount();
// Create a folder that is parented to itself.
StarredEntry entry1;
entry1.folder_id = entry1.parent_folder_id = 100;
entry1.visual_order = 10;
entry1.type = StarredEntry::USER_FOLDER;
CreateStarredEntry(&entry1);
ASSERT_TRUE(EnsureStarredIntegrity());
// Make sure no new entries were added.
ASSERT_EQ(initial_count + 1, GetStarredEntryCount());
// Make sure the folder were moved to the bookmark bar and the visual order
// order was updated appropriately.
ASSERT_TRUE(GetStarredEntry(entry1.id, &entry1));
ASSERT_EQ(HistoryService::kBookmarkBarID, entry1.parent_folder_id);
ASSERT_EQ(0, entry1.visual_order);
}
TEST_F(StarredURLDatabaseTest, FixFolderCycleDepth1) {
const int initial_count = GetStarredEntryCount();
StarredEntry entry1;
entry1.folder_id = 100;
entry1.parent_folder_id = 101;
entry1.visual_order = 10;
entry1.type = StarredEntry::USER_FOLDER;
CreateStarredEntry(&entry1);
StarredEntry entry2;
entry2.folder_id = 101;
entry2.parent_folder_id = 100;
entry2.visual_order = 11;
entry2.type = StarredEntry::USER_FOLDER;
CreateStarredEntry(&entry2);
ASSERT_TRUE(EnsureStarredIntegrity());
// Make sure no new entries were added.
ASSERT_EQ(initial_count + 2, GetStarredEntryCount());
// Because the folders caused a cycle, entry1 is moved the bookmark bar, which
// breaks the cycle.
ASSERT_TRUE(GetStarredEntry(entry1.id, &entry1));
ASSERT_TRUE(GetStarredEntry(entry2.id, &entry2));
ASSERT_EQ(HistoryService::kBookmarkBarID, entry1.parent_folder_id);
ASSERT_EQ(100, entry2.parent_folder_id);
ASSERT_EQ(0, entry1.visual_order);
ASSERT_EQ(0, entry2.visual_order);
}
TEST_F(StarredURLDatabaseTest, FixVisualOrder) {
const int initial_count = GetStarredEntryCount();
// Star two urls.
StarredEntry entry1;
entry1.url = GURL("http://google.com/1");
entry1.parent_folder_id = HistoryService::kBookmarkBarID;
entry1.visual_order = 5;
CreateStarredEntry(&entry1);
// Add url2 and star it.
StarredEntry entry2;
entry2.url = GURL("http://google.com/2");
entry2.parent_folder_id = HistoryService::kBookmarkBarID;
entry2.visual_order = 10;
CreateStarredEntry(&entry2);
ASSERT_TRUE(EnsureStarredIntegrity());
// Make sure no new entries were added.
ASSERT_EQ(initial_count + 2, GetStarredEntryCount());
StarredEntry entry;
ASSERT_TRUE(GetStarredEntry(entry1.id, &entry));
entry1.visual_order = 0;
CompareEntryByID(entry1);
ASSERT_TRUE(GetStarredEntry(entry2.id, &entry));
entry2.visual_order = 1;
CompareEntryByID(entry2);
}
TEST_F(StarredURLDatabaseTest, FixDuplicateFolderIDs) {
const int initial_count = GetStarredEntryCount();
// Create two folders with the same folder id.
StarredEntry entry1;
entry1.type = StarredEntry::USER_FOLDER;
entry1.folder_id = 10;
entry1.parent_folder_id = HistoryService::kBookmarkBarID;
CreateStarredEntry(&entry1);
StarredEntry entry2 = entry1;
CreateStarredEntry(&entry2);
ASSERT_TRUE(EnsureStarredIntegrity());
// Make sure only one folder exists.
ASSERT_EQ(initial_count + 1, GetStarredEntryCount());
StarredEntry entry;
ASSERT_TRUE(GetStarredEntry(entry1.id, &entry) ||
GetStarredEntry(entry2.id, &entry));
}
TEST_F(StarredURLDatabaseTest, RemoveStarredEntriesWithEmptyURL) {
const int initial_count = GetStarredEntryCount();
StarredEntry entry;
entry.url = GURL("http://google.com");
entry.title = UTF8ToUTF16("FOO");
entry.parent_folder_id = HistoryService::kBookmarkBarID;
ASSERT_NE(0, CreateStarredEntry(&entry));
// Remove the URL.
DeleteURLRow(entry.url_id);
// Fix up the table.
ASSERT_TRUE(EnsureStarredIntegrity());
// The entry we just created should have been nuked.
ASSERT_EQ(initial_count, GetStarredEntryCount());
}
} // namespace history