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

Side by Side Diff: components/favicon/core/favicon_handler_unittest.cc

Issue 2799273002: Add support to process favicons from Web Manifests (Closed)
Patch Set: Addressed comments. Created 3 years, 7 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/favicon/core/favicon_handler.h" 5 #include "components/favicon/core/favicon_handler.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <map> 9 #include <map>
10 #include <memory> 10 #include <memory>
11 #include <set> 11 #include <set>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/run_loop.h" 16 #include "base/run_loop.h"
17 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
18 #include "base/test/histogram_tester.h" 18 #include "base/test/histogram_tester.h"
19 #include "base/test/scoped_feature_list.h"
19 #include "base/test/scoped_task_environment.h" 20 #include "base/test/scoped_task_environment.h"
20 #include "base/test/test_simple_task_runner.h" 21 #include "base/test/test_simple_task_runner.h"
21 #include "components/favicon/core/favicon_driver.h" 22 #include "components/favicon/core/favicon_driver.h"
22 #include "components/favicon/core/test/mock_favicon_service.h" 23 #include "components/favicon/core/test/mock_favicon_service.h"
23 #include "testing/gmock/include/gmock/gmock.h" 24 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h" 25 #include "testing/gtest/include/gtest/gtest.h"
25 #include "third_party/skia/include/core/SkBitmap.h" 26 #include "third_party/skia/include/core/SkBitmap.h"
26 #include "third_party/skia/include/core/SkColor.h" 27 #include "third_party/skia/include/core/SkColor.h"
27 #include "ui/base/layout.h" 28 #include "ui/base/layout.h"
28 #include "ui/gfx/codec/png_codec.h" 29 #include "ui/gfx/codec/png_codec.h"
29 #include "ui/gfx/favicon_size.h" 30 #include "ui/gfx/favicon_size.h"
30 #include "ui/gfx/image/image.h" 31 #include "ui/gfx/image/image.h"
31 32
32 namespace favicon { 33 namespace favicon {
33 namespace { 34 namespace {
34 35
35 using favicon_base::FAVICON; 36 using favicon_base::FAVICON;
36 using favicon_base::FaviconRawBitmapResult; 37 using favicon_base::FaviconRawBitmapResult;
37 using favicon_base::TOUCH_ICON; 38 using favicon_base::TOUCH_ICON;
38 using favicon_base::TOUCH_PRECOMPOSED_ICON; 39 using favicon_base::TOUCH_PRECOMPOSED_ICON;
39 using testing::Assign; 40 using testing::Assign;
41 using testing::Contains;
40 using testing::ElementsAre; 42 using testing::ElementsAre;
41 using testing::InSequence; 43 using testing::InSequence;
42 using testing::Invoke; 44 using testing::Invoke;
43 using testing::IsEmpty; 45 using testing::IsEmpty;
46 using testing::Not;
44 using testing::Return; 47 using testing::Return;
45 using testing::_; 48 using testing::_;
46 49
47 using DownloadOutcome = FaviconHandler::DownloadOutcome; 50 using DownloadOutcome = FaviconHandler::DownloadOutcome;
48 using IntVector = std::vector<int>; 51 using IntVector = std::vector<int>;
49 using URLVector = std::vector<GURL>; 52 using URLVector = std::vector<GURL>;
50 using BitmapVector = std::vector<SkBitmap>; 53 using BitmapVector = std::vector<SkBitmap>;
51 using SizeVector = std::vector<gfx::Size>; 54 using SizeVector = std::vector<gfx::Size>;
52 55
53 MATCHER_P2(ImageSizeIs, width, height, "") { 56 MATCHER_P2(ImageSizeIs, width, height, "") {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 // Fake that implements the calls to FaviconHandler::Delegate's DownloadImage(), 113 // Fake that implements the calls to FaviconHandler::Delegate's DownloadImage(),
111 // delegated to this class through MockDelegate. 114 // delegated to this class through MockDelegate.
112 class FakeImageDownloader { 115 class FakeImageDownloader {
113 public: 116 public:
114 struct Response { 117 struct Response {
115 int http_status_code = 404; 118 int http_status_code = 404;
116 BitmapVector bitmaps; 119 BitmapVector bitmaps;
117 SizeVector original_bitmap_sizes; 120 SizeVector original_bitmap_sizes;
118 }; 121 };
119 122
120 FakeImageDownloader() : next_download_id_(1) {} 123 // |downloads| must not be nullptr and must outlive this object.
124 FakeImageDownloader(URLVector* downloads)
125 : downloads_(downloads), next_download_id_(1) {}
121 126
122 // Implementation of FaviconHalder::Delegate's DownloadImage(). If a given 127 // Implementation of FaviconHalder::Delegate's DownloadImage(). If a given
123 // URL is not known (i.e. not previously added via Add()), it produces 404s. 128 // URL is not known (i.e. not previously added via Add()), it produces 404s.
124 int DownloadImage(const GURL& url, 129 int DownloadImage(const GURL& url,
125 int max_image_size, 130 int max_image_size,
126 FaviconHandler::Delegate::ImageDownloadCallback callback) { 131 FaviconHandler::Delegate::ImageDownloadCallback callback) {
127 downloads_.push_back(url); 132 downloads_->push_back(url);
128 133
129 const Response& response = responses_[url]; 134 const Response& response = responses_[url];
130 int download_id = next_download_id_++; 135 int download_id = next_download_id_++;
131 base::Closure bound_callback = 136 base::Closure bound_callback =
132 base::Bind(callback, download_id, response.http_status_code, url, 137 base::Bind(callback, download_id, response.http_status_code, url,
133 response.bitmaps, response.original_bitmap_sizes); 138 response.bitmaps, response.original_bitmap_sizes);
134 if (url == manual_callback_url_) 139 if (url == manual_callback_url_)
135 manual_callback_ = bound_callback; 140 manual_callback_ = bound_callback;
136 else 141 else
137 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, bound_callback); 142 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, bound_callback);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 // Triggers the response for a download previously selected for manual 182 // Triggers the response for a download previously selected for manual
178 // triggering via SetRunCallbackManuallyForUrl(). 183 // triggering via SetRunCallbackManuallyForUrl().
179 bool RunCallbackManually() { 184 bool RunCallbackManually() {
180 if (!HasPendingManualCallback()) 185 if (!HasPendingManualCallback())
181 return false; 186 return false;
182 manual_callback_.Run(); 187 manual_callback_.Run();
183 manual_callback_.Reset(); 188 manual_callback_.Reset();
184 return true; 189 return true;
185 } 190 }
186 191
187 // Returns pending and completed download URLs.
188 const URLVector& downloads() const { return downloads_; }
189
190 void ClearDownloads() { downloads_.clear(); }
191
192 private: 192 private:
193 URLVector* downloads_;
193 int next_download_id_; 194 int next_download_id_;
194 195
195 // Pending and completed download URLs.
196 URLVector downloads_;
197
198 // URL to disable automatic callbacks for. 196 // URL to disable automatic callbacks for.
199 GURL manual_callback_url_; 197 GURL manual_callback_url_;
200 198
201 // Callback for DownloadImage() request for |manual_callback_url_|. 199 // Callback for DownloadImage() request for |manual_callback_url_|.
202 base::Closure manual_callback_; 200 base::Closure manual_callback_;
203 201
204 // Registered responses. 202 // Registered responses.
205 std::map<GURL, Response> responses_; 203 std::map<GURL, Response> responses_;
206 204
207 DISALLOW_COPY_AND_ASSIGN(FakeImageDownloader); 205 DISALLOW_COPY_AND_ASSIGN(FakeImageDownloader);
208 }; 206 };
209 207
208 // Fake that implements the calls to FaviconHandler::Delegate's
209 // DownloadManifest(), delegated to this class through MockDelegate.
210 class FakeManifestDownloader {
211 public:
212 struct Response {
213 int http_status_code = 404;
214 std::vector<favicon::FaviconURL> favicon_urls;
215 };
216
217 // |downloads| must not be nullptr and must outlive this object.
218 FakeManifestDownloader(URLVector* downloads) : downloads_(downloads) {}
219
220 // Implementation of FaviconHalder::Delegate's DownloadManifest(). If a given
221 // URL is not known (i.e. not previously added via Add()), it produces 404s.
222 void DownloadManifest(
223 const GURL& url,
224 FaviconHandler::Delegate::ManifestDownloadCallback callback) {
225 downloads_->push_back(url);
226
227 const Response& response = responses_[url];
228 base::Closure bound_callback =
229 base::Bind(callback, response.http_status_code, response.favicon_urls);
230 if (url == manual_callback_url_)
231 manual_callback_ = bound_callback;
232 else
233 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, bound_callback);
234 }
235
236 void Add(const GURL& manifest_url,
237 const std::vector<favicon::FaviconURL>& favicon_urls) {
238 Response response;
239 response.http_status_code = 200;
240 response.favicon_urls = favicon_urls;
241 responses_[manifest_url] = response;
242 }
243
244 void AddError(const GURL& manifest_url, int http_status_code) {
245 Response response;
246 response.http_status_code = http_status_code;
247 responses_[manifest_url] = response;
248 }
249
250 // Disables automatic callback for |url|. This is useful for emulating a
251 // download taking a long time. The callback for DownloadManifest() will be
252 // stored in |manual_callback_|.
253 void SetRunCallbackManuallyForUrl(const GURL& url) {
254 manual_callback_url_ = url;
255 }
256
257 // Returns whether an ongoing download exists for a url previously selected
258 // via SetRunCallbackManuallyForUrl().
259 bool HasPendingManualCallback() { return !manual_callback_.is_null(); }
260
261 // Triggers the response for a download previously selected for manual
262 // triggering via SetRunCallbackManuallyForUrl().
263 bool RunCallbackManually() {
264 if (!HasPendingManualCallback())
265 return false;
266 manual_callback_.Run();
267 manual_callback_.Reset();
268 return true;
269 }
270
271 private:
272 URLVector* downloads_;
273
274 // URL to disable automatic callbacks for.
275 GURL manual_callback_url_;
276
277 // Callback for DownloadManifest() request for |manual_callback_url_|.
278 base::Closure manual_callback_;
279
280 // Registered responses.
281 std::map<GURL, Response> responses_;
282
283 DISALLOW_COPY_AND_ASSIGN(FakeManifestDownloader);
284 };
285
210 class MockDelegate : public FaviconHandler::Delegate { 286 class MockDelegate : public FaviconHandler::Delegate {
211 public: 287 public:
212 MockDelegate() { 288 MockDelegate()
289 : fake_image_downloader_(&downloads_),
290 fake_manifest_downloader_(&downloads_) {
213 // Delegate image downloading to FakeImageDownloader. 291 // Delegate image downloading to FakeImageDownloader.
214 ON_CALL(*this, DownloadImage(_, _, _)) 292 ON_CALL(*this, DownloadImage(_, _, _))
215 .WillByDefault(Invoke(&fake_image_downloader_, 293 .WillByDefault(Invoke(&fake_image_downloader_,
216 &FakeImageDownloader::DownloadImage)); 294 &FakeImageDownloader::DownloadImage));
295 // Delegate manifest downloading to FakeManifestDownloader.
296 ON_CALL(*this, DownloadManifest(_, _))
297 .WillByDefault(Invoke(&fake_manifest_downloader_,
298 &FakeManifestDownloader::DownloadManifest));
217 } 299 }
218 300
219 MOCK_METHOD3(DownloadImage, 301 MOCK_METHOD3(DownloadImage,
220 int(const GURL& url, 302 int(const GURL& url,
221 int max_image_size, 303 int max_image_size,
222 ImageDownloadCallback callback)); 304 ImageDownloadCallback callback));
305 MOCK_METHOD2(DownloadManifest,
306 void(const GURL& url, ManifestDownloadCallback callback));
223 MOCK_METHOD0(IsOffTheRecord, bool()); 307 MOCK_METHOD0(IsOffTheRecord, bool());
224 MOCK_METHOD1(IsBookmarked, bool(const GURL& url)); 308 MOCK_METHOD1(IsBookmarked, bool(const GURL& url));
225 MOCK_METHOD5(OnFaviconUpdated, 309 MOCK_METHOD5(OnFaviconUpdated,
226 void(const GURL& page_url, 310 void(const GURL& page_url,
227 FaviconDriverObserver::NotificationIconType type, 311 FaviconDriverObserver::NotificationIconType type,
228 const GURL& icon_url, 312 const GURL& icon_url,
229 bool icon_url_changed, 313 bool icon_url_changed,
230 const gfx::Image& image)); 314 const gfx::Image& image));
231 315
232 FakeImageDownloader& fake_image_downloader() { 316 FakeImageDownloader& fake_image_downloader() {
233 return fake_image_downloader_; 317 return fake_image_downloader_;
234 } 318 }
235 319
236 // Convenience getter for test readability. Returns pending and completed 320 FakeManifestDownloader& fake_manifest_downloader() {
237 // download URLs. 321 return fake_manifest_downloader_;
238 const URLVector& downloads() const {
239 return fake_image_downloader_.downloads();
240 } 322 }
241 323
324 // Returns pending and completed download URLs.
325 const URLVector& downloads() const { return downloads_; }
326
327 void ClearDownloads() { downloads_.clear(); }
328
242 private: 329 private:
330 // Pending and completed download URLs.
331 URLVector downloads_;
243 FakeImageDownloader fake_image_downloader_; 332 FakeImageDownloader fake_image_downloader_;
333 FakeManifestDownloader fake_manifest_downloader_;
244 }; 334 };
245 335
246 // FakeFaviconService mimics a FaviconService backend that allows setting up 336 // FakeFaviconService mimics a FaviconService backend that allows setting up
247 // test data stored via Store(). If Store() has not been called for a 337 // test data stored via Store(). If Store() has not been called for a
248 // particular URL, the callback is called with empty database results. 338 // particular URL, the callback is called with empty database results.
249 class FakeFaviconService { 339 class FakeFaviconService {
250 public: 340 public:
251 FakeFaviconService() 341 FakeFaviconService()
252 : manual_callback_task_runner_(new base::TestSimpleTaskRunner()) {} 342 : manual_callback_task_runner_(new base::TestSimpleTaskRunner()) {}
253 343
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 // a downloaded bitmap in FaviconHandler::OnDidDownloadFavicon(). 487 // a downloaded bitmap in FaviconHandler::OnDidDownloadFavicon().
398 // Force the values of the scale factors so that the tests produce the same 488 // Force the values of the scale factors so that the tests produce the same
399 // results on all platforms. 489 // results on all platforms.
400 scoped_set_supported_scale_factors_.reset( 490 scoped_set_supported_scale_factors_.reset(
401 new ui::test::ScopedSetSupportedScaleFactors({ui::SCALE_FACTOR_100P})); 491 new ui::test::ScopedSetSupportedScaleFactors({ui::SCALE_FACTOR_100P}));
402 } 492 }
403 493
404 bool VerifyAndClearExpectations() { 494 bool VerifyAndClearExpectations() {
405 base::RunLoop().RunUntilIdle(); 495 base::RunLoop().RunUntilIdle();
406 favicon_service_.fake()->ClearDbRequests(); 496 favicon_service_.fake()->ClearDbRequests();
407 delegate_.fake_image_downloader().ClearDownloads(); 497 delegate_.ClearDownloads();
408 return testing::Mock::VerifyAndClearExpectations(&favicon_service_) && 498 return testing::Mock::VerifyAndClearExpectations(&favicon_service_) &&
409 testing::Mock::VerifyAndClearExpectations(&delegate_); 499 testing::Mock::VerifyAndClearExpectations(&delegate_);
410 } 500 }
411 501
412 // Creates a new handler and feeds in the page URL and the candidates. 502 // Creates a new handler and feeds in the page URL and the candidates.
413 // Returns the handler in case tests want to exercise further steps. 503 // Returns the handler in case tests want to exercise further steps.
414 std::unique_ptr<FaviconHandler> RunHandlerWithCandidates( 504 std::unique_ptr<FaviconHandler> RunHandlerWithCandidates(
415 FaviconDriverObserver::NotificationIconType handler_type, 505 FaviconDriverObserver::NotificationIconType handler_type,
416 const std::vector<favicon::FaviconURL>& candidates) { 506 const std::vector<favicon::FaviconURL>& candidates,
507 const base::Optional<GURL>& manifest_url = base::nullopt) {
417 auto handler = base::MakeUnique<FaviconHandler>(&favicon_service_, 508 auto handler = base::MakeUnique<FaviconHandler>(&favicon_service_,
418 &delegate_, handler_type); 509 &delegate_, handler_type);
419 handler->FetchFavicon(kPageURL); 510 handler->FetchFavicon(kPageURL);
420 // The first RunUntilIdle() causes the FaviconService lookups be faster than 511 // The first RunUntilIdle() causes the FaviconService lookups be faster than
421 // OnUpdateCandidates(), which is the most likely scenario. 512 // OnUpdateCandidates(), which is the most likely scenario.
422 base::RunLoop().RunUntilIdle(); 513 base::RunLoop().RunUntilIdle();
423 handler->OnUpdateCandidates(kPageURL, candidates); 514 handler->OnUpdateCandidates(kPageURL, candidates, manifest_url);
424 base::RunLoop().RunUntilIdle(); 515 base::RunLoop().RunUntilIdle();
425 return handler; 516 return handler;
426 } 517 }
427 518
428 // Same as above, but for the simplest case where all types are FAVICON and 519 // Same as above, but for the simplest case where all types are FAVICON and
429 // no sizes are provided, using a FaviconHandler of type NON_TOUCH_16_DIP. 520 // no sizes are provided, using a FaviconHandler of type NON_TOUCH_16_DIP.
430 std::unique_ptr<FaviconHandler> RunHandlerWithSimpleFaviconCandidates( 521 std::unique_ptr<FaviconHandler> RunHandlerWithSimpleFaviconCandidates(
431 const std::vector<GURL>& urls) { 522 const std::vector<GURL>& urls,
523 const base::Optional<GURL>& manifest_url = base::nullopt) {
432 std::vector<favicon::FaviconURL> candidates; 524 std::vector<favicon::FaviconURL> candidates;
433 for (const GURL& url : urls) { 525 for (const GURL& url : urls) {
434 candidates.emplace_back(url, FAVICON, kEmptySizes); 526 candidates.emplace_back(url, FAVICON, kEmptySizes);
435 } 527 }
436 return RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, 528 return RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP,
437 candidates); 529 candidates, manifest_url);
438 } 530 }
439 531
440 base::test::ScopedTaskEnvironment scoped_task_environment_; 532 base::test::ScopedTaskEnvironment scoped_task_environment_;
441 std::unique_ptr<ui::test::ScopedSetSupportedScaleFactors> 533 std::unique_ptr<ui::test::ScopedSetSupportedScaleFactors>
442 scoped_set_supported_scale_factors_; 534 scoped_set_supported_scale_factors_;
443 testing::NiceMock<MockFaviconServiceWithFake> favicon_service_; 535 testing::NiceMock<MockFaviconServiceWithFake> favicon_service_;
444 testing::NiceMock<MockDelegate> delegate_; 536 testing::NiceMock<MockDelegate> delegate_;
445 }; 537 };
446 538
447 TEST_F(FaviconHandlerTest, GetFaviconFromHistory) { 539 TEST_F(FaviconHandlerTest, GetFaviconFromHistory) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 ASSERT_TRUE(favicon_service_.fake()->RunCallbackManually()); 589 ASSERT_TRUE(favicon_service_.fake()->RunCallbackManually());
498 ASSERT_TRUE(VerifyAndClearExpectations()); 590 ASSERT_TRUE(VerifyAndClearExpectations());
499 591
500 EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, FAVICON, 592 EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, FAVICON,
501 ImageSizeIs(16, 16))); 593 ImageSizeIs(16, 16)));
502 EXPECT_CALL(delegate_, OnFaviconUpdated( 594 EXPECT_CALL(delegate_, OnFaviconUpdated(
503 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, 595 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP,
504 kIconURL16x16, /*icon_url_changed=*/true, _)); 596 kIconURL16x16, /*icon_url_changed=*/true, _));
505 // Feed in favicons now that the database lookup is completed. 597 // Feed in favicons now that the database lookup is completed.
506 handler.OnUpdateCandidates(kPageURL, 598 handler.OnUpdateCandidates(kPageURL,
507 {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}); 599 {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)},
600 base::nullopt);
508 base::RunLoop().RunUntilIdle(); 601 base::RunLoop().RunUntilIdle();
509 602
510 EXPECT_THAT(favicon_service_.fake()->db_requests(), 603 EXPECT_THAT(favicon_service_.fake()->db_requests(),
511 ElementsAre(kIconURL16x16)); 604 ElementsAre(kIconURL16x16));
512 EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL16x16)); 605 EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL16x16));
513 } 606 }
514 607
515 // Test that the FaviconHandler process finishes when: 608 // Test that the FaviconHandler process finishes when:
516 // - There is data in the database for neither the page URL nor the icon URL. 609 // - There is data in the database for neither the page URL nor the icon URL.
517 // AND 610 // AND
518 // - FaviconService::GetFaviconForPageURL() callback returns after 611 // - FaviconService::GetFaviconForPageURL() callback returns after
519 // FaviconHandler::OnUpdateCandidates() is called. 612 // FaviconHandler::OnUpdateCandidates() is called.
520 TEST_F(FaviconHandlerTest, DownloadUnknownFaviconIfCandidatesFaster) { 613 TEST_F(FaviconHandlerTest, DownloadUnknownFaviconIfCandidatesFaster) {
521 // Defer the database lookup completion to control the exact timing. 614 // Defer the database lookup completion to control the exact timing.
522 favicon_service_.fake()->SetRunCallbackManuallyForUrl(kPageURL); 615 favicon_service_.fake()->SetRunCallbackManuallyForUrl(kPageURL);
523 616
524 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0); 617 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0);
525 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)).Times(0); 618 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)).Times(0);
526 619
527 FaviconHandler handler(&favicon_service_, &delegate_, 620 FaviconHandler handler(&favicon_service_, &delegate_,
528 FaviconDriverObserver::NON_TOUCH_16_DIP); 621 FaviconDriverObserver::NON_TOUCH_16_DIP);
529 handler.FetchFavicon(kPageURL); 622 handler.FetchFavicon(kPageURL);
530 base::RunLoop().RunUntilIdle(); 623 base::RunLoop().RunUntilIdle();
531 // Feed in favicons before completing the database lookup. 624 // Feed in favicons before completing the database lookup.
532 handler.OnUpdateCandidates(kPageURL, 625 handler.OnUpdateCandidates(kPageURL,
533 {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}); 626 {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)},
627 base::nullopt);
534 628
535 ASSERT_TRUE(VerifyAndClearExpectations()); 629 ASSERT_TRUE(VerifyAndClearExpectations());
536 // Database lookup for |kPageURL| is ongoing. 630 // Database lookup for |kPageURL| is ongoing.
537 ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback()); 631 ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
538 632
539 EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, FAVICON, 633 EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, FAVICON,
540 ImageSizeIs(16, 16))); 634 ImageSizeIs(16, 16)));
541 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL16x16, _, _)); 635 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL16x16, _, _));
542 636
543 // Complete the lookup for |kPageURL|. 637 // Complete the lookup for |kPageURL|.
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 std::unique_ptr<FaviconHandler> handler = 831 std::unique_ptr<FaviconHandler> handler =
738 RunHandlerWithSimpleFaviconCandidates({kIconURL1, kIconURL2}); 832 RunHandlerWithSimpleFaviconCandidates({kIconURL1, kIconURL2});
739 833
740 ASSERT_TRUE(VerifyAndClearExpectations()); 834 ASSERT_TRUE(VerifyAndClearExpectations());
741 ASSERT_TRUE(delegate_.fake_image_downloader().HasPendingManualCallback()); 835 ASSERT_TRUE(delegate_.fake_image_downloader().HasPendingManualCallback());
742 836
743 // Favicon update should invalidate the ongoing download. 837 // Favicon update should invalidate the ongoing download.
744 EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL3, _, _)); 838 EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL3, _, _));
745 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL3, _, _)); 839 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL3, _, _));
746 840
747 handler->OnUpdateCandidates(kPageURL, 841 handler->OnUpdateCandidates(
748 {FaviconURL(kIconURL3, FAVICON, kEmptySizes)}); 842 kPageURL, {FaviconURL(kIconURL3, FAVICON, kEmptySizes)}, base::nullopt);
749 843
750 // Finalizes download, which should be thrown away as the favicon URLs were 844 // Finalizes download, which should be thrown away as the favicon URLs were
751 // updated. 845 // updated.
752 EXPECT_TRUE(delegate_.fake_image_downloader().RunCallbackManually()); 846 EXPECT_TRUE(delegate_.fake_image_downloader().RunCallbackManually());
753 base::RunLoop().RunUntilIdle(); 847 base::RunLoop().RunUntilIdle();
754 848
755 EXPECT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kIconURL3)); 849 EXPECT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kIconURL3));
756 EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL3)); 850 EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL3));
757 } 851 }
758 852
(...skipping 15 matching lines...) Expand all
774 RunHandlerWithSimpleFaviconCandidates(URLVector{kIconURL1}); 868 RunHandlerWithSimpleFaviconCandidates(URLVector{kIconURL1});
775 869
776 ASSERT_TRUE(VerifyAndClearExpectations()); 870 ASSERT_TRUE(VerifyAndClearExpectations());
777 ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback()); 871 ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
778 872
779 // SetFavicons() and OnFaviconUpdated() should be called for the new icon URL 873 // SetFavicons() and OnFaviconUpdated() should be called for the new icon URL
780 // and not |kIconURL1|. 874 // and not |kIconURL1|.
781 EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL2, _, _)); 875 EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL2, _, _));
782 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL2, _, _)); 876 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL2, _, _));
783 877
784 handler->OnUpdateCandidates(kPageURL, 878 handler->OnUpdateCandidates(
785 {FaviconURL(kIconURL2, FAVICON, kEmptySizes)}); 879 kPageURL, {FaviconURL(kIconURL2, FAVICON, kEmptySizes)}, base::nullopt);
786 880
787 // Finalizes the DB lookup, which should be thrown away as the favicon URLs 881 // Finalizes the DB lookup, which should be thrown away as the favicon URLs
788 // were updated. 882 // were updated.
789 EXPECT_TRUE(favicon_service_.fake()->RunCallbackManually()); 883 EXPECT_TRUE(favicon_service_.fake()->RunCallbackManually());
790 base::RunLoop().RunUntilIdle(); 884 base::RunLoop().RunUntilIdle();
791 885
792 EXPECT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kIconURL2)); 886 EXPECT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kIconURL2));
793 EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL2)); 887 EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL2));
794 } 888 }
795 889
(...skipping 16 matching lines...) Expand all
812 std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates( 906 std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates(
813 FaviconDriverObserver::NON_TOUCH_16_DIP, favicon_urls); 907 FaviconDriverObserver::NON_TOUCH_16_DIP, favicon_urls);
814 908
815 ASSERT_THAT(favicon_service_.fake()->db_requests(), 909 ASSERT_THAT(favicon_service_.fake()->db_requests(),
816 ElementsAre(kPageURL, kIconURL64x64, kSlowLoadingIconURL)); 910 ElementsAre(kPageURL, kIconURL64x64, kSlowLoadingIconURL));
817 ASSERT_TRUE(VerifyAndClearExpectations()); 911 ASSERT_TRUE(VerifyAndClearExpectations());
818 ASSERT_TRUE(delegate_.fake_image_downloader().HasPendingManualCallback()); 912 ASSERT_TRUE(delegate_.fake_image_downloader().HasPendingManualCallback());
819 913
820 // Calling OnUpdateCandidates() with the same icon URLs should have no effect, 914 // Calling OnUpdateCandidates() with the same icon URLs should have no effect,
821 // despite the ongoing download. 915 // despite the ongoing download.
822 handler->OnUpdateCandidates(kPageURL, favicon_urls); 916 handler->OnUpdateCandidates(kPageURL, favicon_urls, base::nullopt);
823 base::RunLoop().RunUntilIdle(); 917 base::RunLoop().RunUntilIdle();
824 EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty()); 918 EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty());
825 EXPECT_THAT(delegate_.downloads(), IsEmpty()); 919 EXPECT_THAT(delegate_.downloads(), IsEmpty());
826 920
827 // Complete the download. 921 // Complete the download.
828 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)); 922 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _));
829 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)); 923 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _));
830 EXPECT_TRUE(delegate_.fake_image_downloader().RunCallbackManually()); 924 EXPECT_TRUE(delegate_.fake_image_downloader().RunCallbackManually());
831 base::RunLoop().RunUntilIdle(); 925 base::RunLoop().RunUntilIdle();
832 EXPECT_THAT(delegate_.downloads(), IsEmpty()); 926 EXPECT_THAT(delegate_.downloads(), IsEmpty());
(...skipping 13 matching lines...) Expand all
846 940
847 // Ongoing database lookup. 941 // Ongoing database lookup.
848 ASSERT_THAT(favicon_service_.fake()->db_requests(), 942 ASSERT_THAT(favicon_service_.fake()->db_requests(),
849 ElementsAre(kPageURL, kIconURL64x64)); 943 ElementsAre(kPageURL, kIconURL64x64));
850 ASSERT_THAT(delegate_.downloads(), IsEmpty()); 944 ASSERT_THAT(delegate_.downloads(), IsEmpty());
851 ASSERT_TRUE(VerifyAndClearExpectations()); 945 ASSERT_TRUE(VerifyAndClearExpectations());
852 ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback()); 946 ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
853 947
854 // Calling OnUpdateCandidates() with the same icon URLs should have no effect, 948 // Calling OnUpdateCandidates() with the same icon URLs should have no effect,
855 // despite the ongoing DB lookup. 949 // despite the ongoing DB lookup.
856 handler->OnUpdateCandidates(kPageURL, favicon_urls); 950 handler->OnUpdateCandidates(kPageURL, favicon_urls, base::nullopt);
857 base::RunLoop().RunUntilIdle(); 951 base::RunLoop().RunUntilIdle();
858 EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty()); 952 EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty());
859 EXPECT_THAT(delegate_.downloads(), IsEmpty()); 953 EXPECT_THAT(delegate_.downloads(), IsEmpty());
860 954
861 // Complete the lookup. 955 // Complete the lookup.
862 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)); 956 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _));
863 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)); 957 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _));
864 EXPECT_TRUE(favicon_service_.fake()->RunCallbackManually()); 958 EXPECT_TRUE(favicon_service_.fake()->RunCallbackManually());
865 base::RunLoop().RunUntilIdle(); 959 base::RunLoop().RunUntilIdle();
866 EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL64x64)); 960 EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL64x64));
(...skipping 10 matching lines...) Expand all
877 971
878 std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates( 972 std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates(
879 FaviconDriverObserver::NON_TOUCH_16_DIP, favicon_urls); 973 FaviconDriverObserver::NON_TOUCH_16_DIP, favicon_urls);
880 974
881 ASSERT_TRUE(VerifyAndClearExpectations()); 975 ASSERT_TRUE(VerifyAndClearExpectations());
882 976
883 // Calling OnUpdateCandidates() with identical data should be a no-op. 977 // Calling OnUpdateCandidates() with identical data should be a no-op.
884 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)).Times(0); 978 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)).Times(0);
885 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0); 979 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0);
886 980
887 handler->OnUpdateCandidates(kPageURL, favicon_urls); 981 handler->OnUpdateCandidates(kPageURL, favicon_urls, base::nullopt);
888 base::RunLoop().RunUntilIdle(); 982 base::RunLoop().RunUntilIdle();
889 EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty()); 983 EXPECT_THAT(favicon_service_.fake()->db_requests(), IsEmpty());
890 EXPECT_THAT(delegate_.downloads(), IsEmpty()); 984 EXPECT_THAT(delegate_.downloads(), IsEmpty());
891 } 985 }
892 986
893 // Fixes crbug.com/544560 987 // Fixes crbug.com/544560
894 // Tests that Delegate::OnFaviconUpdated() is called if: 988 // Tests that Delegate::OnFaviconUpdated() is called if:
895 // - The best icon on the initial page is not the last icon. 989 // - The best icon on the initial page is not the last icon.
896 // - All of the initial page's icons are downloaded. 990 // - All of the initial page's icons are downloaded.
897 // AND 991 // AND
(...skipping 21 matching lines...) Expand all
919 // database and downloaded. |kIconURL2| should have been fetched from the 1013 // database and downloaded. |kIconURL2| should have been fetched from the
920 // database and downloaded last. 1014 // database and downloaded last.
921 ASSERT_THAT(delegate_.downloads(), ElementsAre(kIconURL1, kIconURL2)); 1015 ASSERT_THAT(delegate_.downloads(), ElementsAre(kIconURL1, kIconURL2));
922 ASSERT_THAT(favicon_service_.fake()->db_requests(), 1016 ASSERT_THAT(favicon_service_.fake()->db_requests(),
923 ElementsAre(kPageURL, kIconURL1, kIconURL2)); 1017 ElementsAre(kPageURL, kIconURL1, kIconURL2));
924 ASSERT_TRUE(VerifyAndClearExpectations()); 1018 ASSERT_TRUE(VerifyAndClearExpectations());
925 1019
926 // Simulate the page changing it's icon URL to just |kIconURL2| via 1020 // Simulate the page changing it's icon URL to just |kIconURL2| via
927 // Javascript. 1021 // Javascript.
928 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL2, _, _)); 1022 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL2, _, _));
929 handler->OnUpdateCandidates(kPageURL, 1023 handler->OnUpdateCandidates(
930 {FaviconURL(kIconURL2, FAVICON, kEmptySizes)}); 1024 kPageURL, {FaviconURL(kIconURL2, FAVICON, kEmptySizes)}, base::nullopt);
931 base::RunLoop().RunUntilIdle(); 1025 base::RunLoop().RunUntilIdle();
932 } 1026 }
933 1027
934 // Test the favicon which is selected when the web page provides several 1028 // Test the favicon which is selected when the web page provides several
935 // favicons and none of the favicons are cached in history. 1029 // favicons and none of the favicons are cached in history.
936 // The goal of this test is to be more of an integration test than 1030 // The goal of this test is to be more of an integration test than
937 // SelectFaviconFramesTest.*. 1031 // SelectFaviconFramesTest.*.
938 class FaviconHandlerMultipleFaviconsTest : public FaviconHandlerTest { 1032 class FaviconHandlerMultipleFaviconsTest : public FaviconHandlerTest {
939 protected: 1033 protected:
940 FaviconHandlerMultipleFaviconsTest() { 1034 FaviconHandlerMultipleFaviconsTest() {
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 RunHandlerWithCandidates( 1225 RunHandlerWithCandidates(
1132 FaviconDriverObserver::NON_TOUCH_LARGEST, 1226 FaviconDriverObserver::NON_TOUCH_LARGEST,
1133 {FaviconURL(kIconURL1024_512, FAVICON, 1227 {FaviconURL(kIconURL1024_512, FAVICON,
1134 {gfx::Size(1024, 1024), gfx::Size(512, 512)}), 1228 {gfx::Size(1024, 1024), gfx::Size(512, 512)}),
1135 FaviconURL(kIconURL15_14, FAVICON, 1229 FaviconURL(kIconURL15_14, FAVICON,
1136 {gfx::Size(15, 15), gfx::Size(14, 14)}), 1230 {gfx::Size(15, 15), gfx::Size(14, 14)}),
1137 FaviconURL(kIconURL16_512, FAVICON, 1231 FaviconURL(kIconURL16_512, FAVICON,
1138 {gfx::Size(16, 16), gfx::Size(512, 512)}), 1232 {gfx::Size(16, 16), gfx::Size(512, 512)}),
1139 FaviconURL(kIconURLWithoutSize1, FAVICON, kEmptySizes), 1233 FaviconURL(kIconURLWithoutSize1, FAVICON, kEmptySizes),
1140 FaviconURL(kIconURLWithoutSize2, FAVICON, kEmptySizes)}); 1234 FaviconURL(kIconURLWithoutSize2, FAVICON, kEmptySizes)});
1141
1142 // Icon URLs are not registered and hence 404s will be produced, which 1235 // Icon URLs are not registered and hence 404s will be produced, which
1143 // allows checking whether the icons were requested according to their size. 1236 // allows checking whether the icons were requested according to their size.
1144 // The favicons should have been requested in decreasing order of their sizes. 1237 // The favicons should have been requested in decreasing order of their sizes.
1145 // Favicons without any <link sizes=""> attribute should have been downloaded 1238 // Favicons without any <link sizes=""> attribute should have been downloaded
1146 // last. 1239 // last.
1147 EXPECT_THAT(delegate_.downloads(), 1240 EXPECT_THAT(delegate_.downloads(),
1148 ElementsAre(kIconURL1024_512, kIconURL16_512, kIconURL15_14, 1241 ElementsAre(kIconURL1024_512, kIconURL16_512, kIconURL15_14,
1149 kIconURLWithoutSize1, kIconURLWithoutSize2)); 1242 kIconURLWithoutSize1, kIconURLWithoutSize2));
1150 } 1243 }
1151 1244
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 .WillByDefault(Return(true)); 1456 .WillByDefault(Return(true));
1364 1457
1365 RunHandlerWithSimpleFaviconCandidates({k404IconURL}); 1458 RunHandlerWithSimpleFaviconCandidates({k404IconURL});
1366 1459
1367 EXPECT_THAT( 1460 EXPECT_THAT(
1368 histogram_tester.GetAllSamples("Favicons.DownloadOutcome"), 1461 histogram_tester.GetAllSamples("Favicons.DownloadOutcome"),
1369 ElementsAre(base::Bucket(static_cast<int>(DownloadOutcome::SKIPPED), 1462 ElementsAre(base::Bucket(static_cast<int>(DownloadOutcome::SKIPPED),
1370 /*expected_count=*/1))); 1463 /*expected_count=*/1)));
1371 } 1464 }
1372 1465
1466 // Test that the support for Web Manifest is disabled by default, unless the
1467 // feature is enabled.
1468 TEST_F(FaviconHandlerTest, IgnoreWebManifestByDefault) {
1469 const GURL kManifestURL("http://www.google.com/manifest.json");
1470
1471 RunHandlerWithSimpleFaviconCandidates({kIconURL16x16}, kManifestURL);
1472 EXPECT_THAT(favicon_service_.fake()->db_requests(),
1473 Not(Contains(kManifestURL)));
1474 EXPECT_THAT(delegate_.downloads(), Not(Contains(kManifestURL)));
1475 }
1476
1477 class FaviconHandlerManifestsEnabledTest : public FaviconHandlerTest {
1478 protected:
1479 FaviconHandlerManifestsEnabledTest() {
1480 override_features_.InitAndEnableFeature(kFaviconsFromWebManifest);
1481 }
1482
1483 private:
1484 base::test::ScopedFeatureList override_features_;
1485 };
1486
1487 // Test that a favicon corresponding to a web manifest is reported when:
1488 // - There is data in the favicon database for the manifest URL.
1489 // AND
1490 // - FaviconService::OnFaviconDataForManifestFromFaviconService() runs before
1491 // FaviconHandler::OnUpdateCandidates() is called.
1492 TEST_F(FaviconHandlerManifestsEnabledTest,
1493 GetFaviconFromManifestInHistoryIfCandidatesSlower) {
1494 const GURL kManifestURL("http://www.google.com/manifest.json");
1495
1496 favicon_service_.fake()->Store(kPageURL, kManifestURL,
1497 CreateRawBitmapResult(kManifestURL));
1498
1499 EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(0);
1500
1501 EXPECT_CALL(favicon_service_,
1502 UpdateFaviconMappingsAndFetch(_, kManifestURL, FAVICON,
1503 /*desired_size_in_dip=*/16, _, _));
1504 EXPECT_CALL(delegate_,
1505 OnFaviconUpdated(_, FaviconDriverObserver::NON_TOUCH_16_DIP,
1506 kManifestURL, _, _))
1507 .Times(2);
1508
1509 RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
1510 EXPECT_THAT(favicon_service_.fake()->db_requests(),
1511 ElementsAre(kPageURL, kManifestURL));
1512 EXPECT_THAT(delegate_.downloads(), IsEmpty());
1513 }
1514
1515 // Test that a favicon corresponding to a web manifest is reported when:
1516 // - There is data in the favicon database for the manifest URL.
1517 // AND
1518 // - FaviconHandler::OnUpdateCandidates() is called before
1519 // FaviconService::OnFaviconDataForManifestFromFaviconService() runs.
1520 TEST_F(FaviconHandlerManifestsEnabledTest,
1521 GetFaviconFromManifestInHistoryIfCandidatesFaster) {
1522 const GURL kManifestURL("http://www.google.com/manifest.json");
1523
1524 favicon_service_.fake()->Store(kPageURL, kManifestURL,
1525 CreateRawBitmapResult(kManifestURL));
1526
1527 EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(0);
1528
1529 EXPECT_CALL(favicon_service_,
1530 UpdateFaviconMappingsAndFetch(_, kManifestURL, FAVICON,
1531 /*desired_size_in_dip=*/16, _, _));
1532 EXPECT_CALL(delegate_,
1533 OnFaviconUpdated(_, FaviconDriverObserver::NON_TOUCH_16_DIP,
1534 kManifestURL, _, _))
1535 .Times(2);
1536
1537 FaviconHandler handler(&favicon_service_, &delegate_,
1538 FaviconDriverObserver::NON_TOUCH_16_DIP);
1539 handler.FetchFavicon(kPageURL);
1540 // Feed in candidates without processing posted tasks (RunUntilIdle()).
1541 handler.OnUpdateCandidates(kPageURL,
1542 {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)},
1543 kManifestURL);
1544 base::RunLoop().RunUntilIdle();
1545
1546 EXPECT_THAT(favicon_service_.fake()->db_requests(),
1547 ElementsAre(kPageURL, kManifestURL));
1548 EXPECT_THAT(delegate_.downloads(), IsEmpty());
1549 }
1550
1551 // Test that a favicon corresponding to a web manifest is reported when there is
1552 // data in the database for neither the page URL nor the manifest URL.
1553 TEST_F(FaviconHandlerManifestsEnabledTest, GetFaviconFromUnknownManifest) {
1554 const GURL kManifestURL("http://www.google.com/manifest.json");
1555 const std::vector<favicon::FaviconURL> kManifestIcons = {
1556 FaviconURL(kIconURL16x16, FAVICON, kEmptySizes),
1557 };
1558
1559 delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
1560
1561 EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(0);
1562
1563 EXPECT_CALL(favicon_service_, SetFavicons(_, kManifestURL, FAVICON, _));
1564 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL, _, _));
1565
1566 RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
1567 EXPECT_THAT(favicon_service_.fake()->db_requests(),
1568 ElementsAre(kPageURL, kManifestURL));
1569 EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL16x16));
1570 }
1571
1572 // Test that the manifest and icon are redownloaded if the icon cached for the
1573 // page URL expired.
1574 TEST_F(FaviconHandlerManifestsEnabledTest, GetFaviconFromExpiredManifest) {
1575 const GURL kManifestURL("http://www.google.com/manifest.json");
1576 const std::vector<favicon::FaviconURL> kManifestIcons = {
1577 FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
1578 };
1579
1580 favicon_service_.fake()->Store(kPageURL, kManifestURL,
1581 CreateRawBitmapResult(kManifestURL, FAVICON,
1582 /*expired=*/true));
1583 delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
1584
1585 // The third notification is unnecessary, but allows simplifying the code.
1586 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL, _, _)).Times(3);
1587 EXPECT_CALL(favicon_service_, SetFavicons(_, kManifestURL, _, _));
1588
1589 RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
1590 EXPECT_THAT(favicon_service_.fake()->db_requests(),
1591 ElementsAre(kPageURL, kManifestURL));
1592 EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL64x64));
1593 }
1594
1595 // Test that the manifest and icon are redownloaded if the icon cached for the
1596 // manifest URL expired, which was observed during a visit to a different page
1597 // URL.
1598 TEST_F(FaviconHandlerManifestsEnabledTest,
1599 GetFaviconFromExpiredManifestLinkedFromOtherPage) {
1600 const GURL kSomePreviousPageURL("https://www.google.com/previous");
1601 const GURL kManifestURL("http://www.google.com/manifest.json");
1602 const std::vector<favicon::FaviconURL> kManifestIcons = {
1603 FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
1604 };
1605
1606 favicon_service_.fake()->Store(kSomePreviousPageURL, kManifestURL,
1607 CreateRawBitmapResult(kManifestURL, FAVICON,
1608 /*expired=*/true));
1609 delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
1610
1611 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL, _, _)).Times(2);
1612 EXPECT_CALL(favicon_service_, SetFavicons(_, kManifestURL, _, _));
1613
1614 RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
1615 EXPECT_THAT(favicon_service_.fake()->db_requests(),
1616 ElementsAre(kPageURL, kManifestURL));
1617 EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL64x64));
1618 }
1619
1620 // Test that a favicon corresponding to a web manifest is reported when:
1621 // - There is data in the database for neither the page URL nor the manifest
1622 // URL.
1623 // - There is data in the database for the icon URL listed in the manifest.
1624 TEST_F(FaviconHandlerManifestsEnabledTest,
1625 GetFaviconFromUnknownManifestButKnownIcon) {
1626 const GURL kSomePreviousPageURL("https://www.google.com/previous");
1627 const GURL kManifestURL("http://www.google.com/manifest.json");
1628 const std::vector<favicon::FaviconURL> kManifestIcons = {
1629 FaviconURL(kIconURL16x16, FAVICON, kEmptySizes),
1630 };
1631
1632 favicon_service_.fake()->Store(kSomePreviousPageURL, kIconURL16x16,
1633 CreateRawBitmapResult(kIconURL16x16));
1634 delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
1635
1636 EXPECT_CALL(favicon_service_, SetFavicons(_, kManifestURL, FAVICON, _));
1637 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL, _, _));
1638
1639 RunHandlerWithSimpleFaviconCandidates(URLVector(), kManifestURL);
1640 EXPECT_THAT(favicon_service_.fake()->db_requests(),
1641 ElementsAre(kPageURL, kManifestURL));
1642 // In the current implementation, the icon is downloaded although it's in the
1643 // database. This is because the icon has been cached earlier using the icon
1644 // URL instead of the manifest's URL.
1645 EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL16x16));
1646 }
1647
1648 // Test that attempting to download a manifest that returns a 404 gets
1649 // blacklisted via UnableToDownloadFavicon() AND that the regular favicon is
1650 // selected as fallback.
1651 TEST_F(FaviconHandlerManifestsEnabledTest, UnknownManifestReturning404) {
1652 const GURL kManifestURL("http://www.google.com/manifest.json");
1653
1654 EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(kManifestURL));
1655 EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL12x12, FAVICON, _));
1656
1657 RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
1658 EXPECT_THAT(favicon_service_.fake()->db_requests(),
1659 ElementsAre(kPageURL, kManifestURL, kIconURL12x12));
1660 EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL12x12));
1661 }
1662
1663 // Test that attempting to download a manifest that returns a 503 does NOT get
1664 // blacklisted via UnableToDownloadFavicon() AND that the regular favicon is
1665 // selected as fallback.
1666 TEST_F(FaviconHandlerManifestsEnabledTest, UnknownManifestReturning503) {
1667 const GURL kManifestURL("http://www.google.com/manifest.json");
1668
1669 delegate_.fake_manifest_downloader().AddError(kManifestURL, 503);
1670
1671 EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(0);
1672
1673 RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
1674 }
1675
1676 // Test that a manifest that was previously blacklisted via
1677 // UnableToDownloadFavicon() is ignored and that the regular favicon is selected
1678 // as fallback.
1679 TEST_F(FaviconHandlerManifestsEnabledTest, IgnoreManifestWithPrior404) {
1680 const GURL kManifestURL("http://www.google.com/manifest.json");
1681
1682 ON_CALL(favicon_service_, WasUnableToDownloadFavicon(kManifestURL))
1683 .WillByDefault(Return(true));
1684
1685 EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL12x12, FAVICON, _));
1686
1687 RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
1688 EXPECT_THAT(favicon_service_.fake()->db_requests(),
1689 ElementsAre(kPageURL, kIconURL12x12));
1690 EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL12x12));
1691 }
1692
1693 // Test that the regular favicon is selected when:
1694 // - The page links to a Web Manifest.
1695 // - The Web Manifest does not contain any icon URLs (it is not a 404).
1696 // - The page has an icon URL provided via a <link rel="icon"> tag.
1697 // - The database does not know about the page URL, manifest URL or icon URL.
1698 TEST_F(FaviconHandlerManifestsEnabledTest, UnknownManifestWithoutIcons) {
1699 const GURL kManifestURL("http://www.google.com/manifest.json");
1700
1701 delegate_.fake_manifest_downloader().Add(kManifestURL,
1702 std::vector<favicon::FaviconURL>());
1703
1704 // UnableToDownloadFavicon() is expected to prevent repeated downloads of the
1705 // same manifest (which is not otherwise cached, since it doesn't contain
1706 // icons).
1707 EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(kManifestURL));
1708 EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL12x12, FAVICON, _));
1709
1710 RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
1711 EXPECT_THAT(favicon_service_.fake()->db_requests(),
1712 ElementsAre(kPageURL, kManifestURL, kIconURL12x12));
1713 EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL12x12));
1714 }
1715
1716 // Test that the regular favicon is selected when:
1717 // - The page links to a Web Manifest.
1718 // - The Web Manifest does not contain any icon URLs (it is not a 404).
1719 // - The page has an icon URL provided via a <link rel="icon"> tag.
1720 // - The database does not know about the page URL.
1721 // - The database does not know about the manifest URL.
1722 // - The database knows about the icon URL.
1723 TEST_F(FaviconHandlerManifestsEnabledTest,
1724 UnknownManifestWithoutIconsAndKnownRegularIcons) {
1725 const GURL kSomePreviousPageURL("https://www.google.com/previous");
1726 const GURL kManifestURL("http://www.google.com/manifest.json");
1727
1728 delegate_.fake_manifest_downloader().Add(kManifestURL,
1729 std::vector<favicon::FaviconURL>());
1730 favicon_service_.fake()->Store(kSomePreviousPageURL, kIconURL12x12,
1731 CreateRawBitmapResult(kIconURL12x12));
1732
1733 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0);
1734
1735 // UnableToDownloadFavicon() is expected to prevent repeated downloads of the
1736 // same manifest (which is not otherwise cached, since it doesn't contain
1737 // icons).
1738 EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(kManifestURL));
1739 EXPECT_CALL(favicon_service_,
1740 UpdateFaviconMappingsAndFetch(_, kManifestURL, _, _, _, _));
1741 EXPECT_CALL(favicon_service_,
1742 UpdateFaviconMappingsAndFetch(_, kIconURL12x12, _, _, _, _));
1743 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL12x12, _, _));
1744
1745 RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
1746 EXPECT_THAT(favicon_service_.fake()->db_requests(),
1747 ElementsAre(kPageURL, kManifestURL, kIconURL12x12));
1748 EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL));
1749 }
1750
1751 // Test that Delegate::OnFaviconUpdated() is called if a page uses Javascript to
1752 // modify the page's <link rel="manifest"> tag to point to a different manifest.
1753 TEST_F(FaviconHandlerManifestsEnabledTest, ManifestUpdateViaJavascript) {
1754 const GURL kManifestURL1("http://www.google.com/manifest1.json");
1755 const GURL kManifestURL2("http://www.google.com/manifest2.json");
1756 const std::vector<favicon::FaviconURL> kManifestIcons1 = {
1757 FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
1758 };
1759 const std::vector<favicon::FaviconURL> kManifestIcons2 = {
1760 FaviconURL(kIconURL10x10, FAVICON, kEmptySizes),
1761 };
1762
1763 delegate_.fake_manifest_downloader().Add(kManifestURL1, kManifestIcons1);
1764 delegate_.fake_manifest_downloader().Add(kManifestURL2, kManifestIcons2);
1765
1766 std::unique_ptr<FaviconHandler> handler =
1767 RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL1);
1768 ASSERT_THAT(favicon_service_.fake()->db_requests(),
1769 ElementsAre(kPageURL, kManifestURL1));
1770 EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL1, kIconURL64x64));
1771 ASSERT_TRUE(VerifyAndClearExpectations());
1772
1773 // Simulate the page changing it's manifest URL via Javascript.
1774 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL2, _, _));
1775 handler->OnUpdateCandidates(kPageURL,
1776 {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)},
1777 kManifestURL2);
1778 base::RunLoop().RunUntilIdle();
1779 ASSERT_THAT(favicon_service_.fake()->db_requests(),
1780 ElementsAre(kManifestURL2));
1781 EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL2, kIconURL10x10));
1782 }
1783
1784 // Test that Delegate::OnFaviconUpdated() is called if a page uses Javascript to
1785 // remove the page's <link rel="manifest"> tag (i.e. no web manifest) WHILE a
1786 // lookup to the history database is ongoing for the manifest URL.
1787 TEST_F(FaviconHandlerManifestsEnabledTest,
1788 RemoveManifestViaJavascriptWhileHistoryQuery) {
1789 const GURL kManifestURL("http://www.google.com/manifest.json");
1790 const std::vector<favicon::FaviconURL> kManifestIcons = {
1791 FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
1792 };
1793
1794 delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
1795 // Defer the database lookup completion such that RunUntilIdle() doesn't
1796 // complete it.
1797 favicon_service_.fake()->SetRunCallbackManuallyForUrl(kManifestURL);
1798
1799 std::unique_ptr<FaviconHandler> handler =
1800 RunHandlerWithSimpleFaviconCandidates({kIconURL12x12}, kManifestURL);
1801 ASSERT_THAT(favicon_service_.fake()->db_requests(),
1802 ElementsAre(kPageURL, kManifestURL));
1803 // Database lookup for |kManifestURL1| is ongoing.
1804 ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
1805
1806 // Simulate the page changing it's manifest URL to empty via Javascript.
1807 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL12x12, _, _));
1808 handler->OnUpdateCandidates(kPageURL,
1809 {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)},
1810 base::nullopt);
1811 // Complete the lookup.
1812 EXPECT_TRUE(favicon_service_.fake()->RunCallbackManually());
1813 base::RunLoop().RunUntilIdle();
1814 ASSERT_THAT(favicon_service_.fake()->db_requests(),
1815 ElementsAre(kPageURL, kManifestURL, kIconURL12x12));
1816 EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL12x12));
1817 }
1818
1819 // Test that Delegate::OnFaviconUpdated() is called a page without manifest uses
1820 // Javascript to add a <link rel="manifest"> tag (i.e. a new web manifest) WHILE
1821 // a lookup to the history database is ongoing for the icon URL.
1822 TEST_F(FaviconHandlerManifestsEnabledTest,
1823 AddManifestViaJavascriptWhileHistoryQuery) {
1824 const GURL kManifestURL("http://www.google.com/manifest.json");
1825 const std::vector<favicon::FaviconURL> kManifestIcons = {
1826 FaviconURL(kIconURL64x64, FAVICON, kEmptySizes),
1827 };
1828
1829 delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons);
1830 // Defer the database lookup completion such that RunUntilIdle() doesn't
1831 // complete it.
1832 favicon_service_.fake()->SetRunCallbackManuallyForUrl(kIconURL12x12);
1833
1834 std::unique_ptr<FaviconHandler> handler =
1835 RunHandlerWithSimpleFaviconCandidates({kIconURL12x12});
1836 ASSERT_THAT(favicon_service_.fake()->db_requests(),
1837 ElementsAre(kPageURL, kIconURL12x12));
1838 // Database lookup for |kIconURL12x12| is ongoing.
1839 ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback());
1840
1841 // Simulate the page changing it's manifest URL to |kManifestURL| via
1842 // Javascript.
1843 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kManifestURL, _, _));
1844 handler->OnUpdateCandidates(kPageURL,
1845 {FaviconURL(kIconURL12x12, FAVICON, kEmptySizes)},
1846 kManifestURL);
1847 // Complete the lookup.
1848 EXPECT_TRUE(favicon_service_.fake()->RunCallbackManually());
1849 base::RunLoop().RunUntilIdle();
1850 ASSERT_THAT(favicon_service_.fake()->db_requests(),
1851 ElementsAre(kPageURL, kIconURL12x12, kManifestURL));
1852 EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL64x64));
1853 }
1854
1373 } // namespace 1855 } // namespace
1374 } // namespace favicon 1856 } // namespace favicon
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698