Index: chrome/browser/history/history_backend_unittest.cc |
diff --git a/chrome/browser/history/history_backend_unittest.cc b/chrome/browser/history/history_backend_unittest.cc |
index 943fc1bdded5a3bf32d8574267cf256b8dbdac1b..6eccc37ad33f9e8e22d3c42e3dc7f067d84a41a9 100644 |
--- a/chrome/browser/history/history_backend_unittest.cc |
+++ b/chrome/browser/history/history_backend_unittest.cc |
@@ -2,6 +2,7 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include <algorithm> |
#include <set> |
#include <vector> |
@@ -45,8 +46,22 @@ namespace { |
static const unsigned char blob1[] = |
"12346102356120394751634516591348710478123649165419234519234512349134"; |
+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(48, 48); |
+static const gfx::Size kLargeSize = gfx::Size(32, 32); |
+ |
+ |
+// Comparison functions as to make it easier to check results of |
+// GetFaviconBitmaps() and GetIconMappings(). |
+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(); |
+} |
} // namepace |
@@ -208,6 +223,22 @@ class HistoryBackendTest : public testing::Test { |
return test_dir_; |
} |
+ // Returns a gfx::Size vector with small size. |
+ const std::vector<gfx::Size>& GetSizesSmall() { |
+ CR_DEFINE_STATIC_LOCAL(std::vector<gfx::Size>, kSizesSmall, ()); |
+ if (kSizesSmall.empty()) |
+ kSizesSmall.push_back(kSmallSize); |
+ return kSizesSmall; |
+ } |
+ |
+ // Returns a gfx::Size vector with large size. |
+ const std::vector<gfx::Size>& GetSizesLarge() { |
+ CR_DEFINE_STATIC_LOCAL(std::vector<gfx::Size>, kSizesLarge, ()); |
+ if (kSizesLarge.empty()) |
+ kSizesLarge.push_back(kSmallSize); |
+ return kSizesLarge; |
+ } |
+ |
// Returns a gfx::Size vector with small and large sizes. |
const std::vector<gfx::Size>& GetSizesSmallAndLarge() { |
CR_DEFINE_STATIC_LOCAL(std::vector<gfx::Size>, kSizesSmallAndLarge, ()); |
@@ -218,13 +249,132 @@ class HistoryBackendTest : public testing::Test { |
return kSizesSmallAndLarge; |
} |
- FaviconID GetFavicon(const GURL& url, IconType icon_type) { |
+ // Returns a gfx::Size vector with tiny, small and large sizes. |
+ const std::vector<gfx::Size>& GetSizesTinySmallAndLarge() { |
+ CR_DEFINE_STATIC_LOCAL(std::vector<gfx::Size>, |
+ kSizesTinySmallAndLarge, ()); |
+ if (kSizesTinySmallAndLarge.empty()) { |
+ kSizesTinySmallAndLarge.push_back(kTinySize); |
+ kSizesTinySmallAndLarge.push_back(kSmallSize); |
+ kSizesTinySmallAndLarge.push_back(kLargeSize); |
+ } |
+ return kSizesTinySmallAndLarge; |
+ } |
+ |
+ // Returns 1x and 2x scale factors. |
+ const std::vector<ui::ScaleFactor>& GetScaleFactors1x2x() { |
+ CR_DEFINE_STATIC_LOCAL(std::vector<ui::ScaleFactor>, kScaleFactors1x2x, ()); |
+ if (kScaleFactors1x2x.empty()) { |
+ kScaleFactors1x2x.push_back(ui::SCALE_FACTOR_100P); |
+ kScaleFactors1x2x.push_back(ui::SCALE_FACTOR_200P); |
+ } |
+ return kScaleFactors1x2x; |
+ } |
+ |
+ // Returns the number of icon mappings of |icon_type| to |page_url|. |
+ size_t NumIconMappingsForPageURL(const GURL& page_url, IconType icon_type) { |
std::vector<IconMapping> icon_mappings; |
- if (backend_->thumbnail_db_->GetIconMappingsForPageURL(url, icon_type, |
- &icon_mappings)) |
- return icon_mappings[0].icon_id; |
- else |
- return 0; |
+ backend_->thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_type, |
+ &icon_mappings); |
+ return icon_mappings.size(); |
+ } |
+ |
+ // Returns the icon mappings for |page_url| sorted alphabetically by icon |
+ // URL in ascending order. |
+ 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; |
+ } |
+ |
+ // Returns the favicon bitmaps for |icon_id| sorted by pixel size in |
+ // ascending order. |
+ bool GetSortedFaviconBitmaps(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; |
+ } |
+ |
+ // Returns true if there is exactly one favicon bitmap associated to |
+ // |icon_url|. If true, returns favicon bitmap in output parameter. |
+ bool GetOnlyFaviconBitmapForIconURL(const GURL& icon_url, |
+ IconType icon_type, |
+ FaviconBitmap* favicon_bitmap) { |
+ FaviconID id = backend_->thumbnail_db_->GetFaviconIDForFaviconURL( |
+ icon_url, icon_type, NULL); |
+ if (!id) |
+ return false; |
+ std::vector<FaviconBitmap> favicon_bitmaps; |
+ if (!backend_->thumbnail_db_->GetFaviconBitmaps(id, &favicon_bitmaps)) |
+ return false; |
+ if (favicon_bitmaps.size() != 1) |
+ return false; |
+ *favicon_bitmap = favicon_bitmaps[0]; |
+ return true; |
+ } |
+ |
+ // Generates |favicon_bitmap_data| with entries for the icon_urls and sizes |
+ // specified. The bitmap_data for entries are lowercase letters of the |
+ // alphabet starting at 'a' for the entry at index 0. |
+ void GenerateFaviconBitmapData( |
+ const GURL& icon_url1, |
+ const std::vector<gfx::Size>& icon_url1_sizes, |
+ std::vector<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<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); |
+ 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); |
+ 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; |
+ } |
+ } |
+ |
+ // Returns true if |bitmap_data| is equal to |expected_data|. |
+ 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_; |
@@ -442,17 +592,17 @@ TEST_F(HistoryBackendTest, DeleteAll) { |
FaviconBitmap favicon_bitmap1 = favicon_bitmaps[0]; |
FaviconBitmap favicon_bitmap2 = favicon_bitmaps[1]; |
- // Bitmaps do not need to be in particular order. |
+ // Favicon bitmaps do not need to be in particular order. |
if (favicon_bitmap1.pixel_size == kLargeSize) { |
FaviconBitmap tmp_favicon_bitmap = favicon_bitmap1; |
favicon_bitmap1 = favicon_bitmap2; |
favicon_bitmap2 = tmp_favicon_bitmap; |
} |
- EXPECT_EQ('a', *favicon_bitmap1.bitmap_data->front()); |
+ EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap1.bitmap_data)); |
EXPECT_EQ(kSmallSize, favicon_bitmap1.pixel_size); |
- EXPECT_EQ('b', *favicon_bitmap2.bitmap_data->front()); |
+ EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmap2.bitmap_data)); |
EXPECT_EQ(kLargeSize, favicon_bitmap2.pixel_size); |
FaviconID out_favicon2 = backend_->thumbnail_db_-> |
@@ -461,7 +611,11 @@ TEST_F(HistoryBackendTest, DeleteAll) { |
// The remaining URL should still reference the same favicon, even if its |
// ID has changed. |
- EXPECT_EQ(out_favicon1, GetFavicon(outrow1.url(), FAVICON)); |
+ std::vector<IconMapping> mappings; |
+ EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
+ outrow1.url(), FAVICON, &mappings)); |
+ EXPECT_EQ(1u, mappings.size()); |
+ EXPECT_EQ(out_favicon1, mappings[0].icon_id); |
// The first URL should still be bookmarked. |
EXPECT_TRUE(bookmark_model_.IsBookmarked(row1.url())); |
@@ -741,8 +895,8 @@ TEST_F(HistoryBackendTest, ImportedFaviconsTest) { |
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_FALSE(GetFavicon(row1.url(), FAVICON) == 0); |
- EXPECT_TRUE(GetFavicon(row2.url(), FAVICON) == 0); |
+ EXPECT_EQ(1u, NumIconMappingsForPageURL(row1.url(), FAVICON)); |
+ EXPECT_EQ(0u, NumIconMappingsForPageURL(row2.url(), FAVICON)); |
// Now provide one imported favicon for both URLs already in the registry. |
// The new favicon should only be used with the URL that doesn't already have |
@@ -757,10 +911,19 @@ TEST_F(HistoryBackendTest, ImportedFaviconsTest) { |
backend_->SetImportedFavicons(favicons); |
EXPECT_FALSE(backend_->db_->GetRowForURL(row1.url(), &url_row1) == 0); |
EXPECT_FALSE(backend_->db_->GetRowForURL(row2.url(), &url_row2) == 0); |
- EXPECT_FALSE(GetFavicon(row1.url(), FAVICON) == 0); |
- EXPECT_FALSE(GetFavicon(row2.url(), FAVICON) == 0); |
- EXPECT_FALSE(GetFavicon(row1.url(), FAVICON) == |
- GetFavicon(row2.url(), FAVICON)); |
+ |
+ std::vector<IconMapping> mappings; |
+ EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
+ row1.url(), 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(), FAVICON, &mappings)); |
+ EXPECT_EQ(1u, mappings.size()); |
+ EXPECT_EQ(favicon.favicon_url, mappings[0].icon_url); |
// A URL should not be added to history (to store favicon), if |
// the URL is not bookmarked. |
@@ -1117,7 +1280,9 @@ TEST_F(HistoryBackendTest, MigrationVisitSource) { |
EXPECT_FALSE(s.Step()); |
} |
-TEST_F(HistoryBackendTest, SetFaviconMapping) { |
+// Test that SetFaviconMappingsForPageAndRedirects correctly updates icon |
+// mappings based on redirects, icon URLs and icon types. |
+TEST_F(HistoryBackendTest, SetFaviconMappingsForPageAndRedirects) { |
// Init recent_redirects_ |
const GURL url1("http://www.google.com"); |
const GURL url2("http://www.google.com/m"); |
@@ -1140,230 +1305,840 @@ TEST_F(HistoryBackendTest, SetFaviconMapping) { |
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"); |
+ |
+ // Create mapping for a page with two favicons. |
+ IconURLSizesMap two_icon_url_sizes; |
+ two_icon_url_sizes[icon_url1] = GetSizesSmallAndLarge(); |
+ two_icon_url_sizes[icon_url2] = GetSizesSmallAndLarge(); |
+ |
+ // Create a mapping for a page with a single favicon. |
+ IconURLSizesMap one_icon_url_sizes; |
+ one_icon_url_sizes[icon_url1] = GetSizesSmallAndLarge(); |
+ |
+ std::vector<FaviconBitmapData> favicon_bitmap_data; |
+ |
+ // Add two favicons |
+ backend_->SetFavicons(url1, FAVICON, favicon_bitmap_data, |
+ two_icon_url_sizes); |
+ EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, FAVICON)); |
+ EXPECT_EQ(2u, NumIconMappingsForPageURL(url2, FAVICON)); |
+ |
+ // Add one touch_icon |
+ backend_->SetFavicons(url1, TOUCH_ICON, favicon_bitmap_data, |
+ one_icon_url_sizes); |
+ EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, TOUCH_ICON)); |
+ EXPECT_EQ(1u, NumIconMappingsForPageURL(url2, TOUCH_ICON)); |
+ EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, FAVICON)); |
+ |
+ // Add one TOUCH_PRECOMPOSED_ICON |
+ backend_->SetFavicons(url1, TOUCH_PRECOMPOSED_ICON, favicon_bitmap_data, |
+ one_icon_url_sizes); |
+ // The touch_icon was replaced. |
+ EXPECT_EQ(0u, NumIconMappingsForPageURL(url1, TOUCH_ICON)); |
+ EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, FAVICON)); |
+ EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, TOUCH_PRECOMPOSED_ICON)); |
+ EXPECT_EQ(1u, NumIconMappingsForPageURL(url2, TOUCH_PRECOMPOSED_ICON)); |
+ |
+ // Add a touch_icon. |
+ backend_->SetFavicons(url1, TOUCH_ICON, favicon_bitmap_data, |
+ one_icon_url_sizes); |
+ EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, TOUCH_ICON)); |
+ EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, FAVICON)); |
+ // The TOUCH_PRECOMPOSED_ICON was replaced. |
+ EXPECT_EQ(0u, NumIconMappingsForPageURL(url1, TOUCH_PRECOMPOSED_ICON)); |
+ |
+ // Add a single favicon. |
+ backend_->SetFavicons(url1, FAVICON, favicon_bitmap_data, |
+ one_icon_url_sizes); |
+ EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, TOUCH_ICON)); |
+ EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, FAVICON)); |
+ EXPECT_EQ(1u, NumIconMappingsForPageURL(url2, FAVICON)); |
+ |
+ // Add two favicons. |
+ backend_->SetFavicons(url1, FAVICON, favicon_bitmap_data, |
+ two_icon_url_sizes); |
+ EXPECT_EQ(1u, NumIconMappingsForPageURL(url1, TOUCH_ICON)); |
+ EXPECT_EQ(2u, NumIconMappingsForPageURL(url1, FAVICON)); |
+} |
+ |
+// Test that there is no churn in icon mappings from calling |
+// SetFavicons() twice with the same |icon_url_sizes| parameter. |
+TEST_F(HistoryBackendTest, SetFaviconMappingsForPageDuplicates) { |
+ const GURL url("http://www.google.com/"); |
const GURL icon_url("http://www.google.com/icon"); |
- std::vector<unsigned char> data(blob1, blob1 + sizeof(blob1)); |
- // Add a favicon |
- backend_->SetFavicon( |
- url1, icon_url, base::RefCountedBytes::TakeVector(&data), FAVICON); |
- EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url1, FAVICON, NULL)); |
- EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url2, FAVICON, NULL)); |
+ std::vector<FaviconBitmapData> favicon_bitmap_data; |
- // Add a touch_icon |
- backend_->SetFavicon( |
- url1, icon_url, base::RefCountedBytes::TakeVector(&data), TOUCH_ICON); |
- EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url1, TOUCH_ICON, NULL)); |
- EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url2, TOUCH_ICON, NULL)); |
- EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url1, FAVICON, NULL)); |
+ IconURLSizesMap icon_url_sizes; |
+ icon_url_sizes[icon_url] = GetSizesSmallAndLarge(); |
- // Add a TOUCH_PRECOMPOSED_ICON |
- backend_->SetFavicon(url1, |
- icon_url, |
- base::RefCountedBytes::TakeVector(&data), |
- TOUCH_PRECOMPOSED_ICON); |
- // The touch_icon was replaced. |
- EXPECT_FALSE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url1, TOUCH_ICON, NULL)); |
- EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url1, FAVICON, NULL)); |
- EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url1, TOUCH_PRECOMPOSED_ICON, NULL)); |
- EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url2, TOUCH_PRECOMPOSED_ICON, NULL)); |
+ backend_->SetFavicons(url, FAVICON, favicon_bitmap_data, icon_url_sizes); |
- // Add a touch_icon |
- backend_->SetFavicon( |
- url1, icon_url, base::RefCountedBytes::TakeVector(&data), TOUCH_ICON); |
+ std::vector<IconMapping> icon_mappings; |
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url1, TOUCH_ICON, NULL)); |
+ url, FAVICON, &icon_mappings)); |
+ EXPECT_EQ(1u, icon_mappings.size()); |
+ IconMappingID mapping_id = icon_mappings[0].mapping_id; |
+ |
+ backend_->SetFavicons(url, FAVICON, favicon_bitmap_data, icon_url_sizes); |
+ |
+ icon_mappings.clear(); |
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url1, FAVICON, NULL)); |
- // The TOUCH_PRECOMPOSED_ICON was replaced. |
- EXPECT_FALSE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url1, TOUCH_PRECOMPOSED_ICON, NULL)); |
+ url, FAVICON, &icon_mappings)); |
+ EXPECT_EQ(1u, icon_mappings.size()); |
- // Add a favicon |
+ // The same row in the icon_mapping table should be used for the mapping as |
+ // before. |
+ EXPECT_EQ(mapping_id, icon_mappings[0].mapping_id); |
+} |
+ |
+// Test that setting favicons for a page which already has data does the |
+// right thing. |
+TEST_F(HistoryBackendTest, SetFavicons) { |
+ const GURL page_url("http://www.google.com/"); |
+ std::vector<FaviconBitmapData> favicon_bitmap_data; |
+ IconURLSizesMap icon_url_sizes; |
+ |
+ // Set |page_url| as having two favicons each available from the web at two |
+ // sizes. |
+ const GURL icon_url1("http://www.google.com/icon1"); |
const GURL icon_url2("http://www.google.com/icon2"); |
- backend_->SetFavicon( |
- url1, icon_url2, base::RefCountedBytes::TakeVector(&data), FAVICON); |
- FaviconID icon_id = backend_->thumbnail_db_->GetFaviconIDForFaviconURL( |
- icon_url2, FAVICON, NULL); |
- EXPECT_NE(0, icon_id); |
- std::vector<IconMapping> icon_mapping; |
+ |
+ icon_url_sizes[icon_url1] = GetSizesSmallAndLarge(); |
+ icon_url_sizes[icon_url2] = GetSizesSmallAndLarge(); |
+ |
+ // Set only sizes info for the favicons. |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ std::vector<IconMapping> icon_mappings; |
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url1, &icon_mapping)); |
- // The old icon was replaced. |
- EXPECT_TRUE(icon_mapping.size() > 1); |
- EXPECT_EQ(icon_id, icon_mapping[1].icon_id); |
+ page_url, &icon_mappings)); |
+ EXPECT_EQ(2u, icon_mappings.size()); |
+ for (size_t i = 0; i < icon_mappings.size(); ++i) { |
+ EXPECT_FALSE(backend_->thumbnail_db_->GetFaviconBitmaps( |
+ icon_mappings[i].icon_id, NULL)); |
+ } |
+ |
+ // Add bitmap data to the favicons. |
+ GenerateFaviconBitmapData(icon_url1, |
+ GetSizesSmall(), |
+ icon_url2, |
+ GetSizesSmallAndLarge(), |
+ &favicon_bitmap_data); |
+ |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ icon_mappings.clear(); |
+ EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url, &icon_mappings)); |
+ EXPECT_EQ(2u, icon_mappings.size()); |
+ |
+ GURL icon_url; |
+ IconType icon_type; |
+ FaviconSizes favicon_sizes; |
+ EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconHeader( |
+ icon_mappings[0].icon_id, &icon_url, &icon_type, &favicon_sizes)); |
+ EXPECT_EQ(icon_url1, icon_url); |
+ EXPECT_EQ(FAVICON, icon_type); |
+ EXPECT_EQ(GetSizesSmallAndLarge(), favicon_sizes); |
+ |
+ std::vector<FaviconBitmap> favicon_bitmaps; |
+ EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps( |
+ icon_mappings[0].icon_id, &favicon_bitmaps)); |
+ EXPECT_EQ(1u, favicon_bitmaps.size()); |
+ EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmaps[0].bitmap_data)); |
+ EXPECT_EQ(kSmallSize, favicon_bitmaps[0].pixel_size); |
+ |
+ favicon_sizes.clear(); |
+ EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconHeader( |
+ icon_mappings[1].icon_id, &icon_url, &icon_type, &favicon_sizes)); |
+ EXPECT_EQ(icon_url2, icon_url); |
+ EXPECT_EQ(FAVICON, icon_type); |
+ EXPECT_EQ(GetSizesSmallAndLarge(), favicon_sizes); |
+ |
+ favicon_bitmaps.clear(); |
+ EXPECT_TRUE(GetSortedFaviconBitmaps(icon_mappings[1].icon_id, |
+ &favicon_bitmaps)); |
+ |
+ EXPECT_EQ(2u, favicon_bitmaps.size()); |
+ EXPECT_EQ(kSmallSize, favicon_bitmaps[0].pixel_size); |
+ EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmaps[0].bitmap_data)); |
+ EXPECT_EQ(kLargeSize, favicon_bitmaps[1].pixel_size); |
+ EXPECT_TRUE(BitmapDataEqual('c', favicon_bitmaps[1].bitmap_data)); |
+ |
+ // Change the sizes for which the favicon at icon_url1 is available at from |
+ // the web. Verify that all the data remains valid. |
+ icon_url_sizes[icon_url1] = GetSizesTinySmallAndLarge(); |
+ favicon_bitmap_data.clear(); |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ icon_mappings.clear(); |
+ EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url, &icon_mappings)); |
+ EXPECT_EQ(2u, icon_mappings.size()); |
+ |
+ favicon_sizes.clear(); |
+ EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconHeader( |
+ icon_mappings[0].icon_id, &icon_url, &icon_type, &favicon_sizes)); |
+ EXPECT_EQ(icon_url1, icon_url); |
+ EXPECT_EQ(FAVICON, icon_type); |
+ EXPECT_EQ(GetSizesTinySmallAndLarge(), favicon_sizes); |
+ |
+ favicon_bitmaps.clear(); |
+ EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps( |
+ icon_mappings[0].icon_id, &favicon_bitmaps)); |
+ EXPECT_EQ(1u, favicon_bitmaps.size()); |
+ |
+ favicon_sizes.clear(); |
+ EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconHeader( |
+ icon_mappings[1].icon_id, &icon_url, &icon_type, &favicon_sizes)); |
+ EXPECT_EQ(icon_url2, icon_url); |
+ EXPECT_EQ(FAVICON, icon_type); |
+ EXPECT_EQ(GetSizesSmallAndLarge(), favicon_sizes); |
+ |
+ favicon_bitmaps.clear(); |
+ EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps( |
+ icon_mappings[1].icon_id, &favicon_bitmaps)); |
+ EXPECT_EQ(2u, favicon_bitmaps.size()); |
} |
-TEST_F(HistoryBackendTest, AddOrUpdateIconMapping) { |
- // Test the same icon and page mapping will not be added twice. other case |
- // should be covered in TEST_F(HistoryBackendTest, SetFaviconMapping) |
- const GURL url("http://www.google.com/"); |
+// Test that changing the sizes that a favicon is available at from the web |
+// deletes stale favicons and favicon bitmaps. |
+TEST_F(HistoryBackendTest, SetFaviconsDeleteBitmaps) { |
+ const GURL page_url("http://www.google.com/"); |
const GURL icon_url("http://www.google.com/icon"); |
- std::vector<unsigned char> data(blob1, blob1 + sizeof(blob1)); |
- backend_->SetFavicon( |
- url, icon_url, base::RefCountedBytes::TakeVector(&data), FAVICON); |
- FaviconID icon_id = backend_->thumbnail_db_->GetFaviconIDForFaviconURL( |
+ // Set |page_url| as having one favicon with two different sizes. |
+ IconURLSizesMap icon_url_sizes; |
+ icon_url_sizes[icon_url] = GetSizesSmallAndLarge(); |
+ |
+ std::vector<FaviconBitmapData> favicon_bitmap_data; |
+ GenerateFaviconBitmapData(icon_url, GetSizesSmallAndLarge(), |
+ &favicon_bitmap_data); |
+ |
+ // Add bitmap data and sizes information to the database. |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ FaviconID favicon_id = backend_->thumbnail_db_->GetFaviconIDForFaviconURL( |
icon_url, FAVICON, NULL); |
+ EXPECT_NE(0, favicon_id); |
- // Add the same mapping |
- FaviconID replaced; |
- EXPECT_FALSE(backend_->AddOrUpdateIconMapping( |
- url, icon_id, FAVICON, &replaced)); |
- EXPECT_EQ(0, replaced); |
+ std::vector<FaviconBitmap> favicon_bitmaps; |
+ EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(favicon_id, |
+ &favicon_bitmaps)); |
+ EXPECT_EQ(2u, favicon_bitmaps.size()); |
- std::vector<IconMapping> icon_mapping; |
- EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url, &icon_mapping)); |
- EXPECT_EQ(1u, icon_mapping.size()); |
+ // Change the bitmap sizes available from the web only to the small size only. |
+ icon_url_sizes[icon_url] = GetSizesSmall(); |
+ favicon_bitmap_data.clear(); |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ favicon_id = backend_->thumbnail_db_->GetFaviconIDForFaviconURL( |
+ icon_url, FAVICON, NULL); |
+ EXPECT_NE(0, favicon_id); |
+ |
+ favicon_bitmaps.clear(); |
+ EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(favicon_id, |
+ &favicon_bitmaps)); |
+ EXPECT_EQ(1u, favicon_bitmaps.size()); |
+ EXPECT_EQ(kSmallSize, favicon_bitmaps[0].pixel_size); |
+ |
+ // Clear |icon_url_sizes|. The remaining favicon and its bitmap should both |
+ // be deleted. |
+ icon_url_sizes.clear(); |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ EXPECT_EQ(0, backend_->thumbnail_db_->GetFaviconIDForFaviconURL( |
+ icon_url, FAVICON, NULL)); |
+ EXPECT_FALSE(backend_->thumbnail_db_->GetFaviconBitmaps(favicon_id, NULL)); |
} |
-// Test that SetFavicon for a page which shares a FaviconID with another does |
-// the right thing. |
-TEST_F(HistoryBackendTest, SetSameFaviconURLForTwoPages) { |
- GURL favicon_url("http://www.google.com/favicon.ico"); |
+// Test updating a single favicon bitmap's data via SetFavicons. |
+TEST_F(HistoryBackendTest, SetFaviconsReplaceBitmapData) { |
+ |
+ const GURL page_url("http://www.google.com/"); |
+ const GURL icon_url("http://www.google.com/icon"); |
+ IconURLSizesMap icon_url_sizes; |
+ icon_url_sizes[icon_url] = GetSizesSmall(); |
+ |
+ std::vector<unsigned char> data_initial; |
+ data_initial.push_back('a'); |
+ |
+ 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<FaviconBitmapData> favicon_bitmap_data; |
+ favicon_bitmap_data.push_back(bitmap_data_element); |
+ |
+ // Add bitmap to the database. |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ FaviconBitmap original_favicon_bitmap; |
+ EXPECT_TRUE(GetOnlyFaviconBitmapForIconURL(icon_url, FAVICON, |
+ &original_favicon_bitmap)); |
+ EXPECT_TRUE(BitmapDataEqual('a', original_favicon_bitmap.bitmap_data)); |
+ |
+ // SetFavicons with identical data but a different bitmap. |
+ std::vector<unsigned char> updated_data; |
+ updated_data.push_back('b'); |
+ favicon_bitmap_data[0].bitmap_data = |
+ base::RefCountedBytes::TakeVector(&updated_data); |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ FaviconBitmap updated_favicon_bitmap; |
+ EXPECT_TRUE(GetOnlyFaviconBitmapForIconURL(icon_url, FAVICON, |
+ &updated_favicon_bitmap)); |
+ EXPECT_TRUE(BitmapDataEqual('b', updated_favicon_bitmap.bitmap_data)); |
+ |
+ // There should be no churn in FaviconIDs or FaviconBitmapIds. |
+ EXPECT_EQ(original_favicon_bitmap.icon_id, updated_favicon_bitmap.icon_id); |
+ EXPECT_EQ(original_favicon_bitmap.bitmap_id, |
+ updated_favicon_bitmap.bitmap_id); |
+} |
+ |
+// Test that if two pages share the same FaviconID, changing the favicon for |
+// one page does not affect the other. |
+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"); |
- scoped_refptr<base::RefCountedMemory> bitmap_data( |
- new base::RefCountedBytes()); |
- backend_->SetFavicon(page_url1, favicon_url, bitmap_data, FAVICON); |
+ IconURLSizesMap icon_url_sizes; |
+ icon_url_sizes[icon_url] = GetSizesSmall(); |
+ |
+ std::vector<FaviconBitmapData> favicon_bitmap_data; |
+ GenerateFaviconBitmapData(icon_url, GetSizesSmallAndLarge(), |
+ &favicon_bitmap_data); |
+ |
+ backend_->SetFavicons(page_url1, FAVICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ std::vector<GURL> icon_urls; |
+ icon_urls.push_back(icon_url); |
scoped_refptr<GetFaviconRequest> request(new GetFaviconRequest( |
base::Bind(&HistoryBackendTest::OnFaviconResults, |
base::Unretained(this)))); |
HistoryBackendCancelableRequest cancellable_request; |
cancellable_request.MockScheduleOfRequest<GetFaviconRequest>(request); |
- backend_->UpdateFaviconMappingAndFetch(request, page_url2, favicon_url, |
- FAVICON); |
+ backend_->UpdateFaviconMappingsAndFetch(request, page_url2, icon_urls, |
+ FAVICON, kSmallSize.width(), GetScaleFactors1x2x()); |
// Check that the same FaviconID is mapped to both page URLs. |
- std::vector<IconMapping> icon_mappings1; |
+ std::vector<IconMapping> icon_mappings; |
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- page_url1, &icon_mappings1)); |
- EXPECT_EQ(1u, icon_mappings1.size()); |
- FaviconID favicon_id = icon_mappings1[0].icon_id; |
+ page_url1, &icon_mappings)); |
+ EXPECT_EQ(1u, icon_mappings.size()); |
+ FaviconID favicon_id = icon_mappings[0].icon_id; |
EXPECT_NE(0, favicon_id); |
- std::vector<IconMapping> icon_mappings2; |
+ icon_mappings.clear(); |
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- page_url2, &icon_mappings2)); |
- EXPECT_EQ(1u, icon_mappings2.size()); |
- EXPECT_EQ(favicon_id, icon_mappings2[0].icon_id); |
- |
- // Update the bitmap data. |
- backend_->SetFavicon(page_url1, favicon_url, bitmap_data, FAVICON); |
- |
- // |page_url1| and |page_url2| should still map to the same FaviconID |
- // and have valid bitmap data. |
- icon_mappings1.clear(); |
+ page_url2, &icon_mappings)); |
+ EXPECT_EQ(1u, icon_mappings.size()); |
+ EXPECT_EQ(favicon_id, icon_mappings[0].icon_id); |
+ |
+ // Change the icon URL that |page_url1| is mapped to. |
+ icon_url_sizes.clear(); |
+ icon_url_sizes[icon_url_new] = GetSizesSmall(); |
+ GenerateFaviconBitmapData(icon_url_new, GetSizesSmall(), |
+ &favicon_bitmap_data); |
+ backend_->SetFavicons(page_url1, FAVICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ // |page_url1| should map to a new FaviconID and have valid bitmap data. |
+ icon_mappings.clear(); |
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- page_url1, &icon_mappings1)); |
- EXPECT_EQ(1u, icon_mappings1.size()); |
- EXPECT_EQ(favicon_id, icon_mappings1[0].icon_id); |
+ 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); |
- icon_mappings2.clear(); |
+ std::vector<FaviconBitmap> favicon_bitmaps; |
+ EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps( |
+ icon_mappings[0].icon_id, &favicon_bitmaps)); |
+ EXPECT_EQ(1u, favicon_bitmaps.size()); |
+ |
+ // |page_url2| should still map to the same FaviconID and have valid bitmap |
+ // data. |
+ icon_mappings.clear(); |
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- page_url2, &icon_mappings2)); |
- EXPECT_EQ(1u, icon_mappings2.size()); |
- EXPECT_EQ(favicon_id, icon_mappings2[0].icon_id); |
+ page_url2, &icon_mappings)); |
+ EXPECT_EQ(1u, icon_mappings.size()); |
+ EXPECT_EQ(favicon_id, icon_mappings[0].icon_id); |
- std::vector<FaviconBitmap> favicon_bitmaps; |
+ favicon_bitmaps.clear(); |
EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconBitmaps(favicon_id, |
&favicon_bitmaps)); |
- EXPECT_EQ(1u, favicon_bitmaps.size()); |
+ EXPECT_EQ(2u, favicon_bitmaps.size()); |
} |
-TEST_F(HistoryBackendTest, GetFaviconForURL) { |
- // This test will add a fav icon and touch icon for the same URL |
- // and check the behaviour of backend's GetFaviconForURL implementation. |
- const GURL url("http://www.google.com/"); |
- const GURL icon_url("http://www.google.com/icon"); |
- std::vector<unsigned char> data(blob1, blob1 + sizeof(blob1)); |
- scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes(data)); |
- // Used for testing the icon data after getting from DB |
- std::string blob_data(bytes->front(), |
- bytes->front() + bytes->size()); |
+// Tests when a merge is valid. |
+TEST_F(HistoryBackendTest, IsMergeValid) { |
+ GURL page_url("http://www.google.com"); |
+ std::vector<FaviconBitmapData> favicon_bitmap_data; |
+ |
+ GURL icon_url("http://www.google.com/favicon.ico"); |
+ const gfx::Size& pixel_size = kLargeSize; |
+ GURL different_icon_url("http://www.google.com/favicon2.ico"); |
+ |
+ // A merge is invalid if icon URLs are already mapped to |page_url| but |
+ // |icon_url| is not one of them. |
+ IconURLSizesMap icon_url_sizes; |
+ icon_url_sizes[different_icon_url] = GetSizesSmallAndLarge(); |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, icon_url_sizes); |
+ |
+ gfx::Size merge_pixel_size; |
+ EXPECT_FALSE(backend_->IsMergeValid(page_url, icon_url, FAVICON, pixel_size, |
+ &merge_pixel_size)); |
+ |
+ // A merge is invalid if the database knows |icon_url| but |pixel_size| is |
+ // not part of the known favicon sizes. |
+ icon_url_sizes.clear(); |
+ icon_url_sizes[icon_url] = GetSizesSmall(); |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, icon_url_sizes); |
+ |
+ EXPECT_FALSE(backend_->IsMergeValid(page_url, icon_url, FAVICON, pixel_size, |
+ &merge_pixel_size)); |
+ |
+ // A merge is valid when |page_url| is not mapped to any favicons and |
+ // |icon_url| is not known by the database. |
+ icon_url_sizes.clear(); |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, icon_url_sizes); |
+ |
+ EXPECT_TRUE(backend_->IsMergeValid(page_url, icon_url, FAVICON, pixel_size, |
+ &merge_pixel_size)); |
+ |
+ // A merge is valid when |icon_url| is known by the database and |pixel_size| |
+ // is part of the known favicon sizes. |
+ icon_url_sizes[icon_url] = GetSizesSmallAndLarge(); |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, icon_url_sizes); |
+ |
+ EXPECT_TRUE(backend_->IsMergeValid(page_url, icon_url, FAVICON, pixel_size, |
+ &merge_pixel_size)); |
+ EXPECT_EQ(kLargeSize, merge_pixel_size); |
+ |
+ // A merge is valid when |icon_url| is known by the database and the favicon |
+ // sizes for the favicon are not known. |
+ icon_url_sizes[icon_url] = GetDefaultFaviconSizes(); |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, icon_url_sizes); |
+ |
+ EXPECT_TRUE(backend_->IsMergeValid(page_url, icon_url, FAVICON, pixel_size, |
+ &merge_pixel_size)); |
+ EXPECT_EQ(gfx::Size(), merge_pixel_size); |
+} |
- // Add a favicon |
- backend_->SetFavicon( |
- url, icon_url, bytes.get(), FAVICON); |
- EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url, FAVICON, NULL)); |
+// Tests calling MergeFavicon() repeatedly when there are initially no mappings |
+// for |page_url| in the database. |
+TEST_F(HistoryBackendTest, MergeFaviconPageURLNotInDB) { |
+ GURL page_url("http://www.google.com"); |
+ GURL icon_url("http://www.google.com/favicon.ico"); |
- // Add a touch_icon |
- backend_->SetFavicon( |
- url, icon_url, bytes.get(), TOUCH_ICON); |
+ std::vector<unsigned char> bitmap_data1; |
+ bitmap_data1.push_back('a'); |
+ backend_->MergeFavicon(page_url, icon_url, FAVICON, |
+ base::RefCountedBytes::TakeVector(&bitmap_data1), kSmallSize); |
+ |
+ std::vector<IconMapping> icon_mappings; |
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
- url, TOUCH_ICON, NULL)); |
- |
- // Test the Fav icon for this URL. |
- std::vector<FaviconBitmapResult> favicon_bitmap_results; |
- ASSERT_TRUE(backend_->GetFaviconFromDB(url, FAVICON, |
- &favicon_bitmap_results)); |
- EXPECT_EQ(1u, favicon_bitmap_results.size()); |
- FaviconBitmapResult bitmap_result = favicon_bitmap_results[0]; |
- std::string favicon_data( |
- bitmap_result.bitmap_data->front(), |
- bitmap_result.bitmap_data->front() + bitmap_result.bitmap_data->size()); |
- |
- EXPECT_EQ(FAVICON, bitmap_result.icon_type); |
- EXPECT_EQ(icon_url, bitmap_result.icon_url); |
- EXPECT_EQ(blob_data, favicon_data); |
- |
- // Test the touch icon for this URL. |
- ASSERT_TRUE(backend_->GetFaviconFromDB(url, TOUCH_ICON, |
- &favicon_bitmap_results)); |
- EXPECT_EQ(1u, favicon_bitmap_results.size()); |
- bitmap_result = favicon_bitmap_results[0]; |
- std::string touchicon_data( |
- bitmap_result.bitmap_data->front(), |
- bitmap_result.bitmap_data->front() + bitmap_result.bitmap_data->size()); |
- |
- EXPECT_EQ(TOUCH_ICON, bitmap_result.icon_type); |
- EXPECT_EQ(icon_url, bitmap_result.icon_url); |
- EXPECT_EQ(blob_data, touchicon_data); |
+ page_url, &icon_mappings)); |
+ EXPECT_EQ(1u, icon_mappings.size()); |
+ |
+ GURL icon_url_out; |
+ IconType icon_type_out; |
+ FaviconSizes favicon_sizes_out; |
+ EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconHeader( |
+ icon_mappings[0].icon_id, &icon_url_out, &icon_type_out, |
+ &favicon_sizes_out)); |
+ EXPECT_EQ(icon_url, icon_url_out); |
+ EXPECT_EQ(FAVICON, icon_type_out); |
+ // The favicon sizes should be default as the real favicon sizes are unknown. |
+ EXPECT_EQ(GetDefaultFaviconSizes(), favicon_sizes_out); |
+ |
+ FaviconBitmap favicon_bitmap; |
+ EXPECT_TRUE(GetOnlyFaviconBitmapForIconURL(icon_url_out, FAVICON, |
+ &favicon_bitmap)); |
+ EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data)); |
+ EXPECT_EQ(gfx::Size(), favicon_bitmap.pixel_size); |
+ |
+ // Changing the bitmap data via merge favicons should work. |
+ std::vector<unsigned char> bitmap_data2; |
+ bitmap_data2.push_back('b'); |
+ backend_->MergeFavicon(page_url, icon_url, FAVICON, |
+ base::RefCountedBytes::TakeVector(&bitmap_data2), kSmallSize); |
+ |
+ // The favicon should still be valid and the bitmap data should have changed. |
+ favicon_sizes_out.clear(); |
+ EXPECT_TRUE(backend_->thumbnail_db_->GetFaviconHeader( |
+ icon_mappings[0].icon_id, &icon_url_out, &icon_type_out, |
+ &favicon_sizes_out)); |
+ EXPECT_EQ(icon_url, icon_url_out); |
+ EXPECT_EQ(FAVICON, icon_type_out); |
+ EXPECT_EQ(GetDefaultFaviconSizes(), favicon_sizes_out); |
+ |
+ EXPECT_TRUE(GetOnlyFaviconBitmapForIconURL(icon_url_out, FAVICON, |
+ &favicon_bitmap)); |
+ EXPECT_TRUE(BitmapDataEqual('b', favicon_bitmap.bitmap_data)); |
+ EXPECT_EQ(gfx::Size(), favicon_bitmap.pixel_size); |
+} |
+ |
+// Test that MergeFavicon() adds the passed in favicon bitmaps to the database |
+// for a |page_url| with preexisting mappings only when it merges cleanly. |
+TEST_F(HistoryBackendTest, MergeFaviconPageURLInDB) { |
+ GURL page_url("http://www.google.com"); |
+ GURL icon_url1("http://www.google.com/favicon1.ico"); |
+ GURL icon_url2("http://www.google.com/favicon2.ico"); |
+ GURL icon_url3("http://www.google.com/favicon3.ico"); |
+ |
+ std::vector<unsigned char> data; |
+ data.push_back('c'); |
+ scoped_refptr<base::RefCountedBytes> bitmap_data( |
+ base::RefCountedBytes::TakeVector(&data)); |
+ |
+ // Set and test initial state. |
+ IconURLSizesMap icon_url_sizes; |
+ icon_url_sizes[icon_url1] = GetSizesSmallAndLarge(); |
+ icon_url_sizes[icon_url2] = GetSizesSmall(); |
+ |
+ std::vector<FaviconBitmapData> favicon_bitmap_data; |
+ GenerateFaviconBitmapData(icon_url1, GetSizesSmall(), |
+ &favicon_bitmap_data); |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ std::vector<IconMapping> icon_mappings; |
+ EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url, &icon_mappings)); |
+ EXPECT_EQ(2u, icon_mappings.size()); |
+ EXPECT_EQ(icon_url1, icon_mappings[0].icon_url); |
+ EXPECT_EQ(icon_url2, icon_mappings[1].icon_url); |
+ |
+ FaviconBitmap favicon_bitmap; |
+ EXPECT_TRUE(GetOnlyFaviconBitmapForIconURL(icon_mappings[0].icon_url, |
+ FAVICON, &favicon_bitmap)); |
+ EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data)); |
+ EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size); |
+ |
+ EXPECT_FALSE(backend_->thumbnail_db_->GetFaviconBitmaps( |
+ icon_mappings[1].icon_id, NULL)); |
+ |
+ // Test that invalid merge does not change the favicon bitmaps mapped to |
+ // |page_url|. |
+ backend_->MergeFavicon(page_url, icon_url3, FAVICON, bitmap_data, |
+ kLargeSize); |
+ |
+ icon_mappings.clear(); |
+ EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url, &icon_mappings)); |
+ EXPECT_EQ(2u, icon_mappings.size()); |
+ EXPECT_EQ(icon_url1, icon_mappings[0].icon_url); |
+ EXPECT_EQ(icon_url2, icon_mappings[1].icon_url); |
+ |
+ EXPECT_TRUE(GetOnlyFaviconBitmapForIconURL(icon_mappings[0].icon_url, |
+ FAVICON, &favicon_bitmap)); |
+ EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmap.bitmap_data)); |
+ EXPECT_EQ(kSmallSize, favicon_bitmap.pixel_size); |
+ |
+ EXPECT_FALSE(backend_->thumbnail_db_->GetFaviconBitmaps( |
+ icon_mappings[1].icon_id, NULL)); |
+ |
+ // Test that a valid merge updates the favicon bitmaps. |
+ backend_->MergeFavicon(page_url, icon_url1, FAVICON, bitmap_data, |
+ kLargeSize); |
+ |
+ icon_mappings.clear(); |
+ EXPECT_TRUE(GetSortedIconMappingsForPageURL(page_url, &icon_mappings)); |
+ EXPECT_EQ(2u, icon_mappings.size()); |
+ EXPECT_EQ(icon_url1, icon_mappings[0].icon_url); |
+ EXPECT_EQ(icon_url2, icon_mappings[1].icon_url); |
+ |
+ std::vector<FaviconBitmap> favicon_bitmaps; |
+ EXPECT_TRUE(GetSortedFaviconBitmaps(icon_mappings[0].icon_id, |
+ &favicon_bitmaps)); |
+ EXPECT_TRUE(BitmapDataEqual('a', favicon_bitmaps[0].bitmap_data)); |
+ EXPECT_EQ(kSmallSize, favicon_bitmaps[0].pixel_size); |
+ EXPECT_TRUE(BitmapDataEqual('c', favicon_bitmaps[1].bitmap_data)); |
+ EXPECT_EQ(kLargeSize, favicon_bitmaps[1].pixel_size); |
+ |
+ EXPECT_FALSE(backend_->thumbnail_db_->GetFaviconBitmaps( |
+ icon_mappings[1].icon_id, NULL)); |
+} |
+ |
+// Test UpdateFaviconMapingsAndFetch() when multiple icon types are passed in. |
+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"); |
+ |
+ // |page_url1| is mapped to |icon_urla| which if of type TOUCH_ICON. |
+ IconURLSizesMap icon_url_sizes; |
+ icon_url_sizes[icon_urla] = GetSizesSmall(); |
+ |
+ std::vector<FaviconBitmapData> favicon_bitmap_data; |
+ GenerateFaviconBitmapData(icon_urla, GetSizesSmall(), &favicon_bitmap_data); |
+ backend_->SetFavicons(page_url1, TOUCH_ICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ // |page_url2| is mapped to |icon_urlb| and |icon_urlc| which is of type |
+ // TOUCH_PRECOMPOSED_ICON. |
+ icon_url_sizes.clear(); |
+ icon_url_sizes[icon_urlb] = GetSizesSmall(); |
+ icon_url_sizes[icon_urlc] = GetSizesSmall(); |
+ GenerateFaviconBitmapData(icon_urlb, GetSizesSmall(), icon_urlc, |
+ GetSizesSmall(), &favicon_bitmap_data); |
+ backend_->SetFavicons(page_url2, TOUCH_PRECOMPOSED_ICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ std::vector<GURL> icon_urls; |
+ icon_urls.push_back(icon_urla); |
+ icon_urls.push_back(icon_urlb); |
+ icon_urls.push_back(icon_urlc); |
+ scoped_refptr<GetFaviconRequest> request(new GetFaviconRequest( |
+ base::Bind(&HistoryBackendTest::OnFaviconResults, |
+ base::Unretained(this)))); |
+ HistoryBackendCancelableRequest cancellable_request; |
+ cancellable_request.MockScheduleOfRequest<GetFaviconRequest>(request); |
+ backend_->UpdateFaviconMappingsAndFetch(request, page_url3, icon_urls, |
+ TOUCH_ICON | TOUCH_PRECOMPOSED_ICON, kSmallSize.width(), |
+ GetScaleFactors1x2x()); |
+ |
+ // |page_url1| and |page_url2| should still be mapped to the same icon URLs. |
+ 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(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(TOUCH_PRECOMPOSED_ICON, icon_mappings[0].icon_type); |
+ EXPECT_EQ(icon_urlc, icon_mappings[1].icon_url); |
+ EXPECT_EQ(TOUCH_PRECOMPOSED_ICON, icon_mappings[1].icon_type); |
+ |
+ // |page_url3| should be mapped only to |icon_urlb| and |icon_urlc| as |
+ // TOUCH_PRECOMPOSED_ICON is the largest IconType. |
+ 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(TOUCH_PRECOMPOSED_ICON, icon_mappings[0].icon_type); |
+ EXPECT_EQ(icon_urlc, icon_mappings[1].icon_url); |
+ EXPECT_EQ(TOUCH_PRECOMPOSED_ICON, icon_mappings[1].icon_type); |
+} |
+ |
+// Test the results of GetFaviconsFromDB() when there are no found |
+// favicons. |
+TEST_F(HistoryBackendTest, GetFaviconsFromDBEmpty) { |
+ const GURL page_url("http://www.google.com/"); |
+ |
+ std::vector<FaviconBitmapResult> bitmap_results; |
+ IconURLSizesMap icon_url_sizes; |
+ EXPECT_FALSE(backend_->GetFaviconsFromDB(page_url, FAVICON, |
+ kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results, |
+ &icon_url_sizes)); |
+ EXPECT_TRUE(bitmap_results.empty()); |
+ EXPECT_TRUE(icon_url_sizes.empty()); |
+} |
+ |
+// Test that GetFaviconsFromDB() returns results for the bitmaps which most |
+// closely match the passed in desired size and scale factors. |
+TEST_F(HistoryBackendTest, GetFaviconsFromDBSelectClosestMatch) { |
+ const GURL page_url("http://www.google.com/"); |
+ |
+ const GURL icon_url("http://www.google.com/icon1"); |
+ IconURLSizesMap icon_url_sizes; |
+ icon_url_sizes[icon_url] = GetSizesTinySmallAndLarge(); |
+ |
+ std::vector<FaviconBitmapData> favicon_bitmap_data; |
+ GenerateFaviconBitmapData(icon_url, GetSizesTinySmallAndLarge(), |
+ &favicon_bitmap_data); |
+ |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ std::vector<FaviconBitmapResult> bitmap_results_out; |
+ IconURLSizesMap icon_url_sizes_out; |
+ EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url, FAVICON, kSmallSize.width(), |
+ GetScaleFactors1x2x(), &bitmap_results_out, &icon_url_sizes_out)); |
+ |
+ // The bitmap data for the 1x and 2x bitmaps should be returned as their sizes |
+ // match exactly. |
+ |
+ EXPECT_EQ(2u, bitmap_results_out.size()); |
+ // No required order for results. |
+ if (bitmap_results_out[0].pixel_size == kLargeSize) { |
+ 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(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(FAVICON, bitmap_results_out[1].icon_type); |
+ |
+ EXPECT_EQ(icon_url_sizes, icon_url_sizes_out); |
+} |
+ |
+// Test that GetFaviconsFromDB() returns results from the icon URL whose |
+// bitmaps most closely match the passed in desired size and scale factors. |
+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"); |
+ IconURLSizesMap icon_url_sizes; |
+ icon_url_sizes[icon_url1] = GetSizesSmall(); |
+ icon_url_sizes[icon_url2] = GetSizesSmallAndLarge(); |
+ |
+ std::vector<FaviconBitmapData> favicon_bitmap_data; |
+ GenerateFaviconBitmapData(icon_url1, GetSizesSmall(), icon_url2, |
+ GetSizesLarge(), &favicon_bitmap_data); |
+ |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ std::vector<FaviconBitmapResult> bitmap_results_out; |
+ IconURLSizesMap icon_url_sizes_out; |
+ EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url, FAVICON, kSmallSize.width(), |
+ GetScaleFactors1x2x(), &bitmap_results_out, &icon_url_sizes_out)); |
+ |
+ // The results should have the large bitmap as downscaling is preferred to |
+ // upscaling. |
+ EXPECT_EQ(1u, bitmap_results_out.size()); |
+ EXPECT_EQ(kSmallSize, bitmap_results_out[0].pixel_size); |
+ EXPECT_EQ(icon_url1, bitmap_results_out[0].icon_url); |
+ |
+ EXPECT_EQ(icon_url_sizes, icon_url_sizes_out); |
+} |
+ |
+// Test the results of GetFaviconsFromDB() when called with different |
+// |icon_types|. |
+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"); |
+ |
+ IconURLSizesMap icon_url_sizes; |
+ icon_url_sizes[icon_url1] = GetSizesSmall(); |
+ icon_url_sizes[icon_url2] = GetSizesSmall(); |
+ |
+ std::vector<FaviconBitmapData> favicon_bitmap_data; |
+ GenerateFaviconBitmapData(icon_url1, GetSizesSmall(), &favicon_bitmap_data); |
+ backend_->SetFavicons(page_url, FAVICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ GenerateFaviconBitmapData(icon_url2, GetSizesSmall(), &favicon_bitmap_data); |
+ backend_->SetFavicons(page_url, TOUCH_ICON, favicon_bitmap_data, |
+ icon_url_sizes); |
+ |
+ std::vector<FaviconBitmapResult> bitmap_results_out; |
+ IconURLSizesMap icon_url_sizes_out; |
+ EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url, FAVICON, |
+ kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out, |
+ &icon_url_sizes_out)); |
+ |
+ EXPECT_EQ(1u, bitmap_results_out.size()); |
+ EXPECT_EQ(FAVICON, bitmap_results_out[0].icon_type); |
+ EXPECT_EQ(icon_url_sizes, icon_url_sizes_out); |
+ |
+ bitmap_results_out.clear(); |
+ icon_url_sizes_out.clear(); |
+ EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url, TOUCH_ICON, |
+ kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out, |
+ &icon_url_sizes_out)); |
+ |
+ EXPECT_EQ(1u, bitmap_results_out.size()); |
+ EXPECT_EQ(TOUCH_ICON, bitmap_results_out[0].icon_type); |
+ EXPECT_EQ(icon_url_sizes, icon_url_sizes_out); |
+} |
+ |
+// Test that GetFaviconsFromDB() correctly sets the expired flag for bitmap |
+// reults. |
+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); |
+ FaviconID icon_id = backend_->thumbnail_db_->AddFavicon(icon_url, FAVICON, |
+ GetSizesSmallAndLarge(), bitmap_data, last_updated, kSmallSize); |
+ EXPECT_NE(0, icon_id); |
+ EXPECT_NE(0, backend_->thumbnail_db_->AddIconMapping(page_url, icon_id)); |
+ |
+ std::vector<FaviconBitmapResult> bitmap_results_out; |
+ IconURLSizesMap icon_url_sizes_out; |
+ EXPECT_TRUE(backend_->GetFaviconsFromDB(page_url, FAVICON, |
+ kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out, |
+ &icon_url_sizes_out)); |
+ |
+ EXPECT_EQ(1u, bitmap_results_out.size()); |
+ EXPECT_TRUE(bitmap_results_out[0].expired); |
} |
TEST_F(HistoryBackendTest, CloneFaviconIsRestrictedToSameDomain) { |
const GURL url("http://www.google.com/"); |
- const GURL icon_url("http://www.google.com/icon"); |
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"); |
// Add a favicon |
- std::vector<unsigned char> data(blob1, blob1 + sizeof(blob1)); |
- scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes(data)); |
- backend_->SetFavicon( |
- url, icon_url, bytes.get(), FAVICON); |
+ IconURLSizesMap icon_url_sizes; |
+ icon_url_sizes[icon_url] = GetSizesSmall(); |
+ |
+ std::vector<FaviconBitmapData> favicon_bitmap_data; |
+ GenerateFaviconBitmapData(icon_url, GetSizesSmall(), &favicon_bitmap_data); |
+ backend_->SetFavicons(url, FAVICON, favicon_bitmap_data, icon_url_sizes); |
EXPECT_TRUE(backend_->thumbnail_db_->GetIconMappingsForPageURL( |
url, FAVICON, NULL)); |
// Validate starting state. |
- std::vector<FaviconBitmapResult> favicon_bitmap_results; |
- EXPECT_TRUE(backend_->GetFaviconFromDB(url, FAVICON, |
- &favicon_bitmap_results)); |
- EXPECT_FALSE(backend_->GetFaviconFromDB(same_domain_url, FAVICON, |
- &favicon_bitmap_results)); |
- EXPECT_FALSE(backend_->GetFaviconFromDB(foreign_domain_url, FAVICON, |
- &favicon_bitmap_results)); |
+ std::vector<FaviconBitmapResult> bitmap_results_out; |
+ IconURLSizesMap icon_url_sizes_out; |
+ EXPECT_TRUE(backend_->GetFaviconsFromDB(url, FAVICON, |
+ kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out, |
+ &icon_url_sizes_out)); |
+ EXPECT_FALSE(backend_->GetFaviconsFromDB(same_domain_url, FAVICON, |
+ kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out, |
+ &icon_url_sizes_out)); |
+ EXPECT_FALSE(backend_->GetFaviconsFromDB(foreign_domain_url, FAVICON, |
+ kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out, |
+ &icon_url_sizes_out)); |
// Same-domain cloning should work. |
- backend_->CloneFavicon(url, same_domain_url); |
- EXPECT_TRUE(backend_->GetFaviconFromDB(same_domain_url, FAVICON, |
- &favicon_bitmap_results)); |
+ backend_->CloneFavicons(url, same_domain_url); |
+ EXPECT_TRUE(backend_->GetFaviconsFromDB(same_domain_url, FAVICON, |
+ kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out, |
+ &icon_url_sizes_out)); |
// Foreign-domain cloning is forbidden. |
- backend_->CloneFavicon(url, foreign_domain_url); |
- EXPECT_FALSE(backend_->GetFaviconFromDB(foreign_domain_url, FAVICON, |
- &favicon_bitmap_results)); |
+ backend_->CloneFavicons(url, foreign_domain_url); |
+ EXPECT_FALSE(backend_->GetFaviconsFromDB(foreign_domain_url, FAVICON, |
+ kSmallSize.width(), GetScaleFactors1x2x(), &bitmap_results_out, |
+ &icon_url_sizes_out)); |
} |
TEST_F(HistoryBackendTest, QueryFilteredURLs) { |