This source file includes following definitions.
- IconMappingLessThan
- FaviconBitmapLessThan
- NotifyProfileError
- NotifyVisitDBObserversOnAddVisit
- MockScheduleOfRequest
- ui_thread_
- OnQueryMostVisited
- OnQueryFiltered
- get_most_visited_list
- get_filtered_list
- num_broadcasted_notifications
- AddRedirectChain
- AddRedirectChainWithTransitionAndTime
- AddClientRedirect
- getTransition
- getTestDir
- GetSizesSmall
- GetSizesLarge
- GetSizesSmallAndLarge
- GetSizesTinySmallAndLarge
- GetScaleFactors1x2x
- NumIconMappingsForPageURL
- GetSortedIconMappingsForPageURL
- GetSortedFaviconBitmaps
- GetOnlyFaviconBitmap
- GenerateFaviconBitmapData
- GenerateFaviconBitmapData
- BitmapDataEqual
- SetUp
- TearDown
- SetInMemoryBackend
- BroadcastNotifications
- SetInMemoryBackend
- BroadcastNotifications
- DBLoaded
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "chrome/browser/history/history_backend.h"
#include <algorithm>
#include <set>
#include <vector>
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/history/history_notifications.h"
#include "chrome/browser/history/history_service.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/history/in_memory_database.h"
#include "chrome/browser/history/in_memory_history_backend.h"
#include "chrome/browser/history/visit_filter.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/importer/imported_favicon_usage.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
using base::Time;
namespace {
static const gfx::Size kTinySize = gfx::Size(10, 10);
static const gfx::Size kSmallSize = gfx::Size(16, 16);
static const gfx::Size kLargeSize = gfx::Size(32, 32);
bool IconMappingLessThan(const history::IconMapping& a,
const history::IconMapping& b) {
return a.icon_url < b.icon_url;
}
bool FaviconBitmapLessThan(const history::FaviconBitmap& a,
const history::FaviconBitmap& b) {
return a.pixel_size.GetArea() < b.pixel_size.GetArea();
}
}
namespace history {
class HistoryBackendTest;
class HistoryBackendTestDelegate : public HistoryBackend::Delegate {
public:
explicit HistoryBackendTestDelegate(HistoryBackendTest* test) : test_(test) {}
virtual void NotifyProfileError(sql::InitStatus init_status) OVERRIDE {}
virtual void SetInMemoryBackend(
scoped_ptr<InMemoryHistoryBackend> backend) OVERRIDE;
virtual void BroadcastNotifications(
int type,
scoped_ptr<HistoryDetails> details) OVERRIDE;
virtual void DBLoaded() OVERRIDE;
virtual void NotifyVisitDBObserversOnAddVisit(
const BriefVisitInfo& info) OVERRIDE {}
private:
HistoryBackendTest* test_;
DISALLOW_COPY_AND_ASSIGN(HistoryBackendTestDelegate);
};
class HistoryBackendCancelableRequest
: public CancelableRequestProvider,
public CancelableRequestConsumerTSimple<int> {
public:
HistoryBackendCancelableRequest() {}
template<class RequestType>
CancelableRequestProvider::Handle MockScheduleOfRequest(
RequestType* request) {
AddRequest(request, this);
return request->handle();
}
};
class HistoryBackendTest : public testing::Test {
public:
HistoryBackendTest()
: bookmark_model_(NULL),
loaded_(false),
num_broadcasted_notifications_(0),
ui_thread_(content::BrowserThread::UI, &message_loop_) {
}
virtual ~HistoryBackendTest() {
}
void OnQueryMostVisited(CancelableRequestProvider::Handle handle,
history::MostVisitedURLList data) {
most_visited_list_.swap(data);
}
void OnQueryFiltered(CancelableRequestProvider::Handle handle,
const history::FilteredURLList& data) {
filtered_list_ = data;
}
const history::MostVisitedURLList& get_most_visited_list() const {
return most_visited_list_;
}
const history::FilteredURLList& get_filtered_list() const {
return filtered_list_;
}
int num_broadcasted_notifications() const {
return num_broadcasted_notifications_;
}
protected:
scoped_refptr<HistoryBackend> backend_;
scoped_ptr<InMemoryHistoryBackend> mem_backend_;
void AddRedirectChain(const char* sequence[], int page_id) {
AddRedirectChainWithTransitionAndTime(sequence, page_id,
content::PAGE_TRANSITION_LINK,
Time::Now());
}
void AddRedirectChainWithTransitionAndTime(
const char* sequence[],
int page_id,
content::PageTransition transition,
base::Time time) {
history::RedirectList redirects;
for (int i = 0; sequence[i] != NULL; ++i)
redirects.push_back(GURL(sequence[i]));
int int_scope = 1;
void* scope = 0;
memcpy(&scope, &int_scope, sizeof(int_scope));
history::HistoryAddPageArgs request(
redirects.back(), time, scope, page_id, GURL(),
redirects, transition, history::SOURCE_BROWSED,
true);
backend_->AddPage(request);
}
void AddClientRedirect(const GURL& url1, const GURL& url2, bool did_replace,
base::Time time,
int* transition1, int* transition2) {
void* const dummy_scope = reinterpret_cast<void*>(0x87654321);
history::RedirectList redirects;
if (url1.is_valid())
redirects.push_back(url1);
if (url2.is_valid())
redirects.push_back(url2);
HistoryAddPageArgs request(
url2, time, dummy_scope, 0, url1,
redirects, content::PAGE_TRANSITION_CLIENT_REDIRECT,
history::SOURCE_BROWSED, did_replace);
backend_->AddPage(request);
*transition1 = getTransition(url1);
*transition2 = getTransition(url2);
}
int getTransition(const GURL& url) {
if (!url.is_valid())
return 0;
URLRow row;
URLID id = backend_->db()->GetRowForURL(url, &row);
VisitVector visits;
EXPECT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
return visits[0].transition;
}
base::FilePath getTestDir() {
return test_dir_;
}
const std::vector<gfx::Size> GetSizesSmall() {
std::vector<gfx::Size> sizes_small;
sizes_small.push_back(kSmallSize);
return sizes_small;
}
const std::vector<gfx::Size> GetSizesLarge() {
std::vector<gfx::Size> sizes_large;
sizes_large.push_back(kLargeSize);
return sizes_large;
}
const std::vector<gfx::Size> GetSizesSmallAndLarge() {
std::vector<gfx::Size> sizes_small_and_large;
sizes_small_and_large.push_back(kSmallSize);
sizes_small_and_large.push_back(kLargeSize);
return sizes_small_and_large;
}
const std::vector<gfx::Size> GetSizesTinySmallAndLarge() {
std::vector<gfx::Size> sizes_tiny_small_and_large;
sizes_tiny_small_and_large.push_back(kTinySize);
sizes_tiny_small_and_large.push_back(kSmallSize);
sizes_tiny_small_and_large.push_back(kLargeSize);
return sizes_tiny_small_and_large;
}
const std::vector<ui::ScaleFactor> GetScaleFactors1x2x() {
std::vector<ui::ScaleFactor> scale_factors_1x_2x;
scale_factors_1x_2x.push_back(ui::SCALE_FACTOR_100P);
scale_factors_1x_2x.push_back(ui::SCALE_FACTOR_200P);
return scale_factors_1x_2x;
}
size_t NumIconMappingsForPageURL(const GURL& page_url,
chrome::IconType icon_type) {
std::vector<IconMapping> icon_mappings;
backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type,
&icon_mappings);
return icon_mappings.size();
}
bool GetSortedIconMappingsForPageURL(
const GURL& page_url,
std::vector<IconMapping>* icon_mappings) {
if (!backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
icon_mappings)) {
return false;
}
std::sort(icon_mappings->begin(), icon_mappings->end(),
IconMappingLessThan);
return true;
}
bool GetSortedFaviconBitmaps(chrome::FaviconID icon_id,
std::vector<FaviconBitmap>* favicon_bitmaps) {
if (!backend_->thumbnail_db_->GetFaviconBitmaps(icon_id, favicon_bitmaps))
return false;
std::sort(favicon_bitmaps->begin(), favicon_bitmaps->end(),
FaviconBitmapLessThan);
return true;
}
bool GetOnlyFaviconBitmap(const chrome::FaviconID icon_id,
FaviconBitmap* favicon_bitmap) {
std::vector<FaviconBitmap> favicon_bitmaps;
if (!backend_->thumbnail_db_->GetFaviconBitmaps(icon_id, &favicon_bitmaps))
return false;
if (favicon_bitmaps.size() != 1)
return false;
*favicon_bitmap = favicon_bitmaps[0];
return true;
}
void GenerateFaviconBitmapData(
const GURL& icon_url1,
const std::vector<gfx::Size>& icon_url1_sizes,
std::vector<chrome::FaviconBitmapData>* favicon_bitmap_data) {
GenerateFaviconBitmapData(icon_url1, icon_url1_sizes, GURL(),
std::vector<gfx::Size>(), favicon_bitmap_data);
}
void GenerateFaviconBitmapData(
const GURL& icon_url1,
const std::vector<gfx::Size>& icon_url1_sizes,
const GURL& icon_url2,
const std::vector<gfx::Size>& icon_url2_sizes,
std::vector<chrome::FaviconBitmapData>* favicon_bitmap_data) {
favicon_bitmap_data->clear();
char bitmap_char = 'a';
for (size_t i = 0; i < icon_url1_sizes.size(); ++i) {
std::vector<unsigned char> data;
data.push_back(bitmap_char);
chrome::FaviconBitmapData bitmap_data_element;
bitmap_data_element.bitmap_data =
base::RefCountedBytes::TakeVector(&data);
bitmap_data_element.pixel_size = icon_url1_sizes[i];
bitmap_data_element.icon_url = icon_url1;
favicon_bitmap_data->push_back(bitmap_data_element);
++bitmap_char;
}
for (size_t i = 0; i < icon_url2_sizes.size(); ++i) {
std::vector<unsigned char> data;
data.push_back(bitmap_char);
chrome::FaviconBitmapData bitmap_data_element;
bitmap_data_element.bitmap_data =
base::RefCountedBytes::TakeVector(&data);
bitmap_data_element.pixel_size = icon_url2_sizes[i];
bitmap_data_element.icon_url = icon_url2;
favicon_bitmap_data->push_back(bitmap_data_element);
++bitmap_char;
}
}
bool BitmapDataEqual(char expected_data,
scoped_refptr<base::RefCountedMemory> bitmap_data) {
return bitmap_data.get() &&
bitmap_data->size() == 1u &&
*bitmap_data->front() == expected_data;
}
BookmarkModel bookmark_model_;
protected:
bool loaded_;
private:
friend class HistoryBackendTestDelegate;
virtual void SetUp() {
if (!base::CreateNewTempDirectory(FILE_PATH_LITERAL("BackendTest"),
&test_dir_))
return;
backend_ = new HistoryBackend(test_dir_,
new HistoryBackendTestDelegate(this),
&bookmark_model_);
backend_->Init(std::string(), false);
}
virtual void TearDown() {
if (backend_.get())
backend_->Closing();
backend_ = NULL;
mem_backend_.reset();
base::DeleteFile(test_dir_, true);
base::RunLoop().RunUntilIdle();
}
void SetInMemoryBackend(scoped_ptr<InMemoryHistoryBackend> backend) {
mem_backend_.swap(backend);
}
void BroadcastNotifications(int type, scoped_ptr<HistoryDetails> details) {
++num_broadcasted_notifications_;
content::Details<HistoryDetails> det(details.get());
mem_backend_->Observe(type, content::Source<HistoryBackendTest>(NULL), det);
}
int num_broadcasted_notifications_;
base::MessageLoop message_loop_;
base::FilePath test_dir_;
history::MostVisitedURLList most_visited_list_;
history::FilteredURLList filtered_list_;
content::TestBrowserThread ui_thread_;
};
void HistoryBackendTestDelegate::SetInMemoryBackend(
scoped_ptr<InMemoryHistoryBackend> backend) {
test_->SetInMemoryBackend(backend.Pass());
}
void HistoryBackendTestDelegate::BroadcastNotifications(
int type,
scoped_ptr<HistoryDetails> details) {
test_->BroadcastNotifications(type, details.Pass());
}
void HistoryBackendTestDelegate::DBLoaded() {
test_->loaded_ = true;
}
#if defined(OS_WIN)
#define MAYBE_Loaded DISABLED_Loaded
#else
#define MAYBE_Loaded Loaded
#endif
TEST_F(HistoryBackendTest, MAYBE_Loaded) {
ASSERT_TRUE(backend_.get());
ASSERT_TRUE(loaded_);
}
TEST_F(HistoryBackendTest, DeleteAll) {
ASSERT_TRUE(backend_.get());
GURL favicon_url1("http://www.google.com/favicon.ico");
GURL favicon_url2("http://news.google.com/favicon.ico");
chrome::FaviconID favicon2 = backend_->thumbnail_db_->AddFavicon(favicon_url2,
chrome::FAVICON);
chrome::FaviconID favicon1 = backend_->thumbnail_db_->AddFavicon(favicon_url1,
chrome::FAVICON);
std::vector<unsigned char> data;
data.push_back('a');
EXPECT_TRUE(backend_->thumbnail_db_->AddFaviconBitmap(favicon1,
new base::RefCountedBytes(data), Time::Now(), kSmallSize));
data[0] = 'b';
EXPECT_TRUE(backend_->thumbnail_db_->AddFaviconBitmap(favicon1,
new base::RefCountedBytes(data), Time::Now(), kLargeSize));
data[0] = 'c';
EXPECT_TRUE(backend_->thumbnail_db_->AddFaviconBitmap(favicon2,
new base::RefCountedBytes(data), Time::Now(), kSmallSize));
data[0] = 'd';
EXPECT_TRUE(backend_->thumbnail_db_->AddFaviconBitmap(favicon2,
new base::RefCountedBytes(data), Time::Now(), kLargeSize));
URLRow row1(GURL("http://www.google.com/"));
row1.set_visit_count(2);
row1.set_typed_count(1);
row1.set_last_visit(Time::Now());
backend_->thumbnail_db_->AddIconMapping(row1.url(), favicon1);
URLRow row2(GURL("http://news.google.com/"));
row2.set_visit_count(1);
row2.set_last_visit(Time::Now());
backend_->thumbnail_db_->AddIconMapping(row2.url(), favicon2);
URLRows rows;
rows.push_back(row2);
rows.push_back(row1);
backend_->AddPagesWithDetails(rows, history::SOURCE_BROWSED);
URLID row1_id = backend_->db_->GetRowForURL(row1.url(), NULL);
URLID row2_id = backend_->db_->GetRowForURL(row2.url(), NULL);
VisitVector visits;
backend_->db_->GetVisitsForURL(row1_id, &visits);
ASSERT_EQ(1U, visits.size());
visits.clear();
backend_->db_->GetVisitsForURL(row2_id, &visits);
ASSERT_EQ(1U, visits.size());
ASSERT_TRUE(mem_backend_.get());
URLRow outrow1;
EXPECT_TRUE(mem_backend_->db_->GetRowForURL(row1.url(), NULL));
bookmark_model_.AddURL(
bookmark_model_.bookmark_bar_node(), 0, base::string16(), row1.url());
backend_->DeleteAllHistory();
EXPECT_TRUE(backend_->db_->GetRowForURL(row1.url(), &outrow1));
EXPECT_EQ(row1.url(), outrow1.url());
EXPECT_EQ(0, outrow1.visit_count());
EXPECT_EQ(0, outrow1.typed_count());
EXPECT_TRUE(Time() == outrow1.last_visit());
URLRow outrow2;
EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), &outrow2));
VisitVector all_visits;
backend_->db_->GetAllVisitsInRange(Time(), Time(), 0, &all_visits);
ASSERT_EQ(0U, all_visits.size());
chrome::FaviconID out_favicon1 = backend_->thumbnail_db_->
GetFaviconIDForFaviconURL(favicon_url1, chrome::FAVICON, NULL);
EXPECT_TRUE(out_favicon1);
std::vector<FaviconBitmap> favicon_bitmaps;
EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(
out_favicon1, &favicon_bitmaps));
ASSERT_EQ(2u, favicon_bitmaps.size());
FaviconBitmap favicon_bitmap1 = favicon_bitmaps[0];
FaviconBitmap favicon_bitmap2 = favicon_bitmaps[1];
if (favicon_bitmap1.pixel_size == kLargeSize) {
FaviconBitmap tmp_favicon_bitmap = favicon_bitmap1;
favicon_bitmap1 = favicon_bitmap2;
favicon_bitmap2 = tmp_favicon_bitmap;
}
EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap1.bitmap_data));
EXPECT_EQ(kSmallSize, favicon_bitmap1.pixel_size);
EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmap2.bitmap_data));
EXPECT_EQ(kLargeSize, favicon_bitmap2.pixel_size);
chrome::FaviconID out_favicon2 = backend_->thumbnail_db_->
GetFaviconIDForFaviconURL(favicon_url2, chrome::FAVICON, NULL);
EXPECT_FALSE(out_favicon2) << "Favicon not deleted";
std::vector<IconMapping> mappings;
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
outrow1.url(), chrome::FAVICON, &mappings));
EXPECT_EQ(1u, mappings.size());
EXPECT_EQ(out_favicon1, mappings[0].icon_id);
EXPECT_TRUE(bookmark_model_.IsBookmarked(row1.url()));
}
TEST_F(HistoryBackendTest, DeleteAllThenAddData) {
ASSERT_TRUE(backend_.get());
Time visit_time = Time::Now();
GURL url("http://www.google.com/");
HistoryAddPageArgs request(url, visit_time, NULL, 0, GURL(),
history::RedirectList(),
content::PAGE_TRANSITION_KEYWORD_GENERATED,
history::SOURCE_BROWSED, false);
backend_->AddPage(request);
URLRow outrow;
EXPECT_TRUE(backend_->db_->GetRowForURL(url, &outrow));
VisitVector all_visits;
backend_->db_->GetAllVisitsInRange(Time(), Time(), 0, &all_visits);
ASSERT_EQ(1U, all_visits.size());
backend_->DeleteAllHistory();
EXPECT_FALSE(backend_->db_->GetRowForURL(url, &outrow));
backend_->db_->GetAllVisitsInRange(Time(), Time(), 0, &all_visits);
ASSERT_EQ(0U, all_visits.size());
backend_->SetPageTitle(url, base::UTF8ToUTF16("Title"));
EXPECT_FALSE(backend_->db_->GetRowForURL(url, &outrow));
backend_->db_->GetAllVisitsInRange(Time(), Time(), 0, &all_visits);
ASSERT_EQ(0U, all_visits.size());
}
TEST_F(HistoryBackendTest, URLsNoLongerBookmarked) {
GURL favicon_url1("http://www.google.com/favicon.ico");
GURL favicon_url2("http://news.google.com/favicon.ico");
std::vector<unsigned char> data;
data.push_back('1');
chrome::FaviconID favicon1 = backend_->thumbnail_db_->AddFavicon(
favicon_url1,
chrome::FAVICON,
new base::RefCountedBytes(data),
Time::Now(),
gfx::Size());
data[0] = '2';
chrome::FaviconID favicon2 = backend_->thumbnail_db_->AddFavicon(
favicon_url2,
chrome::FAVICON,
new base::RefCountedBytes(data),
Time::Now(),
gfx::Size());
URLRow row1(GURL("http://www.google.com/"));
row1.set_visit_count(2);
row1.set_typed_count(1);
row1.set_last_visit(Time::Now());
EXPECT_TRUE(backend_->thumbnail_db_->AddIconMapping(row1.url(), favicon1));
URLRow row2(GURL("http://news.google.com/"));
row2.set_visit_count(1);
row2.set_last_visit(Time::Now());
EXPECT_TRUE(backend_->thumbnail_db_->AddIconMapping(row2.url(), favicon2));
URLRows rows;
rows.push_back(row2);
rows.push_back(row1);
backend_->AddPagesWithDetails(rows, history::SOURCE_BROWSED);
URLID row1_id = backend_->db_->GetRowForURL(row1.url(), NULL);
URLID row2_id = backend_->db_->GetRowForURL(row2.url(), NULL);
bookmark_utils::AddIfNotBookmarked(&bookmark_model_, row1.url(),
base::string16());
bookmark_utils::AddIfNotBookmarked(&bookmark_model_, row2.url(),
base::string16());
backend_->expirer_.DeleteURL(row2.url());
URLRow tmp_url_row;
EXPECT_EQ(row2_id, backend_->db_->GetRowForURL(row2.url(), NULL));
VisitVector visits;
backend_->db_->GetVisitsForURL(row2_id, &visits);
EXPECT_EQ(0U, visits.size());
EXPECT_EQ(favicon2,
backend_->thumbnail_db_->GetFaviconIDForFaviconURL(favicon_url2,
chrome::FAVICON,
NULL));
bookmark_utils::RemoveAllBookmarks(&bookmark_model_, row2.url());
std::set<GURL> unstarred_urls;
unstarred_urls.insert(row2.url());
backend_->URLsNoLongerBookmarked(unstarred_urls);
EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), &tmp_url_row));
EXPECT_EQ(0,
backend_->thumbnail_db_->GetFaviconIDForFaviconURL(favicon_url2,
chrome::FAVICON,
NULL));
bookmark_utils::RemoveAllBookmarks(&bookmark_model_, row1.url());
unstarred_urls.clear();
unstarred_urls.insert(row1.url());
backend_->URLsNoLongerBookmarked(unstarred_urls);
EXPECT_EQ(row1_id, backend_->db_->GetRowForURL(row1.url(), NULL));
visits.clear();
backend_->db_->GetVisitsForURL(row1_id, &visits);
EXPECT_EQ(1U, visits.size());
EXPECT_EQ(favicon1,
backend_->thumbnail_db_->GetFaviconIDForFaviconURL(favicon_url1,
chrome::FAVICON,
NULL));
}
TEST_F(HistoryBackendTest, KeywordGenerated) {
ASSERT_TRUE(backend_.get());
GURL url("http://google.com");
Time visit_time = Time::Now() - base::TimeDelta::FromDays(1);
HistoryAddPageArgs request(url, visit_time, NULL, 0, GURL(),
history::RedirectList(),
content::PAGE_TRANSITION_KEYWORD_GENERATED,
history::SOURCE_BROWSED, false);
backend_->AddPage(request);
URLRow row;
URLID url_id = backend_->db()->GetRowForURL(url, &row);
ASSERT_NE(0, url_id);
ASSERT_EQ(1, row.typed_count());
std::string segment_name = VisitSegmentDatabase::ComputeSegmentName(url);
EXPECT_EQ(0, backend_->db()->GetSegmentNamed(segment_name));
VisitVector visits;
EXPECT_TRUE(backend_->db()->GetVisitsForURL(url_id, &visits));
EXPECT_EQ(1U, visits.size());
visits.clear();
QueryOptions query_options;
query_options.max_count = 1;
backend_->db()->GetVisibleVisitsInRange(query_options, &visits);
EXPECT_TRUE(visits.empty());
std::set<GURL> restrict_urls;
backend_->expire_backend()->ExpireHistoryBetween(restrict_urls,
visit_time, Time::Now());
visits.clear();
EXPECT_TRUE(backend_->db()->GetVisitsForURL(url_id, &visits));
EXPECT_TRUE(visits.empty());
ASSERT_EQ(0, backend_->db()->GetRowForURL(url, &row));
}
TEST_F(HistoryBackendTest, ClientRedirect) {
ASSERT_TRUE(backend_.get());
int transition1;
int transition2;
GURL url_a("http://google.com/a");
AddClientRedirect(GURL(), url_a, false, base::Time(),
&transition1, &transition2);
EXPECT_TRUE(transition2 & content::PAGE_TRANSITION_CHAIN_END);
GURL url_b("http://google.com/b");
AddClientRedirect(url_a, url_b, false, base::Time(),
&transition1, &transition2);
EXPECT_TRUE(transition1 & content::PAGE_TRANSITION_CHAIN_END);
EXPECT_TRUE(transition2 & content::PAGE_TRANSITION_CHAIN_END);
GURL url_c("http://google.com/c");
AddClientRedirect(url_b, url_c, true, base::Time(),
&transition1, &transition2);
EXPECT_FALSE(transition1 & content::PAGE_TRANSITION_CHAIN_END);
EXPECT_TRUE(transition2 & content::PAGE_TRANSITION_CHAIN_END);
}
TEST_F(HistoryBackendTest, ImportedFaviconsTest) {
GURL favicon_url1("http://www.google.com/favicon.ico");
std::vector<unsigned char> data;
data.push_back('1');
chrome::FaviconID favicon1 = backend_->thumbnail_db_->AddFavicon(
favicon_url1,
chrome::FAVICON,
base::RefCountedBytes::TakeVector(&data),
Time::Now(),
gfx::Size());
URLRow row1(GURL("http://www.google.com/"));
row1.set_visit_count(1);
row1.set_last_visit(Time::Now());
EXPECT_TRUE(backend_->thumbnail_db_->AddIconMapping(row1.url(), favicon1));
URLRow row2(GURL("http://news.google.com/"));
row2.set_visit_count(1);
row2.set_last_visit(Time::Now());
URLRows rows;
rows.push_back(row1);
rows.push_back(row2);
backend_->AddPagesWithDetails(rows, history::SOURCE_BROWSED);
URLRow url_row1, url_row2;
EXPECT_FALSE(backend_->db_->GetRowForURL(row1.url(), &url_row1) == 0);
EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), &url_row2) == 0);
EXPECT_EQ(1u, NumIconMappingsForPageURL(row1.url(), chrome::FAVICON));
EXPECT_EQ(0u, NumIconMappingsForPageURL(row2.url(), chrome::FAVICON));
std::vector<ImportedFaviconUsage> favicons;
ImportedFaviconUsage favicon;
favicon.favicon_url = GURL("http://news.google.com/favicon.ico");
favicon.png_data.push_back('2');
favicon.urls.insert(row1.url());
favicon.urls.insert(row2.url());
favicons.push_back(favicon);
backend_->SetImportedFavicons(favicons);
EXPECT_FALSE(backend_->db_->GetRowForURL(row1.url(), &url_row1) == 0);
EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), &url_row2) == 0);
std::vector<IconMapping> mappings;
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
row1.url(), chrome::FAVICON, &mappings));
EXPECT_EQ(1u, mappings.size());
EXPECT_EQ(favicon1, mappings[0].icon_id);
EXPECT_EQ(favicon_url1, mappings[0].icon_url);
mappings.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
row2.url(), chrome::FAVICON, &mappings));
EXPECT_EQ(1u, mappings.size());
EXPECT_EQ(favicon.favicon_url, mappings[0].icon_url);
GURL url3("http://mail.google.com");
favicons.clear();
favicon.favicon_url = GURL("http://mail.google.com/favicon.ico");
favicon.png_data.push_back('3');
favicon.urls.insert(url3);
favicons.push_back(favicon);
backend_->SetImportedFavicons(favicons);
URLRow url_row3;
EXPECT_TRUE(backend_->db_->GetRowForURL(url3, &url_row3) == 0);
bookmark_model_.AddURL(bookmark_model_.bookmark_bar_node(), 0,
base::string16(), url3);
backend_->SetImportedFavicons(favicons);
EXPECT_FALSE(backend_->db_->GetRowForURL(url3, &url_row3) == 0);
EXPECT_TRUE(url_row3.visit_count() == 0);
}
TEST_F(HistoryBackendTest, StripUsernamePasswordTest) {
ASSERT_TRUE(backend_.get());
GURL url("http://anyuser:anypass@www.google.com");
GURL stripped_url("http://www.google.com");
backend_->DeleteAllHistory();
backend_->AddPageVisit(url, base::Time::Now(), 0,
content::PageTransitionFromInt(
content::PageTransitionGetQualifier(content::PAGE_TRANSITION_TYPED)),
history::SOURCE_BROWSED);
VisitVector visits;
URLID row_id = backend_->db_->GetRowForURL(stripped_url, NULL);
backend_->db_->GetVisitsForURL(row_id, &visits);
ASSERT_EQ(1U, visits.size());
}
TEST_F(HistoryBackendTest, AddPageVisitSource) {
ASSERT_TRUE(backend_.get());
GURL url("http://www.google.com");
backend_->DeleteAllHistory();
backend_->AddPageVisit(
url, base::Time::Now(), 0, content::PAGE_TRANSITION_TYPED,
history::SOURCE_EXTENSION);
backend_->AddPageVisit(url, base::Time::Now(), 0,
content::PAGE_TRANSITION_TYPED,
history::SOURCE_FIREFOX_IMPORTED);
backend_->AddPageVisit(url, base::Time::Now(), 0,
content::PAGE_TRANSITION_TYPED,
history::SOURCE_SYNCED);
VisitVector visits;
URLID row_id = backend_->db_->GetRowForURL(url, NULL);
backend_->db_->GetVisitsForURL(row_id, &visits);
ASSERT_EQ(3U, visits.size());
VisitSourceMap visit_sources;
ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
ASSERT_EQ(3U, visit_sources.size());
int sources = 0;
for (int i = 0; i < 3; i++) {
switch (visit_sources[visits[i].visit_id]) {
case history::SOURCE_EXTENSION:
sources |= 0x1;
break;
case history::SOURCE_FIREFOX_IMPORTED:
sources |= 0x2;
break;
case history::SOURCE_SYNCED:
sources |= 0x4;
default:
break;
}
}
EXPECT_EQ(0x7, sources);
}
TEST_F(HistoryBackendTest, AddPageVisitNotLastVisit) {
ASSERT_TRUE(backend_.get());
GURL url("http://www.google.com");
backend_->DeleteAllHistory();
base::Time recent_time = base::Time::Now();
base::TimeDelta visit_age = base::TimeDelta::FromDays(3);
base::Time older_time = recent_time - visit_age;
backend_->AddPageVisit(url, recent_time, 0,
content::PageTransitionFromInt(
content::PageTransitionGetQualifier(content::PAGE_TRANSITION_TYPED)),
history::SOURCE_BROWSED);
backend_->AddPageVisit(url, older_time, 0,
content::PageTransitionFromInt(
content::PageTransitionGetQualifier(content::PAGE_TRANSITION_TYPED)),
history::SOURCE_SYNCED);
VisitVector visits;
URLRow row;
URLID row_id = backend_->db_->GetRowForURL(url, &row);
backend_->db_->GetVisitsForURL(row_id, &visits);
ASSERT_EQ(2U, visits.size());
ASSERT_EQ(recent_time, row.last_visit());
}
TEST_F(HistoryBackendTest, AddPageArgsSource) {
ASSERT_TRUE(backend_.get());
GURL url("http://testpageargs.com");
HistoryAddPageArgs request1(url, base::Time::Now(), NULL, 0, GURL(),
history::RedirectList(),
content::PAGE_TRANSITION_KEYWORD_GENERATED,
history::SOURCE_BROWSED, false);
backend_->AddPage(request1);
HistoryAddPageArgs request2(url, base::Time::Now(), NULL, 0, GURL(),
history::RedirectList(),
content::PAGE_TRANSITION_LINK,
history::SOURCE_SYNCED, false);
backend_->AddPage(request2);
HistoryAddPageArgs request3(url, base::Time::Now(), NULL, 0, GURL(),
history::RedirectList(),
content::PAGE_TRANSITION_TYPED,
history::SOURCE_BROWSED, false);
backend_->AddPage(request3);
VisitVector visits;
URLRow row;
URLID id = backend_->db()->GetRowForURL(url, &row);
ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
ASSERT_EQ(3U, visits.size());
VisitSourceMap visit_sources;
ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
ASSERT_EQ(1U, visit_sources.size());
EXPECT_EQ(history::SOURCE_SYNCED, visit_sources.begin()->second);
}
TEST_F(HistoryBackendTest, AddVisitsSource) {
ASSERT_TRUE(backend_.get());
GURL url1("http://www.cnn.com");
std::vector<VisitInfo> visits1, visits2;
visits1.push_back(VisitInfo(
Time::Now() - base::TimeDelta::FromDays(5),
content::PAGE_TRANSITION_LINK));
visits1.push_back(VisitInfo(
Time::Now() - base::TimeDelta::FromDays(1),
content::PAGE_TRANSITION_LINK));
visits1.push_back(VisitInfo(
Time::Now(), content::PAGE_TRANSITION_LINK));
GURL url2("http://www.example.com");
visits2.push_back(VisitInfo(
Time::Now() - base::TimeDelta::FromDays(10),
content::PAGE_TRANSITION_LINK));
visits2.push_back(VisitInfo(Time::Now(), content::PAGE_TRANSITION_LINK));
backend_->DeleteAllHistory();
backend_->AddVisits(url1, visits1, history::SOURCE_IE_IMPORTED);
backend_->AddVisits(url2, visits2, history::SOURCE_SYNCED);
VisitVector visits;
URLRow row;
URLID id = backend_->db()->GetRowForURL(url1, &row);
ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
ASSERT_EQ(3U, visits.size());
VisitSourceMap visit_sources;
ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
ASSERT_EQ(3U, visit_sources.size());
for (int i = 0; i < 3; i++)
EXPECT_EQ(history::SOURCE_IE_IMPORTED, visit_sources[visits[i].visit_id]);
id = backend_->db()->GetRowForURL(url2, &row);
ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
ASSERT_EQ(2U, visits.size());
ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
ASSERT_EQ(2U, visit_sources.size());
for (int i = 0; i < 2; i++)
EXPECT_EQ(history::SOURCE_SYNCED, visit_sources[visits[i].visit_id]);
}
TEST_F(HistoryBackendTest, GetMostRecentVisits) {
ASSERT_TRUE(backend_.get());
GURL url1("http://www.cnn.com");
std::vector<VisitInfo> visits1;
visits1.push_back(VisitInfo(
Time::Now() - base::TimeDelta::FromDays(5),
content::PAGE_TRANSITION_LINK));
visits1.push_back(VisitInfo(
Time::Now() - base::TimeDelta::FromDays(1),
content::PAGE_TRANSITION_LINK));
visits1.push_back(VisitInfo(
Time::Now(), content::PAGE_TRANSITION_LINK));
backend_->DeleteAllHistory();
backend_->AddVisits(url1, visits1, history::SOURCE_IE_IMPORTED);
VisitVector visits;
URLRow row;
URLID id = backend_->db()->GetRowForURL(url1, &row);
ASSERT_TRUE(backend_->db()->GetMostRecentVisitsForURL(id, 1, &visits));
ASSERT_EQ(1U, visits.size());
EXPECT_EQ(visits1[2].first, visits[0].visit_time);
}
TEST_F(HistoryBackendTest, RemoveVisitsTransitions) {
ASSERT_TRUE(backend_.get());
backend_->DeleteAllHistory();
GURL url1("http://www.cnn.com");
VisitInfo typed_visit(
Time::Now() - base::TimeDelta::FromDays(6),
content::PAGE_TRANSITION_TYPED);
VisitInfo reload_visit(
Time::Now() - base::TimeDelta::FromDays(5),
content::PAGE_TRANSITION_RELOAD);
VisitInfo link_visit(
Time::Now() - base::TimeDelta::FromDays(4),
content::PAGE_TRANSITION_LINK);
std::vector<VisitInfo> visits_to_add;
visits_to_add.push_back(typed_visit);
visits_to_add.push_back(reload_visit);
visits_to_add.push_back(link_visit);
backend_->AddVisits(url1, visits_to_add, history::SOURCE_SYNCED);
VisitVector visits;
URLRow row;
URLID id = backend_->db()->GetRowForURL(url1, &row);
ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
ASSERT_EQ(3U, visits.size());
ASSERT_EQ(1, row.typed_count());
ASSERT_EQ(2, row.visit_count());
ASSERT_TRUE(backend_->RemoveVisits(VisitVector(1, visits[0])));
id = backend_->db()->GetRowForURL(url1, &row);
ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
ASSERT_EQ(2U, visits.size());
ASSERT_EQ(0, row.typed_count());
ASSERT_EQ(1, row.visit_count());
ASSERT_TRUE(backend_->RemoveVisits(VisitVector(1, visits[0])));
id = backend_->db()->GetRowForURL(url1, &row);
ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
ASSERT_EQ(1U, visits.size());
ASSERT_EQ(0, row.typed_count());
ASSERT_EQ(1, row.visit_count());
ASSERT_TRUE(backend_->RemoveVisits(VisitVector(1, visits[0])));
ASSERT_EQ(0, backend_->db()->GetRowForURL(url1, &row));
}
TEST_F(HistoryBackendTest, RemoveVisitsSource) {
ASSERT_TRUE(backend_.get());
GURL url1("http://www.cnn.com");
std::vector<VisitInfo> visits1, visits2;
visits1.push_back(VisitInfo(
Time::Now() - base::TimeDelta::FromDays(5),
content::PAGE_TRANSITION_LINK));
visits1.push_back(VisitInfo(Time::Now(),
content::PAGE_TRANSITION_LINK));
GURL url2("http://www.example.com");
visits2.push_back(VisitInfo(
Time::Now() - base::TimeDelta::FromDays(10),
content::PAGE_TRANSITION_LINK));
visits2.push_back(VisitInfo(Time::Now(), content::PAGE_TRANSITION_LINK));
backend_->DeleteAllHistory();
backend_->AddVisits(url1, visits1, history::SOURCE_IE_IMPORTED);
backend_->AddVisits(url2, visits2, history::SOURCE_SYNCED);
VisitVector visits;
URLRow row;
URLID id = backend_->db()->GetRowForURL(url1, &row);
ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
ASSERT_EQ(2U, visits.size());
ASSERT_TRUE(backend_->RemoveVisits(visits));
VisitSourceMap visit_sources;
ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
ASSERT_EQ(0U, visit_sources.size());
id = backend_->db()->GetRowForURL(url2, &row);
ASSERT_TRUE(backend_->db()->GetVisitsForURL(id, &visits));
ASSERT_EQ(2U, visits.size());
ASSERT_TRUE(backend_->GetVisitsSource(visits, &visit_sources));
ASSERT_EQ(2U, visit_sources.size());
for (int i = 0; i < 2; i++)
EXPECT_EQ(history::SOURCE_SYNCED, visit_sources[visits[i].visit_id]);
}
TEST_F(HistoryBackendTest, MigrationVisitSource) {
ASSERT_TRUE(backend_.get());
backend_->Closing();
backend_ = NULL;
base::FilePath old_history_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &old_history_path));
old_history_path = old_history_path.AppendASCII("History");
old_history_path = old_history_path.AppendASCII("HistoryNoSource");
base::FilePath new_history_path(getTestDir());
base::DeleteFile(new_history_path, true);
base::CreateDirectory(new_history_path);
base::FilePath new_history_file =
new_history_path.Append(chrome::kHistoryFilename);
ASSERT_TRUE(base::CopyFile(old_history_path, new_history_file));
backend_ = new HistoryBackend(new_history_path,
new HistoryBackendTestDelegate(this),
&bookmark_model_);
backend_->Init(std::string(), false);
backend_->Closing();
backend_ = NULL;
int cur_version = HistoryDatabase::GetCurrentVersion();
sql::Connection db;
ASSERT_TRUE(db.Open(new_history_file));
sql::Statement s(db.GetUniqueStatement(
"SELECT value FROM meta WHERE key = 'version'"));
ASSERT_TRUE(s.Step());
int file_version = s.ColumnInt(0);
EXPECT_EQ(cur_version, file_version);
s.Assign(db.GetUniqueStatement(
"SELECT name FROM sqlite_master WHERE name=\"visit_source\""));
ASSERT_TRUE(s.Step());
s.Assign(db.GetUniqueStatement("SELECT * FROM visit_source LIMIT 10"));
EXPECT_FALSE(s.Step());
}
TEST_F(HistoryBackendTest, SetFaviconMappingsForPageAndRedirects) {
const GURL url1("http://www.google.com");
const GURL url2("http://www.google.com/m");
URLRow url_info1(url1);
url_info1.set_visit_count(0);
url_info1.set_typed_count(0);
url_info1.set_last_visit(base::Time());
url_info1.set_hidden(false);
backend_->db_->AddURL(url_info1);
URLRow url_info2(url2);
url_info2.set_visit_count(0);
url_info2.set_typed_count(0);
url_info2.set_last_visit(base::Time());
url_info2.set_hidden(false);
backend_->db_->AddURL(url_info2);
history::RedirectList redirects;
redirects.push_back(url2);
redirects.push_back(url1);
backend_->recent_redirects_.Put(url1, redirects);
const GURL icon_url1("http://www.google.com/icon");
const GURL icon_url2("http://www.google.com/icon2");
std::vector<chrome::FaviconBitmapData> two_favicon_bitmap_data;
GenerateFaviconBitmapData(icon_url1, GetSizesSmallAndLarge(),
icon_url2, GetSizesSmallAndLarge(), &two_favicon_bitmap_data);
std::vector<chrome::FaviconBitmapData> one_favicon_bitmap_data;
GenerateFaviconBitmapData(icon_url1, GetSizesSmallAndLarge(),
&one_favicon_bitmap_data);
backend_->SetFavicons(url1, chrome::FAVICON, two_favicon_bitmap_data);
EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
EXPECT_EQ(2u, NumIconMappingsForPageURL(url2, chrome::FAVICON));
backend_->SetFavicons(url1, chrome::TOUCH_ICON, one_favicon_bitmap_data);
EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
EXPECT_EQ(1u, NumIconMappingsForPageURL(url2, chrome::TOUCH_ICON));
EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
backend_->SetFavicons(
url1, chrome::TOUCH_PRECOMPOSED_ICON, one_favicon_bitmap_data);
EXPECT_EQ(0u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
EXPECT_EQ(1u,
NumIconMappingsForPageURL(url1, chrome::TOUCH_PRECOMPOSED_ICON));
EXPECT_EQ(1u,
NumIconMappingsForPageURL(url2, chrome::TOUCH_PRECOMPOSED_ICON));
backend_->SetFavicons(url1, chrome::TOUCH_ICON, one_favicon_bitmap_data);
EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
EXPECT_EQ(0u,
NumIconMappingsForPageURL(url1, chrome::TOUCH_PRECOMPOSED_ICON));
backend_->SetFavicons(url1, chrome::FAVICON, one_favicon_bitmap_data);
EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
EXPECT_EQ(1u, NumIconMappingsForPageURL(url2, chrome::FAVICON));
backend_->SetFavicons(url1, chrome::FAVICON, two_favicon_bitmap_data);
EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, chrome::TOUCH_ICON));
EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, chrome::FAVICON));
}
TEST_F(HistoryBackendTest, SetFaviconMappingsForPageDuplicates) {
const GURL url("http://www.google.com/");
const GURL icon_url("http://www.google.com/icon");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
GenerateFaviconBitmapData(icon_url, GetSizesSmallAndLarge(),
&favicon_bitmap_data);
backend_->SetFavicons(url, chrome::FAVICON, favicon_bitmap_data);
std::vector<IconMapping> icon_mappings;
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
url, chrome::FAVICON, &icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
IconMappingID mapping_id = icon_mappings[0].mapping_id;
backend_->SetFavicons(url, chrome::FAVICON, favicon_bitmap_data);
icon_mappings.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
url, chrome::FAVICON, &icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(mapping_id, icon_mappings[0].mapping_id);
}
TEST_F(HistoryBackendTest, SetFaviconsDeleteBitmaps) {
const GURL page_url("http://www.google.com/");
const GURL icon_url("http://www.google.com/icon");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
GenerateFaviconBitmapData(icon_url, GetSizesSmallAndLarge(),
&favicon_bitmap_data);
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
std::vector<IconMapping> icon_mappings;
EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url, &icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(icon_url, icon_mappings[0].icon_url);
EXPECT_EQ(chrome::FAVICON, icon_mappings[0].icon_type);
chrome::FaviconID favicon_id = icon_mappings[0].icon_id;
std::vector<FaviconBitmap> favicon_bitmaps;
EXPECT_TRUE(GetSortedFaviconBitmaps(favicon_id, &favicon_bitmaps));
EXPECT_EQ(2u, favicon_bitmaps.size());
FaviconBitmapID small_bitmap_id = favicon_bitmaps[0].bitmap_id;
EXPECT_NE(0, small_bitmap_id);
EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmaps[0].bitmap_data));
EXPECT_EQ(kSmallSize, favicon_bitmaps[0].pixel_size);
FaviconBitmapID large_bitmap_id = favicon_bitmaps[1].bitmap_id;
EXPECT_NE(0, large_bitmap_id);
EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmaps[1].bitmap_data));
EXPECT_EQ(kLargeSize, favicon_bitmaps[1].pixel_size);
GenerateFaviconBitmapData(icon_url, GetSizesLarge(), &favicon_bitmap_data);
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
scoped_refptr<base::RefCountedMemory> bitmap_data_out;
gfx::Size pixel_size_out;
EXPECT_FALSE(backend_->thumbnail_db_->GetFaviconBitmap(small_bitmap_id,
NULL, &bitmap_data_out, &pixel_size_out));
EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmap(large_bitmap_id,
NULL, &bitmap_data_out, &pixel_size_out));
EXPECT_TRUE(BitmapDataEqual('a', bitmap_data_out));
EXPECT_EQ(kLargeSize, pixel_size_out);
icon_mappings.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
&icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);
favicon_bitmap_data.clear();
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
EXPECT_FALSE(backend_->thumbnail_db_->GetFaviconBitmap(large_bitmap_id, NULL,
NULL, NULL));
icon_mappings.clear();
EXPECT_FALSE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
&icon_mappings));
EXPECT_EQ(3, num_broadcasted_notifications());
}
TEST_F(HistoryBackendTest, SetFaviconsReplaceBitmapData) {
const GURL page_url("http://www.google.com/");
const GURL icon_url("http://www.google.com/icon");
std::vector<unsigned char> data_initial;
data_initial.push_back('a');
chrome::FaviconBitmapData bitmap_data_element;
bitmap_data_element.bitmap_data =
base::RefCountedBytes::TakeVector(&data_initial);
bitmap_data_element.pixel_size = kSmallSize;
bitmap_data_element.icon_url = icon_url;
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
favicon_bitmap_data.push_back(bitmap_data_element);
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
chrome::FaviconID original_favicon_id =
backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
icon_url, chrome::FAVICON, NULL);
EXPECT_NE(0, original_favicon_id);
FaviconBitmap original_favicon_bitmap;
EXPECT_TRUE(
GetOnlyFaviconBitmap(original_favicon_id, &original_favicon_bitmap));
EXPECT_TRUE(BitmapDataEqual('a', original_favicon_bitmap.bitmap_data));
EXPECT_EQ(1, num_broadcasted_notifications());
std::vector<unsigned char> updated_data;
updated_data.push_back('a');
favicon_bitmap_data[0].bitmap_data = new base::RefCountedBytes(updated_data);
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
chrome::FaviconID updated_favicon_id =
backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
icon_url, chrome::FAVICON, NULL);
EXPECT_NE(0, updated_favicon_id);
FaviconBitmap updated_favicon_bitmap;
EXPECT_TRUE(
GetOnlyFaviconBitmap(updated_favicon_id, &updated_favicon_bitmap));
EXPECT_TRUE(BitmapDataEqual('a', updated_favicon_bitmap.bitmap_data));
EXPECT_EQ(1, num_broadcasted_notifications());
updated_data[0] = 'b';
favicon_bitmap_data[0].bitmap_data = new base::RefCountedBytes(updated_data);
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
updated_favicon_id =
backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
icon_url, chrome::FAVICON, NULL);
EXPECT_NE(0, updated_favicon_id);
EXPECT_TRUE(
GetOnlyFaviconBitmap(updated_favicon_id, &updated_favicon_bitmap));
EXPECT_TRUE(BitmapDataEqual('b', updated_favicon_bitmap.bitmap_data));
EXPECT_EQ(original_favicon_bitmap.icon_id, updated_favicon_bitmap.icon_id);
EXPECT_EQ(original_favicon_bitmap.bitmap_id,
updated_favicon_bitmap.bitmap_id);
EXPECT_EQ(2, num_broadcasted_notifications());
}
TEST_F(HistoryBackendTest, SetFaviconsSameFaviconURLForTwoPages) {
GURL icon_url("http://www.google.com/favicon.ico");
GURL icon_url_new("http://www.google.com/favicon2.ico");
GURL page_url1("http://www.google.com");
GURL page_url2("http://www.google.ca");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
GenerateFaviconBitmapData(icon_url, GetSizesSmallAndLarge(),
&favicon_bitmap_data);
backend_->SetFavicons(page_url1, chrome::FAVICON, favicon_bitmap_data);
std::vector<GURL> icon_urls;
icon_urls.push_back(icon_url);
std::vector<chrome::FaviconBitmapResult> bitmap_results;
backend_->UpdateFaviconMappingsAndFetch(
page_url2, icon_urls, chrome::FAVICON, kSmallSize.width(),
GetScaleFactors1x2x(), &bitmap_results);
std::vector<IconMapping> icon_mappings;
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
page_url1, &icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
chrome::FaviconID favicon_id = icon_mappings[0].icon_id;
EXPECT_NE(0, favicon_id);
icon_mappings.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
page_url2, &icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);
GenerateFaviconBitmapData(icon_url_new, GetSizesSmall(),
&favicon_bitmap_data);
backend_->SetFavicons(page_url1, chrome::FAVICON, favicon_bitmap_data);
icon_mappings.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
page_url1, &icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(icon_url_new, icon_mappings[0].icon_url);
EXPECT_NE(favicon_id, icon_mappings[0].icon_id);
std::vector<FaviconBitmap> favicon_bitmaps;
EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(
icon_mappings[0].icon_id, &favicon_bitmaps));
EXPECT_EQ(1u, favicon_bitmaps.size());
icon_mappings.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
page_url2, &icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);
favicon_bitmaps.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(favicon_id,
&favicon_bitmaps));
EXPECT_EQ(2u, favicon_bitmaps.size());
EXPECT_EQ(3, num_broadcasted_notifications());
}
TEST_F(HistoryBackendTest, UpdateFaviconMappingsAndFetchNoChange) {
GURL page_url("http://www.google.com");
GURL icon_url("http://www.google.com/favicon.ico");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
GenerateFaviconBitmapData(icon_url, GetSizesSmall(), &favicon_bitmap_data);
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
chrome::FaviconID icon_id =
backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
icon_url, chrome::FAVICON, NULL);
EXPECT_NE(0, icon_id);
EXPECT_EQ(1, num_broadcasted_notifications());
std::vector<GURL> icon_urls;
icon_urls.push_back(icon_url);
std::vector<chrome::FaviconBitmapResult> bitmap_results;
backend_->UpdateFaviconMappingsAndFetch(
page_url, icon_urls, chrome::FAVICON, kSmallSize.width(),
GetScaleFactors1x2x(), &bitmap_results);
EXPECT_EQ(icon_id, backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
icon_url, chrome::FAVICON, NULL));
EXPECT_EQ(1, num_broadcasted_notifications());
}
TEST_F(HistoryBackendTest, MergeFaviconPageURLNotInDB) {
GURL page_url("http://www.google.com");
GURL icon_url("http:/www.google.com/favicon.ico");
std::vector<unsigned char> data;
data.push_back('a');
scoped_refptr<base::RefCountedBytes> bitmap_data(
new base::RefCountedBytes(data));
backend_->MergeFavicon(
page_url, icon_url, chrome::FAVICON, bitmap_data, kSmallSize);
std::vector<IconMapping> icon_mappings;
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
&icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(icon_url, icon_mappings[0].icon_url);
FaviconBitmap favicon_bitmap;
EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
data[0] = 'b';
bitmap_data = new base::RefCountedBytes(data);
backend_->MergeFavicon(
page_url, icon_url, chrome::FAVICON, bitmap_data, kSmallSize);
icon_mappings.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
&icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(icon_url, icon_mappings[0].icon_url);
EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmap.bitmap_data));
EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
}
TEST_F(HistoryBackendTest, MergeFaviconPageURLInDB) {
GURL page_url("http://www.google.com");
GURL icon_url1("http:/www.google.com/favicon.ico");
GURL icon_url2("http://www.google.com/favicon2.ico");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
GenerateFaviconBitmapData(icon_url1, GetSizesSmall(),
&favicon_bitmap_data);
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
std::vector<IconMapping> icon_mappings;
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
&icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(icon_url1, icon_mappings[0].icon_url);
FaviconBitmap favicon_bitmap;
EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
EXPECT_EQ(1, num_broadcasted_notifications());
std::vector<unsigned char> data;
data.push_back('a');
scoped_refptr<base::RefCountedBytes> bitmap_data(
new base::RefCountedBytes(data));
backend_->MergeFavicon(
page_url, icon_url1, chrome::FAVICON, bitmap_data, kSmallSize);
icon_mappings.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
&icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(icon_url1, icon_mappings[0].icon_url);
EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
EXPECT_EQ(1, num_broadcasted_notifications());
data[0] = 'b';
bitmap_data = new base::RefCountedBytes(data);
backend_->MergeFavicon(
page_url, icon_url1, chrome::FAVICON, bitmap_data, kSmallSize);
icon_mappings.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
&icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(icon_url1, icon_mappings[0].icon_url);
EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmap.bitmap_data));
EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
data[0] = 'c';
bitmap_data = new base::RefCountedBytes(data);
backend_->MergeFavicon(
page_url, icon_url1, chrome::FAVICON, bitmap_data, kTinySize);
icon_mappings.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
&icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(icon_url1, icon_mappings[0].icon_url);
std::vector<FaviconBitmap> favicon_bitmaps;
EXPECT_TRUE(GetSortedFaviconBitmaps(icon_mappings[0].icon_id,
&favicon_bitmaps));
EXPECT_NE(base::Time(), favicon_bitmaps[0].last_updated);
EXPECT_TRUE(BitmapDataEqual('c', favicon_bitmaps[0].bitmap_data));
EXPECT_EQ(kTinySize, favicon_bitmaps[0].pixel_size);
EXPECT_EQ(base::Time(), favicon_bitmaps[1].last_updated);
EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmaps[1].bitmap_data));
EXPECT_EQ(kSmallSize, favicon_bitmaps[1].pixel_size);
data[0] = 'd';
bitmap_data = new base::RefCountedBytes(data);
backend_->MergeFavicon(
page_url, icon_url2, chrome::FAVICON, bitmap_data, kSmallSize);
icon_mappings.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
&icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(icon_url2, icon_mappings[0].icon_url);
favicon_bitmaps.clear();
EXPECT_TRUE(GetSortedFaviconBitmaps(icon_mappings[0].icon_id,
&favicon_bitmaps));
EXPECT_EQ(base::Time(), favicon_bitmaps[0].last_updated);
EXPECT_TRUE(BitmapDataEqual('c', favicon_bitmaps[0].bitmap_data));
EXPECT_EQ(kTinySize, favicon_bitmaps[0].pixel_size);
EXPECT_NE(base::Time(), favicon_bitmaps[1].last_updated);
EXPECT_TRUE(BitmapDataEqual('d', favicon_bitmaps[1].bitmap_data));
EXPECT_EQ(kSmallSize, favicon_bitmaps[1].pixel_size);
EXPECT_EQ(4, num_broadcasted_notifications());
}
TEST_F(HistoryBackendTest, MergeFaviconIconURLMappedToDifferentPageURL) {
GURL page_url1("http://www.google.com");
GURL page_url2("http://news.google.com");
GURL page_url3("http://maps.google.com");
GURL icon_url("http:/www.google.com/favicon.ico");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
GenerateFaviconBitmapData(icon_url, GetSizesSmall(),
&favicon_bitmap_data);
backend_->SetFavicons(page_url1, chrome::FAVICON, favicon_bitmap_data);
std::vector<IconMapping> icon_mappings;
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url1,
&icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(icon_url, icon_mappings[0].icon_url);
FaviconBitmap favicon_bitmap;
EXPECT_TRUE(GetOnlyFaviconBitmap(icon_mappings[0].icon_id, &favicon_bitmap));
EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
std::vector<unsigned char> data;
data.push_back('a');
scoped_refptr<base::RefCountedBytes> bitmap_data(
new base::RefCountedBytes(data));
backend_->MergeFavicon(
page_url2, icon_url, chrome::FAVICON, bitmap_data, kSmallSize);
chrome::FaviconID favicon_id =
backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
icon_url, chrome::FAVICON, NULL);
EXPECT_NE(0, favicon_id);
EXPECT_TRUE(GetOnlyFaviconBitmap(favicon_id, &favicon_bitmap));
EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data));
EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
bitmap_data->data()[0] = 'b';
backend_->MergeFavicon(
page_url3, icon_url, chrome::FAVICON, bitmap_data, kSmallSize);
favicon_id = backend_->thumbnail_db_->GetFaviconIDForFaviconURL(
icon_url, chrome::FAVICON, NULL);
EXPECT_NE(0, favicon_id);
EXPECT_TRUE(GetOnlyFaviconBitmap(favicon_id, &favicon_bitmap));
EXPECT_NE(base::Time(), favicon_bitmap.last_updated);
EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmap.bitmap_data));
EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size);
icon_mappings.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url1,
&icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);
icon_mappings.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url2,
&icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);
icon_mappings.clear();
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url3,
&icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(favicon_id, icon_mappings[0].icon_id);
EXPECT_EQ(3, num_broadcasted_notifications());
}
TEST_F(HistoryBackendTest, MergeFaviconMaxFaviconBitmapsPerIconURL) {
GURL page_url("http://www.google.com");
std::string icon_url_string("http://www.google.com/favicon.ico");
size_t replace_index = icon_url_string.size() - 1;
std::vector<unsigned char> data;
data.push_back('a');
scoped_refptr<base::RefCountedMemory> bitmap_data =
base::RefCountedBytes::TakeVector(&data);
int pixel_size = 1;
for (size_t i = 0; i < kMaxFaviconBitmapsPerIconURL + 1; ++i) {
icon_url_string[replace_index] = '0' + i;
GURL icon_url(icon_url_string);
backend_->MergeFavicon(page_url, icon_url, chrome::FAVICON, bitmap_data,
gfx::Size(pixel_size, pixel_size));
++pixel_size;
}
std::vector<IconMapping> icon_mappings;
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url,
&icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
std::vector<FaviconBitmap> favicon_bitmaps;
EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(
icon_mappings[0].icon_id, &favicon_bitmaps));
EXPECT_EQ(kMaxFaviconBitmapsPerIconURL, favicon_bitmaps.size());
}
TEST_F(HistoryBackendTest, MergeFaviconShowsUpInGetFaviconsForURLResult) {
GURL page_url("http://www.google.com");
GURL icon_url("http://www.google.com/favicon.ico");
GURL merged_icon_url("http://wwww.google.com/favicon2.ico");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
GenerateFaviconBitmapData(icon_url, GetSizesSmallAndLarge(),
&favicon_bitmap_data);
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
std::vector<unsigned char> data;
data.push_back('c');
scoped_refptr<base::RefCountedBytes> bitmap_data(
new base::RefCountedBytes(data));
backend_->MergeFavicon(
page_url, merged_icon_url, chrome::FAVICON, bitmap_data, kSmallSize);
std::vector<chrome::FaviconBitmapResult> bitmap_results;
backend_->GetFaviconsForURL(page_url, chrome::FAVICON, kSmallSize.width(),
GetScaleFactors1x2x(), &bitmap_results);
EXPECT_EQ(2u, bitmap_results.size());
const chrome::FaviconBitmapResult& first_result = bitmap_results[0];
const chrome::FaviconBitmapResult& result =
(first_result.pixel_size == kSmallSize) ? first_result
: bitmap_results[1];
EXPECT_TRUE(BitmapDataEqual('c', result.bitmap_data));
}
TEST_F(HistoryBackendTest, TestGetFaviconsForURLWithIconTypesPriority) {
GURL page_url("http://www.google.com");
GURL icon_url("http://www.google.com/favicon.ico");
GURL touch_icon_url("http://wwww.google.com/touch_icon.ico");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
std::vector<gfx::Size> favicon_size;
favicon_size.push_back(gfx::Size(16, 16));
favicon_size.push_back(gfx::Size(32, 32));
GenerateFaviconBitmapData(icon_url, favicon_size, &favicon_bitmap_data);
ASSERT_EQ(2u, favicon_bitmap_data.size());
std::vector<chrome::FaviconBitmapData> touch_icon_bitmap_data;
std::vector<gfx::Size> touch_icon_size;
touch_icon_size.push_back(gfx::Size(64, 64));
GenerateFaviconBitmapData(icon_url, touch_icon_size, &touch_icon_bitmap_data);
ASSERT_EQ(1u, touch_icon_bitmap_data.size());
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
backend_->SetFavicons(page_url, chrome::TOUCH_ICON, touch_icon_bitmap_data);
chrome::FaviconBitmapResult result;
std::vector<int> icon_types;
icon_types.push_back(chrome::FAVICON);
icon_types.push_back(chrome::TOUCH_ICON);
backend_->GetLargestFaviconForURL(page_url, icon_types, 16, &result);
EXPECT_EQ(gfx::Size(32, 32), result.pixel_size);
EXPECT_EQ(chrome::FAVICON, result.icon_type);
backend_->GetLargestFaviconForURL(page_url, icon_types, 32, &result);
EXPECT_EQ(gfx::Size(64, 64), result.pixel_size);
EXPECT_EQ(chrome::TOUCH_ICON, result.icon_type);
}
TEST_F(HistoryBackendTest, TestGetFaviconsForURLReturnFavicon) {
GURL page_url("http://www.google.com");
GURL icon_url("http://www.google.com/favicon.ico");
GURL touch_icon_url("http://wwww.google.com/touch_icon.ico");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
std::vector<gfx::Size> favicon_size;
favicon_size.push_back(gfx::Size(16, 16));
favicon_size.push_back(gfx::Size(32, 32));
GenerateFaviconBitmapData(icon_url, favicon_size, &favicon_bitmap_data);
ASSERT_EQ(2u, favicon_bitmap_data.size());
std::vector<chrome::FaviconBitmapData> touch_icon_bitmap_data;
std::vector<gfx::Size> touch_icon_size;
touch_icon_size.push_back(gfx::Size(32, 32));
GenerateFaviconBitmapData(icon_url, touch_icon_size, &touch_icon_bitmap_data);
ASSERT_EQ(1u, touch_icon_bitmap_data.size());
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
backend_->SetFavicons(page_url, chrome::TOUCH_ICON, touch_icon_bitmap_data);
chrome::FaviconBitmapResult result;
std::vector<int> icon_types;
icon_types.push_back(chrome::FAVICON);
icon_types.push_back(chrome::TOUCH_ICON);
backend_->GetLargestFaviconForURL(page_url, icon_types, 16, &result);
EXPECT_EQ(gfx::Size(32, 32), result.pixel_size);
EXPECT_EQ(chrome::FAVICON, result.icon_type);
chrome::FaviconBitmapResult result1;
backend_->GetLargestFaviconForURL(page_url, icon_types, 32, &result1);
EXPECT_EQ(gfx::Size(32, 32), result1.pixel_size);
EXPECT_EQ(chrome::FAVICON, result1.icon_type);
}
TEST_F(HistoryBackendTest, TestGetFaviconsForURLReturnFaviconEvenItSmaller) {
GURL page_url("http://www.google.com");
GURL icon_url("http://www.google.com/favicon.ico");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
std::vector<gfx::Size> favicon_size;
favicon_size.push_back(gfx::Size(16, 16));
GenerateFaviconBitmapData(icon_url, favicon_size, &favicon_bitmap_data);
ASSERT_EQ(1u, favicon_bitmap_data.size());
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
chrome::FaviconBitmapResult result;
std::vector<int> icon_types;
icon_types.push_back(chrome::FAVICON);
icon_types.push_back(chrome::TOUCH_ICON);
backend_->GetLargestFaviconForURL(page_url, icon_types, 32, &result);
EXPECT_EQ(gfx::Size(16, 16), result.pixel_size);
EXPECT_EQ(chrome::FAVICON, result.icon_type);
}
TEST_F(HistoryBackendTest, UpdateFaviconMappingsAndFetchMultipleIconTypes) {
GURL page_url1("http://www.google.com");
GURL page_url2("http://news.google.com");
GURL page_url3("http://mail.google.com");
GURL icon_urla("http://www.google.com/favicon1.ico");
GURL icon_urlb("http://www.google.com/favicon2.ico");
GURL icon_urlc("http://www.google.com/favicon3.ico");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
GenerateFaviconBitmapData(icon_urla, GetSizesSmall(), &favicon_bitmap_data);
backend_->SetFavicons(page_url1, chrome::TOUCH_ICON, favicon_bitmap_data);
GenerateFaviconBitmapData(icon_urlb, GetSizesSmall(), icon_urlc,
GetSizesSmall(), &favicon_bitmap_data);
backend_->SetFavicons(
page_url2, chrome::TOUCH_PRECOMPOSED_ICON, favicon_bitmap_data);
std::vector<GURL> icon_urls;
icon_urls.push_back(icon_urla);
icon_urls.push_back(icon_urlb);
icon_urls.push_back(icon_urlc);
std::vector<chrome::FaviconBitmapResult> bitmap_results;
backend_->UpdateFaviconMappingsAndFetch(
page_url3,
icon_urls,
(chrome::TOUCH_ICON | chrome::TOUCH_PRECOMPOSED_ICON),
kSmallSize.width(),
GetScaleFactors1x2x(),
&bitmap_results);
std::vector<IconMapping> icon_mappings;
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url1,
&icon_mappings));
EXPECT_EQ(1u, icon_mappings.size());
EXPECT_EQ(icon_urla, icon_mappings[0].icon_url);
EXPECT_EQ(chrome::TOUCH_ICON, icon_mappings[0].icon_type);
icon_mappings.clear();
EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url2, &icon_mappings));
EXPECT_EQ(2u, icon_mappings.size());
EXPECT_EQ(icon_urlb, icon_mappings[0].icon_url);
EXPECT_EQ(chrome::TOUCH_PRECOMPOSED_ICON, icon_mappings[0].icon_type);
EXPECT_EQ(icon_urlc, icon_mappings[1].icon_url);
EXPECT_EQ(chrome::TOUCH_PRECOMPOSED_ICON, icon_mappings[1].icon_type);
icon_mappings.clear();
EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url3, &icon_mappings));
EXPECT_EQ(2u, icon_mappings.size());
EXPECT_EQ(icon_urlb, icon_mappings[0].icon_url);
EXPECT_EQ(chrome::TOUCH_PRECOMPOSED_ICON, icon_mappings[0].icon_type);
EXPECT_EQ(icon_urlc, icon_mappings[1].icon_url);
EXPECT_EQ(chrome::TOUCH_PRECOMPOSED_ICON, icon_mappings[1].icon_type);
}
TEST_F(HistoryBackendTest, GetFaviconsFromDBEmpty) {
const GURL page_url("http://www.google.com/");
std::vector<chrome::FaviconBitmapResult> bitmap_results;
EXPECT_FALSE(backend_->GetFaviconsFromDB(page_url, chrome::FAVICON,
kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results));
EXPECT_TRUE(bitmap_results.empty());
}
TEST_F(HistoryBackendTest, GetFaviconsFromDBNoFaviconBitmaps) {
const GURL page_url("http://www.google.com/");
const GURL icon_url("http://www.google.com/icon1");
chrome::FaviconID icon_id = backend_->thumbnail_db_->AddFavicon(
icon_url, chrome::FAVICON);
EXPECT_NE(0, icon_id);
EXPECT_NE(0, backend_->thumbnail_db_->AddIconMapping(page_url, icon_id));
std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
EXPECT_FALSE(backend_->GetFaviconsFromDB(page_url, chrome::FAVICON,
kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
EXPECT_TRUE(bitmap_results_out.empty());
}
TEST_F(HistoryBackendTest, GetFaviconsFromDBSelectClosestMatch) {
const GURL page_url("http://www.google.com/");
const GURL icon_url("http://www.google.com/icon1");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
GenerateFaviconBitmapData(icon_url, GetSizesTinySmallAndLarge(),
&favicon_bitmap_data);
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url,
chrome::FAVICON,
kSmallSize.width(),
GetScaleFactors1x2x(),
&bitmap_results_out));
EXPECT_EQ(2u, bitmap_results_out.size());
if (bitmap_results_out[0].pixel_size == kLargeSize) {
chrome::FaviconBitmapResult tmp_result = bitmap_results_out[0];
bitmap_results_out[0] = bitmap_results_out[1];
bitmap_results_out[1] = tmp_result;
}
EXPECT_FALSE(bitmap_results_out[0].expired);
EXPECT_TRUE(BitmapDataEqual('b', bitmap_results_out[0].bitmap_data));
EXPECT_EQ(kSmallSize, bitmap_results_out[0].pixel_size);
EXPECT_EQ(icon_url, bitmap_results_out[0].icon_url);
EXPECT_EQ(chrome::FAVICON, bitmap_results_out[0].icon_type);
EXPECT_FALSE(bitmap_results_out[1].expired);
EXPECT_TRUE(BitmapDataEqual('c', bitmap_results_out[1].bitmap_data));
EXPECT_EQ(kLargeSize, bitmap_results_out[1].pixel_size);
EXPECT_EQ(icon_url, bitmap_results_out[1].icon_url);
EXPECT_EQ(chrome::FAVICON, bitmap_results_out[1].icon_type);
}
TEST_F(HistoryBackendTest, GetFaviconsFromDBSingleIconURL) {
const GURL page_url("http://www.google.com/");
const GURL icon_url1("http://www.google.com/icon1");
const GURL icon_url2("http://www.google.com/icon2");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
GenerateFaviconBitmapData(icon_url1, GetSizesSmall(), icon_url2,
GetSizesLarge(), &favicon_bitmap_data);
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url,
chrome::FAVICON,
kSmallSize.width(),
GetScaleFactors1x2x(),
&bitmap_results_out));
EXPECT_EQ(1u, bitmap_results_out.size());
EXPECT_EQ(kLargeSize, bitmap_results_out[0].pixel_size);
EXPECT_EQ(icon_url2, bitmap_results_out[0].icon_url);
}
TEST_F(HistoryBackendTest, GetFaviconsFromDBIconType) {
const GURL page_url("http://www.google.com/");
const GURL icon_url1("http://www.google.com/icon1.png");
const GURL icon_url2("http://www.google.com/icon2.png");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
GenerateFaviconBitmapData(icon_url1, GetSizesSmall(), &favicon_bitmap_data);
backend_->SetFavicons(page_url, chrome::FAVICON, favicon_bitmap_data);
GenerateFaviconBitmapData(icon_url2, GetSizesSmall(), &favicon_bitmap_data);
backend_->SetFavicons(page_url, chrome::TOUCH_ICON, favicon_bitmap_data);
std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url, chrome::FAVICON,
kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
EXPECT_EQ(1u, bitmap_results_out.size());
EXPECT_EQ(chrome::FAVICON, bitmap_results_out[0].icon_type);
EXPECT_EQ(icon_url1, bitmap_results_out[0].icon_url);
bitmap_results_out.clear();
EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url, chrome::TOUCH_ICON,
kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
EXPECT_EQ(1u, bitmap_results_out.size());
EXPECT_EQ(chrome::TOUCH_ICON, bitmap_results_out[0].icon_type);
EXPECT_EQ(icon_url2, bitmap_results_out[0].icon_url);
}
TEST_F(HistoryBackendTest, GetFaviconsFromDBExpired) {
const GURL page_url("http://www.google.com/");
const GURL icon_url("http://www.google.com/icon.png");
std::vector<unsigned char> data;
data.push_back('a');
scoped_refptr<base::RefCountedBytes> bitmap_data(
base::RefCountedBytes::TakeVector(&data));
base::Time last_updated = base::Time::FromTimeT(0);
chrome::FaviconID icon_id =
backend_->thumbnail_db_->AddFavicon(icon_url,
chrome::FAVICON,
bitmap_data,
last_updated,
kSmallSize);
EXPECT_NE(0, icon_id);
EXPECT_NE(0, backend_->thumbnail_db_->AddIconMapping(page_url, icon_id));
std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url, chrome::FAVICON,
kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
EXPECT_EQ(1u, bitmap_results_out.size());
EXPECT_TRUE(bitmap_results_out[0].expired);
}
TEST_F(HistoryBackendTest, UpdateFaviconMappingsAndFetchNoDB) {
backend_->thumbnail_db_.reset();
std::vector<chrome::FaviconBitmapResult> bitmap_results;
backend_->UpdateFaviconMappingsAndFetch(
GURL(), std::vector<GURL>(), chrome::FAVICON, kSmallSize.width(),
GetScaleFactors1x2x(), &bitmap_results);
EXPECT_TRUE(bitmap_results.empty());
}
TEST_F(HistoryBackendTest, CloneFaviconIsRestrictedToSameDomain) {
const GURL url("http://www.google.com/");
const GURL same_domain_url("http://www.google.com/subdir/index.html");
const GURL foreign_domain_url("http://www.not-google.com/");
const GURL icon_url("http://www.google.com/icon.png");
std::vector<chrome::FaviconBitmapData> favicon_bitmap_data;
GenerateFaviconBitmapData(icon_url, GetSizesSmall(), &favicon_bitmap_data);
backend_->SetFavicons(url, chrome::FAVICON, favicon_bitmap_data);
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL(
url, chrome::FAVICON, NULL));
std::vector<chrome::FaviconBitmapResult> bitmap_results_out;
EXPECT_TRUE(backend_->GetFaviconsFromDB(url, chrome::FAVICON,
kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
EXPECT_FALSE(backend_->GetFaviconsFromDB(same_domain_url, chrome::FAVICON,
kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
EXPECT_FALSE(backend_->GetFaviconsFromDB(foreign_domain_url, chrome::FAVICON,
kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
backend_->CloneFavicons(url, same_domain_url);
EXPECT_TRUE(backend_->GetFaviconsFromDB(same_domain_url, chrome::FAVICON,
kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
backend_->CloneFavicons(url, foreign_domain_url);
EXPECT_FALSE(backend_->GetFaviconsFromDB(foreign_domain_url, chrome::FAVICON,
kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out));
}
TEST_F(HistoryBackendTest, QueryFilteredURLs) {
const char* google = "http://www.google.com/";
const char* yahoo = "http://www.yahoo.com/";
const char* yahoo_sports = "http://sports.yahoo.com/";
const char* yahoo_sports_with_article1 =
"http://sports.yahoo.com/article1.htm";
const char* yahoo_sports_with_article2 =
"http://sports.yahoo.com/article2.htm";
const char* yahoo_sports_soccer = "http://sports.yahoo.com/soccer";
const char* apple = "http://www.apple.com/";
backend_->DeleteAllHistory();
Time tested_time = Time::Now().LocalMidnight() +
base::TimeDelta::FromHours(4);
base::TimeDelta half_an_hour = base::TimeDelta::FromMinutes(30);
base::TimeDelta one_hour = base::TimeDelta::FromHours(1);
base::TimeDelta one_day = base::TimeDelta::FromDays(1);
const content::PageTransition kTypedTransition =
content::PAGE_TRANSITION_TYPED;
const content::PageTransition kKeywordGeneratedTransition =
content::PAGE_TRANSITION_KEYWORD_GENERATED;
const char* redirect_sequence[2];
redirect_sequence[1] = NULL;
redirect_sequence[0] = google;
AddRedirectChainWithTransitionAndTime(
redirect_sequence, 0, kTypedTransition,
tested_time - one_day - half_an_hour * 2);
AddRedirectChainWithTransitionAndTime(
redirect_sequence, 0,
kTypedTransition, tested_time - one_day);
AddRedirectChainWithTransitionAndTime(
redirect_sequence, 0,
kTypedTransition, tested_time - half_an_hour / 2);
AddRedirectChainWithTransitionAndTime(
redirect_sequence, 0,
kTypedTransition, tested_time);
redirect_sequence[0] = apple;
AddRedirectChainWithTransitionAndTime(
redirect_sequence, 0, kKeywordGeneratedTransition,
tested_time - one_day + one_hour * 6);
redirect_sequence[0] = yahoo;
AddRedirectChainWithTransitionAndTime(
redirect_sequence, 0, kTypedTransition,
tested_time - one_day + half_an_hour);
AddRedirectChainWithTransitionAndTime(
redirect_sequence, 0, kTypedTransition,
tested_time - one_day + half_an_hour * 2);
redirect_sequence[0] = yahoo_sports;
AddRedirectChainWithTransitionAndTime(
redirect_sequence, 0, kTypedTransition,
tested_time - one_day - half_an_hour * 2);
AddRedirectChainWithTransitionAndTime(
redirect_sequence, 0, kTypedTransition,
tested_time - one_day);
int transition1, transition2;
AddClientRedirect(GURL(yahoo_sports), GURL(yahoo_sports_with_article1), false,
tested_time - one_day + half_an_hour,
&transition1, &transition2);
AddClientRedirect(GURL(yahoo_sports_with_article1),
GURL(yahoo_sports_with_article2),
false,
tested_time - one_day + half_an_hour * 2,
&transition1, &transition2);
redirect_sequence[0] = yahoo_sports_soccer;
AddRedirectChainWithTransitionAndTime(redirect_sequence, 0,
kTypedTransition,
tested_time - half_an_hour);
backend_->Commit();
scoped_refptr<QueryFilteredURLsRequest> request1 =
new history::QueryFilteredURLsRequest(
base::Bind(&HistoryBackendTest::OnQueryFiltered,
base::Unretained(static_cast<HistoryBackendTest*>(this))));
HistoryBackendCancelableRequest cancellable_request;
cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
request1.get());
VisitFilter filter;
base::TimeDelta three_quarters_of_an_hour = base::TimeDelta::FromMinutes(45);
filter.SetFilterTime(tested_time);
filter.SetFilterWidth(three_quarters_of_an_hour);
backend_->QueryFilteredURLs(request1, 100, filter, false);
ASSERT_EQ(4U, get_filtered_list().size());
EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
EXPECT_EQ(std::string(yahoo_sports_soccer),
get_filtered_list()[1].url.spec());
EXPECT_EQ(std::string(yahoo), get_filtered_list()[2].url.spec());
EXPECT_EQ(std::string(yahoo_sports),
get_filtered_list()[3].url.spec());
scoped_refptr<QueryFilteredURLsRequest> request2 =
new history::QueryFilteredURLsRequest(
base::Bind(&HistoryBackendTest::OnQueryFiltered,
base::Unretained(static_cast<HistoryBackendTest*>(this))));
cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
request2.get());
filter.SetFilterTime(tested_time + one_hour);
filter.SetFilterWidth(one_hour);
backend_->QueryFilteredURLs(request2, 100, filter, false);
ASSERT_EQ(3U, get_filtered_list().size());
EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
EXPECT_EQ(std::string(yahoo), get_filtered_list()[1].url.spec());
EXPECT_EQ(std::string(yahoo_sports), get_filtered_list()[2].url.spec());
scoped_refptr<QueryFilteredURLsRequest> request3 =
new history::QueryFilteredURLsRequest(
base::Bind(&HistoryBackendTest::OnQueryFiltered,
base::Unretained(static_cast<HistoryBackendTest*>(this))));
cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
request3.get());
filter.SetFilterTime(tested_time - one_hour);
filter.SetFilterWidth(one_hour);
backend_->QueryFilteredURLs(request3, 100, filter, false);
ASSERT_EQ(3U, get_filtered_list().size());
EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
EXPECT_EQ(std::string(yahoo_sports_soccer),
get_filtered_list()[1].url.spec());
EXPECT_EQ(std::string(yahoo_sports), get_filtered_list()[2].url.spec());
filter.ClearFilters();
base::Time::Exploded exploded_time;
tested_time.LocalExplode(&exploded_time);
scoped_refptr<QueryFilteredURLsRequest> request4 =
new history::QueryFilteredURLsRequest(
base::Bind(&HistoryBackendTest::OnQueryFiltered,
base::Unretained(static_cast<HistoryBackendTest*>(this))));
cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
request4.get());
filter.SetFilterTime(tested_time);
filter.SetDayOfTheWeekFilter(static_cast<int>(exploded_time.day_of_week));
backend_->QueryFilteredURLs(request4, 100, filter, false);
ASSERT_EQ(2U, get_filtered_list().size());
EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
EXPECT_EQ(std::string(yahoo_sports_soccer),
get_filtered_list()[1].url.spec());
scoped_refptr<QueryFilteredURLsRequest> request5 =
new history::QueryFilteredURLsRequest(
base::Bind(&HistoryBackendTest::OnQueryFiltered,
base::Unretained(static_cast<HistoryBackendTest*>(this))));
cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
request5.get());
filter.SetFilterTime(tested_time - base::TimeDelta::FromMinutes(40));
filter.SetFilterWidth(base::TimeDelta::FromMinutes(20));
backend_->QueryFilteredURLs(request5, 100, filter, false);
ASSERT_EQ(1U, get_filtered_list().size());
EXPECT_EQ(std::string(yahoo_sports_soccer),
get_filtered_list()[0].url.spec());
scoped_refptr<QueryFilteredURLsRequest> request6 =
new history::QueryFilteredURLsRequest(
base::Bind(&HistoryBackendTest::OnQueryFiltered,
base::Unretained(static_cast<HistoryBackendTest*>(this))));
cancellable_request.MockScheduleOfRequest<QueryFilteredURLsRequest>(
request6.get());
filter.SetFilterTime(tested_time);
filter.SetFilterWidth(one_hour * 2);
backend_->QueryFilteredURLs(request6, 100, filter, true);
ASSERT_GE(get_filtered_list().size(), 2U);
EXPECT_EQ(std::string(google), get_filtered_list()[0].url.spec());
EXPECT_EQ(std::string(yahoo_sports_soccer),
get_filtered_list()[1].url.spec());
EXPECT_EQ(4U, get_filtered_list()[0].extended_info.total_visits);
EXPECT_EQ(1U, get_filtered_list()[1].extended_info.total_visits);
}
TEST_F(HistoryBackendTest, UpdateVisitDuration) {
ASSERT_TRUE(backend_.get());
GURL url1("http://www.cnn.com");
std::vector<VisitInfo> visit_info1, visit_info2;
Time start_ts = Time::Now() - base::TimeDelta::FromDays(5);
Time end_ts = start_ts + base::TimeDelta::FromDays(2);
visit_info1.push_back(VisitInfo(start_ts, content::PAGE_TRANSITION_LINK));
GURL url2("http://www.example.com");
visit_info2.push_back(VisitInfo(Time::Now() - base::TimeDelta::FromDays(10),
content::PAGE_TRANSITION_LINK));
backend_->DeleteAllHistory();
backend_->AddVisits(url1, visit_info1, history::SOURCE_BROWSED);
backend_->AddVisits(url2, visit_info2, history::SOURCE_BROWSED);
VisitVector visits1, visits2;
URLRow row;
URLID url_id1 = backend_->db()->GetRowForURL(url1, &row);
ASSERT_TRUE(backend_->db()->GetVisitsForURL(url_id1, &visits1));
ASSERT_EQ(1U, visits1.size());
EXPECT_EQ(0, visits1[0].visit_duration.ToInternalValue());
URLID url_id2 = backend_->db()->GetRowForURL(url2, &row);
ASSERT_TRUE(backend_->db()->GetVisitsForURL(url_id2, &visits2));
ASSERT_EQ(1U, visits2.size());
EXPECT_EQ(0, visits2[0].visit_duration.ToInternalValue());
backend_->UpdateVisitDuration(visits1[0].visit_id, end_ts);
ASSERT_TRUE(backend_->db()->GetVisitsForURL(url_id1, &visits1));
ASSERT_EQ(1U, visits1.size());
base::TimeDelta expected_duration = end_ts - start_ts;
EXPECT_EQ(expected_duration.ToInternalValue(),
visits1[0].visit_duration.ToInternalValue());
ASSERT_TRUE(backend_->RemoveVisits(visits1));
}
TEST_F(HistoryBackendTest, MigrationVisitDuration) {
ASSERT_TRUE(backend_.get());
backend_->Closing();
backend_ = NULL;
base::FilePath old_history_path, old_history, old_archived;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &old_history_path));
old_history_path = old_history_path.AppendASCII("History");
old_history = old_history_path.AppendASCII("HistoryNoDuration");
old_archived = old_history_path.AppendASCII("ArchivedNoDuration");
base::FilePath new_history_path(getTestDir());
base::DeleteFile(new_history_path, true);
base::CreateDirectory(new_history_path);
base::FilePath new_history_file =
new_history_path.Append(chrome::kHistoryFilename);
base::FilePath new_archived_file =
new_history_path.Append(chrome::kArchivedHistoryFilename);
ASSERT_TRUE(base::CopyFile(old_history, new_history_file));
ASSERT_TRUE(base::CopyFile(old_archived, new_archived_file));
backend_ = new HistoryBackend(new_history_path,
new HistoryBackendTestDelegate(this),
&bookmark_model_);
backend_->Init(std::string(), false);
backend_->Closing();
backend_ = NULL;
int cur_version = HistoryDatabase::GetCurrentVersion();
sql::Connection db;
ASSERT_TRUE(db.Open(new_history_file));
sql::Statement s(db.GetUniqueStatement(
"SELECT value FROM meta WHERE key = 'version'"));
ASSERT_TRUE(s.Step());
int file_version = s.ColumnInt(0);
EXPECT_EQ(cur_version, file_version);
s.Assign(db.GetUniqueStatement(
"SELECT visit_duration FROM visits LIMIT 1"));
ASSERT_TRUE(s.Step());
EXPECT_EQ(0, s.ColumnInt(0));
cur_version = ArchivedDatabase::GetCurrentVersion();
sql::Connection archived_db;
ASSERT_TRUE(archived_db.Open(new_archived_file));
sql::Statement s1(archived_db.GetUniqueStatement(
"SELECT value FROM meta WHERE key = 'version'"));
ASSERT_TRUE(s1.Step());
file_version = s1.ColumnInt(0);
EXPECT_EQ(cur_version, file_version);
s1.Assign(archived_db.GetUniqueStatement(
"SELECT visit_duration FROM visits LIMIT 1"));
ASSERT_TRUE(s1.Step());
EXPECT_EQ(0, s1.ColumnInt(0));
}
TEST_F(HistoryBackendTest, AddPageNoVisitForBookmark) {
ASSERT_TRUE(backend_.get());
GURL url("http://www.google.com");
base::string16 title(base::UTF8ToUTF16("Bookmark title"));
backend_->AddPageNoVisitForBookmark(url, title);
URLRow row;
backend_->GetURL(url, &row);
EXPECT_EQ(url, row.url());
EXPECT_EQ(title, row.title());
EXPECT_EQ(0, row.visit_count());
backend_->DeleteURL(url);
backend_->AddPageNoVisitForBookmark(url, base::string16());
backend_->GetURL(url, &row);
EXPECT_EQ(url, row.url());
EXPECT_EQ(base::UTF8ToUTF16(url.spec()), row.title());
EXPECT_EQ(0, row.visit_count());
}
TEST_F(HistoryBackendTest, ExpireHistoryForTimes) {
ASSERT_TRUE(backend_.get());
HistoryAddPageArgs args[10];
for (size_t i = 0; i < arraysize(args); ++i) {
args[i].url = GURL("http://example" +
std::string((i % 2 == 0 ? ".com" : ".net")));
args[i].time = base::Time::FromInternalValue(i);
backend_->AddPage(args[i]);
}
EXPECT_EQ(base::Time(), backend_->GetFirstRecordedTimeForTest());
URLRow row;
for (size_t i = 0; i < arraysize(args); ++i) {
EXPECT_TRUE(backend_->GetURL(args[i].url, &row));
}
std::set<base::Time> times;
times.insert(args[5].time);
backend_->ExpireHistoryForTimes(times,
base::Time::FromInternalValue(2),
base::Time::FromInternalValue(8));
EXPECT_EQ(base::Time::FromInternalValue(0),
backend_->GetFirstRecordedTimeForTest());
VisitVector visit_vector;
EXPECT_TRUE(backend_->GetVisitsForURL(
backend_->db_->GetRowForURL(GURL("http://example.com"), NULL),
&visit_vector));
ASSERT_EQ(5u, visit_vector.size());
EXPECT_EQ(base::Time::FromInternalValue(0), visit_vector[0].visit_time);
EXPECT_EQ(base::Time::FromInternalValue(2), visit_vector[1].visit_time);
EXPECT_EQ(base::Time::FromInternalValue(4), visit_vector[2].visit_time);
EXPECT_EQ(base::Time::FromInternalValue(6), visit_vector[3].visit_time);
EXPECT_EQ(base::Time::FromInternalValue(8), visit_vector[4].visit_time);
visit_vector.clear();
EXPECT_TRUE(backend_->GetVisitsForURL(
backend_->db_->GetRowForURL(GURL("http://example.net"), NULL),
&visit_vector));
ASSERT_EQ(2u, visit_vector.size());
EXPECT_EQ(base::Time::FromInternalValue(1), visit_vector[0].visit_time);
EXPECT_EQ(base::Time::FromInternalValue(9), visit_vector[1].visit_time);
EXPECT_EQ(base::Time::FromInternalValue(0),
backend_->GetFirstRecordedTimeForTest());
}
TEST_F(HistoryBackendTest, ExpireHistory) {
ASSERT_TRUE(backend_.get());
base::Time reference_time = base::Time::UnixEpoch().LocalMidnight() +
base::TimeDelta::FromHours(12);
HistoryAddPageArgs args[4];
for (size_t i = 0; i < arraysize(args); ++i) {
args[i].url = GURL("http://example" + base::IntToString(i) + ".com");
args[i].time = reference_time + base::TimeDelta::FromDays(i);
backend_->AddPage(args[i]);
}
URLRow url_rows[4];
for (unsigned int i = 0; i < arraysize(args); ++i)
ASSERT_TRUE(backend_->GetURL(args[i].url, &url_rows[i]));
std::vector<ExpireHistoryArgs> expire_list;
VisitVector visits;
backend_->ExpireHistory(expire_list);
backend_->db()->GetAllVisitsInRange(base::Time(), base::Time(), 0, &visits);
EXPECT_EQ(4U, visits.size());
expire_list.resize(expire_list.size() + 1);
expire_list[0].SetTimeRangeForOneDay(args[0].time);
expire_list[0].urls.insert(GURL("http://google.does-not-exist"));
backend_->ExpireHistory(expire_list);
backend_->db()->GetAllVisitsInRange(base::Time(), base::Time(), 0, &visits);
EXPECT_EQ(4U, visits.size());
expire_list.back().urls.insert(url_rows[0].url());
backend_->ExpireHistory(expire_list);
backend_->db()->GetAllVisitsInRange(base::Time(), base::Time(), 0, &visits);
ASSERT_EQ(3U, visits.size());
EXPECT_EQ(visits[0].url_id, url_rows[1].id());
EXPECT_EQ(visits[1].url_id, url_rows[2].id());
EXPECT_EQ(visits[2].url_id, url_rows[3].id());
EXPECT_EQ(backend_->GetFirstRecordedTimeForTest(), args[1].time);
for (unsigned int i = 1; i < arraysize(args); ++i) {
expire_list.resize(expire_list.size() + 1);
expire_list[i].SetTimeRangeForOneDay(args[i].time);
expire_list[i].urls.insert(args[i].url);
}
backend_->ExpireHistory(expire_list);
backend_->db()->GetAllVisitsInRange(base::Time(), base::Time(), 0, &visits);
ASSERT_EQ(0U, visits.size());
}
TEST_F(HistoryBackendTest, DeleteMatchingUrlsForKeyword) {
GURL url1("https://www.bing.com/?q=bar");
URLRow url_info1(url1);
url_info1.set_visit_count(0);
url_info1.set_typed_count(0);
url_info1.set_last_visit(Time());
url_info1.set_hidden(false);
const URLID url1_id = backend_->db()->AddURL(url_info1);
EXPECT_NE(0, url1_id);
TemplateURLID keyword_id = 1;
base::string16 keyword = base::UTF8ToUTF16("bar");
ASSERT_TRUE(backend_->db()->SetKeywordSearchTermsForURL(
url1_id, keyword_id, keyword));
GURL url2("https://www.google.com/?q=bar");
URLRow url_info2(url2);
url_info2.set_visit_count(0);
url_info2.set_typed_count(0);
url_info2.set_last_visit(Time());
url_info2.set_hidden(false);
const URLID url2_id = backend_->db()->AddURL(url_info2);
EXPECT_NE(0, url2_id);
TemplateURLID keyword_id2 = 2;
ASSERT_TRUE(backend_->db()->SetKeywordSearchTermsForURL(
url2_id, keyword_id2, keyword));
URLRow url_info3(url2);
url_info3.set_visit_count(0);
url_info3.set_typed_count(0);
url_info3.set_last_visit(Time());
url_info3.set_hidden(false);
const URLID url3_id = backend_->db()->AddURL(url_info3);
EXPECT_NE(0, url3_id);
ASSERT_TRUE(backend_->db()->SetKeywordSearchTermsForURL(
url3_id, keyword_id2, keyword));
backend_->DeleteMatchingURLsForKeyword(keyword_id2, keyword);
URLRow row;
EXPECT_TRUE(backend_->db()->GetURLRow(url1_id, &row));
EXPECT_EQ(url1.spec(), row.url().spec());
EXPECT_FALSE(backend_->db()->GetURLRow(url2_id, &row));
EXPECT_FALSE(backend_->db()->GetURLRow(url3_id, &row));
EXPECT_TRUE(backend_->db()->GetKeywordSearchTermRow(url1_id, NULL));
EXPECT_FALSE(backend_->db()->GetKeywordSearchTermRow(url2_id, NULL));
EXPECT_FALSE(backend_->db()->GetKeywordSearchTermRow(url3_id, NULL));
}
TEST_F(HistoryBackendTest, RemoveNotification) {
scoped_ptr<TestingProfile> profile(new TestingProfile());
ASSERT_TRUE(profile->CreateHistoryService(false, false));
profile->CreateBookmarkModel(true);
BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile.get());
test::WaitForBookmarkModelToLoad(model);
GURL url("http://www.google.com");
bookmark_utils::AddIfNotBookmarked(model, url, base::string16());
HistoryService* service = HistoryServiceFactory::GetForProfile(
profile.get(), Profile::EXPLICIT_ACCESS);
service->AddPage(
url, base::Time::Now(), NULL, 1, GURL(), RedirectList(),
content::PAGE_TRANSITION_TYPED, SOURCE_BROWSED, false);
service->DeleteURL(url);
}
TEST_F(HistoryBackendTest, DeleteFTSIndexDatabases) {
ASSERT_TRUE(backend_.get());
base::FilePath history_path(getTestDir());
base::FilePath db1(history_path.AppendASCII("History Index 2013-05"));
base::FilePath db1_journal(db1.InsertBeforeExtensionASCII("-journal"));
base::FilePath db1_wal(db1.InsertBeforeExtensionASCII("-wal"));
base::FilePath db2_symlink(history_path.AppendASCII("History Index 2013-06"));
base::FilePath db2_actual(history_path.AppendASCII("Underlying DB"));
const char* data = "Dummy";
const size_t data_len = 5;
ASSERT_TRUE(base::WriteFile(db1, data, data_len));
ASSERT_TRUE(base::WriteFile(db1_journal, data, data_len));
ASSERT_TRUE(base::WriteFile(db1_wal, data, data_len));
ASSERT_TRUE(base::WriteFile(db2_actual, data, data_len));
#if defined(OS_POSIX)
EXPECT_TRUE(base::CreateSymbolicLink(db2_actual, db2_symlink));
#endif
backend_->DeleteFTSIndexDatabases();
EXPECT_FALSE(base::PathExists(db1));
EXPECT_FALSE(base::PathExists(db1_wal));
EXPECT_FALSE(base::PathExists(db1_journal));
EXPECT_FALSE(base::PathExists(db2_symlink));
EXPECT_TRUE(base::PathExists(db2_actual));
}
}