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

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

Issue 2721363002: Extend LargeIconService to fetch missing favicons from a Google server (Closed)
Patch Set: Addressed comments. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/favicon/core/large_icon_service.h" 5 #include "components/favicon/core/large_icon_service.h"
6 6
7 #include <deque> 7 #include <deque>
8 #include <memory> 8 #include <memory>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/memory/ptr_util.h"
12 #include "base/memory/ref_counted_memory.h" 13 #include "base/memory/ref_counted_memory.h"
13 #include "base/message_loop/message_loop.h" 14 #include "base/message_loop/message_loop.h"
14 #include "base/run_loop.h" 15 #include "base/run_loop.h"
15 #include "base/task/cancelable_task_tracker.h" 16 #include "base/task/cancelable_task_tracker.h"
17 #include "base/test/mock_callback.h"
16 #include "base/threading/thread_task_runner_handle.h" 18 #include "base/threading/thread_task_runner_handle.h"
17 #include "components/favicon/core/favicon_client.h" 19 #include "components/favicon/core/favicon_client.h"
18 #include "components/favicon/core/test/mock_favicon_service.h" 20 #include "components/favicon/core/test/mock_favicon_service.h"
19 #include "components/favicon_base/fallback_icon_style.h" 21 #include "components/favicon_base/fallback_icon_style.h"
20 #include "components/favicon_base/favicon_types.h" 22 #include "components/favicon_base/favicon_types.h"
23 #include "components/image_fetcher/image_fetcher.h"
21 #include "testing/gmock/include/gmock/gmock.h" 24 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h" 25 #include "testing/gtest/include/gtest/gtest.h"
23 #include "third_party/skia/include/core/SkBitmap.h" 26 #include "third_party/skia/include/core/SkBitmap.h"
24 #include "third_party/skia/include/core/SkColor.h" 27 #include "third_party/skia/include/core/SkColor.h"
25 #include "ui/gfx/codec/png_codec.h" 28 #include "ui/gfx/codec/png_codec.h"
26 #include "ui/gfx/geometry/size.h" 29 #include "ui/gfx/geometry/size.h"
27 #include "ui/gfx/image/image.h" 30 #include "ui/gfx/image/image.h"
28 #include "url/gurl.h" 31 #include "url/gurl.h"
29 32
30 namespace favicon { 33 namespace favicon {
31 namespace { 34 namespace {
32 35
36 using testing::NiceMock;
37 using testing::Return;
38 using testing::SaveArg;
33 using testing::_; 39 using testing::_;
34 40
35 const char kDummyUrl[] = "http://www.example.com"; 41 const char kDummyUrl[] = "http://www.example.com";
36 const char kDummyIconUrl[] = "http://www.example.com/touch_icon.png"; 42 const char kDummyIconUrl[] = "http://www.example.com/touch_icon.png";
37 const SkColor kTestColor = SK_ColorRED; 43 const SkColor kTestColor = SK_ColorRED;
38 44
39 favicon_base::FaviconRawBitmapResult CreateTestBitmap( 45 ACTION_P(PostFetchReply, p0) {
40 int w, int h, SkColor color) { 46 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
47 base::Bind(arg2, arg0, p0));
48 }
49
50 SkBitmap CreateTestSkBitmap(int w, int h, SkColor color) {
51 SkBitmap bitmap;
52 bitmap.allocN32Pixels(w, h);
53 bitmap.eraseColor(color);
54 return bitmap;
55 }
56
57 favicon_base::FaviconRawBitmapResult CreateTestBitmapResult(int w,
58 int h,
59 SkColor color) {
41 favicon_base::FaviconRawBitmapResult result; 60 favicon_base::FaviconRawBitmapResult result;
42 result.expired = false; 61 result.expired = false;
43 62
44 // Create bitmap and fill with |color|. 63 // Create bitmap and fill with |color|.
45 scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes()); 64 scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes());
46 SkBitmap bitmap; 65 SkBitmap bitmap;
47 bitmap.allocN32Pixels(w, h); 66 bitmap.allocN32Pixels(w, h);
48 bitmap.eraseColor(color); 67 bitmap.eraseColor(color);
49 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &data->data()); 68 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &data->data());
50 result.bitmap_data = data; 69 result.bitmap_data = data;
51 70
52 result.pixel_size = gfx::Size(w, h); 71 result.pixel_size = gfx::Size(w, h);
53 result.icon_url = GURL(kDummyIconUrl); 72 result.icon_url = GURL(kDummyIconUrl);
54 result.icon_type = favicon_base::TOUCH_ICON; 73 result.icon_type = favicon_base::TOUCH_ICON;
55 CHECK(result.is_valid()); 74 CHECK(result.is_valid());
56 return result; 75 return result;
57 } 76 }
58 77
78 class MockImageFetcher : public image_fetcher::ImageFetcher {
79 public:
80 MOCK_METHOD1(SetImageFetcherDelegate,
81 void(image_fetcher::ImageFetcherDelegate* delegate));
82 MOCK_METHOD1(SetDataUseServiceName,
83 void(image_fetcher::ImageFetcher::DataUseServiceName name));
84 MOCK_METHOD3(StartOrQueueNetworkRequest,
85 void(const std::string& id,
86 const GURL& image_url,
87 base::Callback<void(const std::string& id,
88 const gfx::Image& image)> callback));
89 };
90
59 class LargeIconServiceTest : public testing::Test { 91 class LargeIconServiceTest : public testing::Test {
60 public: 92 public:
61 LargeIconServiceTest() 93 LargeIconServiceTest()
62 : large_icon_service_(&mock_favicon_service_, 94 : mock_image_fetcher_(new NiceMock<MockImageFetcher>()),
63 base::ThreadTaskRunnerHandle::Get()), 95 large_icon_service_(&mock_favicon_service_,
96 base::ThreadTaskRunnerHandle::Get(),
97 base::WrapUnique(mock_image_fetcher_)),
64 is_callback_invoked_(false) {} 98 is_callback_invoked_(false) {}
65 99
66 ~LargeIconServiceTest() override { 100 ~LargeIconServiceTest() override {
67 } 101 }
68 102
69 void ResultCallback(const favicon_base::LargeIconResult& result) { 103 void ResultCallback(const favicon_base::LargeIconResult& result) {
70 is_callback_invoked_ = true; 104 is_callback_invoked_ = true;
71 105
72 // Checking presence and absence of results. 106 // Checking presence and absence of results.
73 EXPECT_EQ(expected_bitmap_.is_valid(), result.bitmap.is_valid()); 107 EXPECT_EQ(expected_bitmap_.is_valid(), result.bitmap.is_valid());
(...skipping 14 matching lines...) Expand all
88 const GURL& page_url, 122 const GURL& page_url,
89 const favicon_base::FaviconRawBitmapResult& mock_result) { 123 const favicon_base::FaviconRawBitmapResult& mock_result) {
90 EXPECT_CALL(mock_favicon_service_, 124 EXPECT_CALL(mock_favicon_service_,
91 GetLargestRawFaviconForPageURL(page_url, _, _, _, _)) 125 GetLargestRawFaviconForPageURL(page_url, _, _, _, _))
92 .WillOnce(PostReply<5>(mock_result)); 126 .WillOnce(PostReply<5>(mock_result));
93 } 127 }
94 128
95 protected: 129 protected:
96 base::MessageLoopForIO loop_; 130 base::MessageLoopForIO loop_;
97 131
98 testing::StrictMock<MockFaviconService> mock_favicon_service_; 132 NiceMock<MockImageFetcher>* mock_image_fetcher_;
133 testing::NiceMock<MockFaviconService> mock_favicon_service_;
99 LargeIconService large_icon_service_; 134 LargeIconService large_icon_service_;
100 base::CancelableTaskTracker cancelable_task_tracker_; 135 base::CancelableTaskTracker cancelable_task_tracker_;
101 136
102 favicon_base::FaviconRawBitmapResult expected_bitmap_; 137 favicon_base::FaviconRawBitmapResult expected_bitmap_;
103 std::unique_ptr<favicon_base::FallbackIconStyle> 138 std::unique_ptr<favicon_base::FallbackIconStyle>
104 expected_fallback_icon_style_; 139 expected_fallback_icon_style_;
105 140
106 bool is_callback_invoked_; 141 bool is_callback_invoked_;
107 142
108 private: 143 private:
109 DISALLOW_COPY_AND_ASSIGN(LargeIconServiceTest); 144 DISALLOW_COPY_AND_ASSIGN(LargeIconServiceTest);
110 }; 145 };
111 146
112 TEST_F(LargeIconServiceTest, SameSize) { 147 TEST_F(LargeIconServiceTest, SameSize) {
113 InjectMockResult(GURL(kDummyUrl), CreateTestBitmap(24, 24, kTestColor)); 148 InjectMockResult(GURL(kDummyUrl), CreateTestBitmapResult(24, 24, kTestColor));
114 expected_bitmap_ = CreateTestBitmap(24, 24, kTestColor); 149 expected_bitmap_ = CreateTestBitmapResult(24, 24, kTestColor);
115 large_icon_service_.GetLargeIconOrFallbackStyle( 150 large_icon_service_.GetLargeIconOrFallbackStyle(
116 GURL(kDummyUrl), 151 GURL(kDummyUrl),
117 24, // |min_source_size_in_pixel| 152 24, // |min_source_size_in_pixel|
118 24, // |desired_size_in_pixel| 153 24, // |desired_size_in_pixel|
119 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)), 154 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
120 &cancelable_task_tracker_); 155 &cancelable_task_tracker_);
121 base::RunLoop().RunUntilIdle(); 156 base::RunLoop().RunUntilIdle();
122 EXPECT_TRUE(is_callback_invoked_); 157 EXPECT_TRUE(is_callback_invoked_);
123 } 158 }
124 159
125 TEST_F(LargeIconServiceTest, ScaleDown) { 160 TEST_F(LargeIconServiceTest, ScaleDown) {
126 InjectMockResult(GURL(kDummyUrl), CreateTestBitmap(32, 32, kTestColor)); 161 InjectMockResult(GURL(kDummyUrl), CreateTestBitmapResult(32, 32, kTestColor));
127 expected_bitmap_ = CreateTestBitmap(24, 24, kTestColor); 162 expected_bitmap_ = CreateTestBitmapResult(24, 24, kTestColor);
128 large_icon_service_.GetLargeIconOrFallbackStyle( 163 large_icon_service_.GetLargeIconOrFallbackStyle(
129 GURL(kDummyUrl), 24, 24, 164 GURL(kDummyUrl), 24, 24,
130 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)), 165 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
131 &cancelable_task_tracker_); 166 &cancelable_task_tracker_);
132 base::RunLoop().RunUntilIdle(); 167 base::RunLoop().RunUntilIdle();
133 EXPECT_TRUE(is_callback_invoked_); 168 EXPECT_TRUE(is_callback_invoked_);
134 } 169 }
135 170
136 TEST_F(LargeIconServiceTest, ScaleUp) { 171 TEST_F(LargeIconServiceTest, ScaleUp) {
137 InjectMockResult(GURL(kDummyUrl), CreateTestBitmap(16, 16, kTestColor)); 172 InjectMockResult(GURL(kDummyUrl), CreateTestBitmapResult(16, 16, kTestColor));
138 expected_bitmap_ = CreateTestBitmap(24, 24, kTestColor); 173 expected_bitmap_ = CreateTestBitmapResult(24, 24, kTestColor);
139 large_icon_service_.GetLargeIconOrFallbackStyle( 174 large_icon_service_.GetLargeIconOrFallbackStyle(
140 GURL(kDummyUrl), 175 GURL(kDummyUrl),
141 14, // Lowered requirement so stored bitmap is admitted. 176 14, // Lowered requirement so stored bitmap is admitted.
142 24, 177 24,
143 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)), 178 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
144 &cancelable_task_tracker_); 179 &cancelable_task_tracker_);
145 base::RunLoop().RunUntilIdle(); 180 base::RunLoop().RunUntilIdle();
146 EXPECT_TRUE(is_callback_invoked_); 181 EXPECT_TRUE(is_callback_invoked_);
147 } 182 }
148 183
149 // |desired_size_in_pixel| == 0 means retrieve original image without scaling. 184 // |desired_size_in_pixel| == 0 means retrieve original image without scaling.
150 TEST_F(LargeIconServiceTest, NoScale) { 185 TEST_F(LargeIconServiceTest, NoScale) {
151 InjectMockResult(GURL(kDummyUrl), CreateTestBitmap(24, 24, kTestColor)); 186 InjectMockResult(GURL(kDummyUrl), CreateTestBitmapResult(24, 24, kTestColor));
152 expected_bitmap_ = CreateTestBitmap(24, 24, kTestColor); 187 expected_bitmap_ = CreateTestBitmapResult(24, 24, kTestColor);
153 large_icon_service_.GetLargeIconOrFallbackStyle( 188 large_icon_service_.GetLargeIconOrFallbackStyle(
154 GURL(kDummyUrl), 16, 0, 189 GURL(kDummyUrl), 16, 0,
155 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)), 190 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
156 &cancelable_task_tracker_); 191 &cancelable_task_tracker_);
157 base::RunLoop().RunUntilIdle(); 192 base::RunLoop().RunUntilIdle();
158 EXPECT_TRUE(is_callback_invoked_); 193 EXPECT_TRUE(is_callback_invoked_);
159 } 194 }
160 195
161 TEST_F(LargeIconServiceTest, FallbackSinceIconTooSmall) { 196 TEST_F(LargeIconServiceTest, FallbackSinceIconTooSmall) {
162 InjectMockResult(GURL(kDummyUrl), CreateTestBitmap(16, 16, kTestColor)); 197 InjectMockResult(GURL(kDummyUrl), CreateTestBitmapResult(16, 16, kTestColor));
163 expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle); 198 expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle);
164 expected_fallback_icon_style_->background_color = kTestColor; 199 expected_fallback_icon_style_->background_color = kTestColor;
165 expected_fallback_icon_style_->is_default_background_color = false; 200 expected_fallback_icon_style_->is_default_background_color = false;
166 large_icon_service_.GetLargeIconOrFallbackStyle( 201 large_icon_service_.GetLargeIconOrFallbackStyle(
167 GURL(kDummyUrl), 24, 24, 202 GURL(kDummyUrl), 24, 24,
168 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)), 203 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
169 &cancelable_task_tracker_); 204 &cancelable_task_tracker_);
170 base::RunLoop().RunUntilIdle(); 205 base::RunLoop().RunUntilIdle();
171 EXPECT_TRUE(is_callback_invoked_); 206 EXPECT_TRUE(is_callback_invoked_);
172 } 207 }
173 208
174 TEST_F(LargeIconServiceTest, FallbackSinceIconNotSquare) { 209 TEST_F(LargeIconServiceTest, FallbackSinceIconNotSquare) {
175 InjectMockResult(GURL(kDummyUrl), CreateTestBitmap(24, 32, kTestColor)); 210 InjectMockResult(GURL(kDummyUrl), CreateTestBitmapResult(24, 32, kTestColor));
176 expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle); 211 expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle);
177 expected_fallback_icon_style_->background_color = kTestColor; 212 expected_fallback_icon_style_->background_color = kTestColor;
178 expected_fallback_icon_style_->is_default_background_color = false; 213 expected_fallback_icon_style_->is_default_background_color = false;
179 large_icon_service_.GetLargeIconOrFallbackStyle( 214 large_icon_service_.GetLargeIconOrFallbackStyle(
180 GURL(kDummyUrl), 24, 24, 215 GURL(kDummyUrl), 24, 24,
181 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)), 216 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
182 &cancelable_task_tracker_); 217 &cancelable_task_tracker_);
183 base::RunLoop().RunUntilIdle(); 218 base::RunLoop().RunUntilIdle();
184 EXPECT_TRUE(is_callback_invoked_); 219 EXPECT_TRUE(is_callback_invoked_);
185 } 220 }
(...skipping 18 matching lines...) Expand all
204 GURL(kDummyUrl), 24, 0, 239 GURL(kDummyUrl), 24, 0,
205 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)), 240 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
206 &cancelable_task_tracker_); 241 &cancelable_task_tracker_);
207 base::RunLoop().RunUntilIdle(); 242 base::RunLoop().RunUntilIdle();
208 EXPECT_TRUE(is_callback_invoked_); 243 EXPECT_TRUE(is_callback_invoked_);
209 } 244 }
210 245
211 // Oddball case where we demand a high resolution icon to scale down. Generates 246 // Oddball case where we demand a high resolution icon to scale down. Generates
212 // fallback even though an icon with the final size is available. 247 // fallback even though an icon with the final size is available.
213 TEST_F(LargeIconServiceTest, FallbackSinceTooPicky) { 248 TEST_F(LargeIconServiceTest, FallbackSinceTooPicky) {
214 InjectMockResult(GURL(kDummyUrl), CreateTestBitmap(24, 24, kTestColor)); 249 InjectMockResult(GURL(kDummyUrl), CreateTestBitmapResult(24, 24, kTestColor));
215 expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle); 250 expected_fallback_icon_style_.reset(new favicon_base::FallbackIconStyle);
216 expected_fallback_icon_style_->background_color = kTestColor; 251 expected_fallback_icon_style_->background_color = kTestColor;
217 expected_fallback_icon_style_->is_default_background_color = false; 252 expected_fallback_icon_style_->is_default_background_color = false;
218 large_icon_service_.GetLargeIconOrFallbackStyle( 253 large_icon_service_.GetLargeIconOrFallbackStyle(
219 GURL(kDummyUrl), 32, 24, 254 GURL(kDummyUrl), 32, 24,
220 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)), 255 base::Bind(&LargeIconServiceTest::ResultCallback, base::Unretained(this)),
221 &cancelable_task_tracker_); 256 &cancelable_task_tracker_);
222 base::RunLoop().RunUntilIdle(); 257 base::RunLoop().RunUntilIdle();
223 EXPECT_TRUE(is_callback_invoked_); 258 EXPECT_TRUE(is_callback_invoked_);
224 } 259 }
225 260
261 TEST_F(LargeIconServiceTest, ShouldGetFromGoogleServer) {
262 const std::string expected_server_url =
263 "https://t0.gstatic.com/faviconV2?url=http://www.example.com/"
264 "&type=APPLE_TOUCH&size=192&min_size=42&max_size=256";
265
266 EXPECT_CALL(mock_favicon_service_, UnableToDownloadFavicon(_)).Times(0);
267
268 base::MockCallback<base::Callback<void(bool success)>> callback;
269 EXPECT_CALL(*mock_image_fetcher_,
270 StartOrQueueNetworkRequest(expected_server_url,
271 GURL(expected_server_url), _))
272 .WillOnce(PostFetchReply(gfx::Image::CreateFrom1xBitmap(
273 CreateTestSkBitmap(64, 64, kTestColor))));
274 EXPECT_CALL(
275 mock_favicon_service_,
276 SetExpiredFaviconsIfNoneKnown(GURL(kDummyUrl), GURL(expected_server_url),
277 favicon_base::IconType::TOUCH_ICON, _));
278 EXPECT_CALL(callback, Run(true));
279
280 large_icon_service_
281 .GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
282 GURL(kDummyUrl), /*min_source_size_in_pixel=*/42, callback.Get());
283
284 base::RunLoop().RunUntilIdle();
285 }
286
287 TEST_F(LargeIconServiceTest, ShouldReportUnavailableIfFetchFromServerFails) {
288 const std::string expected_server_url =
289 "https://t0.gstatic.com/faviconV2?url=http://www.example.com/"
290 "&type=APPLE_TOUCH&size=192&min_size=42&max_size=256";
291
292 EXPECT_CALL(mock_favicon_service_, SetExpiredFaviconsIfNoneKnown(_, _, _, _))
293 .Times(0);
294
295 base::MockCallback<base::Callback<void(bool success)>> callback;
296 EXPECT_CALL(*mock_image_fetcher_,
297 StartOrQueueNetworkRequest(expected_server_url,
298 GURL(expected_server_url), _))
299 .WillOnce(PostFetchReply(gfx::Image()));
300 EXPECT_CALL(mock_favicon_service_,
301 UnableToDownloadFavicon(GURL(expected_server_url)));
302 EXPECT_CALL(callback, Run(false));
303
304 large_icon_service_
305 .GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
306 GURL(kDummyUrl), /*min_source_size_in_pixel=*/42, callback.Get());
307
308 base::RunLoop().RunUntilIdle();
309 }
310
311 TEST_F(LargeIconServiceTest, ShoutNotGetFromGoogleServerIfUnavailable) {
312 ON_CALL(mock_favicon_service_,
313 WasUnableToDownloadFavicon(GURL(
314 "https://t0.gstatic.com/faviconV2?url=http://www.example.com/"
315 "&type=APPLE_TOUCH&size=192&min_size=42&max_size=256")))
316 .WillByDefault(Return(true));
317
318 EXPECT_CALL(mock_favicon_service_, UnableToDownloadFavicon(_)).Times(0);
319 EXPECT_CALL(*mock_image_fetcher_, StartOrQueueNetworkRequest(_, _, _))
320 .Times(0);
321 EXPECT_CALL(mock_favicon_service_, SetExpiredFaviconsIfNoneKnown(_, _, _, _))
322 .Times(0);
323
324 base::MockCallback<base::Callback<void(bool success)>> callback;
325 large_icon_service_
326 .GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
327 GURL(kDummyUrl), /*min_source_size_in_pixel=*/42, callback.Get());
328
329 EXPECT_CALL(callback, Run(false));
330 base::RunLoop().RunUntilIdle();
331 }
332
226 } // namespace 333 } // namespace
227 } // namespace favicon 334 } // namespace favicon
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698