Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / components / favicon / core / favicon_handler_unittest.cc
blob598895bfb17133a4707dd0963ebecbd6e094f867
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
3 // found in the LICENSE file.
5 #include "components/favicon/core/favicon_handler.h"
7 #include<set>
8 #include<vector>
10 #include "base/memory/scoped_ptr.h"
11 #include "components/favicon/core/favicon_driver.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/skia/include/core/SkBitmap.h"
14 #include "ui/base/layout.h"
15 #include "ui/gfx/codec/png_codec.h"
16 #include "ui/gfx/favicon_size.h"
17 #include "ui/gfx/image/image.h"
19 namespace favicon {
20 namespace {
22 // Fill the given bmp with valid png data.
23 void FillDataToBitmap(int w, int h, SkBitmap* bmp) {
24 bmp->allocN32Pixels(w, h);
26 unsigned char* src_data =
27 reinterpret_cast<unsigned char*>(bmp->getAddr32(0, 0));
28 for (int i = 0; i < w * h; i++) {
29 src_data[i * 4 + 0] = static_cast<unsigned char>(i % 255);
30 src_data[i * 4 + 1] = static_cast<unsigned char>(i % 255);
31 src_data[i * 4 + 2] = static_cast<unsigned char>(i % 255);
32 src_data[i * 4 + 3] = static_cast<unsigned char>(i % 255);
36 // Fill the given data buffer with valid png data.
37 void FillBitmap(int w, int h, std::vector<unsigned char>* output) {
38 SkBitmap bitmap;
39 FillDataToBitmap(w, h, &bitmap);
40 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, output);
43 void SetFaviconRawBitmapResult(
44 const GURL& icon_url,
45 favicon_base::IconType icon_type,
46 bool expired,
47 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) {
48 scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes());
49 FillBitmap(gfx::kFaviconSize, gfx::kFaviconSize, &data->data());
50 favicon_base::FaviconRawBitmapResult bitmap_result;
51 bitmap_result.expired = expired;
52 bitmap_result.bitmap_data = data;
53 // Use a pixel size other than (0,0) as (0,0) has a special meaning.
54 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize);
55 bitmap_result.icon_type = icon_type;
56 bitmap_result.icon_url = icon_url;
58 favicon_bitmap_results->push_back(bitmap_result);
61 void SetFaviconRawBitmapResult(
62 const GURL& icon_url,
63 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) {
64 SetFaviconRawBitmapResult(icon_url,
65 favicon_base::FAVICON,
66 false /* expired */,
67 favicon_bitmap_results);
70 // This class is used to save the download request for verifying with test case.
71 // It also will be used to invoke the onDidDownload callback.
72 class DownloadHandler {
73 public:
74 explicit DownloadHandler(FaviconHandler* favicon_handler)
75 : favicon_handler_(favicon_handler), callback_invoked_(false) {}
77 ~DownloadHandler() {}
79 void Reset() {
80 download_.reset();
81 callback_invoked_ = false;
82 // Does not affect |should_fail_download_icon_urls_| and
83 // |failed_download_icon_urls_|.
86 // Make downloads for any of |icon_urls| fail.
87 void FailDownloadForIconURLs(const std::set<GURL>& icon_urls) {
88 should_fail_download_icon_urls_ = icon_urls;
91 // Returns whether a download for |icon_url| did fail.
92 bool DidFailDownloadForIconURL(const GURL& icon_url) const {
93 return failed_download_icon_urls_.count(icon_url);
96 void AddDownload(
97 int download_id,
98 const GURL& image_url,
99 const std::vector<int>& image_sizes,
100 int max_image_size) {
101 download_.reset(new Download(
102 download_id, image_url, image_sizes, max_image_size));
105 void InvokeCallback();
107 bool HasDownload() const { return download_.get(); }
108 const GURL& GetImageUrl() const { return download_->image_url; }
109 void SetImageSizes(const std::vector<int>& sizes) {
110 download_->image_sizes = sizes; }
112 private:
113 struct Download {
114 Download(int id,
115 GURL url,
116 const std::vector<int>& sizes,
117 int max_size)
118 : download_id(id),
119 image_url(url),
120 image_sizes(sizes),
121 max_image_size(max_size) {}
122 ~Download() {}
123 int download_id;
124 GURL image_url;
125 std::vector<int> image_sizes;
126 int max_image_size;
129 FaviconHandler* favicon_handler_;
130 scoped_ptr<Download> download_;
131 bool callback_invoked_;
133 // The icon URLs for which the download should fail.
134 std::set<GURL> should_fail_download_icon_urls_;
136 // The icon URLs for which the download did fail. This should be a subset of
137 // |should_fail_download_icon_urls_|.
138 std::set<GURL> failed_download_icon_urls_;
140 DISALLOW_COPY_AND_ASSIGN(DownloadHandler);
143 // This class is used to save the history request for verifying with test case.
144 // It also will be used to simulate the history response.
145 class HistoryRequestHandler {
146 public:
147 HistoryRequestHandler(const GURL& page_url,
148 const GURL& icon_url,
149 int icon_type,
150 const favicon_base::FaviconResultsCallback& callback)
151 : page_url_(page_url),
152 icon_url_(icon_url),
153 icon_type_(icon_type),
154 callback_(callback) {
157 HistoryRequestHandler(const GURL& page_url,
158 const GURL& icon_url,
159 int icon_type,
160 const std::vector<unsigned char>& bitmap_data,
161 const gfx::Size& size)
162 : page_url_(page_url),
163 icon_url_(icon_url),
164 icon_type_(icon_type),
165 bitmap_data_(bitmap_data),
166 size_(size) {
169 ~HistoryRequestHandler() {}
170 void InvokeCallback();
172 const GURL page_url_;
173 const GURL icon_url_;
174 const int icon_type_;
175 const std::vector<unsigned char> bitmap_data_;
176 const gfx::Size size_;
177 std::vector<favicon_base::FaviconRawBitmapResult> history_results_;
178 favicon_base::FaviconResultsCallback callback_;
180 private:
181 DISALLOW_COPY_AND_ASSIGN(HistoryRequestHandler);
184 } // namespace
186 class TestFaviconDriver : public FaviconDriver {
187 public:
188 TestFaviconDriver()
189 : favicon_validity_(false),
190 num_active_favicon_(0),
191 num_favicon_available_(0),
192 update_active_favicon_(false) {}
194 ~TestFaviconDriver() override {}
196 // FaviconDriver implementation.
197 void FetchFavicon(const GURL& url) override {
198 ADD_FAILURE() << "TestFaviconDriver::FetchFavicon() "
199 << "should never be called in tests.";
202 void SaveFavicon() override {
203 ADD_FAILURE() << "TestFaviconDriver::SaveFavicon() "
204 << "should never be called in tests.";
207 gfx::Image GetFavicon() const override {
208 ADD_FAILURE() << "TestFaviconDriver::GetFavicon() "
209 << "should never be called in tests.";
210 return gfx::Image();
213 bool FaviconIsValid() const override {
214 ADD_FAILURE() << "TestFaviconDriver::FaviconIsValid() "
215 << "should never be called in tests.";
216 return false;
219 bool HasPendingTasksForTest() override {
220 ADD_FAILURE() << "TestFaviconDriver::HasPendingTasksForTest() "
221 << "should never be called in tests.";
222 return false;
225 int StartDownload(const GURL& url, int max_bitmap_size) override {
226 ADD_FAILURE() << "TestFaviconDriver::StartDownload() "
227 << "should never be called in tests.";
228 return -1;
231 bool IsOffTheRecord() override { return false; }
233 bool IsBookmarked(const GURL& url) override { return false; }
235 GURL GetActiveURL() override { return url_; }
237 base::string16 GetActiveTitle() override { return base::string16(); }
239 bool GetActiveFaviconValidity() override { return favicon_validity_; }
241 void SetActiveFaviconValidity(bool favicon_validity) override {
242 favicon_validity_ = favicon_validity;
245 GURL GetActiveFaviconURL() override { return favicon_url_; }
247 void SetActiveFaviconURL(const GURL& favicon_url) override {
248 favicon_url_ = favicon_url;
251 gfx::Image GetActiveFaviconImage() override { return image_; }
253 void SetActiveFaviconImage(const gfx::Image& image) override {
254 image_ = image;
257 void OnFaviconAvailable(const gfx::Image& image,
258 const GURL& icon_url,
259 bool update_active_favicon) override {
260 ++num_favicon_available_;
261 available_image_ = image;
262 available_icon_url_ = icon_url;
263 update_active_favicon_ = update_active_favicon;
264 if (!update_active_favicon)
265 return;
267 ++num_active_favicon_;
268 SetActiveFaviconURL(icon_url);
269 SetActiveFaviconValidity(true);
270 SetActiveFaviconImage(image);
273 size_t num_active_favicon() const { return num_active_favicon_; }
274 size_t num_favicon_available() const { return num_favicon_available_; }
275 void ResetNumActiveFavicon() { num_active_favicon_ = 0; }
276 void ResetNumFaviconAvailable() { num_favicon_available_ = 0; }
278 void SetActiveURL(GURL url) { url_ = url; }
280 const gfx::Image available_favicon() { return available_image_; }
282 const GURL available_icon_url() { return available_icon_url_; }
284 bool update_active_favicon() { return update_active_favicon_; }
286 private:
287 GURL favicon_url_;
288 GURL url_;
289 gfx::Image image_;
290 bool favicon_validity_;
292 // The number of times that NotifyFaviconAvailable() has been called with
293 // |is_active_favicon| is true.
294 size_t num_active_favicon_;
295 // The number of times that NotifyFaviconAvailable() has been called.
296 size_t num_favicon_available_;
297 gfx::Image available_image_;
298 GURL available_icon_url_;
299 bool update_active_favicon_;
301 DISALLOW_COPY_AND_ASSIGN(TestFaviconDriver);
304 // This class is used to catch the FaviconHandler's download and history
305 // request, and also provide the methods to access the FaviconHandler
306 // internals.
307 class TestFaviconHandler : public FaviconHandler {
308 public:
309 static int GetMaximalIconSize(favicon_base::IconType icon_type) {
310 return FaviconHandler::GetMaximalIconSize(icon_type);
313 TestFaviconHandler(const GURL& page_url,
314 TestFaviconDriver* driver,
315 Type type,
316 bool download_largest_icon)
317 : FaviconHandler(nullptr, driver, type, download_largest_icon),
318 download_id_(0) {
319 driver->SetActiveURL(page_url);
320 download_handler_.reset(new DownloadHandler(this));
323 ~TestFaviconHandler() override {}
325 HistoryRequestHandler* history_handler() {
326 return history_handler_.get();
329 // This method will take the ownership of the given handler.
330 void set_history_handler(HistoryRequestHandler* handler) {
331 history_handler_.reset(handler);
334 DownloadHandler* download_handler() {
335 return download_handler_.get();
338 // Methods to access favicon internals.
339 const std::vector<FaviconURL>& urls() {
340 return image_urls_;
343 FaviconURL* current_candidate() {
344 return FaviconHandler::current_candidate();
347 const FaviconCandidate& best_favicon_candidate() {
348 return best_favicon_candidate_;
351 protected:
352 void UpdateFaviconMappingAndFetch(
353 const GURL& page_url,
354 const GURL& icon_url,
355 favicon_base::IconType icon_type,
356 const favicon_base::FaviconResultsCallback& callback,
357 base::CancelableTaskTracker* tracker) override {
358 history_handler_.reset(new HistoryRequestHandler(page_url, icon_url,
359 icon_type, callback));
362 void GetFaviconFromFaviconService(
363 const GURL& icon_url,
364 favicon_base::IconType icon_type,
365 const favicon_base::FaviconResultsCallback& callback,
366 base::CancelableTaskTracker* tracker) override {
367 history_handler_.reset(new HistoryRequestHandler(GURL(), icon_url,
368 icon_type, callback));
371 void GetFaviconForURLFromFaviconService(
372 const GURL& page_url,
373 int icon_types,
374 const favicon_base::FaviconResultsCallback& callback,
375 base::CancelableTaskTracker* tracker) override {
376 history_handler_.reset(new HistoryRequestHandler(page_url, GURL(),
377 icon_types, callback));
380 int DownloadFavicon(const GURL& image_url, int max_bitmap_size) override {
381 // Do not do a download if downloading |image_url| failed previously. This
382 // emulates the behavior of FaviconDriver::StartDownload()
383 if (download_handler_->DidFailDownloadForIconURL(image_url)) {
384 download_handler_->AddDownload(download_id_, image_url,
385 std::vector<int>(), 0);
386 return 0;
389 download_id_++;
390 std::vector<int> sizes;
391 sizes.push_back(0);
392 download_handler_->AddDownload(
393 download_id_, image_url, sizes, max_bitmap_size);
394 return download_id_;
397 void SetHistoryFavicons(const GURL& page_url,
398 const GURL& icon_url,
399 favicon_base::IconType icon_type,
400 const gfx::Image& image) override {
401 scoped_refptr<base::RefCountedMemory> bytes = image.As1xPNGBytes();
402 std::vector<unsigned char> bitmap_data(bytes->front(),
403 bytes->front() + bytes->size());
404 history_handler_.reset(new HistoryRequestHandler(
405 page_url, icon_url, icon_type, bitmap_data, image.Size()));
408 bool ShouldSaveFavicon(const GURL& url) override { return true; }
410 GURL page_url_;
412 private:
414 // The unique id of a download request. It will be returned to a
415 // FaviconHandler.
416 int download_id_;
418 scoped_ptr<DownloadHandler> download_handler_;
419 scoped_ptr<HistoryRequestHandler> history_handler_;
421 DISALLOW_COPY_AND_ASSIGN(TestFaviconHandler);
424 namespace {
426 void HistoryRequestHandler::InvokeCallback() {
427 if (!callback_.is_null()) {
428 callback_.Run(history_results_);
432 void DownloadHandler::InvokeCallback() {
433 if (callback_invoked_)
434 return;
436 std::vector<gfx::Size> original_bitmap_sizes;
437 std::vector<SkBitmap> bitmaps;
438 if (should_fail_download_icon_urls_.count(download_->image_url)) {
439 failed_download_icon_urls_.insert(download_->image_url);
440 } else {
441 for (std::vector<int>::const_iterator i = download_->image_sizes.begin();
442 i != download_->image_sizes.end(); ++i) {
443 int original_size = (*i > 0) ? *i : gfx::kFaviconSize;
444 int downloaded_size = original_size;
445 if (download_->max_image_size != 0 &&
446 downloaded_size > download_->max_image_size) {
447 downloaded_size = download_->max_image_size;
449 SkBitmap bitmap;
450 FillDataToBitmap(downloaded_size, downloaded_size, &bitmap);
451 bitmaps.push_back(bitmap);
452 original_bitmap_sizes.push_back(gfx::Size(original_size, original_size));
455 favicon_handler_->OnDidDownloadFavicon(download_->download_id,
456 download_->image_url, bitmaps,
457 original_bitmap_sizes);
458 callback_invoked_ = true;
461 class FaviconHandlerTest : public testing::Test {
462 public:
463 FaviconHandlerTest() {
466 ~FaviconHandlerTest() override {}
468 // Simulates requesting a favicon for |page_url| given:
469 // - We have not previously cached anything in history for |page_url| or for
470 // any of |candidates|.
471 // - The page provides favicons at |candidate_icons|.
472 // - The favicons at |candidate_icons| have edge pixel sizes of
473 // |candidate_icon_sizes|.
474 void DownloadTillDoneIgnoringHistory(
475 TestFaviconDriver* favicon_driver,
476 TestFaviconHandler* favicon_handler,
477 const GURL& page_url,
478 const std::vector<FaviconURL>& candidate_icons,
479 const int* candidate_icon_sizes) {
480 UpdateFaviconURL(
481 favicon_driver, favicon_handler, page_url, candidate_icons);
482 EXPECT_EQ(candidate_icons.size(), favicon_handler->image_urls().size());
484 DownloadHandler* download_handler = favicon_handler->download_handler();
485 for (size_t i = 0; i < candidate_icons.size(); ++i) {
486 favicon_handler->history_handler()->history_results_.clear();
487 favicon_handler->history_handler()->InvokeCallback();
488 ASSERT_TRUE(download_handler->HasDownload());
489 EXPECT_EQ(download_handler->GetImageUrl(),
490 candidate_icons[i].icon_url);
491 std::vector<int> sizes;
492 sizes.push_back(candidate_icon_sizes[i]);
493 download_handler->SetImageSizes(sizes);
494 download_handler->InvokeCallback();
496 download_handler->Reset();
498 if (favicon_driver->num_active_favicon())
499 return;
503 void UpdateFaviconURL(TestFaviconDriver* favicon_driver,
504 TestFaviconHandler* favicon_handler,
505 const GURL& page_url,
506 const std::vector<FaviconURL>& candidate_icons) {
507 favicon_driver->ResetNumActiveFavicon();
509 favicon_handler->FetchFavicon(page_url);
510 favicon_handler->history_handler()->InvokeCallback();
512 favicon_handler->OnUpdateFaviconURL(candidate_icons);
515 void SetUp() override {
516 // The score computed by SelectFaviconFrames() is dependent on the supported
517 // scale factors of the platform. It is used for determining the goodness of
518 // a downloaded bitmap in FaviconHandler::OnDidDownloadFavicon().
519 // Force the values of the scale factors so that the tests produce the same
520 // results on all platforms.
521 std::vector<ui::ScaleFactor> scale_factors;
522 scale_factors.push_back(ui::SCALE_FACTOR_100P);
523 scoped_set_supported_scale_factors_.reset(
524 new ui::test::ScopedSetSupportedScaleFactors(scale_factors));
525 testing::Test::SetUp();
528 private:
529 scoped_ptr<ui::test::ScopedSetSupportedScaleFactors>
530 scoped_set_supported_scale_factors_;
531 DISALLOW_COPY_AND_ASSIGN(FaviconHandlerTest);
534 TEST_F(FaviconHandlerTest, GetFaviconFromHistory) {
535 const GURL page_url("http://www.google.com");
536 const GURL icon_url("http://www.google.com/favicon");
538 TestFaviconDriver driver;
539 TestFaviconHandler helper(page_url, &driver, FaviconHandler::FAVICON, false);
541 helper.FetchFavicon(page_url);
542 HistoryRequestHandler* history_handler = helper.history_handler();
543 // Ensure the data given to history is correct.
544 ASSERT_TRUE(history_handler);
545 EXPECT_EQ(page_url, history_handler->page_url_);
546 EXPECT_EQ(GURL(), history_handler->icon_url_);
547 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
549 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
551 // Send history response.
552 history_handler->InvokeCallback();
553 // Verify FaviconHandler status
554 EXPECT_TRUE(driver.GetActiveFaviconValidity());
555 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
557 // Simulates update favicon url.
558 std::vector<FaviconURL> urls;
559 urls.push_back(
560 FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
561 helper.OnUpdateFaviconURL(urls);
563 // Verify FaviconHandler status
564 EXPECT_EQ(1U, helper.urls().size());
565 ASSERT_TRUE(helper.current_candidate());
566 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
567 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
569 // Favicon shouldn't request to download icon.
570 EXPECT_FALSE(helper.download_handler()->HasDownload());
573 TEST_F(FaviconHandlerTest, DownloadFavicon) {
574 const GURL page_url("http://www.google.com");
575 const GURL icon_url("http://www.google.com/favicon");
577 TestFaviconDriver driver;
578 TestFaviconHandler helper(page_url, &driver, FaviconHandler::FAVICON, false);
580 helper.FetchFavicon(page_url);
581 HistoryRequestHandler* history_handler = helper.history_handler();
582 // Ensure the data given to history is correct.
583 ASSERT_TRUE(history_handler);
584 EXPECT_EQ(page_url, history_handler->page_url_);
585 EXPECT_EQ(GURL(), history_handler->icon_url_);
586 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
588 // Set icon data expired
589 SetFaviconRawBitmapResult(icon_url,
590 favicon_base::FAVICON,
591 true /* expired */,
592 &history_handler->history_results_);
593 // Send history response.
594 history_handler->InvokeCallback();
595 // Verify FaviconHandler status
596 EXPECT_TRUE(driver.GetActiveFaviconValidity());
597 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
599 // Simulates update favicon url.
600 std::vector<FaviconURL> urls;
601 urls.push_back(
602 FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
603 helper.OnUpdateFaviconURL(urls);
605 // Verify FaviconHandler status
606 EXPECT_EQ(1U, helper.urls().size());
607 ASSERT_TRUE(helper.current_candidate());
608 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
609 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
611 // Favicon should request to download icon now.
612 DownloadHandler* download_handler = helper.download_handler();
613 EXPECT_TRUE(helper.download_handler()->HasDownload());
615 // Verify the download request.
616 EXPECT_EQ(icon_url, download_handler->GetImageUrl());
618 // Reset the history_handler to verify whether favicon is set.
619 helper.set_history_handler(nullptr);
621 // Smulates download done.
622 download_handler->InvokeCallback();
624 // New icon should be saved to history backend and navigation entry.
625 history_handler = helper.history_handler();
626 ASSERT_TRUE(history_handler);
627 EXPECT_EQ(icon_url, history_handler->icon_url_);
628 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
629 EXPECT_LT(0U, history_handler->bitmap_data_.size());
630 EXPECT_EQ(page_url, history_handler->page_url_);
632 // Verify NavigationEntry.
633 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
634 EXPECT_TRUE(driver.GetActiveFaviconValidity());
635 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
636 EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width());
639 TEST_F(FaviconHandlerTest, UpdateAndDownloadFavicon) {
640 const GURL page_url("http://www.google.com");
641 const GURL icon_url("http://www.google.com/favicon");
642 const GURL new_icon_url("http://www.google.com/new_favicon");
644 TestFaviconDriver driver;
645 TestFaviconHandler helper(page_url, &driver, FaviconHandler::FAVICON, false);
647 helper.FetchFavicon(page_url);
648 HistoryRequestHandler* history_handler = helper.history_handler();
649 // Ensure the data given to history is correct.
650 ASSERT_TRUE(history_handler);
651 EXPECT_EQ(page_url, history_handler->page_url_);
652 EXPECT_EQ(GURL(), history_handler->icon_url_);
653 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
655 // Set valid icon data.
656 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
658 // Send history response.
659 history_handler->InvokeCallback();
660 // Verify FaviconHandler status.
661 EXPECT_TRUE(driver.GetActiveFaviconValidity());
662 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
664 // Reset the history_handler to verify whether new icon is requested from
665 // history.
666 helper.set_history_handler(nullptr);
668 // Simulates update with the different favicon url.
669 std::vector<FaviconURL> urls;
670 urls.push_back(FaviconURL(
671 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
672 helper.OnUpdateFaviconURL(urls);
674 // Verify FaviconHandler status.
675 EXPECT_EQ(1U, helper.urls().size());
676 ASSERT_TRUE(helper.current_candidate());
677 ASSERT_EQ(new_icon_url, helper.current_candidate()->icon_url);
678 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
680 // Favicon should be requested from history.
681 history_handler = helper.history_handler();
682 ASSERT_TRUE(history_handler);
683 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
684 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
685 EXPECT_EQ(page_url, history_handler->page_url_);
687 // Simulate not find icon.
688 history_handler->history_results_.clear();
689 history_handler->InvokeCallback();
691 // Favicon should request to download icon now.
692 DownloadHandler* download_handler = helper.download_handler();
693 EXPECT_TRUE(helper.download_handler()->HasDownload());
695 // Verify the download request.
696 EXPECT_EQ(new_icon_url, download_handler->GetImageUrl());
698 // Reset the history_handler to verify whether favicon is set.
699 helper.set_history_handler(nullptr);
701 // Smulates download done.
702 download_handler->InvokeCallback();
704 // New icon should be saved to history backend and navigation entry.
705 history_handler = helper.history_handler();
706 ASSERT_TRUE(history_handler);
707 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
708 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
709 EXPECT_LT(0U, history_handler->bitmap_data_.size());
710 EXPECT_EQ(page_url, history_handler->page_url_);
712 // Verify NavigationEntry.
713 EXPECT_EQ(new_icon_url, driver.GetActiveFaviconURL());
714 EXPECT_TRUE(driver.GetActiveFaviconValidity());
715 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
716 EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width());
719 TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) {
720 const GURL page_url("http://www.google.com");
721 const GURL icon_url("http://www.google.com/favicon");
723 TestFaviconDriver driver;
724 TestFaviconHandler helper(page_url, &driver, FaviconHandler::FAVICON, false);
726 helper.FetchFavicon(page_url);
727 HistoryRequestHandler* history_handler = helper.history_handler();
728 // Ensure the data given to history is correct.
729 ASSERT_TRUE(history_handler);
730 EXPECT_EQ(page_url, history_handler->page_url_);
731 EXPECT_EQ(GURL(), history_handler->icon_url_);
732 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
734 // Set non empty but invalid data.
735 favicon_base::FaviconRawBitmapResult bitmap_result;
736 bitmap_result.expired = false;
737 // Empty bitmap data is invalid.
738 bitmap_result.bitmap_data = new base::RefCountedBytes();
739 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize);
740 bitmap_result.icon_type = favicon_base::FAVICON;
741 bitmap_result.icon_url = icon_url;
742 history_handler->history_results_.clear();
743 history_handler->history_results_.push_back(bitmap_result);
745 // Send history response.
746 history_handler->InvokeCallback();
747 // The NavigationEntry should not be set yet as the history data is invalid.
748 EXPECT_FALSE(driver.GetActiveFaviconValidity());
749 EXPECT_EQ(GURL(), driver.GetActiveFaviconURL());
751 // Reset the history_handler to verify whether new icon is requested from
752 // history.
753 helper.set_history_handler(nullptr);
755 // Simulates update with matching favicon URL.
756 std::vector<FaviconURL> urls;
757 urls.push_back(
758 FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
759 helper.OnUpdateFaviconURL(urls);
761 // A download for the favicon should be requested, and we should not do
762 // another history request.
763 DownloadHandler* download_handler = helper.download_handler();
764 EXPECT_TRUE(helper.download_handler()->HasDownload());
765 EXPECT_EQ(nullptr, helper.history_handler());
767 // Verify the download request.
768 EXPECT_EQ(icon_url, download_handler->GetImageUrl());
770 // Simulates download done.
771 download_handler->InvokeCallback();
773 // New icon should be saved to history backend and navigation entry.
774 history_handler = helper.history_handler();
775 ASSERT_TRUE(history_handler);
776 EXPECT_EQ(icon_url, history_handler->icon_url_);
777 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
778 EXPECT_LT(0U, history_handler->bitmap_data_.size());
779 EXPECT_EQ(page_url, history_handler->page_url_);
781 // Verify NavigationEntry.
782 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
783 EXPECT_TRUE(driver.GetActiveFaviconValidity());
784 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
785 EXPECT_EQ(gfx::kFaviconSize, driver.GetActiveFaviconImage().Width());
788 TEST_F(FaviconHandlerTest, UpdateFavicon) {
789 const GURL page_url("http://www.google.com");
790 const GURL icon_url("http://www.google.com/favicon");
791 const GURL new_icon_url("http://www.google.com/new_favicon");
793 TestFaviconDriver driver;
794 TestFaviconHandler helper(page_url, &driver, FaviconHandler::FAVICON, false);
796 helper.FetchFavicon(page_url);
797 HistoryRequestHandler* history_handler = helper.history_handler();
798 // Ensure the data given to history is correct.
799 ASSERT_TRUE(history_handler);
800 EXPECT_EQ(page_url, history_handler->page_url_);
801 EXPECT_EQ(GURL(), history_handler->icon_url_);
802 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
804 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
806 // Send history response.
807 history_handler->InvokeCallback();
808 // Verify FaviconHandler status.
809 EXPECT_TRUE(driver.GetActiveFaviconValidity());
810 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
812 // Reset the history_handler to verify whether new icon is requested from
813 // history.
814 helper.set_history_handler(nullptr);
816 // Simulates update with the different favicon url.
817 std::vector<FaviconURL> urls;
818 urls.push_back(FaviconURL(
819 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
820 helper.OnUpdateFaviconURL(urls);
822 // Verify FaviconHandler status.
823 EXPECT_EQ(1U, helper.urls().size());
824 ASSERT_TRUE(helper.current_candidate());
825 ASSERT_EQ(new_icon_url, helper.current_candidate()->icon_url);
826 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
828 // Favicon should be requested from history.
829 history_handler = helper.history_handler();
830 ASSERT_TRUE(history_handler);
831 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
832 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
833 EXPECT_EQ(page_url, history_handler->page_url_);
835 // Simulate find icon.
836 SetFaviconRawBitmapResult(new_icon_url, &history_handler->history_results_);
837 history_handler->InvokeCallback();
839 // Shouldn't request download favicon
840 EXPECT_FALSE(helper.download_handler()->HasDownload());
842 // Verify the favicon status.
843 EXPECT_EQ(new_icon_url, driver.GetActiveFaviconURL());
844 EXPECT_TRUE(driver.GetActiveFaviconValidity());
845 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
848 TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) {
849 const GURL page_url("http://www.google.com");
850 const GURL icon_url("http://www.google.com/favicon");
851 const GURL new_icon_url("http://www.google.com/new_favicon");
853 TestFaviconDriver driver;
854 TestFaviconHandler helper(page_url, &driver, FaviconHandler::TOUCH, false);
855 std::set<GURL> fail_downloads;
856 fail_downloads.insert(icon_url);
857 helper.download_handler()->FailDownloadForIconURLs(fail_downloads);
859 helper.FetchFavicon(page_url);
860 HistoryRequestHandler* history_handler = helper.history_handler();
861 // Ensure the data given to history is correct.
862 ASSERT_TRUE(history_handler);
863 EXPECT_EQ(page_url, history_handler->page_url_);
864 EXPECT_EQ(GURL(), history_handler->icon_url_);
865 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON,
866 history_handler->icon_type_);
868 // Icon not found.
869 history_handler->history_results_.clear();
870 // Send history response.
871 history_handler->InvokeCallback();
872 // Verify FaviconHandler status.
873 EXPECT_FALSE(driver.GetActiveFaviconValidity());
874 EXPECT_EQ(GURL(), driver.GetActiveFaviconURL());
876 // Reset the history_handler to verify whether new icon is requested from
877 // history.
878 helper.set_history_handler(nullptr);
880 // Simulates update with the different favicon url.
881 std::vector<FaviconURL> urls;
882 urls.push_back(FaviconURL(icon_url,
883 favicon_base::TOUCH_PRECOMPOSED_ICON,
884 std::vector<gfx::Size>()));
885 urls.push_back(FaviconURL(
886 new_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>()));
887 urls.push_back(FaviconURL(
888 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
889 helper.OnUpdateFaviconURL(urls);
891 // Verify FaviconHandler status.
892 EXPECT_EQ(2U, helper.urls().size());
893 ASSERT_TRUE(helper.current_candidate());
894 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
895 ASSERT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON,
896 helper.current_candidate()->icon_type);
898 // Favicon should be requested from history.
899 history_handler = helper.history_handler();
900 ASSERT_TRUE(history_handler);
901 EXPECT_EQ(icon_url, history_handler->icon_url_);
902 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON, history_handler->icon_type_);
903 EXPECT_EQ(page_url, history_handler->page_url_);
905 // Simulate not find icon.
906 history_handler->history_results_.clear();
907 history_handler->InvokeCallback();
909 // Should request download favicon.
910 DownloadHandler* download_handler = helper.download_handler();
911 EXPECT_TRUE(helper.download_handler()->HasDownload());
913 // Verify the download request.
914 EXPECT_EQ(icon_url, download_handler->GetImageUrl());
916 // Reset the history_handler to verify whether favicon is request from
917 // history.
918 helper.set_history_handler(nullptr);
919 download_handler->InvokeCallback();
921 // Left 1 url.
922 EXPECT_EQ(1U, helper.urls().size());
923 ASSERT_TRUE(helper.current_candidate());
924 EXPECT_EQ(new_icon_url, helper.current_candidate()->icon_url);
925 EXPECT_EQ(favicon_base::TOUCH_ICON, helper.current_candidate()->icon_type);
927 // Favicon should be requested from history.
928 history_handler = helper.history_handler();
929 ASSERT_TRUE(history_handler);
930 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
931 EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_);
932 EXPECT_EQ(page_url, history_handler->page_url_);
934 // Reset download handler
935 download_handler->Reset();
937 // Simulates getting a expired icon from history.
938 SetFaviconRawBitmapResult(new_icon_url,
939 favicon_base::TOUCH_ICON,
940 true /* expired */,
941 &history_handler->history_results_);
942 history_handler->InvokeCallback();
944 // Verify the download request.
945 EXPECT_TRUE(helper.download_handler()->HasDownload());
946 EXPECT_EQ(new_icon_url, download_handler->GetImageUrl());
948 helper.set_history_handler(nullptr);
950 // Simulates icon being downloaded.
951 download_handler->InvokeCallback();
953 // New icon should be saved to history backend.
954 history_handler = helper.history_handler();
955 ASSERT_TRUE(history_handler);
956 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
957 EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_);
958 EXPECT_LT(0U, history_handler->bitmap_data_.size());
959 EXPECT_EQ(page_url, history_handler->page_url_);
962 TEST_F(FaviconHandlerTest, UpdateDuringDownloading) {
963 const GURL page_url("http://www.google.com");
964 const GURL icon_url("http://www.google.com/favicon");
965 const GURL new_icon_url("http://www.google.com/new_favicon");
967 TestFaviconDriver driver;
968 TestFaviconHandler helper(page_url, &driver, FaviconHandler::TOUCH, false);
970 helper.FetchFavicon(page_url);
971 HistoryRequestHandler* history_handler = helper.history_handler();
972 // Ensure the data given to history is correct.
973 ASSERT_TRUE(history_handler);
974 EXPECT_EQ(page_url, history_handler->page_url_);
975 EXPECT_EQ(GURL(), history_handler->icon_url_);
976 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON,
977 history_handler->icon_type_);
979 // Icon not found.
980 history_handler->history_results_.clear();
981 // Send history response.
982 history_handler->InvokeCallback();
983 // Verify FaviconHandler status.
984 EXPECT_FALSE(driver.GetActiveFaviconValidity());
985 EXPECT_EQ(GURL(), driver.GetActiveFaviconURL());
987 // Reset the history_handler to verify whether new icon is requested from
988 // history.
989 helper.set_history_handler(nullptr);
991 // Simulates update with the different favicon url.
992 std::vector<FaviconURL> urls;
993 urls.push_back(FaviconURL(icon_url,
994 favicon_base::TOUCH_PRECOMPOSED_ICON,
995 std::vector<gfx::Size>()));
996 urls.push_back(FaviconURL(
997 new_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>()));
998 urls.push_back(FaviconURL(
999 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
1000 helper.OnUpdateFaviconURL(urls);
1002 // Verify FaviconHandler status.
1003 EXPECT_EQ(2U, helper.urls().size());
1004 ASSERT_TRUE(helper.current_candidate());
1005 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url);
1006 ASSERT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON,
1007 helper.current_candidate()->icon_type);
1009 // Favicon should be requested from history.
1010 history_handler = helper.history_handler();
1011 ASSERT_TRUE(history_handler);
1012 EXPECT_EQ(icon_url, history_handler->icon_url_);
1013 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON, history_handler->icon_type_);
1014 EXPECT_EQ(page_url, history_handler->page_url_);
1016 // Simulate not find icon.
1017 history_handler->history_results_.clear();
1018 history_handler->InvokeCallback();
1020 // Should request download favicon.
1021 DownloadHandler* download_handler = helper.download_handler();
1022 EXPECT_TRUE(helper.download_handler()->HasDownload());
1024 // Verify the download request.
1025 EXPECT_EQ(icon_url, download_handler->GetImageUrl());
1027 // Reset the history_handler to verify whether favicon is request from
1028 // history.
1029 helper.set_history_handler(nullptr);
1030 const GURL latest_icon_url("http://www.google.com/latest_favicon");
1031 std::vector<FaviconURL> latest_urls;
1032 latest_urls.push_back(FaviconURL(
1033 latest_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>()));
1034 helper.OnUpdateFaviconURL(latest_urls);
1036 EXPECT_EQ(1U, helper.urls().size());
1037 EXPECT_EQ(latest_icon_url, helper.current_candidate()->icon_url);
1038 EXPECT_EQ(favicon_base::TOUCH_ICON, helper.current_candidate()->icon_type);
1040 // Whether new icon is requested from history
1041 history_handler = helper.history_handler();
1042 ASSERT_TRUE(history_handler);
1043 EXPECT_EQ(latest_icon_url, history_handler->icon_url_);
1044 EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_);
1045 EXPECT_EQ(page_url, history_handler->page_url_);
1047 // Reset the history_handler to verify whether favicon is request from
1048 // history.
1049 // Save the callback for late use.
1050 favicon_base::FaviconResultsCallback callback = history_handler->callback_;
1051 helper.set_history_handler(nullptr);
1053 // Simulates download succeed.
1054 download_handler->InvokeCallback();
1055 // The downloaded icon should be thrown away as there is favicon update.
1056 EXPECT_FALSE(helper.history_handler());
1058 download_handler->Reset();
1060 // Simulates getting the icon from history.
1061 scoped_ptr<HistoryRequestHandler> handler;
1062 handler.reset(new HistoryRequestHandler(
1063 page_url, latest_icon_url, favicon_base::TOUCH_ICON, callback));
1064 SetFaviconRawBitmapResult(latest_icon_url,
1065 favicon_base::TOUCH_ICON,
1066 false /* expired */,
1067 &handler->history_results_);
1068 handler->InvokeCallback();
1070 // No download request.
1071 EXPECT_FALSE(download_handler->HasDownload());
1074 // Test the favicon which is selected when the web page provides several
1075 // favicons and none of the favicons are cached in history.
1076 // The goal of this test is to be more of an integration test than
1077 // SelectFaviconFramesTest.*.
1078 TEST_F(FaviconHandlerTest, MultipleFavicons) {
1079 const GURL kPageURL("http://www.google.com");
1080 const FaviconURL kSourceIconURLs[] = {
1081 FaviconURL(GURL("http://www.google.com/a"),
1082 favicon_base::FAVICON,
1083 std::vector<gfx::Size>()),
1084 FaviconURL(GURL("http://www.google.com/b"),
1085 favicon_base::FAVICON,
1086 std::vector<gfx::Size>()),
1087 FaviconURL(GURL("http://www.google.com/c"),
1088 favicon_base::FAVICON,
1089 std::vector<gfx::Size>()),
1090 FaviconURL(GURL("http://www.google.com/d"),
1091 favicon_base::FAVICON,
1092 std::vector<gfx::Size>()),
1093 FaviconURL(GURL("http://www.google.com/e"),
1094 favicon_base::FAVICON,
1095 std::vector<gfx::Size>())};
1097 // Set the supported scale factors to 1x and 2x. This affects the behavior of
1098 // SelectFaviconFrames().
1099 std::vector<ui::ScaleFactor> scale_factors;
1100 scale_factors.push_back(ui::SCALE_FACTOR_100P);
1101 scale_factors.push_back(ui::SCALE_FACTOR_200P);
1102 ui::test::ScopedSetSupportedScaleFactors scoped_supported(scale_factors);
1104 // 1) Test that if there are several single resolution favicons to choose from
1105 // that the largest exact match is chosen.
1106 TestFaviconDriver driver1;
1107 TestFaviconHandler handler1(kPageURL, &driver1, FaviconHandler::FAVICON,
1108 false);
1110 const int kSizes1[] = { 16, 24, 32, 48, 256 };
1111 std::vector<FaviconURL> urls1(kSourceIconURLs,
1112 kSourceIconURLs + arraysize(kSizes1));
1113 DownloadTillDoneIgnoringHistory(
1114 &driver1, &handler1, kPageURL, urls1, kSizes1);
1116 EXPECT_EQ(0u, handler1.image_urls().size());
1117 EXPECT_TRUE(driver1.GetActiveFaviconValidity());
1118 EXPECT_FALSE(driver1.GetActiveFaviconImage().IsEmpty());
1119 EXPECT_EQ(gfx::kFaviconSize, driver1.GetActiveFaviconImage().Width());
1121 size_t expected_index = 2u;
1122 EXPECT_EQ(32, kSizes1[expected_index]);
1123 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
1124 driver1.GetActiveFaviconURL());
1126 // 2) Test that if there are several single resolution favicons to choose
1127 // from, the exact match is preferred even if it results in upsampling.
1128 TestFaviconDriver driver2;
1129 TestFaviconHandler handler2(kPageURL, &driver2, FaviconHandler::FAVICON,
1130 false);
1132 const int kSizes2[] = { 16, 24, 48, 256 };
1133 std::vector<FaviconURL> urls2(kSourceIconURLs,
1134 kSourceIconURLs + arraysize(kSizes2));
1135 DownloadTillDoneIgnoringHistory(
1136 &driver2, &handler2, kPageURL, urls2, kSizes2);
1137 EXPECT_TRUE(driver2.GetActiveFaviconValidity());
1138 expected_index = 0u;
1139 EXPECT_EQ(16, kSizes2[expected_index]);
1140 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
1141 driver2.GetActiveFaviconURL());
1143 // 3) Test that favicons which need to be upsampled a little or downsampled
1144 // a little are preferred over huge favicons.
1145 TestFaviconDriver driver3;
1146 TestFaviconHandler handler3(kPageURL, &driver3, FaviconHandler::FAVICON,
1147 false);
1149 const int kSizes3[] = { 256, 48 };
1150 std::vector<FaviconURL> urls3(kSourceIconURLs,
1151 kSourceIconURLs + arraysize(kSizes3));
1152 DownloadTillDoneIgnoringHistory(
1153 &driver3, &handler3, kPageURL, urls3, kSizes3);
1154 EXPECT_TRUE(driver3.GetActiveFaviconValidity());
1155 expected_index = 1u;
1156 EXPECT_EQ(48, kSizes3[expected_index]);
1157 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
1158 driver3.GetActiveFaviconURL());
1160 TestFaviconDriver driver4;
1161 TestFaviconHandler handler4(kPageURL, &driver4, FaviconHandler::FAVICON,
1162 false);
1164 const int kSizes4[] = { 17, 256 };
1165 std::vector<FaviconURL> urls4(kSourceIconURLs,
1166 kSourceIconURLs + arraysize(kSizes4));
1167 DownloadTillDoneIgnoringHistory(
1168 &driver4, &handler4, kPageURL, urls4, kSizes4);
1169 EXPECT_TRUE(driver4.GetActiveFaviconValidity());
1170 expected_index = 0u;
1171 EXPECT_EQ(17, kSizes4[expected_index]);
1172 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url,
1173 driver4.GetActiveFaviconURL());
1176 // Test that the best favicon is selected when:
1177 // - The page provides several favicons.
1178 // - Downloading one of the page's icon URLs previously returned a 404.
1179 // - None of the favicons are cached in the Favicons database.
1180 TEST_F(FaviconHandlerTest, MultipleFavicons404) {
1181 const GURL kPageURL("http://www.google.com");
1182 const GURL k404IconURL("http://www.google.com/404.png");
1183 const FaviconURL k404FaviconURL(
1184 k404IconURL, favicon_base::FAVICON, std::vector<gfx::Size>());
1185 const FaviconURL kFaviconURLs[] = {
1186 FaviconURL(GURL("http://www.google.com/a"),
1187 favicon_base::FAVICON,
1188 std::vector<gfx::Size>()),
1189 k404FaviconURL,
1190 FaviconURL(GURL("http://www.google.com/c"),
1191 favicon_base::FAVICON,
1192 std::vector<gfx::Size>()),
1195 TestFaviconDriver driver;
1196 TestFaviconHandler handler(kPageURL, &driver, FaviconHandler::FAVICON, false);
1197 DownloadHandler* download_handler = handler.download_handler();
1199 std::set<GURL> k404URLs;
1200 k404URLs.insert(k404IconURL);
1201 download_handler->FailDownloadForIconURLs(k404URLs);
1203 // Make the initial download for |k404IconURL| fail.
1204 const int kSizes1[] = { 0 };
1205 std::vector<FaviconURL> urls1(1u, k404FaviconURL);
1206 DownloadTillDoneIgnoringHistory(
1207 &driver, &handler, kPageURL, urls1, kSizes1);
1208 EXPECT_TRUE(download_handler->DidFailDownloadForIconURL(k404IconURL));
1210 // Do a fetch now that the initial download for |k404IconURL| has failed. The
1211 // behavior is different because OnDidDownloadFavicon() is invoked
1212 // synchronously from DownloadFavicon().
1213 const int kSizes2[] = { 10, 0, 16 };
1214 std::vector<FaviconURL> urls2(kFaviconURLs,
1215 kFaviconURLs + arraysize(kFaviconURLs));
1216 DownloadTillDoneIgnoringHistory(
1217 &driver, &handler, kPageURL, urls2, kSizes2);
1219 EXPECT_EQ(0u, handler.image_urls().size());
1220 EXPECT_TRUE(driver.GetActiveFaviconValidity());
1221 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
1222 int expected_index = 2u;
1223 EXPECT_EQ(16, kSizes2[expected_index]);
1224 EXPECT_EQ(kFaviconURLs[expected_index].icon_url,
1225 driver.GetActiveFaviconURL());
1228 // Test that no favicon is selected when:
1229 // - The page provides several favicons.
1230 // - Downloading the page's icons has previously returned a 404.
1231 // - None of the favicons are cached in the Favicons database.
1232 TEST_F(FaviconHandlerTest, MultipleFaviconsAll404) {
1233 const GURL kPageURL("http://www.google.com");
1234 const GURL k404IconURL1("http://www.google.com/4041.png");
1235 const GURL k404IconURL2("http://www.google.com/4042.png");
1236 const FaviconURL kFaviconURLs[] = {
1237 FaviconURL(k404IconURL1,
1238 favicon_base::FAVICON,
1239 std::vector<gfx::Size>()),
1240 FaviconURL(k404IconURL2,
1241 favicon_base::FAVICON,
1242 std::vector<gfx::Size>()),
1245 TestFaviconDriver driver;
1246 TestFaviconHandler handler(kPageURL, &driver, FaviconHandler::FAVICON, false);
1247 DownloadHandler* download_handler = handler.download_handler();
1249 std::set<GURL> k404URLs;
1250 k404URLs.insert(k404IconURL1);
1251 k404URLs.insert(k404IconURL2);
1252 download_handler->FailDownloadForIconURLs(k404URLs);
1254 // Make the initial downloads for |kFaviconURLs| fail.
1255 for (const FaviconURL& favicon_url : kFaviconURLs) {
1256 const int kSizes[] = { 0 };
1257 std::vector<FaviconURL> urls(1u, favicon_url);
1258 DownloadTillDoneIgnoringHistory(&driver, &handler, kPageURL, urls, kSizes);
1260 EXPECT_TRUE(download_handler->DidFailDownloadForIconURL(k404IconURL1));
1261 EXPECT_TRUE(download_handler->DidFailDownloadForIconURL(k404IconURL2));
1263 // Do a fetch now that the initial downloads for |kFaviconURLs| have failed.
1264 // The behavior is different because OnDidDownloadFavicon() is invoked
1265 // synchronously from DownloadFavicon().
1266 const int kSizes[] = { 0, 0 };
1267 std::vector<FaviconURL> urls(kFaviconURLs,
1268 kFaviconURLs + arraysize(kFaviconURLs));
1269 DownloadTillDoneIgnoringHistory(&driver, &handler, kPageURL, urls, kSizes);
1271 EXPECT_EQ(0u, handler.image_urls().size());
1272 EXPECT_FALSE(driver.GetActiveFaviconValidity());
1273 EXPECT_TRUE(driver.GetActiveFaviconImage().IsEmpty());
1276 // Test that no favicon is selected when the page's only icon uses an invalid
1277 // URL syntax.
1278 TEST_F(FaviconHandlerTest, FaviconInvalidURL) {
1279 const GURL kPageURL("http://www.google.com");
1280 const GURL kInvalidFormatURL("invalid");
1281 ASSERT_TRUE(kInvalidFormatURL.is_empty());
1283 FaviconURL favicon_url(kInvalidFormatURL, favicon_base::FAVICON,
1284 std::vector<gfx::Size>());
1286 TestFaviconDriver driver;
1287 TestFaviconHandler handler(kPageURL, &driver, FaviconHandler::FAVICON, false);
1288 UpdateFaviconURL(&driver, &handler, kPageURL,
1289 std::vector<FaviconURL>(1u, favicon_url));
1290 EXPECT_EQ(0u, handler.image_urls().size());
1293 TEST_F(FaviconHandlerTest, TestSortFavicon) {
1294 const GURL kPageURL("http://www.google.com");
1295 std::vector<gfx::Size> icon1;
1296 icon1.push_back(gfx::Size(1024, 1024));
1297 icon1.push_back(gfx::Size(512, 512));
1299 std::vector<gfx::Size> icon2;
1300 icon2.push_back(gfx::Size(15, 15));
1301 icon2.push_back(gfx::Size(16, 16));
1303 std::vector<gfx::Size> icon3;
1304 icon3.push_back(gfx::Size(16, 16));
1305 icon3.push_back(gfx::Size(14, 14));
1307 const FaviconURL kSourceIconURLs[] = {
1308 FaviconURL(GURL("http://www.google.com/a"), favicon_base::FAVICON, icon1),
1309 FaviconURL(GURL("http://www.google.com/b"), favicon_base::FAVICON, icon2),
1310 FaviconURL(GURL("http://www.google.com/c"), favicon_base::FAVICON, icon3),
1311 FaviconURL(GURL("http://www.google.com/d"),
1312 favicon_base::FAVICON,
1313 std::vector<gfx::Size>()),
1314 FaviconURL(GURL("http://www.google.com/e"),
1315 favicon_base::FAVICON,
1316 std::vector<gfx::Size>())};
1318 TestFaviconDriver driver1;
1319 TestFaviconHandler handler1(kPageURL, &driver1, FaviconHandler::FAVICON,
1320 true);
1321 std::vector<FaviconURL> urls1(kSourceIconURLs,
1322 kSourceIconURLs + arraysize(kSourceIconURLs));
1323 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1325 struct ExpectedResult {
1326 // The favicon's index in kSourceIconURLs.
1327 size_t favicon_index;
1328 // Width of largest bitmap.
1329 int width;
1330 } results[] = {
1331 // First is icon1, though its size larger than maximal.
1332 {0, 1024},
1333 // Second is icon2
1334 // The 16x16 is largest.
1335 {1, 16},
1336 // Third is icon3 though it has same size as icon2.
1337 // The 16x16 is largest.
1338 {2, 16},
1339 // The rest of bitmaps come in order, there is no sizes attribute.
1340 {3, -1},
1341 {4, -1},
1343 const std::vector<FaviconURL>& icons = handler1.image_urls();
1344 ASSERT_EQ(5u, icons.size());
1345 for (size_t i = 0; i < icons.size(); ++i) {
1346 EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url,
1347 icons[i].icon_url);
1348 if (results[i].width != -1)
1349 EXPECT_EQ(results[i].width, icons[i].icon_sizes[0].width());
1353 TEST_F(FaviconHandlerTest, TestDownloadLargestFavicon) {
1354 const GURL kPageURL("http://www.google.com");
1355 std::vector<gfx::Size> icon1;
1356 icon1.push_back(gfx::Size(1024, 1024));
1357 icon1.push_back(gfx::Size(512, 512));
1359 std::vector<gfx::Size> icon2;
1360 icon2.push_back(gfx::Size(15, 15));
1361 icon2.push_back(gfx::Size(14, 14));
1363 std::vector<gfx::Size> icon3;
1364 icon3.push_back(gfx::Size(16, 16));
1365 icon3.push_back(gfx::Size(512, 512));
1367 const FaviconURL kSourceIconURLs[] = {
1368 FaviconURL(
1369 GURL("http://www.google.com/a"), favicon_base::FAVICON, icon1),
1370 FaviconURL(
1371 GURL("http://www.google.com/b"), favicon_base::FAVICON, icon2),
1372 FaviconURL(
1373 GURL("http://www.google.com/c"), favicon_base::FAVICON, icon3),
1374 FaviconURL(GURL("http://www.google.com/d"),
1375 favicon_base::FAVICON,
1376 std::vector<gfx::Size>()),
1377 FaviconURL(GURL("http://www.google.com/e"),
1378 favicon_base::FAVICON,
1379 std::vector<gfx::Size>())};
1381 TestFaviconDriver driver1;
1382 TestFaviconHandler handler1(kPageURL, &driver1, FaviconHandler::FAVICON,
1383 true);
1385 std::set<GURL> fail_icon_urls;
1386 for (size_t i = 0; i < arraysize(kSourceIconURLs); ++i) {
1387 fail_icon_urls.insert(kSourceIconURLs[i].icon_url);
1389 handler1.download_handler()->FailDownloadForIconURLs(fail_icon_urls);
1391 std::vector<FaviconURL> urls1(kSourceIconURLs,
1392 kSourceIconURLs + arraysize(kSourceIconURLs));
1393 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1395 // Simulate the download failed, to check whether the icons were requested
1396 // to download according their size.
1397 struct ExpectedResult {
1398 // The size of image_urls_.
1399 size_t image_urls_size;
1400 // The favicon's index in kSourceIconURLs.
1401 size_t favicon_index;
1402 // Width of largest bitmap.
1403 int width;
1404 } results[] = {
1405 {5, 0, 1024},
1406 {4, 2, 512},
1407 {3, 1, 15},
1408 // The rest of bitmaps come in order.
1409 {2, 3, -1},
1410 {1, 4, -1},
1413 for (int i = 0; i < 5; ++i) {
1414 ASSERT_EQ(results[i].image_urls_size, handler1.image_urls().size());
1415 EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url,
1416 handler1.current_candidate()->icon_url);
1417 if (results[i].width != -1) {
1418 EXPECT_EQ(results[i].width, handler1.current_candidate()->
1419 icon_sizes[0].width());
1422 // Simulate no favicon from history.
1423 handler1.history_handler()->history_results_.clear();
1424 handler1.history_handler()->InvokeCallback();
1426 // Verify download request
1427 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1428 EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url,
1429 handler1.download_handler()->GetImageUrl());
1431 handler1.download_handler()->InvokeCallback();
1432 handler1.download_handler()->Reset();
1436 TEST_F(FaviconHandlerTest, TestSelectLargestFavicon) {
1437 const GURL kPageURL("http://www.google.com");
1439 std::vector<gfx::Size> one_icon;
1440 one_icon.push_back(gfx::Size(15, 15));
1442 std::vector<gfx::Size> two_icons;
1443 two_icons.push_back(gfx::Size(14, 14));
1444 two_icons.push_back(gfx::Size(16, 16));
1446 const FaviconURL kSourceIconURLs[] = {
1447 FaviconURL(
1448 GURL("http://www.google.com/b"), favicon_base::FAVICON, one_icon),
1449 FaviconURL(
1450 GURL("http://www.google.com/c"), favicon_base::FAVICON, two_icons)};
1452 TestFaviconDriver driver1;
1453 TestFaviconHandler handler1(kPageURL, &driver1, FaviconHandler::FAVICON,
1454 true);
1455 std::vector<FaviconURL> urls1(kSourceIconURLs,
1456 kSourceIconURLs + arraysize(kSourceIconURLs));
1457 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1459 ASSERT_EQ(2u, handler1.urls().size());
1461 // Index of largest favicon in kSourceIconURLs.
1462 size_t i = 1;
1463 // The largest bitmap's index in Favicon .
1464 int b = 1;
1466 // Verify the icon_bitmaps_ was initialized correctly.
1467 EXPECT_EQ(kSourceIconURLs[i].icon_url,
1468 handler1.current_candidate()->icon_url);
1469 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b],
1470 handler1.current_candidate()->icon_sizes[0]);
1472 // Simulate no favicon from history.
1473 handler1.history_handler()->history_results_.clear();
1474 handler1.history_handler()->InvokeCallback();
1476 // Verify download request
1477 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1478 EXPECT_EQ(kSourceIconURLs[i].icon_url,
1479 handler1.download_handler()->GetImageUrl());
1481 // Give the correct download result.
1482 std::vector<int> sizes;
1483 for (std::vector<gfx::Size>::const_iterator j =
1484 kSourceIconURLs[i].icon_sizes.begin();
1485 j != kSourceIconURLs[i].icon_sizes.end(); ++j)
1486 sizes.push_back(j->width());
1488 handler1.download_handler()->SetImageSizes(sizes);
1489 handler1.download_handler()->InvokeCallback();
1491 // Verify the largest bitmap has been saved into history.
1492 EXPECT_EQ(kSourceIconURLs[i].icon_url, handler1.history_handler()->icon_url_);
1493 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b],
1494 handler1.history_handler()->size_);
1495 // Verify NotifyFaviconAvailable().
1496 EXPECT_FALSE(driver1.update_active_favicon());
1497 EXPECT_EQ(kSourceIconURLs[i].icon_url, driver1.available_icon_url());
1498 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b],
1499 driver1.available_favicon().Size());
1502 TEST_F(FaviconHandlerTest, TestFaviconWasScaledAfterDownload) {
1503 const GURL kPageURL("http://www.google.com");
1504 const int kMaximalSize =
1505 TestFaviconHandler::GetMaximalIconSize(favicon_base::FAVICON);
1507 std::vector<gfx::Size> icon1;
1508 icon1.push_back(gfx::Size(kMaximalSize + 1, kMaximalSize + 1));
1510 std::vector<gfx::Size> icon2;
1511 icon2.push_back(gfx::Size(kMaximalSize + 2, kMaximalSize + 2));
1513 const FaviconURL kSourceIconURLs[] = {
1514 FaviconURL(
1515 GURL("http://www.google.com/b"), favicon_base::FAVICON, icon1),
1516 FaviconURL(
1517 GURL("http://www.google.com/c"), favicon_base::FAVICON, icon2)};
1519 TestFaviconDriver driver1;
1520 TestFaviconHandler handler1(kPageURL, &driver1, FaviconHandler::FAVICON,
1521 true);
1522 std::vector<FaviconURL> urls1(kSourceIconURLs,
1523 kSourceIconURLs + arraysize(kSourceIconURLs));
1524 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1526 ASSERT_EQ(2u, handler1.urls().size());
1528 // Index of largest favicon in kSourceIconURLs.
1529 size_t i = 1;
1530 // The largest bitmap's index in Favicon .
1531 int b = 0;
1533 // Verify the icon_bitmaps_ was initialized correctly.
1534 EXPECT_EQ(kSourceIconURLs[i].icon_url,
1535 handler1.current_candidate()->icon_url);
1536 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b],
1537 handler1.current_candidate()->icon_sizes[0]);
1539 // Simulate no favicon from history.
1540 handler1.history_handler()->history_results_.clear();
1541 handler1.history_handler()->InvokeCallback();
1543 // Verify download request
1544 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1545 EXPECT_EQ(kSourceIconURLs[i].icon_url,
1546 handler1.download_handler()->GetImageUrl());
1548 // Give the scaled download bitmap.
1549 std::vector<int> sizes;
1550 sizes.push_back(kMaximalSize);
1552 handler1.download_handler()->SetImageSizes(sizes);
1553 handler1.download_handler()->InvokeCallback();
1555 // Verify the largest bitmap has been saved into history though it was
1556 // scaled down to maximal size and smaller than icon1 now.
1557 EXPECT_EQ(kSourceIconURLs[i].icon_url, handler1.history_handler()->icon_url_);
1558 EXPECT_EQ(gfx::Size(kMaximalSize, kMaximalSize),
1559 handler1.history_handler()->size_);
1562 TEST_F(FaviconHandlerTest, TestKeepDownloadedLargestFavicon) {
1563 const GURL kPageURL("http://www.google.com");
1565 std::vector<gfx::Size> icon1;
1566 icon1.push_back(gfx::Size(16, 16));
1567 const int actual_size1 = 10;
1569 std::vector<gfx::Size> icon2;
1570 icon2.push_back(gfx::Size(15, 15));
1571 const int actual_size2 = 12;
1573 const FaviconURL kSourceIconURLs[] = {
1574 FaviconURL(GURL("http://www.google.com/b"), favicon_base::FAVICON, icon1),
1575 FaviconURL(GURL("http://www.google.com/c"), favicon_base::FAVICON, icon2),
1576 FaviconURL(GURL("http://www.google.com/d"),
1577 favicon_base::FAVICON,
1578 std::vector<gfx::Size>())};
1580 TestFaviconDriver driver1;
1581 TestFaviconHandler handler1(kPageURL, &driver1, FaviconHandler::FAVICON,
1582 true);
1583 std::vector<FaviconURL> urls1(kSourceIconURLs,
1584 kSourceIconURLs + arraysize(kSourceIconURLs));
1585 UpdateFaviconURL(&driver1, &handler1, kPageURL, urls1);
1586 ASSERT_EQ(3u, handler1.urls().size());
1588 // Simulate no favicon from history.
1589 handler1.history_handler()->history_results_.clear();
1590 handler1.history_handler()->InvokeCallback();
1592 // Verify the first icon was request to download
1593 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1594 EXPECT_EQ(kSourceIconURLs[0].icon_url,
1595 handler1.download_handler()->GetImageUrl());
1597 // Give the incorrect size.
1598 std::vector<int> sizes;
1599 sizes.push_back(actual_size1);
1600 handler1.download_handler()->SetImageSizes(sizes);
1601 handler1.download_handler()->InvokeCallback();
1602 handler1.download_handler()->Reset();
1604 // Simulate no favicon from history.
1605 handler1.history_handler()->history_results_.clear();
1606 handler1.history_handler()->InvokeCallback();
1608 // Verify the 2nd icon was request to download
1609 ASSERT_TRUE(handler1.download_handler()->HasDownload());
1610 EXPECT_EQ(kSourceIconURLs[1].icon_url,
1611 handler1.download_handler()->GetImageUrl());
1613 // Very the best candidate is icon1
1614 EXPECT_EQ(kSourceIconURLs[0].icon_url,
1615 handler1.best_favicon_candidate().image_url);
1616 EXPECT_EQ(gfx::Size(actual_size1, actual_size1),
1617 handler1.best_favicon_candidate().image.Size());
1619 // Give the incorrect size.
1620 sizes.clear();
1621 sizes.push_back(actual_size2);
1622 handler1.download_handler()->SetImageSizes(sizes);
1623 handler1.download_handler()->InvokeCallback();
1624 handler1.download_handler()->Reset();
1626 // Verify icon2 has been saved into history.
1627 EXPECT_EQ(kSourceIconURLs[1].icon_url, handler1.history_handler()->icon_url_);
1628 EXPECT_EQ(gfx::Size(actual_size2, actual_size2),
1629 handler1.history_handler()->size_);
1632 class FaviconHandlerActiveFaviconValidityParamTest :
1633 public FaviconHandlerTest,
1634 public ::testing::WithParamInterface<bool> {
1635 public:
1636 FaviconHandlerActiveFaviconValidityParamTest() {}
1638 ~FaviconHandlerActiveFaviconValidityParamTest() override {}
1640 bool GetActiveFaviconValiditySetting() {
1641 return GetParam();
1644 private:
1645 DISALLOW_COPY_AND_ASSIGN(FaviconHandlerActiveFaviconValidityParamTest);
1648 TEST_P(FaviconHandlerActiveFaviconValidityParamTest,
1649 TestDownloadLargestIconDoesNotImpactActiveFaviconValidity) {
1650 const GURL page_url("http://www.google.com");
1652 std::vector<gfx::Size> one_icon;
1653 one_icon.push_back(gfx::Size(15, 15));
1655 const GURL old_favicon_url("http://www.google.com/old");
1656 const GURL new_favicon_url("http://www.google.com/b");
1657 const FaviconURL source_icon_urls[] = {
1658 FaviconURL(new_favicon_url, favicon_base::FAVICON, one_icon)};
1659 TestFaviconDriver driver1;
1660 TestFaviconHandler handler1(page_url, &driver1, FaviconHandler::FAVICON,
1661 true);
1662 std::vector<FaviconURL> urls1(source_icon_urls,
1663 source_icon_urls + arraysize(source_icon_urls));
1664 UpdateFaviconURL(&driver1, &handler1, page_url, urls1);
1666 HistoryRequestHandler* history_handler = handler1.history_handler();
1668 // Simulate the active favicon is updated, this shouldn't happen in real
1669 // use case, but we want to verify the behavior below is not impacted by
1670 // accident.
1671 driver1.SetActiveFaviconValidity(GetActiveFaviconValiditySetting());
1672 // Simulate the get favicon from history, but favicon URL didn't match.
1673 SetFaviconRawBitmapResult(old_favicon_url,
1674 &history_handler->history_results_);
1675 history_handler->InvokeCallback();
1676 // Since we downloaded largest icon, and don't want to set active favicon
1677 // NotifyFaviconAvaliable() should be called with is_active_favicon as false.
1678 EXPECT_EQ(old_favicon_url, driver1.available_icon_url());
1679 EXPECT_FALSE(driver1.update_active_favicon());
1680 EXPECT_EQ(1u, driver1.num_favicon_available());
1682 // We are trying to get favicon from history again.
1683 history_handler = handler1.history_handler();
1684 EXPECT_EQ(new_favicon_url, history_handler->icon_url_);
1685 // Simulate the get expired favicon from history.
1686 history_handler->history_results_.clear();
1687 SetFaviconRawBitmapResult(new_favicon_url, favicon_base::FAVICON, true,
1688 &history_handler->history_results_);
1689 history_handler->InvokeCallback();
1690 // Since we downloaded largest icon, and don't want to set active favicon
1691 // NotifyFaviconAvaliable() should be called with is_active_favicon as false.
1692 EXPECT_EQ(new_favicon_url, driver1.available_icon_url());
1693 EXPECT_FALSE(driver1.update_active_favicon());
1694 EXPECT_EQ(2u, driver1.num_favicon_available());
1696 // We are trying to download favicon.
1697 DownloadHandler* download_handler = handler1.download_handler();
1698 EXPECT_TRUE(download_handler->HasDownload());
1699 EXPECT_EQ(new_favicon_url, download_handler->GetImageUrl());
1700 // Simulate the download succeed.
1701 download_handler->InvokeCallback();
1702 // Since we downloaded largest icon, and don't want to set active favicon
1703 // NotifyFaviconAvaliable() should be called with is_active_favicon as false.
1704 EXPECT_EQ(new_favicon_url, driver1.available_icon_url());
1705 EXPECT_FALSE(driver1.update_active_favicon());
1706 EXPECT_EQ(3u, driver1.num_favicon_available());
1709 INSTANTIATE_TEST_CASE_P(FaviconHandlerTestActiveFaviconValidityTrueOrFalse,
1710 FaviconHandlerActiveFaviconValidityParamTest,
1711 ::testing::Bool());
1713 } // namespace
1714 } // namespace favicon