| Index: components/favicon/core/favicon_handler_unittest.cc
|
| diff --git a/components/favicon/core/favicon_handler_unittest.cc b/components/favicon/core/favicon_handler_unittest.cc
|
| index 5cddc0241d9b3a618a03077eff2de517ed1320c8..598895bfb17133a4707dd0963ebecbd6e094f867 100644
|
| --- a/components/favicon/core/favicon_handler_unittest.cc
|
| +++ b/components/favicon/core/favicon_handler_unittest.cc
|
| @@ -4,6 +4,9 @@
|
|
|
| #include "components/favicon/core/favicon_handler.h"
|
|
|
| +#include<set>
|
| +#include<vector>
|
| +
|
| #include "base/memory/scoped_ptr.h"
|
| #include "components/favicon/core/favicon_driver.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| @@ -69,13 +72,25 @@ void SetFaviconRawBitmapResult(
|
| class DownloadHandler {
|
| public:
|
| explicit DownloadHandler(FaviconHandler* favicon_handler)
|
| - : favicon_handler_(favicon_handler), failed_(false) {}
|
| + : favicon_handler_(favicon_handler), callback_invoked_(false) {}
|
|
|
| ~DownloadHandler() {}
|
|
|
| void Reset() {
|
| download_.reset();
|
| - failed_ = false;
|
| + callback_invoked_ = false;
|
| + // Does not affect |should_fail_download_icon_urls_| and
|
| + // |failed_download_icon_urls_|.
|
| + }
|
| +
|
| + // Make downloads for any of |icon_urls| fail.
|
| + void FailDownloadForIconURLs(const std::set<GURL>& icon_urls) {
|
| + should_fail_download_icon_urls_ = icon_urls;
|
| + }
|
| +
|
| + // Returns whether a download for |icon_url| did fail.
|
| + bool DidFailDownloadForIconURL(const GURL& icon_url) const {
|
| + return failed_download_icon_urls_.count(icon_url);
|
| }
|
|
|
| void AddDownload(
|
| @@ -84,13 +99,11 @@ class DownloadHandler {
|
| const std::vector<int>& image_sizes,
|
| int max_image_size) {
|
| download_.reset(new Download(
|
| - download_id, image_url, image_sizes, max_image_size, false));
|
| + download_id, image_url, image_sizes, max_image_size));
|
| }
|
|
|
| void InvokeCallback();
|
|
|
| - void set_failed(bool failed) { failed_ = failed; }
|
| -
|
| bool HasDownload() const { return download_.get(); }
|
| const GURL& GetImageUrl() const { return download_->image_url; }
|
| void SetImageSizes(const std::vector<int>& sizes) {
|
| @@ -101,8 +114,7 @@ class DownloadHandler {
|
| Download(int id,
|
| GURL url,
|
| const std::vector<int>& sizes,
|
| - int max_size,
|
| - bool failed)
|
| + int max_size)
|
| : download_id(id),
|
| image_url(url),
|
| image_sizes(sizes),
|
| @@ -116,7 +128,14 @@ class DownloadHandler {
|
|
|
| FaviconHandler* favicon_handler_;
|
| scoped_ptr<Download> download_;
|
| - bool failed_;
|
| + bool callback_invoked_;
|
| +
|
| + // The icon URLs for which the download should fail.
|
| + std::set<GURL> should_fail_download_icon_urls_;
|
| +
|
| + // The icon URLs for which the download did fail. This should be a subset of
|
| + // |should_fail_download_icon_urls_|.
|
| + std::set<GURL> failed_download_icon_urls_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(DownloadHandler);
|
| };
|
| @@ -359,6 +378,14 @@ class TestFaviconHandler : public FaviconHandler {
|
| }
|
|
|
| int DownloadFavicon(const GURL& image_url, int max_bitmap_size) override {
|
| + // Do not do a download if downloading |image_url| failed previously. This
|
| + // emulates the behavior of FaviconDriver::StartDownload()
|
| + if (download_handler_->DidFailDownloadForIconURL(image_url)) {
|
| + download_handler_->AddDownload(download_id_, image_url,
|
| + std::vector<int>(), 0);
|
| + return 0;
|
| + }
|
| +
|
| download_id_++;
|
| std::vector<int> sizes;
|
| sizes.push_back(0);
|
| @@ -403,9 +430,14 @@ void HistoryRequestHandler::InvokeCallback() {
|
| }
|
|
|
| void DownloadHandler::InvokeCallback() {
|
| + if (callback_invoked_)
|
| + return;
|
| +
|
| std::vector<gfx::Size> original_bitmap_sizes;
|
| std::vector<SkBitmap> bitmaps;
|
| - if (!failed_) {
|
| + if (should_fail_download_icon_urls_.count(download_->image_url)) {
|
| + failed_download_icon_urls_.insert(download_->image_url);
|
| + } else {
|
| for (std::vector<int>::const_iterator i = download_->image_sizes.begin();
|
| i != download_->image_sizes.end(); ++i) {
|
| int original_size = (*i > 0) ? *i : gfx::kFaviconSize;
|
| @@ -423,6 +455,7 @@ void DownloadHandler::InvokeCallback() {
|
| favicon_handler_->OnDidDownloadFavicon(download_->download_id,
|
| download_->image_url, bitmaps,
|
| original_bitmap_sizes);
|
| + callback_invoked_ = true;
|
| }
|
|
|
| class FaviconHandlerTest : public testing::Test {
|
| @@ -460,6 +493,8 @@ class FaviconHandlerTest : public testing::Test {
|
| download_handler->SetImageSizes(sizes);
|
| download_handler->InvokeCallback();
|
|
|
| + download_handler->Reset();
|
| +
|
| if (favicon_driver->num_active_favicon())
|
| return;
|
| }
|
| @@ -817,6 +852,9 @@ TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) {
|
|
|
| TestFaviconDriver driver;
|
| TestFaviconHandler helper(page_url, &driver, FaviconHandler::TOUCH, false);
|
| + std::set<GURL> fail_downloads;
|
| + fail_downloads.insert(icon_url);
|
| + helper.download_handler()->FailDownloadForIconURLs(fail_downloads);
|
|
|
| helper.FetchFavicon(page_url);
|
| HistoryRequestHandler* history_handler = helper.history_handler();
|
| @@ -878,8 +916,6 @@ TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) {
|
| // Reset the history_handler to verify whether favicon is request from
|
| // history.
|
| helper.set_history_handler(nullptr);
|
| - // Smulates download failed.
|
| - download_handler->set_failed(true);
|
| download_handler->InvokeCallback();
|
|
|
| // Left 1 url.
|
| @@ -1035,8 +1071,6 @@ TEST_F(FaviconHandlerTest, UpdateDuringDownloading) {
|
| EXPECT_FALSE(download_handler->HasDownload());
|
| }
|
|
|
| -#if !defined(OS_ANDROID)
|
| -
|
| // Test the favicon which is selected when the web page provides several
|
| // favicons and none of the favicons are cached in history.
|
| // The goal of this test is to be more of an integration test than
|
| @@ -1139,7 +1173,122 @@ TEST_F(FaviconHandlerTest, MultipleFavicons) {
|
| driver4.GetActiveFaviconURL());
|
| }
|
|
|
| -#endif
|
| +// Test that the best favicon is selected when:
|
| +// - The page provides several favicons.
|
| +// - Downloading one of the page's icon URLs previously returned a 404.
|
| +// - None of the favicons are cached in the Favicons database.
|
| +TEST_F(FaviconHandlerTest, MultipleFavicons404) {
|
| + const GURL kPageURL("http://www.google.com");
|
| + const GURL k404IconURL("http://www.google.com/404.png");
|
| + const FaviconURL k404FaviconURL(
|
| + k404IconURL, favicon_base::FAVICON, std::vector<gfx::Size>());
|
| + const FaviconURL kFaviconURLs[] = {
|
| + FaviconURL(GURL("http://www.google.com/a"),
|
| + favicon_base::FAVICON,
|
| + std::vector<gfx::Size>()),
|
| + k404FaviconURL,
|
| + FaviconURL(GURL("http://www.google.com/c"),
|
| + favicon_base::FAVICON,
|
| + std::vector<gfx::Size>()),
|
| + };
|
| +
|
| + TestFaviconDriver driver;
|
| + TestFaviconHandler handler(kPageURL, &driver, FaviconHandler::FAVICON, false);
|
| + DownloadHandler* download_handler = handler.download_handler();
|
| +
|
| + std::set<GURL> k404URLs;
|
| + k404URLs.insert(k404IconURL);
|
| + download_handler->FailDownloadForIconURLs(k404URLs);
|
| +
|
| + // Make the initial download for |k404IconURL| fail.
|
| + const int kSizes1[] = { 0 };
|
| + std::vector<FaviconURL> urls1(1u, k404FaviconURL);
|
| + DownloadTillDoneIgnoringHistory(
|
| + &driver, &handler, kPageURL, urls1, kSizes1);
|
| + EXPECT_TRUE(download_handler->DidFailDownloadForIconURL(k404IconURL));
|
| +
|
| + // Do a fetch now that the initial download for |k404IconURL| has failed. The
|
| + // behavior is different because OnDidDownloadFavicon() is invoked
|
| + // synchronously from DownloadFavicon().
|
| + const int kSizes2[] = { 10, 0, 16 };
|
| + std::vector<FaviconURL> urls2(kFaviconURLs,
|
| + kFaviconURLs + arraysize(kFaviconURLs));
|
| + DownloadTillDoneIgnoringHistory(
|
| + &driver, &handler, kPageURL, urls2, kSizes2);
|
| +
|
| + EXPECT_EQ(0u, handler.image_urls().size());
|
| + EXPECT_TRUE(driver.GetActiveFaviconValidity());
|
| + EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
|
| + int expected_index = 2u;
|
| + EXPECT_EQ(16, kSizes2[expected_index]);
|
| + EXPECT_EQ(kFaviconURLs[expected_index].icon_url,
|
| + driver.GetActiveFaviconURL());
|
| +}
|
| +
|
| +// Test that no favicon is selected when:
|
| +// - The page provides several favicons.
|
| +// - Downloading the page's icons has previously returned a 404.
|
| +// - None of the favicons are cached in the Favicons database.
|
| +TEST_F(FaviconHandlerTest, MultipleFaviconsAll404) {
|
| + const GURL kPageURL("http://www.google.com");
|
| + const GURL k404IconURL1("http://www.google.com/4041.png");
|
| + const GURL k404IconURL2("http://www.google.com/4042.png");
|
| + const FaviconURL kFaviconURLs[] = {
|
| + FaviconURL(k404IconURL1,
|
| + favicon_base::FAVICON,
|
| + std::vector<gfx::Size>()),
|
| + FaviconURL(k404IconURL2,
|
| + favicon_base::FAVICON,
|
| + std::vector<gfx::Size>()),
|
| + };
|
| +
|
| + TestFaviconDriver driver;
|
| + TestFaviconHandler handler(kPageURL, &driver, FaviconHandler::FAVICON, false);
|
| + DownloadHandler* download_handler = handler.download_handler();
|
| +
|
| + std::set<GURL> k404URLs;
|
| + k404URLs.insert(k404IconURL1);
|
| + k404URLs.insert(k404IconURL2);
|
| + download_handler->FailDownloadForIconURLs(k404URLs);
|
| +
|
| + // Make the initial downloads for |kFaviconURLs| fail.
|
| + for (const FaviconURL& favicon_url : kFaviconURLs) {
|
| + const int kSizes[] = { 0 };
|
| + std::vector<FaviconURL> urls(1u, favicon_url);
|
| + DownloadTillDoneIgnoringHistory(&driver, &handler, kPageURL, urls, kSizes);
|
| + }
|
| + EXPECT_TRUE(download_handler->DidFailDownloadForIconURL(k404IconURL1));
|
| + EXPECT_TRUE(download_handler->DidFailDownloadForIconURL(k404IconURL2));
|
| +
|
| + // Do a fetch now that the initial downloads for |kFaviconURLs| have failed.
|
| + // The behavior is different because OnDidDownloadFavicon() is invoked
|
| + // synchronously from DownloadFavicon().
|
| + const int kSizes[] = { 0, 0 };
|
| + std::vector<FaviconURL> urls(kFaviconURLs,
|
| + kFaviconURLs + arraysize(kFaviconURLs));
|
| + DownloadTillDoneIgnoringHistory(&driver, &handler, kPageURL, urls, kSizes);
|
| +
|
| + EXPECT_EQ(0u, handler.image_urls().size());
|
| + EXPECT_FALSE(driver.GetActiveFaviconValidity());
|
| + EXPECT_TRUE(driver.GetActiveFaviconImage().IsEmpty());
|
| +}
|
| +
|
| +// Test that no favicon is selected when the page's only icon uses an invalid
|
| +// URL syntax.
|
| +TEST_F(FaviconHandlerTest, FaviconInvalidURL) {
|
| + const GURL kPageURL("http://www.google.com");
|
| + const GURL kInvalidFormatURL("invalid");
|
| + ASSERT_TRUE(kInvalidFormatURL.is_empty());
|
| +
|
| + FaviconURL favicon_url(kInvalidFormatURL, favicon_base::FAVICON,
|
| + std::vector<gfx::Size>());
|
| +
|
| + TestFaviconDriver driver;
|
| + TestFaviconHandler handler(kPageURL, &driver, FaviconHandler::FAVICON, false);
|
| + UpdateFaviconURL(&driver, &handler, kPageURL,
|
| + std::vector<FaviconURL>(1u, favicon_url));
|
| + EXPECT_EQ(0u, handler.image_urls().size());
|
| +}
|
|
|
| TEST_F(FaviconHandlerTest, TestSortFavicon) {
|
| const GURL kPageURL("http://www.google.com");
|
| @@ -1232,6 +1381,13 @@ TEST_F(FaviconHandlerTest, TestDownloadLargestFavicon) {
|
| TestFaviconDriver driver1;
|
| TestFaviconHandler handler1(kPageURL, &driver1, FaviconHandler::FAVICON,
|
| true);
|
| +
|
| + std::set<GURL> fail_icon_urls;
|
| + for (size_t i = 0; i < arraysize(kSourceIconURLs); ++i) {
|
| + fail_icon_urls.insert(kSourceIconURLs[i].icon_url);
|
| + }
|
| + handler1.download_handler()->FailDownloadForIconURLs(fail_icon_urls);
|
| +
|
| std::vector<FaviconURL> urls1(kSourceIconURLs,
|
| kSourceIconURLs + arraysize(kSourceIconURLs));
|
| UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
|
| @@ -1272,9 +1428,8 @@ TEST_F(FaviconHandlerTest, TestDownloadLargestFavicon) {
|
| EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url,
|
| handler1.download_handler()->GetImageUrl());
|
|
|
| - // Simulate the download failed.
|
| - handler1.download_handler()->set_failed(true);
|
| handler1.download_handler()->InvokeCallback();
|
| + handler1.download_handler()->Reset();
|
| }
|
| }
|
|
|
| @@ -1444,6 +1599,7 @@ TEST_F(FaviconHandlerTest, TestKeepDownloadedLargestFavicon) {
|
| sizes.push_back(actual_size1);
|
| handler1.download_handler()->SetImageSizes(sizes);
|
| handler1.download_handler()->InvokeCallback();
|
| + handler1.download_handler()->Reset();
|
|
|
| // Simulate no favicon from history.
|
| handler1.history_handler()->history_results_.clear();
|
| @@ -1465,6 +1621,7 @@ TEST_F(FaviconHandlerTest, TestKeepDownloadedLargestFavicon) {
|
| sizes.push_back(actual_size2);
|
| handler1.download_handler()->SetImageSizes(sizes);
|
| handler1.download_handler()->InvokeCallback();
|
| + handler1.download_handler()->Reset();
|
|
|
| // Verify icon2 has been saved into history.
|
| EXPECT_EQ(kSourceIconURLs[1].icon_url, handler1.history_handler()->icon_url_);
|
|
|