OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |