Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(261)

Unified Diff: components/favicon/core/favicon_handler_unittest.cc

Issue 2799273002: Add support to process favicons from Web Manifests (Closed)
Patch Set: Add hacks for demoing (DONOTSUBMIT) Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 4a997f382474f3ff6783867958eccd253e6ccf70..69824ad521953864f560bd996043569358dcaafb 100644
--- a/components/favicon/core/favicon_handler_unittest.cc
+++ b/components/favicon/core/favicon_handler_unittest.cc
@@ -104,14 +104,16 @@ class FakeImageDownloader {
SizeVector original_bitmap_sizes;
};
- FakeImageDownloader() : next_download_id_(1) {}
+ // |downloads| must not be nullptr and must outlive this object.
+ FakeImageDownloader(URLVector* downloads)
+ : downloads_(downloads), next_download_id_(1) {}
// Implementation of FaviconHalder::Delegate's DownloadImage(). If a given
// URL is not known (i.e. not previously added via Add()), it produces 404s.
int DownloadImage(const GURL& url,
int max_image_size,
FaviconHandler::Delegate::ImageDownloadCallback callback) {
- downloads_.push_back(url);
+ downloads_->push_back(url);
const Response& response = responses_[url];
int download_id = next_download_id_++;
@@ -169,17 +171,10 @@ class FakeImageDownloader {
return true;
}
- // Returns pending and completed download URLs.
- const URLVector& downloads() const { return downloads_; }
-
- void ClearDownloads() { downloads_.clear(); }
-
private:
+ URLVector* downloads_;
int next_download_id_;
- // Pending and completed download URLs.
- URLVector downloads_;
-
// URL to disable automatic callbacks for.
GURL manual_callback_url_;
@@ -192,19 +187,105 @@ class FakeImageDownloader {
DISALLOW_COPY_AND_ASSIGN(FakeImageDownloader);
};
+// Fake that implements the calls to FaviconHandler::Delegate's
+// DownloadManifest(), delegated to this class through MockDelegate.
+class FakeManifestDownloader {
+ public:
+ struct Response {
+ int http_status_code = 404;
+ std::vector<favicon::FaviconURL> favicon_urls;
+ };
+
+ // |downloads| must not be nullptr and must outlive this object.
+ FakeManifestDownloader(URLVector* downloads) : downloads_(downloads) {}
+
+ // Implementation of FaviconHalder::Delegate's DownloadManifest(). If a given
+ // URL is not known (i.e. not previously added via Add()), it produces 404s.
+ void DownloadManifest(
+ const GURL& url,
+ FaviconHandler::Delegate::ManifestDownloadCallback callback) {
+ downloads_->push_back(url);
+
+ const Response& response = responses_[url];
+ base::Closure bound_callback =
+ base::Bind(callback, response.http_status_code, response.favicon_urls);
+ if (url == manual_callback_url_)
+ manual_callback_ = bound_callback;
+ else
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, bound_callback);
+ }
+
+ void Add(const GURL& manifest_url,
+ const std::vector<favicon::FaviconURL>& favicon_urls) {
+ Response response;
+ response.http_status_code = 200;
+ response.favicon_urls = favicon_urls;
+ responses_[manifest_url] = response;
+ }
+
+ void AddError(const GURL& manifest_url, int http_status_code) {
+ Response response;
+ response.http_status_code = http_status_code;
+ responses_[manifest_url] = response;
+ }
+
+ // Disables automatic callback for |url|. This is useful for emulating a
+ // download taking a long time. The callback for DownloadManifest() will be
+ // stored in |manual_callback_|.
+ void SetRunCallbackManuallyForUrl(const GURL& url) {
+ manual_callback_url_ = url;
+ }
+
+ // Returns whether an ongoing download exists for a url previously selected
+ // via SetRunCallbackManuallyForUrl().
+ bool HasPendingManualCallback() { return !manual_callback_.is_null(); }
+
+ // Triggers the response for a download previously selected for manual
+ // triggering via SetRunCallbackManuallyForUrl().
+ bool RunCallbackManually() {
+ if (!HasPendingManualCallback())
+ return false;
+ manual_callback_.Run();
+ manual_callback_.Reset();
+ return true;
+ }
+
+ private:
+ URLVector* downloads_;
+
+ // URL to disable automatic callbacks for.
+ GURL manual_callback_url_;
+
+ // Callback for DownloadManifest() request for |manual_callback_url_|.
+ base::Closure manual_callback_;
+
+ // Registered responses.
+ std::map<GURL, Response> responses_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeManifestDownloader);
+};
+
class MockDelegate : public FaviconHandler::Delegate {
public:
- MockDelegate() {
+ MockDelegate()
+ : fake_image_downloader_(&downloads_),
+ fake_manifest_downloader_(&downloads_) {
// Delegate image downloading to FakeImageDownloader.
ON_CALL(*this, DownloadImage(_, _, _))
- .WillByDefault(
- Invoke(&fake_downloader_, &FakeImageDownloader::DownloadImage));
+ .WillByDefault(Invoke(&fake_image_downloader_,
+ &FakeImageDownloader::DownloadImage));
+ // Delegate manifest downloading to FakeManifestDownloader.
+ ON_CALL(*this, DownloadManifest(_, _))
+ .WillByDefault(Invoke(&fake_manifest_downloader_,
+ &FakeManifestDownloader::DownloadManifest));
}
MOCK_METHOD3(DownloadImage,
int(const GURL& url,
int max_image_size,
ImageDownloadCallback callback));
+ MOCK_METHOD2(DownloadManifest,
+ void(const GURL& url, ManifestDownloadCallback callback));
MOCK_METHOD0(IsOffTheRecord, bool());
MOCK_METHOD1(IsBookmarked, bool(const GURL& url));
MOCK_METHOD5(OnFaviconUpdated,
@@ -214,14 +295,24 @@ class MockDelegate : public FaviconHandler::Delegate {
bool icon_url_changed,
const gfx::Image& image));
- FakeImageDownloader& fake_downloader() { return fake_downloader_; }
+ FakeImageDownloader& fake_image_downloader() {
+ return fake_image_downloader_;
+ }
+
+ FakeManifestDownloader& fake_manifest_downloader() {
+ return fake_manifest_downloader_;
+ }
- // Convenience getter for test readability. Returns pending and completed
- // download URLs.
- const URLVector& downloads() const { return fake_downloader_.downloads(); }
+ // Returns pending and completed download URLs.
+ const URLVector& downloads() const { return downloads_; }
+
+ void ClearDownloads() { downloads_.clear(); }
private:
- FakeImageDownloader fake_downloader_;
+ // Pending and completed download URLs.
+ URLVector downloads_;
+ FakeImageDownloader fake_image_downloader_;
+ FakeManifestDownloader fake_manifest_downloader_;
};
// FakeFaviconService mimics a FaviconService backend that allows setting up
@@ -327,10 +418,10 @@ class FaviconHandlerTest : public testing::Test {
FaviconHandlerTest() {
// Register various known icon URLs.
- delegate_.fake_downloader().Add(kIconURL10x10, IntVector{10});
- delegate_.fake_downloader().Add(kIconURL12x12, IntVector{12});
- delegate_.fake_downloader().Add(kIconURL16x16, IntVector{16});
- delegate_.fake_downloader().Add(kIconURL64x64, IntVector{64});
+ delegate_.fake_image_downloader().Add(kIconURL10x10, IntVector{10});
+ delegate_.fake_image_downloader().Add(kIconURL12x12, IntVector{12});
+ delegate_.fake_image_downloader().Add(kIconURL16x16, IntVector{16});
+ delegate_.fake_image_downloader().Add(kIconURL64x64, IntVector{64});
// The score computed by SelectFaviconFrames() is dependent on the supported
// scale factors of the platform. It is used for determining the goodness of
@@ -344,7 +435,7 @@ class FaviconHandlerTest : public testing::Test {
bool VerifyAndClearExpectations() {
base::RunLoop().RunUntilIdle();
favicon_service_.fake()->ClearDbRequests();
- delegate_.fake_downloader().ClearDownloads();
+ delegate_.ClearDownloads();
return testing::Mock::VerifyAndClearExpectations(&favicon_service_) &&
testing::Mock::VerifyAndClearExpectations(&delegate_);
}
@@ -353,14 +444,15 @@ class FaviconHandlerTest : public testing::Test {
// Returns the handler in case tests want to exercise further steps.
std::unique_ptr<FaviconHandler> RunHandlerWithCandidates(
FaviconDriverObserver::NotificationIconType handler_type,
- const std::vector<favicon::FaviconURL>& candidates) {
+ const std::vector<favicon::FaviconURL>& candidates,
+ const base::Optional<GURL>& manifest_url = base::nullopt) {
auto handler = base::MakeUnique<FaviconHandler>(&favicon_service_,
&delegate_, handler_type);
handler->FetchFavicon(kPageURL);
// The first RunUntilIdle() causes the FaviconService lookups be faster than
- // OnUpdateFaviconURL(), which is the most likely scenario.
+ // OnUpdateCandidates(), which is the most likely scenario.
base::RunLoop().RunUntilIdle();
- handler->OnUpdateFaviconURL(kPageURL, candidates);
+ handler->OnUpdateCandidates(kPageURL, candidates, manifest_url);
base::RunLoop().RunUntilIdle();
return handler;
}
@@ -368,13 +460,14 @@ class FaviconHandlerTest : public testing::Test {
// Same as above, but for the simplest case where all types are FAVICON and
// no sizes are provided, using a FaviconHandler of type NON_TOUCH_16_DIP.
std::unique_ptr<FaviconHandler> RunHandlerWithSimpleFaviconCandidates(
- const std::vector<GURL>& urls) {
+ const std::vector<GURL>& urls,
+ const base::Optional<GURL>& manifest_url = base::nullopt) {
std::vector<favicon::FaviconURL> candidates;
for (const GURL& url : urls) {
candidates.emplace_back(url, FAVICON, kEmptySizes);
}
return RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP,
- candidates);
+ candidates, manifest_url);
}
base::MessageLoopForUI message_loop_;
@@ -419,7 +512,7 @@ TEST_F(FaviconHandlerTest, UpdateFaviconMappingsAndFetch) {
// - There is data in the database for neither the page URL nor the icon URL.
// AND
// - FaviconService::GetFaviconForPageURL() callback returns before
-// FaviconHandler::OnUpdateFaviconURL() is called.
+// FaviconHandler::OnUpdateCandidates() is called.
TEST_F(FaviconHandlerTest, DownloadUnknownFaviconIfCandidatesSlower) {
EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, FAVICON,
ImageSizeIs(16, 16)));
@@ -430,10 +523,11 @@ TEST_F(FaviconHandlerTest, DownloadUnknownFaviconIfCandidatesSlower) {
FaviconHandler handler(&favicon_service_, &delegate_,
FaviconDriverObserver::NON_TOUCH_16_DIP);
handler.FetchFavicon(kPageURL);
- // Causes FaviconService lookups be faster than OnUpdateFaviconURL().
+ // Causes FaviconService lookups be faster than OnUpdateCandidates().
base::RunLoop().RunUntilIdle();
- handler.OnUpdateFaviconURL(kPageURL,
- {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)});
+ handler.OnUpdateCandidates(kPageURL,
+ {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)},
+ base::nullopt);
base::RunLoop().RunUntilIdle();
EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL16x16));
@@ -445,7 +539,7 @@ TEST_F(FaviconHandlerTest, DownloadUnknownFaviconIfCandidatesSlower) {
// - There is data in the database for neither the page URL nor the icon URL.
// AND
// - FaviconService::GetFaviconForPageURL() callback returns after
-// FaviconHandler::OnUpdateFaviconURL() is called.
+// FaviconHandler::OnUpdateCandidates() is called.
TEST_F(FaviconHandlerTest, DownloadUnknownFaviconIfCandidatesFaster) {
EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, FAVICON,
ImageSizeIs(16, 16)));
@@ -457,8 +551,9 @@ TEST_F(FaviconHandlerTest, DownloadUnknownFaviconIfCandidatesFaster) {
ASSERT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kPageURL));
// Feed in favicons without processing posted tasks (RunUntilIdle()).
- handler.OnUpdateFaviconURL(kPageURL,
- {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)});
+ handler.OnUpdateCandidates(kPageURL,
+ {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)},
+ base::nullopt);
base::RunLoop().RunUntilIdle();
EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL16x16));
@@ -589,7 +684,7 @@ TEST_F(FaviconHandlerTest, UpdateFavicon) {
TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) {
const GURL kIconURLReturning500("http://www.google.com/500.png");
- delegate_.fake_downloader().AddError(kIconURLReturning500, 500);
+ delegate_.fake_image_downloader().AddError(kIconURLReturning500, 500);
favicon_service_.fake()->Store(
kPageURL, kIconURL64x64,
@@ -616,7 +711,7 @@ TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) {
// Test that download data for icon URLs other than the current favicon
// candidate URLs is ignored. This test tests the scenario where a download is
-// in flight when FaviconHandler::OnUpdateFaviconURL() is called.
+// in flight when FaviconHandler::OnUpdateCandidates() is called.
// TODO(mastiz): Make this test deal with FaviconURLs of type
// favicon_base::FAVICON and add new ones like OnlyDownloadMatchingIconType and
// CallSetFaviconsWithCorrectIconType.
@@ -627,27 +722,27 @@ TEST_F(FaviconHandlerTest, UpdateDuringDownloading) {
// Defer the download completion such that RunUntilIdle() doesn't complete
// the download.
- delegate_.fake_downloader().SetRunCallbackManuallyForUrl(kIconURL1);
+ delegate_.fake_image_downloader().SetRunCallbackManuallyForUrl(kIconURL1);
- delegate_.fake_downloader().Add(kIconURL1, IntVector{16});
- delegate_.fake_downloader().Add(kIconURL3, IntVector{64});
+ delegate_.fake_image_downloader().Add(kIconURL1, IntVector{16});
+ delegate_.fake_image_downloader().Add(kIconURL3, IntVector{64});
std::unique_ptr<FaviconHandler> handler =
RunHandlerWithSimpleFaviconCandidates({kIconURL1, kIconURL2});
ASSERT_TRUE(VerifyAndClearExpectations());
- ASSERT_TRUE(delegate_.fake_downloader().HasPendingManualCallback());
+ ASSERT_TRUE(delegate_.fake_image_downloader().HasPendingManualCallback());
// Favicon update should invalidate the ongoing download.
EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL3, _, _));
EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL3, _, _));
- handler->OnUpdateFaviconURL(kPageURL,
- {FaviconURL(kIconURL3, FAVICON, kEmptySizes)});
+ handler->OnUpdateCandidates(
+ kPageURL, {FaviconURL(kIconURL3, FAVICON, kEmptySizes)}, base::nullopt);
// Finalizes download, which should be thrown away as the favicon URLs were
// updated.
- EXPECT_TRUE(delegate_.fake_downloader().RunCallbackManually());
+ EXPECT_TRUE(delegate_.fake_image_downloader().RunCallbackManually());
base::RunLoop().RunUntilIdle();
EXPECT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kIconURL3));
@@ -666,8 +761,9 @@ TEST_F(FaviconHandlerTest, UpdateSameIconURLsWhileProcessingShouldBeNoop) {
// Defer the download completion such that RunUntilIdle() doesn't complete
// the download.
- delegate_.fake_downloader().SetRunCallbackManuallyForUrl(kSlowLoadingIconURL);
- delegate_.fake_downloader().Add(kSlowLoadingIconURL, IntVector{16});
+ delegate_.fake_image_downloader().SetRunCallbackManuallyForUrl(
+ kSlowLoadingIconURL);
+ delegate_.fake_image_downloader().Add(kSlowLoadingIconURL, IntVector{16});
std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates(
FaviconDriverObserver::NON_TOUCH_16_DIP, favicon_urls);
@@ -675,17 +771,17 @@ TEST_F(FaviconHandlerTest, UpdateSameIconURLsWhileProcessingShouldBeNoop) {
ASSERT_THAT(favicon_service_.fake()->db_requests(),
ElementsAre(kPageURL, kIconURL64x64, kSlowLoadingIconURL));
ASSERT_TRUE(VerifyAndClearExpectations());
- ASSERT_TRUE(delegate_.fake_downloader().HasPendingManualCallback());
+ ASSERT_TRUE(delegate_.fake_image_downloader().HasPendingManualCallback());
- // Calling OnUpdateFaviconURL() with the same icon URLs should have no effect,
+ // Calling OnUpdateCandidates() with the same icon URLs should have no effect,
// despite the ongoing download.
- handler->OnUpdateFaviconURL(kPageURL, favicon_urls);
+ handler->OnUpdateCandidates(kPageURL, favicon_urls, base::nullopt);
base::RunLoop().RunUntilIdle();
// Complete the download.
EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _));
EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _));
- EXPECT_TRUE(delegate_.fake_downloader().RunCallbackManually());
+ EXPECT_TRUE(delegate_.fake_image_downloader().RunCallbackManually());
base::RunLoop().RunUntilIdle();
EXPECT_THAT(delegate_.downloads(), IsEmpty());
}
@@ -704,11 +800,11 @@ TEST_F(FaviconHandlerTest, UpdateSameIconURLsAfterFinishedShouldBeNoop) {
ASSERT_TRUE(VerifyAndClearExpectations());
- // Calling OnUpdateFaviconURL() with identical data should be a no-op.
+ // Calling OnUpdateCandidates() with identical data should be a no-op.
EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)).Times(0);
EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0);
- handler->OnUpdateFaviconURL(kPageURL, favicon_urls);
+ handler->OnUpdateCandidates(kPageURL, favicon_urls, base::nullopt);
base::RunLoop().RunUntilIdle();
EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty());
EXPECT_THAT(delegate_.downloads(), IsEmpty());
@@ -729,8 +825,8 @@ TEST_F(FaviconHandlerTest,
"http://wwww.page_which_animates_favicon.com/frame2.png");
// |kIconURL1| is the better match.
- delegate_.fake_downloader().Add(kIconURL1, IntVector{15});
- delegate_.fake_downloader().Add(kIconURL2, IntVector{10});
+ delegate_.fake_image_downloader().Add(kIconURL1, IntVector{15});
+ delegate_.fake_image_downloader().Add(kIconURL2, IntVector{10});
// Two FaviconDriver::OnFaviconUpdated() notifications should be sent for
// |kIconURL1|, one before and one after the download.
@@ -750,8 +846,8 @@ TEST_F(FaviconHandlerTest,
// Simulate the page changing it's icon URL to just |kIconURL2| via
// Javascript.
EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL2, _, _));
- handler->OnUpdateFaviconURL(kPageURL,
- {FaviconURL(kIconURL2, FAVICON, kEmptySizes)});
+ handler->OnUpdateCandidates(
+ kPageURL, {FaviconURL(kIconURL2, FAVICON, kEmptySizes)}, base::nullopt);
base::RunLoop().RunUntilIdle();
}
@@ -788,7 +884,7 @@ class FaviconHandlerMultipleFaviconsTest : public FaviconHandlerTest {
const GURL icon_url(base::StringPrintf(
"https://www.google.com/generated/%dx%d", icon_size, icon_size));
// Set up 200 responses for all images, and the corresponding size.
- delegate_.fake_downloader().Add(icon_url, IntVector{icon_size});
+ delegate_.fake_image_downloader().Add(icon_url, IntVector{icon_size});
// Create test candidates of type FAVICON and a fake URL.
candidate_icons.emplace_back(icon_url, FAVICON, kEmptySizes);
@@ -844,7 +940,7 @@ TEST_F(FaviconHandlerTest, Report404) {
TEST_F(FaviconHandlerTest, NotReport503) {
const GURL k503IconURL("http://www.google.com/503.png");
- delegate_.fake_downloader().AddError(k503IconURL, 503);
+ delegate_.fake_image_downloader().AddError(k503IconURL, 503);
EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(0);
@@ -977,8 +1073,8 @@ TEST_F(FaviconHandlerTest, TestSelectLargestFavicon) {
const GURL kIconURL1("http://www.google.com/b");
const GURL kIconURL2("http://www.google.com/c");
- delegate_.fake_downloader().Add(kIconURL1, IntVector{15});
- delegate_.fake_downloader().Add(kIconURL2, IntVector{14, 16});
+ delegate_.fake_image_downloader().Add(kIconURL1, IntVector{15});
+ delegate_.fake_image_downloader().Add(kIconURL2, IntVector{14, 16});
// Verify NotifyFaviconAvailable().
EXPECT_CALL(delegate_,
@@ -1003,9 +1099,9 @@ TEST_F(FaviconHandlerTest, TestFaviconWasScaledAfterDownload) {
const int kOriginalSize1 = kMaximalSize + 1;
const int kOriginalSize2 = kMaximalSize + 2;
- delegate_.fake_downloader().AddWithOriginalSizes(
+ delegate_.fake_image_downloader().AddWithOriginalSizes(
kIconURL1, IntVector{kMaximalSize}, IntVector{kOriginalSize1});
- delegate_.fake_downloader().AddWithOriginalSizes(
+ delegate_.fake_image_downloader().AddWithOriginalSizes(
kIconURL2, IntVector{kMaximalSize}, IntVector{kOriginalSize2});
// Verify the best bitmap was selected (although smaller than |kIconURL2|)
@@ -1165,7 +1261,7 @@ TEST_F(FaviconHandlerTest, TestRecordFailingDownloadAttempt) {
base::HistogramTester histogram_tester;
const GURL k404IconURL("http://www.google.com/404.png");
- delegate_.fake_downloader().AddError(k404IconURL, 404);
+ delegate_.fake_image_downloader().AddError(k404IconURL, 404);
EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(k404IconURL));
@@ -1192,5 +1288,349 @@ TEST_F(FaviconHandlerTest, TestRecordSkippedDownloadForKnownFailingUrl) {
/*expected_count=*/1)));
}
pkotwicz 2017/05/01 04:56:53 Each test should be preceeded with a comment which
mastiz 2017/05/04 10:57:53 Done. No intent for sarcasm here but, based on my
+TEST_F(FaviconHandlerTest, GetFaviconFromManifestInHistory) {
+ const GURL kManifestURL("http://www.google.com/manifest.json");
+
+ favicon_service_.fake()->Store(kPageURL, kManifestURL,
+ CreateRawBitmapResult(kManifestURL));
+
+ EXPECT_CALL(delegate_, DownloadManifest(_, _)).Times(0);
+ EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(0);
+
+ EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch(
+ kPageURL, URLVector{kManifestURL}, FAVICON,
+ /*desired_size_in_dip=*/16, _, _));
+ EXPECT_CALL(delegate_, OnFaviconUpdated(
+ kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP,
+ kManifestURL, _, _))
+ .Times(2);
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ EXPECT_THAT(delegate_.downloads(), IsEmpty());
+}
+
+TEST_F(FaviconHandlerTest, GetFaviconFromManifestInHistoryIfCandidatesFaster) {
+ const GURL kManifestURL("http://www.google.com/manifest.json");
+
+ favicon_service_.fake()->Store(kPageURL, kManifestURL,
+ CreateRawBitmapResult(kManifestURL));
+
+ EXPECT_CALL(delegate_, DownloadManifest(_, _)).Times(0);
+ EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(0);
+
+ EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch(
+ kPageURL, URLVector{kManifestURL}, FAVICON,
+ /*desired_size_in_dip=*/16, _, _));
+ EXPECT_CALL(delegate_, OnFaviconUpdated(
+ kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP,
+ kManifestURL, _, _))
+ .Times(2);
+
+ FaviconHandler handler(&favicon_service_, &delegate_,
+ FaviconDriverObserver::NON_TOUCH_16_DIP);
+ handler.FetchFavicon(kPageURL);
+ // Feed in candidates without processing posted tasks (RunUntilIdle()).
+ handler.OnUpdateCandidates(kPageURL,
+ {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)},
+ kManifestURL);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ EXPECT_THAT(delegate_.downloads(), IsEmpty());
+}
+
+TEST_F(FaviconHandlerTest, GetFaviconFromUnknownManifest) {
+ const GURL kManifestURL("http://www.google.com/manifest.json");
+ const std::vector<favicon::FaviconURL> kManifestIcons = {
+ FaviconURL(kIconURL16x16, FAVICON, kEmptySizes),
+ };
+
+ delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
+
+ EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(0);
+
+ EXPECT_CALL(delegate_, DownloadManifest(kManifestURL, _));
+ EXPECT_CALL(favicon_service_,
+ SetFavicons(kPageURL, kManifestURL, FAVICON, _));
pkotwicz 2017/05/01 04:56:53 kManifestURL is the only parameter we care about
mastiz 2017/05/04 10:57:53 Removed kPageURL. I think FAVICON is worth verifyi
pkotwicz 2017/05/04 17:28:25 Fair enough
+ EXPECT_CALL(delegate_, OnFaviconUpdated(kPageURL, _, kManifestURL, _, _));
pkotwicz 2017/05/01 04:56:53 We don't care about the page URL
mastiz 2017/05/04 10:57:53 Done.
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL16x16));
+}
+
+TEST_F(FaviconHandlerTest, GetFaviconFromExpiredManifest) {
+ const GURL kManifestURL("http://www.google.com/manifest.json");
+ const std::vector<favicon::FaviconURL> kManifestIcons = {
+ FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
+ };
+
+ favicon_service_.fake()->Store(kPageURL, kManifestURL,
+ CreateRawBitmapResult(kManifestURL, FAVICON,
+ /*expired=*/true));
+ delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
+
+ // The third notification is unnecessary, but allows simplifying the code.
+ EXPECT_CALL(delegate_, OnFaviconUpdated(kPageURL, _, kManifestURL, _, _))
+ .Times(3);
+ EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kManifestURL, _, _));
pkotwicz 2017/05/01 04:56:53 We don't care about the page URL for either OnFavi
mastiz 2017/05/04 10:57:53 Done.
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL64x64));
+}
+
+TEST_F(FaviconHandlerTest, GetFaviconFromExpiredManifestLinkedFromOtherPage) {
+ const GURL kSomePreviousPageURL("https://www.google.com/previous");
+ const GURL kManifestURL("http://www.google.com/manifest.json");
+ const std::vector<favicon::FaviconURL> kManifestIcons = {
+ FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
+ };
+
+ favicon_service_.fake()->Store(kSomePreviousPageURL, kManifestURL,
+ CreateRawBitmapResult(kManifestURL, FAVICON,
+ /*expired=*/true));
+ delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
+
+ EXPECT_CALL(delegate_, OnFaviconUpdated(kPageURL, _, kManifestURL, _, _))
+ .Times(2);
+ EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kManifestURL, _, _));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL64x64));
+}
+
+TEST_F(FaviconHandlerTest, GetFaviconFromUnknownManifestButKnownIcon) {
+ const GURL kSomePreviousPageURL("https://www.google.com/previous");
+ const GURL kManifestURL("http://www.google.com/manifest.json");
+ const std::vector<favicon::FaviconURL> kManifestIcons = {
+ FaviconURL(kIconURL16x16, FAVICON, kEmptySizes),
+ };
+
+ favicon_service_.fake()->Store(kSomePreviousPageURL, kIconURL16x16,
+ CreateRawBitmapResult(kIconURL16x16));
+ delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
+
+ EXPECT_CALL(favicon_service_,
+ SetFavicons(kPageURL, kManifestURL, FAVICON, _));
+ EXPECT_CALL(delegate_, OnFaviconUpdated(kPageURL, _, kManifestURL, _, _));
+
+ RunHandlerWithSimpleFaviconCandidates(URLVector(), kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ // In the current implementation, the icon is downloaded although it's in the
+ // database, simply because it's not associated to the manifest's URL.
pkotwicz 2017/05/01 04:56:53 This comment is confusing. Maybe remove the "simp
mastiz 2017/05/04 10:57:53 Rephrased, since I believe the "because" part is p
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL16x16));
+}
+
+TEST_F(FaviconHandlerTest, UnknownManifestReturning404) {
+ const GURL kManifestURL("http://www.google.com/manifest.json");
+
+ EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(kManifestURL));
+ EXPECT_CALL(favicon_service_,
+ SetFavicons(kPageURL, kIconURL12x12, FAVICON, _));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL, kIconURL12x12));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL12x12));
+}
+
+TEST_F(FaviconHandlerTest, UnknownManifestReturning503) {
+ const GURL kManifestURL("http://www.google.com/manifest.json");
+
+ delegate_.fake_manifest_downloader().AddError(kManifestURL, 503);
+
+ EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(0);
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+}
+
+TEST_F(FaviconHandlerTest, IgnoreManifestWithPrior404) {
+ const GURL kManifestURL("http://www.google.com/manifest.json");
+
+ ON_CALL(favicon_service_, WasUnableToDownloadFavicon(kManifestURL))
+ .WillByDefault(Return(true));
+
+ EXPECT_CALL(delegate_, DownloadManifest(_, _)).Times(0);
pkotwicz 2017/05/01 04:56:53 Isn't this covered by the expectation on line 1469
mastiz 2017/05/04 10:57:53 Unless DownloadManifest were used with kIconURL12x
pkotwicz 2017/05/04 17:28:25 I would rather that you drop it
mastiz 2017/05/10 10:03:52 Done.
+ EXPECT_CALL(favicon_service_,
+ SetFavicons(kPageURL, kIconURL12x12, FAVICON, _));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kIconURL12x12));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL12x12));
+}
+
+// Test that the regular favicon is selected when:
+// - The page links to a Web Manifest.
+// - The Web Manifest does not contain any icon URLs (it is not a 404).
+// - The page has an icon URL provided via a <link rel="icon"> tag.
+// - The database does not know about the page URL, manifest URL or icon URL.
+TEST_F(FaviconHandlerTest, UnknownManifestWithoutIcons) {
+ const GURL kManifestURL("http://www.google.com/manifest.json");
+
+ delegate_.fake_manifest_downloader().Add(kManifestURL,
+ std::vector<favicon::FaviconURL>());
+
+ // UnableToDownloadFavicon() is expected to prevent repeated downloads of the
+ // same manifest (which is not otherwise cached, since it doesn't contain
+ // icons).
+ EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(kManifestURL));
+ EXPECT_CALL(favicon_service_,
+ SetFavicons(kPageURL, kIconURL12x12, FAVICON, _));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL, kIconURL12x12));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL12x12));
+}
+
+// Test that the regular favicon is selected when:
+// - The page links to a Web Manifest.
+// - The Web Manifest does not contain any icon URLs (it is not a 404).
+// - The page has an icon URL provided via a <link rel="icon"> tag.
+// - The database does not know about the page URL.
+// - The database does not know about the manifest URL.
+// - The database knows about the icon URL.
+TEST_F(FaviconHandlerTest, UnknownManifestWithoutIconsAndKnownRegularIcons) {
+ const GURL kSomePreviousPageURL("https://www.google.com/previous");
+ const GURL kManifestURL("http://www.google.com/manifest.json");
+
+ delegate_.fake_manifest_downloader().Add(kManifestURL,
+ std::vector<favicon::FaviconURL>());
+ favicon_service_.fake()->Store(kSomePreviousPageURL, kIconURL12x12,
+ CreateRawBitmapResult(kIconURL12x12));
+
+ EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0);
+
+ // UnableToDownloadFavicon() is expected to prevent repeated downloads of the
+ // same manifest (which is not otherwise cached, since it doesn't contain
+ // icons).
+ EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(kManifestURL));
+ EXPECT_CALL(favicon_service_,
+ UpdateFaviconMappingsAndFetch(kPageURL, URLVector{kManifestURL},
+ _, _, _, _));
+ EXPECT_CALL(favicon_service_,
+ UpdateFaviconMappingsAndFetch(kPageURL, URLVector{kIconURL12x12},
+ _, _, _, _));
+ EXPECT_CALL(delegate_, OnFaviconUpdated(kPageURL, _, kIconURL12x12, _, _));
+
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
+ EXPECT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL, kIconURL12x12));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL));
+}
+
+TEST_F(FaviconHandlerTest, ManifestUpdateViaJavascript) {
+ const GURL kManifestURL1("http://www.google.com/manifest1.json");
+ const GURL kManifestURL2("http://www.google.com/manifest2.json");
+ const std::vector<favicon::FaviconURL> kManifestIcons1 = {
+ FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
+ };
+ const std::vector<favicon::FaviconURL> kManifestIcons2 = {
+ FaviconURL(kIconURL10x10, FAVICON, kEmptySizes),
+ };
+
+ delegate_.fake_manifest_downloader().Add(kManifestURL1, kManifestIcons1);
+ delegate_.fake_manifest_downloader().Add(kManifestURL2, kManifestIcons2);
+
+ EXPECT_CALL(delegate_, DownloadManifest(kManifestURL1, _));
pkotwicz 2017/05/01 04:56:53 This is redundant with line 1551?
mastiz 2017/05/04 10:57:53 Ditto. I can either ignore the problem and drop th
pkotwicz 2017/05/04 17:28:25 I would vote for dropping the line and ignoring th
mastiz 2017/05/10 10:03:52 Done.
+
+ std::unique_ptr<FaviconHandler> handler =
+ RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL1);
+ ASSERT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL1));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL1, kIconURL64x64));
+ ASSERT_TRUE(VerifyAndClearExpectations());
+
+ // Simulate the page changing it's manifest URL via Javascript.
+ EXPECT_CALL(delegate_, DownloadManifest(kManifestURL2, _));
pkotwicz 2017/05/01 04:56:53 Isn't this redundant with line 1563?
mastiz 2017/05/04 10:57:53 Ditto.
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL2, _, _));
+ handler->OnUpdateCandidates(kPageURL,
+ {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)},
+ kManifestURL2);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kManifestURL2));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL2, kIconURL10x10));
+}
+
+TEST_F(FaviconHandlerTest, RemoveManifestViaJavascriptWhileHistoryQuery) {
+ const GURL kManifestURL("http://www.google.com/manifest.json");
+ const std::vector<favicon::FaviconURL> kManifestIcons = {
+ FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
+ };
+
+ delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
+
+ EXPECT_CALL(delegate_, DownloadManifest(_, _)).Times(0);
+
+ auto handler = base::MakeUnique<FaviconHandler>(
+ &favicon_service_, &delegate_, FaviconDriverObserver::NON_TOUCH_16_DIP);
+ handler->FetchFavicon(kPageURL);
+ ASSERT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kPageURL));
+ base::RunLoop().RunUntilIdle();
+ ASSERT_FALSE(handler->HasPendingTasksForTest());
+ handler->OnUpdateCandidates(kPageURL,
+ {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)},
+ kManifestURL);
+ ASSERT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL));
+ // Database lookup for |kManifestURL1| is ongoing.
+ ASSERT_TRUE(handler->HasPendingTasksForTest());
+
+ // Simulate the page changing it's manifest URL to empty via Javascript.
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL12x12, _, _));
+ handler->OnUpdateCandidates(kPageURL,
+ {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)},
+ base::nullopt);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kManifestURL, kIconURL12x12));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL12x12));
+}
+
+TEST_F(FaviconHandlerTest, AddManifestViaJavascriptWhileHistoryQuery) {
+ const GURL kManifestURL("http://www.google.com/manifest.json");
+ const std::vector<favicon::FaviconURL> kManifestIcons = {
+ FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
+ };
+
+ delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
+
+ auto handler = base::MakeUnique<FaviconHandler>(
+ &favicon_service_, &delegate_, FaviconDriverObserver::NON_TOUCH_16_DIP);
+ handler->FetchFavicon(kPageURL);
+ ASSERT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kPageURL));
+ base::RunLoop().RunUntilIdle();
+ ASSERT_FALSE(handler->HasPendingTasksForTest());
+ handler->OnUpdateCandidates(kPageURL,
+ {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)},
+ base::nullopt);
+ ASSERT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kIconURL12x12));
+ // Database lookup for |kIconURL12x12| is ongoing.
+ ASSERT_TRUE(handler->HasPendingTasksForTest());
+
+ // Simulate the page changing it's manifest URL to |kManifestURL| via
+ // Javascript.
+ EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL, _, _));
+ handler->OnUpdateCandidates(kPageURL,
+ {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)},
+ kManifestURL);
+ base::RunLoop().RunUntilIdle();
+ ASSERT_THAT(favicon_service_.fake()->db_requests(),
+ ElementsAre(kPageURL, kIconURL12x12, kManifestURL));
+ EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL64x64));
+}
+
} // namespace
} // namespace favicon

Powered by Google App Engine
This is Rietveld 408576698