1 // Copyright (c) 2011 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 "chrome/browser/favicon/favicon_handler.h"
6 #include "chrome/browser/profiles/profile.h"
7 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
8 #include "content/browser/tab_contents/navigation_entry.h"
9 #include "content/browser/tab_contents/test_tab_contents.h"
10 #include "ui/gfx/codec/png_codec.h"
11 #include "ui/gfx/favicon_size.h"
12 #include "ui/gfx/image/image.h"
14 class TestFaviconHandler
;
18 // Fill the given bmp with valid png data.
19 void FillDataToBitmap(int w
, int h
, SkBitmap
* bmp
) {
20 bmp
->setConfig(SkBitmap::kARGB_8888_Config
, w
, h
);
23 unsigned char* src_data
=
24 reinterpret_cast<unsigned char*>(bmp
->getAddr32(0, 0));
25 for (int i
= 0; i
< w
* h
; i
++) {
26 src_data
[i
* 4 + 0] = static_cast<unsigned char>(i
% 255);
27 src_data
[i
* 4 + 1] = static_cast<unsigned char>(i
% 255);
28 src_data
[i
* 4 + 2] = static_cast<unsigned char>(i
% 255);
29 src_data
[i
* 4 + 3] = static_cast<unsigned char>(i
% 255);
33 // Fill the given data buffer with valid png data.
34 void FillBitmap(int w
, int h
, std::vector
<unsigned char>* output
) {
36 FillDataToBitmap(w
, h
, &bitmap
);
37 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap
, false, output
);
40 // This class is used to save the download request for verifying with test case.
41 // It also will be used to invoke the onDidDownload callback.
42 class DownloadHandler
{
44 DownloadHandler(int download_id
,
45 const GURL
& image_url
,
47 TestFaviconHandler
* favicon_helper
)
48 : image_url_(image_url
),
49 image_size_(image_size
),
51 download_id_(download_id
),
52 favicon_helper_(favicon_helper
) {
53 FillDataToBitmap(16, 16, &bitmap_
);
56 virtual ~DownloadHandler() {
59 static void UpdateFaviconURL(FaviconHandler
* helper
,
60 const std::vector
<FaviconURL
> urls
);
62 void InvokeCallback();
64 void UpdateFaviconURL(const std::vector
<FaviconURL
> urls
);
66 const GURL image_url_
;
67 const int image_size_
;
69 // Simulates download failed or not.
73 // Identified the specific download, will also be passed in
74 // OnDidDownloadFavicon callback.
76 TestFaviconHandler
* favicon_helper_
;
79 DISALLOW_COPY_AND_ASSIGN(DownloadHandler
);
82 // This class is used to save the history request for verifying with test case.
83 // It also will be used to simulate the history response.
84 class HistoryRequestHandler
{
86 HistoryRequestHandler(const GURL
& page_url
,
89 const FaviconService::FaviconDataCallback
& callback
)
90 : page_url_(page_url
),
92 icon_type_(icon_type
),
96 HistoryRequestHandler(const GURL
& page_url
,
99 const std::vector
<unsigned char>& image_data
,
100 const FaviconService::FaviconDataCallback
& callback
)
101 : page_url_(page_url
),
103 icon_type_(icon_type
),
104 image_data_(image_data
),
105 callback_(callback
) {
108 virtual ~HistoryRequestHandler() {}
109 void InvokeCallback();
111 const GURL page_url_
;
112 const GURL icon_url_
;
113 const int icon_type_
;
114 const std::vector
<unsigned char> image_data_
;
115 history::FaviconData favicon_data_
;
116 FaviconService::FaviconDataCallback callback_
;
119 DISALLOW_COPY_AND_ASSIGN(HistoryRequestHandler
);
125 // This class is used as a temporary hack to provide working implementations of
126 // the various delegate methods. Most of these methods are actually never
128 // TODO(rohitrao): Refactor the tests to override these delegate methods instead
130 class TestFaviconHandlerDelegate
: public FaviconHandlerDelegate
{
132 explicit TestFaviconHandlerDelegate(TabContents
* tab_contents
)
133 : tab_contents_(tab_contents
) {
136 virtual NavigationEntry
* GetActiveEntry() {
137 ADD_FAILURE() << "TestFaviconHandlerDelegate::GetActiveEntry() "
138 << "should never be called in tests.";
142 virtual void StartDownload(int id
, const GURL
& url
, int image_size
) {
143 ADD_FAILURE() << "TestFaviconHandlerDelegate::StartDownload() "
144 << "should never be called in tests.";
147 virtual void NotifyFaviconUpdated() {
148 tab_contents_
->NotifyNavigationStateChanged(TabContents::INVALIDATE_TAB
);
152 TabContents
* tab_contents_
; // weak
155 // This class is used to catch the FaviconHandler's download and history
156 // request, and also provide the methods to access the FaviconHandler internal.
157 class TestFaviconHandler
: public FaviconHandler
{
159 TestFaviconHandler(const GURL
& page_url
,
161 FaviconHandlerDelegate
* delegate
,
163 : FaviconHandler(profile
, delegate
, type
),
164 download_image_size_(0),
166 entry_
.set_url(page_url
);
169 virtual ~TestFaviconHandler() {
172 HistoryRequestHandler
* history_handler() {
173 return history_handler_
.get();
176 // This method will take the ownership of the given handler.
177 void set_history_handler(HistoryRequestHandler
* handler
) {
178 history_handler_
.reset(handler
);
181 DownloadHandler
* download_handler() {
182 return download_handler_
.get();
185 // This method will take the ownership of the given download_handler.
186 void set_download_handler(DownloadHandler
* download_handler
) {
187 download_handler_
.reset(download_handler
);
190 virtual NavigationEntry
* GetEntry() {
194 const std::vector
<FaviconURL
>& urls() {
198 void FetchFavicon(const GURL
& url
) {
199 FaviconHandler::FetchFavicon(url
);
202 // The methods to access favicon internal.
203 FaviconURL
* current_candidate() {
204 return FaviconHandler::current_candidate();
207 void OnDidDownloadFavicon(int id
,
208 const GURL
& image_url
,
211 FaviconHandler::OnDidDownloadFavicon(id
, image_url
, errored
, image
);
215 virtual void UpdateFaviconMappingAndFetch(
216 const GURL
& page_url
,
217 const GURL
& icon_url
,
218 history::IconType icon_type
,
219 CancelableRequestConsumerBase
* consumer
,
220 const FaviconService::FaviconDataCallback
& callback
) OVERRIDE
{
221 history_handler_
.reset(new HistoryRequestHandler(page_url
, icon_url
,
222 icon_type
, callback
));
225 virtual void GetFavicon(
226 const GURL
& icon_url
,
227 history::IconType icon_type
,
228 CancelableRequestConsumerBase
* consumer
,
229 const FaviconService::FaviconDataCallback
& callback
) OVERRIDE
{
230 history_handler_
.reset(new HistoryRequestHandler(GURL(), icon_url
,
231 icon_type
, callback
));
234 virtual void GetFaviconForURL(
235 const GURL
& page_url
,
237 CancelableRequestConsumerBase
* consumer
,
238 const FaviconService::FaviconDataCallback
& callback
) OVERRIDE
{
239 history_handler_
.reset(new HistoryRequestHandler(page_url
, GURL(),
240 icon_types
, callback
));
243 virtual int DownloadFavicon(const GURL
& image_url
, int image_size
) OVERRIDE
{
245 download_handler_
.reset(new DownloadHandler(download_id_
, image_url
,
250 virtual void SetHistoryFavicon(const GURL
& page_url
,
251 const GURL
& icon_url
,
252 const std::vector
<unsigned char>& image_data
,
253 history::IconType icon_type
) OVERRIDE
{
254 history_handler_
.reset(new HistoryRequestHandler(
255 page_url
, icon_url
,icon_type
, image_data
,
256 FaviconService::FaviconDataCallback()));
259 virtual FaviconService
* GetFaviconService() OVERRIDE
{
260 // Just give none NULL value, so overridden methods can be hit.
261 return (FaviconService
*)(1);
264 virtual bool ShouldSaveFavicon(const GURL
& url
) OVERRIDE
{
270 GURL download_image_url_
;
271 int download_image_size_
;
274 NavigationEntry entry_
;
276 // The unique id of a download request. It will be returned to a
280 scoped_ptr
<DownloadHandler
> download_handler_
;
281 scoped_ptr
<HistoryRequestHandler
> history_handler_
;
283 DISALLOW_COPY_AND_ASSIGN(TestFaviconHandler
);
288 void DownloadHandler::UpdateFaviconURL(FaviconHandler
* helper
,
289 const std::vector
<FaviconURL
> urls
) {
290 helper
->OnUpdateFaviconURL(0, urls
);
293 void DownloadHandler::UpdateFaviconURL(const std::vector
<FaviconURL
> urls
) {
294 UpdateFaviconURL(favicon_helper_
, urls
);
297 void DownloadHandler::InvokeCallback() {
298 gfx::Image
image(new SkBitmap(bitmap_
));
299 favicon_helper_
->OnDidDownloadFavicon(download_id_
, image_url_
, failed_
,
303 void HistoryRequestHandler::InvokeCallback() {
304 callback_
.Run(0, favicon_data_
);
307 class FaviconHandlerTest
: public ChromeRenderViewHostTestHarness
{
310 TEST_F(FaviconHandlerTest
, GetFaviconFromHistory
) {
311 const GURL
page_url("http://www.google.com");
312 const GURL
icon_url("http://www.google.com/favicon");
314 TestFaviconHandlerDelegate
delegate(contents());
315 Profile
* profile
= Profile::FromBrowserContext(contents()->browser_context());
316 TestFaviconHandler
helper(page_url
, profile
,
317 &delegate
, FaviconHandler::FAVICON
);
319 helper
.FetchFavicon(page_url
);
320 HistoryRequestHandler
* history_handler
= helper
.history_handler();
321 // Ensure the data given to history is correct.
322 ASSERT_TRUE(history_handler
);
323 EXPECT_EQ(page_url
, history_handler
->page_url_
);
324 EXPECT_EQ(GURL(), history_handler
->icon_url_
);
325 EXPECT_EQ(history::FAVICON
, history_handler
->icon_type_
);
327 // Set valid icon data.
328 history_handler
->favicon_data_
.known_icon
= true;
329 history_handler
->favicon_data_
.icon_type
= history::FAVICON
;
330 history_handler
->favicon_data_
.expired
= false;
331 history_handler
->favicon_data_
.icon_url
= icon_url
;
332 scoped_refptr
<RefCountedBytes
> data
= new RefCountedBytes();
333 FillBitmap(gfx::kFaviconSize
, gfx::kFaviconSize
, &data
->data());
334 history_handler
->favicon_data_
.image_data
= data
;
336 // Send history response.
337 history_handler
->InvokeCallback();
338 // Verify FaviconHandler status
339 EXPECT_TRUE(helper
.GetEntry()->favicon().is_valid());
340 EXPECT_EQ(icon_url
, helper
.GetEntry()->favicon().url());
342 // Simulates update favicon url.
343 std::vector
<FaviconURL
> urls
;
344 urls
.push_back(FaviconURL(icon_url
, FaviconURL::FAVICON
));
345 DownloadHandler::UpdateFaviconURL(&helper
, urls
);
347 // Verify FaviconHandler status
348 EXPECT_EQ(1U, helper
.urls().size());
349 ASSERT_TRUE(helper
.current_candidate());
350 ASSERT_EQ(icon_url
, helper
.current_candidate()->icon_url
);
351 ASSERT_EQ(FaviconURL::FAVICON
, helper
.current_candidate()->icon_type
);
353 // Favicon shouldn't request to download icon.
354 DownloadHandler
* download_handler
= helper
.download_handler();
355 ASSERT_FALSE(download_handler
);
358 TEST_F(FaviconHandlerTest
, DownloadFavicon
) {
359 const GURL
page_url("http://www.google.com");
360 const GURL
icon_url("http://www.google.com/favicon");
362 TestFaviconHandlerDelegate
delegate(contents());
363 Profile
* profile
= Profile::FromBrowserContext(contents()->browser_context());
364 TestFaviconHandler
helper(page_url
, profile
,
365 &delegate
, FaviconHandler::FAVICON
);
367 helper
.FetchFavicon(page_url
);
368 HistoryRequestHandler
* history_handler
= helper
.history_handler();
369 // Ensure the data given to history is correct.
370 ASSERT_TRUE(history_handler
);
371 EXPECT_EQ(page_url
, history_handler
->page_url_
);
372 EXPECT_EQ(GURL(), history_handler
->icon_url_
);
373 EXPECT_EQ(history::FAVICON
, history_handler
->icon_type_
);
375 // Set icon data expired
376 history_handler
->favicon_data_
.known_icon
= true;
377 history_handler
->favicon_data_
.icon_type
= history::FAVICON
;
378 history_handler
->favicon_data_
.expired
= true;
379 history_handler
->favicon_data_
.icon_url
= icon_url
;
380 // Send history response.
381 history_handler
->InvokeCallback();
382 // Verify FaviconHandler status
383 EXPECT_TRUE(helper
.GetEntry()->favicon().is_valid());
384 EXPECT_EQ(icon_url
, helper
.GetEntry()->favicon().url());
386 // Simulates update favicon url.
387 std::vector
<FaviconURL
> urls
;
388 urls
.push_back(FaviconURL(icon_url
, FaviconURL::FAVICON
));
389 DownloadHandler::UpdateFaviconURL(&helper
, urls
);
391 // Verify FaviconHandler status
392 EXPECT_EQ(1U, helper
.urls().size());
393 ASSERT_TRUE(helper
.current_candidate());
394 ASSERT_EQ(icon_url
, helper
.current_candidate()->icon_url
);
395 ASSERT_EQ(FaviconURL::FAVICON
, helper
.current_candidate()->icon_type
);
397 // Favicon should request to download icon now.
398 DownloadHandler
* download_handler
= helper
.download_handler();
399 ASSERT_TRUE(download_handler
);
400 // Verify the download request.
401 EXPECT_EQ(icon_url
, download_handler
->image_url_
);
402 EXPECT_EQ(gfx::kFaviconSize
, download_handler
->image_size_
);
404 // Reset the history_handler to verify whether favicon is set.
405 helper
.set_history_handler(NULL
);
407 // Smulates download done.
408 download_handler
->InvokeCallback();
410 // New icon should be saved to history backend and navigation entry.
411 history_handler
= helper
.history_handler();
412 ASSERT_TRUE(history_handler
);
413 EXPECT_EQ(icon_url
, history_handler
->icon_url_
);
414 EXPECT_EQ(FaviconURL::FAVICON
, history_handler
->icon_type_
);
415 EXPECT_LT(0U, history_handler
->image_data_
.size());
416 EXPECT_EQ(page_url
, history_handler
->page_url_
);
418 // Verify NavigationEntry.
419 EXPECT_EQ(icon_url
, helper
.GetEntry()->favicon().url());
420 EXPECT_TRUE(helper
.GetEntry()->favicon().is_valid());
421 EXPECT_FALSE(helper
.GetEntry()->favicon().bitmap().empty());
424 TEST_F(FaviconHandlerTest
, UpdateAndDownloadFavicon
) {
425 const GURL
page_url("http://www.google.com");
426 const GURL
icon_url("http://www.google.com/favicon");
427 const GURL
new_icon_url("http://www.google.com/new_favicon");
429 TestFaviconHandlerDelegate
delegate(contents());
430 Profile
* profile
= Profile::FromBrowserContext(contents()->browser_context());
431 TestFaviconHandler
helper(page_url
, profile
,
432 &delegate
, FaviconHandler::FAVICON
);
434 helper
.FetchFavicon(page_url
);
435 HistoryRequestHandler
* history_handler
= helper
.history_handler();
436 // Ensure the data given to history is correct.
437 ASSERT_TRUE(history_handler
);
438 EXPECT_EQ(page_url
, history_handler
->page_url_
);
439 EXPECT_EQ(GURL(), history_handler
->icon_url_
);
440 EXPECT_EQ(history::FAVICON
, history_handler
->icon_type_
);
442 // Set valid icon data.
443 history_handler
->favicon_data_
.known_icon
= true;
444 history_handler
->favicon_data_
.icon_type
= history::FAVICON
;
445 history_handler
->favicon_data_
.expired
= false;
446 history_handler
->favicon_data_
.icon_url
= icon_url
;
447 scoped_refptr
<RefCountedBytes
> data
= new RefCountedBytes();
448 FillBitmap(gfx::kFaviconSize
, gfx::kFaviconSize
, &data
->data());
449 history_handler
->favicon_data_
.image_data
= data
;
451 // Send history response.
452 history_handler
->InvokeCallback();
453 // Verify FaviconHandler status.
454 EXPECT_TRUE(helper
.GetEntry()->favicon().is_valid());
455 EXPECT_EQ(icon_url
, helper
.GetEntry()->favicon().url());
457 // Reset the history_handler to verify whether new icon is requested from
459 helper
.set_history_handler(NULL
);
461 // Simulates update with the different favicon url.
462 std::vector
<FaviconURL
> urls
;
463 urls
.push_back(FaviconURL(new_icon_url
, FaviconURL::FAVICON
));
464 DownloadHandler::UpdateFaviconURL(&helper
, urls
);
466 // Verify FaviconHandler status.
467 EXPECT_EQ(1U, helper
.urls().size());
468 ASSERT_TRUE(helper
.current_candidate());
469 ASSERT_EQ(new_icon_url
, helper
.current_candidate()->icon_url
);
470 ASSERT_EQ(FaviconURL::FAVICON
, helper
.current_candidate()->icon_type
);
471 // The favicon status's url should be updated.
472 ASSERT_EQ(new_icon_url
, helper
.GetEntry()->favicon().url());
474 // Favicon should be requested from history.
475 history_handler
= helper
.history_handler();
476 ASSERT_TRUE(history_handler
);
477 EXPECT_EQ(new_icon_url
, history_handler
->icon_url_
);
478 EXPECT_EQ(FaviconURL::FAVICON
, history_handler
->icon_type_
);
479 EXPECT_EQ(page_url
, history_handler
->page_url_
);
481 // Simulate not find icon.
482 history_handler
->favicon_data_
.known_icon
= false;
483 history_handler
->InvokeCallback();
485 // Favicon should request to download icon now.
486 DownloadHandler
* download_handler
= helper
.download_handler();
487 ASSERT_TRUE(download_handler
);
488 // Verify the download request.
489 EXPECT_EQ(new_icon_url
, download_handler
->image_url_
);
490 EXPECT_EQ(gfx::kFaviconSize
, download_handler
->image_size_
);
492 // Reset the history_handler to verify whether favicon is set.
493 helper
.set_history_handler(NULL
);
495 // Smulates download done.
496 download_handler
->InvokeCallback();
498 // New icon should be saved to history backend and navigation entry.
499 history_handler
= helper
.history_handler();
500 ASSERT_TRUE(history_handler
);
501 EXPECT_EQ(new_icon_url
, history_handler
->icon_url_
);
502 EXPECT_EQ(FaviconURL::FAVICON
, history_handler
->icon_type_
);
503 EXPECT_LT(0U, history_handler
->image_data_
.size());
504 EXPECT_EQ(page_url
, history_handler
->page_url_
);
506 // Verify NavigationEntry.
507 EXPECT_EQ(new_icon_url
, helper
.GetEntry()->favicon().url());
508 EXPECT_TRUE(helper
.GetEntry()->favicon().is_valid());
509 EXPECT_FALSE(helper
.GetEntry()->favicon().bitmap().empty());
512 TEST_F(FaviconHandlerTest
, UpdateFavicon
) {
513 const GURL
page_url("http://www.google.com");
514 const GURL
icon_url("http://www.google.com/favicon");
515 const GURL
new_icon_url("http://www.google.com/new_favicon");
517 TestFaviconHandlerDelegate
delegate(contents());
518 Profile
* profile
= Profile::FromBrowserContext(contents()->browser_context());
519 TestFaviconHandler
helper(page_url
, profile
,
520 &delegate
, FaviconHandler::FAVICON
);
522 helper
.FetchFavicon(page_url
);
523 HistoryRequestHandler
* history_handler
= helper
.history_handler();
524 // Ensure the data given to history is correct.
525 ASSERT_TRUE(history_handler
);
526 EXPECT_EQ(page_url
, history_handler
->page_url_
);
527 EXPECT_EQ(GURL(), history_handler
->icon_url_
);
528 EXPECT_EQ(history::FAVICON
, history_handler
->icon_type_
);
530 // Set valid icon data.
531 history_handler
->favicon_data_
.known_icon
= true;
532 history_handler
->favicon_data_
.icon_type
= history::FAVICON
;
533 history_handler
->favicon_data_
.expired
= false;
534 history_handler
->favicon_data_
.icon_url
= icon_url
;
535 scoped_refptr
<RefCountedBytes
> data
= new RefCountedBytes();
536 FillBitmap(gfx::kFaviconSize
, gfx::kFaviconSize
, &data
->data());
537 history_handler
->favicon_data_
.image_data
= data
;
539 // Send history response.
540 history_handler
->InvokeCallback();
541 // Verify FaviconHandler status.
542 EXPECT_TRUE(helper
.GetEntry()->favicon().is_valid());
543 EXPECT_EQ(icon_url
, helper
.GetEntry()->favicon().url());
545 // Reset the history_handler to verify whether new icon is requested from
547 helper
.set_history_handler(NULL
);
549 // Simulates update with the different favicon url.
550 std::vector
<FaviconURL
> urls
;
551 urls
.push_back(FaviconURL(new_icon_url
, FaviconURL::FAVICON
));
552 DownloadHandler::UpdateFaviconURL(&helper
, urls
);
554 // Verify FaviconHandler status.
555 EXPECT_EQ(1U, helper
.urls().size());
556 ASSERT_TRUE(helper
.current_candidate());
557 ASSERT_EQ(new_icon_url
, helper
.current_candidate()->icon_url
);
558 ASSERT_EQ(FaviconURL::FAVICON
, helper
.current_candidate()->icon_type
);
559 // The favicon status's url should be updated.
560 ASSERT_EQ(new_icon_url
, helper
.GetEntry()->favicon().url());
562 // Favicon should be requested from history.
563 history_handler
= helper
.history_handler();
564 ASSERT_TRUE(history_handler
);
565 EXPECT_EQ(new_icon_url
, history_handler
->icon_url_
);
566 EXPECT_EQ(FaviconURL::FAVICON
, history_handler
->icon_type_
);
567 EXPECT_EQ(page_url
, history_handler
->page_url_
);
569 // Simulate find icon.
570 history_handler
->favicon_data_
.known_icon
= true;
571 history_handler
->favicon_data_
.icon_type
= history::FAVICON
;
572 history_handler
->favicon_data_
.expired
= false;
573 history_handler
->favicon_data_
.icon_url
= new_icon_url
;
574 history_handler
->favicon_data_
.image_data
= data
;
575 history_handler
->InvokeCallback();
577 // Shouldn't request download favicon
578 EXPECT_FALSE(helper
.download_handler());
580 // Verify the favicon status.
581 EXPECT_EQ(new_icon_url
, helper
.GetEntry()->favicon().url());
582 EXPECT_TRUE(helper
.GetEntry()->favicon().is_valid());
583 EXPECT_FALSE(helper
.GetEntry()->favicon().bitmap().empty());
586 TEST_F(FaviconHandlerTest
, Download2ndFaviconURLCandidate
) {
587 const GURL
page_url("http://www.google.com");
588 const GURL
icon_url("http://www.google.com/favicon");
589 const GURL
new_icon_url("http://www.google.com/new_favicon");
591 TestFaviconHandlerDelegate
delegate(contents());
592 Profile
* profile
= Profile::FromBrowserContext(contents()->browser_context());
593 TestFaviconHandler
helper(page_url
, profile
,
594 &delegate
, FaviconHandler::TOUCH
);
596 helper
.FetchFavicon(page_url
);
597 HistoryRequestHandler
* history_handler
= helper
.history_handler();
598 // Ensure the data given to history is correct.
599 ASSERT_TRUE(history_handler
);
600 EXPECT_EQ(page_url
, history_handler
->page_url_
);
601 EXPECT_EQ(GURL(), history_handler
->icon_url_
);
602 EXPECT_EQ(history::TOUCH_PRECOMPOSED_ICON
| history::TOUCH_ICON
,
603 history_handler
->icon_type_
);
606 history_handler
->favicon_data_
.known_icon
= false;
607 // Send history response.
608 history_handler
->InvokeCallback();
609 // Verify FaviconHandler status.
610 EXPECT_FALSE(helper
.GetEntry()->favicon().is_valid());
611 EXPECT_EQ(GURL(), helper
.GetEntry()->favicon().url());
613 // Reset the history_handler to verify whether new icon is requested from
615 helper
.set_history_handler(NULL
);
617 // Simulates update with the different favicon url.
618 std::vector
<FaviconURL
> urls
;
619 urls
.push_back(FaviconURL(icon_url
, FaviconURL::TOUCH_PRECOMPOSED_ICON
));
620 urls
.push_back(FaviconURL(new_icon_url
, FaviconURL::TOUCH_ICON
));
621 urls
.push_back(FaviconURL(new_icon_url
, FaviconURL::FAVICON
));
623 DownloadHandler::UpdateFaviconURL(&helper
, urls
);
625 // Verify FaviconHandler status.
626 EXPECT_EQ(2U, helper
.urls().size());
627 ASSERT_TRUE(helper
.current_candidate());
628 ASSERT_EQ(icon_url
, helper
.current_candidate()->icon_url
);
629 ASSERT_EQ(FaviconURL::TOUCH_PRECOMPOSED_ICON
,
630 helper
.current_candidate()->icon_type
);
632 // Favicon should be requested from history.
633 history_handler
= helper
.history_handler();
634 ASSERT_TRUE(history_handler
);
635 EXPECT_EQ(icon_url
, history_handler
->icon_url_
);
636 EXPECT_EQ(FaviconURL::TOUCH_PRECOMPOSED_ICON
, history_handler
->icon_type_
);
637 EXPECT_EQ(page_url
, history_handler
->page_url_
);
639 // Simulate not find icon.
640 history_handler
->favicon_data_
.known_icon
= false;
641 history_handler
->InvokeCallback();
643 // Should request download favicon.
644 DownloadHandler
* download_handler
= helper
.download_handler();
645 EXPECT_TRUE(download_handler
);
646 // Verify the download request.
647 EXPECT_EQ(icon_url
, download_handler
->image_url_
);
648 EXPECT_EQ(0, download_handler
->image_size_
);
650 // Reset the history_handler to verify whether favicon is request from
652 helper
.set_history_handler(NULL
);
653 // Smulates download failed.
654 download_handler
->failed_
= true;
655 download_handler
->InvokeCallback();
658 EXPECT_EQ(1U, helper
.urls().size());
659 ASSERT_TRUE(helper
.current_candidate());
660 EXPECT_EQ(new_icon_url
, helper
.current_candidate()->icon_url
);
661 EXPECT_EQ(FaviconURL::TOUCH_ICON
, helper
.current_candidate()->icon_type
);
663 // Favicon should be requested from history.
664 history_handler
= helper
.history_handler();
665 ASSERT_TRUE(history_handler
);
666 EXPECT_EQ(new_icon_url
, history_handler
->icon_url_
);
667 EXPECT_EQ(FaviconURL::TOUCH_ICON
, history_handler
->icon_type_
);
668 EXPECT_EQ(page_url
, history_handler
->page_url_
);
670 // Reset download handler
671 helper
.set_download_handler(NULL
);
673 // Smulates getting a expired icon from history.
674 history_handler
->favicon_data_
.known_icon
= true;
675 history_handler
->favicon_data_
.icon_type
= history::TOUCH_ICON
;
676 history_handler
->favicon_data_
.expired
= true;
677 history_handler
->favicon_data_
.icon_url
= new_icon_url
;
678 scoped_refptr
<RefCountedBytes
> data
= new RefCountedBytes();
679 FillBitmap(gfx::kFaviconSize
, gfx::kFaviconSize
, &data
->data());
680 history_handler
->favicon_data_
.image_data
= data
;
681 history_handler
->InvokeCallback();
683 // Verify the download request.
684 download_handler
= helper
.download_handler();
685 EXPECT_TRUE(download_handler
);
686 EXPECT_EQ(new_icon_url
, download_handler
->image_url_
);
687 EXPECT_EQ(0, download_handler
->image_size_
);
689 helper
.set_history_handler(NULL
);
691 // Simulates icon being downloaded.
692 download_handler
->InvokeCallback();
694 // New icon should be saved to history backend.
695 history_handler
= helper
.history_handler();
696 ASSERT_TRUE(history_handler
);
697 EXPECT_EQ(new_icon_url
, history_handler
->icon_url_
);
698 EXPECT_EQ(FaviconURL::TOUCH_ICON
, history_handler
->icon_type_
);
699 EXPECT_LT(0U, history_handler
->image_data_
.size());
700 EXPECT_EQ(page_url
, history_handler
->page_url_
);
703 TEST_F(FaviconHandlerTest
, UpdateDuringDownloading
) {
704 const GURL
page_url("http://www.google.com");
705 const GURL
icon_url("http://www.google.com/favicon");
706 const GURL
new_icon_url("http://www.google.com/new_favicon");
708 TestFaviconHandlerDelegate
delegate(contents());
709 Profile
* profile
= Profile::FromBrowserContext(contents()->browser_context());
710 TestFaviconHandler
helper(page_url
, profile
,
711 &delegate
, FaviconHandler::TOUCH
);
713 helper
.FetchFavicon(page_url
);
714 HistoryRequestHandler
* history_handler
= helper
.history_handler();
715 // Ensure the data given to history is correct.
716 ASSERT_TRUE(history_handler
);
717 EXPECT_EQ(page_url
, history_handler
->page_url_
);
718 EXPECT_EQ(GURL(), history_handler
->icon_url_
);
719 EXPECT_EQ(history::TOUCH_PRECOMPOSED_ICON
| history::TOUCH_ICON
,
720 history_handler
->icon_type_
);
723 history_handler
->favicon_data_
.known_icon
= false;
724 // Send history response.
725 history_handler
->InvokeCallback();
726 // Verify FaviconHandler status.
727 EXPECT_FALSE(helper
.GetEntry()->favicon().is_valid());
728 EXPECT_EQ(GURL(), helper
.GetEntry()->favicon().url());
730 // Reset the history_handler to verify whether new icon is requested from
732 helper
.set_history_handler(NULL
);
734 // Simulates update with the different favicon url.
735 std::vector
<FaviconURL
> urls
;
736 urls
.push_back(FaviconURL(icon_url
, FaviconURL::TOUCH_PRECOMPOSED_ICON
));
737 urls
.push_back(FaviconURL(new_icon_url
, FaviconURL::TOUCH_ICON
));
738 urls
.push_back(FaviconURL(new_icon_url
, FaviconURL::FAVICON
));
740 DownloadHandler::UpdateFaviconURL(&helper
, urls
);
742 // Verify FaviconHandler status.
743 EXPECT_EQ(2U, helper
.urls().size());
744 ASSERT_TRUE(helper
.current_candidate());
745 ASSERT_EQ(icon_url
, helper
.current_candidate()->icon_url
);
746 ASSERT_EQ(FaviconURL::TOUCH_PRECOMPOSED_ICON
,
747 helper
.current_candidate()->icon_type
);
749 // Favicon should be requested from history.
750 history_handler
= helper
.history_handler();
751 ASSERT_TRUE(history_handler
);
752 EXPECT_EQ(icon_url
, history_handler
->icon_url_
);
753 EXPECT_EQ(FaviconURL::TOUCH_PRECOMPOSED_ICON
, history_handler
->icon_type_
);
754 EXPECT_EQ(page_url
, history_handler
->page_url_
);
756 // Simulate not find icon.
757 history_handler
->favicon_data_
.known_icon
= false;
758 history_handler
->InvokeCallback();
760 // Should request download favicon.
761 DownloadHandler
* download_handler
= helper
.download_handler();
762 EXPECT_TRUE(download_handler
);
763 // Verify the download request.
764 EXPECT_EQ(icon_url
, download_handler
->image_url_
);
765 EXPECT_EQ(0, download_handler
->image_size_
);
767 // Reset the history_handler to verify whether favicon is request from
769 helper
.set_history_handler(NULL
);
770 const GURL
latest_icon_url("http://www.google.com/latest_favicon");
771 std::vector
<FaviconURL
> latest_urls
;
772 latest_urls
.push_back(FaviconURL(latest_icon_url
, FaviconURL::TOUCH_ICON
));
773 DownloadHandler::UpdateFaviconURL(&helper
, latest_urls
);
774 EXPECT_EQ(1U, helper
.urls().size());
775 EXPECT_EQ(latest_icon_url
, helper
.current_candidate()->icon_url
);
776 EXPECT_EQ(FaviconURL::TOUCH_ICON
, helper
.current_candidate()->icon_type
);
778 // Whether new icon is requested from history
779 history_handler
= helper
.history_handler();
780 ASSERT_TRUE(history_handler
);
781 EXPECT_EQ(latest_icon_url
, history_handler
->icon_url_
);
782 EXPECT_EQ(FaviconURL::TOUCH_ICON
, history_handler
->icon_type_
);
783 EXPECT_EQ(page_url
, history_handler
->page_url_
);
785 // Reset the history_handler to verify whether favicon is request from
787 // Save the callback for late use.
788 FaviconService::FaviconDataCallback callback
= history_handler
->callback_
;
789 helper
.set_history_handler(NULL
);
791 // Simulates download succeed.
792 download_handler
->InvokeCallback();
793 // The downloaded icon should be thrown away as there is favicon update.
794 EXPECT_FALSE(helper
.history_handler());
796 helper
.set_download_handler(NULL
);
798 // Simulates getting the icon from history.
799 scoped_ptr
<HistoryRequestHandler
> handler
;
800 handler
.reset(new HistoryRequestHandler(page_url
, latest_icon_url
,
801 history::TOUCH_ICON
, callback
));
802 handler
->favicon_data_
.known_icon
= true;
803 handler
->favicon_data_
.expired
= false;
804 handler
->favicon_data_
.icon_type
= history::TOUCH_ICON
;
805 handler
->favicon_data_
.icon_url
= latest_icon_url
;
806 scoped_refptr
<RefCountedBytes
> data
= new RefCountedBytes();
807 FillBitmap(gfx::kFaviconSize
, gfx::kFaviconSize
, &data
->data());
808 handler
->favicon_data_
.image_data
= data
;
810 handler
->InvokeCallback();
812 // No download request.
813 EXPECT_FALSE(helper
.download_handler());