OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/favicon/core/favicon_handler.h" | 5 #include "components/favicon/core/favicon_handler.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <set> | 10 #include <set> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/macros.h" | 13 #include "base/macros.h" |
14 #include "base/memory/ptr_util.h" | |
15 #include "base/message_loop/message_loop.h" | |
16 #include "base/run_loop.h" | |
17 #include "components/favicon/core/favicon_client.h" | |
14 #include "components/favicon/core/favicon_driver.h" | 18 #include "components/favicon/core/favicon_driver.h" |
19 #include "components/favicon/core/test/mock_favicon_service.h" | |
20 #include "testing/gmock/include/gmock/gmock.h" | |
15 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
16 #include "third_party/skia/include/core/SkBitmap.h" | 22 #include "third_party/skia/include/core/SkBitmap.h" |
17 #include "ui/base/layout.h" | 23 #include "ui/base/layout.h" |
18 #include "ui/gfx/codec/png_codec.h" | 24 #include "ui/gfx/codec/png_codec.h" |
19 #include "ui/gfx/favicon_size.h" | 25 #include "ui/gfx/favicon_size.h" |
20 #include "ui/gfx/image/image.h" | 26 #include "ui/gfx/image/image.h" |
21 | 27 |
22 namespace favicon { | 28 namespace favicon { |
23 namespace { | 29 namespace { |
24 | 30 |
25 // Fill the given bmp with valid png data. | 31 using favicon_base::FAVICON; |
26 void FillDataToBitmap(int w, int h, SkBitmap* bmp) { | 32 using favicon_base::FaviconRawBitmapResult; |
27 bmp->allocN32Pixels(w, h); | 33 using favicon_base::TOUCH_ICON; |
34 using favicon_base::TOUCH_PRECOMPOSED_ICON; | |
35 using testing::AnyNumber; | |
36 using testing::AtMost; | |
37 using testing::InSequence; | |
38 using testing::Invoke; | |
39 using testing::Return; | |
40 using testing::SaveArg; | |
41 using testing::_; | |
42 | |
43 using IntVector = std::vector<int>; | |
44 using URLVector = std::vector<GURL>; | |
45 using BitmapVector = std::vector<SkBitmap>; | |
46 using SizeVector = std::vector<gfx::Size>; | |
47 | |
48 MATCHER_P2(ImageSizeIs, width, height, "") { | |
49 *result_listener << "where size is " << arg.Width() << "x" << arg.Height(); | |
50 return arg.Size() == gfx::Size(width, height); | |
51 } | |
52 | |
53 // Fill the given bmp with some test data. | |
54 SkBitmap CreateBitmap(int w, int h) { | |
55 SkBitmap bmp; | |
56 bmp.allocN32Pixels(w, h); | |
28 | 57 |
29 unsigned char* src_data = | 58 unsigned char* src_data = |
30 reinterpret_cast<unsigned char*>(bmp->getAddr32(0, 0)); | 59 reinterpret_cast<unsigned char*>(bmp.getAddr32(0, 0)); |
31 for (int i = 0; i < w * h; i++) { | 60 for (int i = 0; i < w * h; i++) { |
32 src_data[i * 4 + 0] = static_cast<unsigned char>(i % 255); | 61 src_data[i * 4 + 0] = static_cast<unsigned char>(i % 255); |
33 src_data[i * 4 + 1] = static_cast<unsigned char>(i % 255); | 62 src_data[i * 4 + 1] = static_cast<unsigned char>(i % 255); |
34 src_data[i * 4 + 2] = static_cast<unsigned char>(i % 255); | 63 src_data[i * 4 + 2] = static_cast<unsigned char>(i % 255); |
35 src_data[i * 4 + 3] = static_cast<unsigned char>(i % 255); | 64 src_data[i * 4 + 3] = static_cast<unsigned char>(i % 255); |
36 } | 65 } |
66 return bmp; | |
37 } | 67 } |
38 | 68 |
39 // Fill the given data buffer with valid png data. | 69 // Fill the given data buffer with valid png data. |
40 void FillBitmap(int w, int h, std::vector<unsigned char>* output) { | 70 void FillBitmap(int w, int h, std::vector<unsigned char>* output) { |
41 SkBitmap bitmap; | 71 SkBitmap bitmap = CreateBitmap(w, h); |
42 FillDataToBitmap(w, h, &bitmap); | |
43 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, output); | 72 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, output); |
44 } | 73 } |
45 | 74 |
46 void SetFaviconRawBitmapResult( | 75 std::vector<gfx::Size> CreateSquareSizes(const IntVector& sizes) { |
76 std::vector<gfx::Size> result; | |
77 for (int size : sizes) { | |
78 result.emplace_back(size, size); | |
79 } | |
80 return result; | |
81 } | |
82 | |
83 std::vector<SkBitmap> CreateBitmaps(const std::vector<gfx::Size>& sizes) { | |
84 std::vector<SkBitmap> bitmaps; | |
85 for (const gfx::Size& size : sizes) { | |
86 bitmaps.push_back(CreateBitmap(size.width(), size.height())); | |
87 } | |
88 return bitmaps; | |
89 } | |
90 | |
91 std::vector<FaviconRawBitmapResult> CreateRawBitmapResult( | |
47 const GURL& icon_url, | 92 const GURL& icon_url, |
48 favicon_base::IconType icon_type, | 93 favicon_base::IconType icon_type, |
49 bool expired, | 94 bool expired) { |
50 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) { | |
51 scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes()); | 95 scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes()); |
52 FillBitmap(gfx::kFaviconSize, gfx::kFaviconSize, &data->data()); | 96 FillBitmap(gfx::kFaviconSize, gfx::kFaviconSize, &data->data()); |
53 favicon_base::FaviconRawBitmapResult bitmap_result; | 97 FaviconRawBitmapResult bitmap_result; |
54 bitmap_result.expired = expired; | 98 bitmap_result.expired = expired; |
55 bitmap_result.bitmap_data = data; | 99 bitmap_result.bitmap_data = data; |
56 // Use a pixel size other than (0,0) as (0,0) has a special meaning. | 100 // Use a pixel size other than (0,0) as (0,0) has a special meaning. |
57 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize); | 101 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize); |
58 bitmap_result.icon_type = icon_type; | 102 bitmap_result.icon_type = icon_type; |
59 bitmap_result.icon_url = icon_url; | 103 bitmap_result.icon_url = icon_url; |
60 | 104 return {bitmap_result}; |
61 favicon_bitmap_results->push_back(bitmap_result); | 105 } |
62 } | 106 |
63 | 107 class MockDelegate : public FaviconHandler::Delegate { |
64 void SetFaviconRawBitmapResult( | |
65 const GURL& icon_url, | |
66 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) { | |
67 SetFaviconRawBitmapResult(icon_url, | |
68 favicon_base::FAVICON, | |
69 false /* expired */, | |
70 favicon_bitmap_results); | |
71 } | |
72 | |
73 // This class is used to save the download request for verifying with test case. | |
74 class DownloadHandler { | |
75 public: | 108 public: |
76 DownloadHandler() : callback_invoked_(false) {} | 109 MOCK_METHOD3(DownloadImage, |
77 ~DownloadHandler() {} | 110 int(const GURL& url, |
78 | |
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_|. | |
84 } | |
85 | |
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; | |
89 } | |
90 | |
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); | |
94 } | |
95 | |
96 void AddDownload(int download_id, | |
97 const GURL& image_url, | |
98 const std::vector<int>& image_sizes, | |
99 int max_image_size, | 111 int max_image_size, |
100 FaviconHandler::Delegate::ImageDownloadCallback callback) { | 112 ImageDownloadCallback callback)); |
101 download_.reset(new Download(download_id, image_url, image_sizes, | 113 MOCK_METHOD0(IsOffTheRecord, bool()); |
102 max_image_size, callback)); | 114 MOCK_METHOD1(IsBookmarked, bool(const GURL& url)); |
103 } | 115 MOCK_METHOD5(OnFaviconUpdated, |
104 | 116 void(const GURL& page_url, |
105 void InvokeCallback(); | 117 FaviconDriverObserver::NotificationIconType type, |
106 | 118 const GURL& icon_url, |
107 bool HasDownload() const { return download_.get(); } | 119 bool icon_url_changed, |
108 const GURL& GetImageUrl() const { return download_->image_url; } | 120 const gfx::Image& image)); |
109 void SetImageSizes(const std::vector<int>& sizes) { | 121 }; |
110 download_->image_sizes = sizes; } | 122 |
123 // Fake that implements the calls to FaviconHalder::Delegate's DownloadImage(), | |
124 // delegated to this class through MockDelegate. | |
125 class FakeImageDownloader { | |
126 public: | |
127 struct Response { | |
128 int http_status_code = 404; | |
129 BitmapVector bitmaps; | |
130 SizeVector original_bitmap_sizes; | |
131 }; | |
132 | |
133 FakeImageDownloader() : num_downloads_(0) {} | |
134 | |
135 // Implementation of FaviconHalder::Delegate's DownloadImage(). If a given | |
136 // URL is not known (i.e. not previously added via Add()), it produces 404s. | |
137 int DownloadImage(const GURL& url, | |
138 int max_image_size, | |
139 FaviconHandler::Delegate::ImageDownloadCallback callback) { | |
140 const Response& response = responses_[url]; | |
141 int download_id = ++num_downloads_; | |
142 base::Closure bound_callback = | |
143 base::Bind(callback, download_id, response.http_status_code, url, | |
144 response.bitmaps, response.original_bitmap_sizes); | |
145 if (url == manual_callback_url_) | |
146 manual_callback_ = bound_callback; | |
147 else | |
148 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, bound_callback); | |
149 return download_id; | |
150 } | |
151 | |
152 void Add(const GURL& icon_url, const IntVector& sizes) { | |
153 AddWithOriginalSizes(icon_url, sizes, sizes); | |
154 } | |
155 | |
156 void AddWithOriginalSizes(const GURL& icon_url, | |
157 const IntVector& sizes, | |
158 const IntVector& original_sizes) { | |
159 DCHECK_EQ(sizes.size(), original_sizes.size()); | |
160 Response response; | |
161 response.http_status_code = 200; | |
162 response.original_bitmap_sizes = CreateSquareSizes(original_sizes); | |
163 response.bitmaps = CreateBitmaps(CreateSquareSizes(sizes)); | |
164 responses_[icon_url] = response; | |
165 } | |
166 | |
167 void AddError(const GURL& icon_url, int http_status_code) { | |
168 Response response; | |
169 response.http_status_code = http_status_code; | |
170 responses_[icon_url] = response; | |
171 } | |
172 | |
173 // Disables automatic callback for |url|. This is useful for emulating a | |
174 // download taking a long time. The callback will for DownloadImage() will be | |
175 // stored in |manual_callback_|. | |
176 void SetRunCallbackManuallyForUrl(const GURL& url) { | |
177 manual_callback_url_ = url; | |
178 } | |
179 | |
180 // Returns whether an ongoing download exists for a url previously selected | |
181 // via SetRunCallbackManuallyForUrl(). | |
182 bool HasPendingManualCallback() { return !manual_callback_.is_null(); } | |
183 | |
184 // Triggers the response for a download previously selected for manual | |
185 // triggering via SetRunCallbackManuallyForUrl(). | |
186 bool RunCallbackManually() { | |
187 if (!HasPendingManualCallback()) | |
188 return false; | |
189 manual_callback_.Run(); | |
190 return true; | |
191 } | |
111 | 192 |
112 private: | 193 private: |
113 struct Download { | 194 int num_downloads_; |
114 Download(int id, | 195 |
115 GURL url, | 196 // URL to disable automatic callbacks for. |
116 const std::vector<int>& sizes, | 197 GURL manual_callback_url_; |
117 int max_size, | 198 |
118 FaviconHandler::Delegate::ImageDownloadCallback callback) | 199 // Callback for DownloadImage() request for |manual_callback_url_|. |
119 : download_id(id), | 200 base::Closure manual_callback_; |
120 image_url(url), | 201 |
121 image_sizes(sizes), | 202 // Registered images. |
122 max_image_size(max_size), | 203 std::map<GURL, Response> responses_; |
123 callback(callback) {} | |
124 ~Download() {} | |
125 int download_id; | |
126 GURL image_url; | |
127 std::vector<int> image_sizes; | |
128 int max_image_size; | |
129 FaviconHandler::Delegate::ImageDownloadCallback callback; | |
130 }; | |
131 | |
132 std::unique_ptr<Download> download_; | |
133 bool callback_invoked_; | |
134 | |
135 // The icon URLs for which the download should fail. | |
136 std::set<GURL> should_fail_download_icon_urls_; | |
137 | |
138 // The icon URLs for which the download did fail. This should be a subset of | |
139 // |should_fail_download_icon_urls_|. | |
140 std::set<GURL> failed_download_icon_urls_; | |
141 | |
142 DISALLOW_COPY_AND_ASSIGN(DownloadHandler); | |
143 }; | 204 }; |
144 | 205 |
145 // This class is used to save the history request for verifying with test case. | |
146 // It also will be used to simulate the history response. | |
147 class HistoryRequestHandler { | |
148 public: | |
149 HistoryRequestHandler(const GURL& page_url, | |
150 const GURL& icon_url, | |
151 int icon_type, | |
152 const favicon_base::FaviconResultsCallback& callback) | |
153 : page_url_(page_url), | |
154 icon_url_(icon_url), | |
155 icon_type_(icon_type), | |
156 callback_(callback) { | |
157 } | |
158 | |
159 HistoryRequestHandler(const GURL& page_url, | |
160 const GURL& icon_url, | |
161 int icon_type, | |
162 const std::vector<unsigned char>& bitmap_data, | |
163 const gfx::Size& size) | |
164 : page_url_(page_url), | |
165 icon_url_(icon_url), | |
166 icon_type_(icon_type), | |
167 bitmap_data_(bitmap_data), | |
168 size_(size) { | |
169 } | |
170 | |
171 ~HistoryRequestHandler() {} | |
172 void InvokeCallback(); | |
173 | |
174 const GURL page_url_; | |
175 const GURL icon_url_; | |
176 const int icon_type_; | |
177 const std::vector<unsigned char> bitmap_data_; | |
178 const gfx::Size size_; | |
179 std::vector<favicon_base::FaviconRawBitmapResult> history_results_; | |
180 favicon_base::FaviconResultsCallback callback_; | |
181 | |
182 private: | |
183 DISALLOW_COPY_AND_ASSIGN(HistoryRequestHandler); | |
184 }; | |
185 | |
186 class TestDelegate : public FaviconHandler::Delegate { | |
187 public: | |
188 TestDelegate() : num_notifications_(0), download_id_(0) {} | |
189 | |
190 int DownloadImage(const GURL& image_url, | |
191 int max_bitmap_size, | |
192 ImageDownloadCallback callback) override { | |
193 // Do not do a download if downloading |image_url| failed previously. This | |
194 // emulates the behavior of FaviconDriver::DownloadImage() | |
195 if (download_handler_.DidFailDownloadForIconURL(image_url)) { | |
196 download_handler_.AddDownload(download_id_, image_url, std::vector<int>(), | |
197 0, callback); | |
198 return 0; | |
199 } | |
200 | |
201 download_id_++; | |
202 std::vector<int> sizes; | |
203 sizes.push_back(0); | |
204 download_handler_.AddDownload(download_id_, image_url, sizes, | |
205 max_bitmap_size, callback); | |
206 return download_id_; | |
207 } | |
208 | |
209 bool IsOffTheRecord() override { return false; } | |
210 | |
211 bool IsBookmarked(const GURL& url) override { return false; } | |
212 | |
213 void OnFaviconUpdated( | |
214 const GURL& page_url, | |
215 FaviconDriverObserver::NotificationIconType notification_icon_type, | |
216 const GURL& icon_url, | |
217 bool icon_url_changed, | |
218 const gfx::Image& image) override { | |
219 ++num_notifications_; | |
220 icon_url_ = icon_url; | |
221 image_ = image; | |
222 } | |
223 | |
224 DownloadHandler* download_handler() { return &download_handler_; } | |
225 const GURL& icon_url() const { return icon_url_; } | |
226 const gfx::Image& image() const { return image_; } | |
227 size_t num_notifications() const { return num_notifications_; } | |
228 void ResetNumNotifications() { num_notifications_ = 0; } | |
229 | |
230 private: | |
231 GURL icon_url_; | |
232 gfx::Image image_; | |
233 size_t num_notifications_; | |
234 | |
235 // The unique id of a download request. It will be returned to a | |
236 // FaviconHandler. | |
237 int download_id_; | |
238 | |
239 DownloadHandler download_handler_; | |
240 | |
241 DISALLOW_COPY_AND_ASSIGN(TestDelegate); | |
242 }; | |
243 | |
244 } // namespace | |
245 | |
246 // This class is used to catch the FaviconHandler's download and history | |
247 // request, and also provide the methods to access the FaviconHandler | |
248 // internals. | |
249 class TestFaviconHandler : public FaviconHandler { | |
250 public: | |
251 static int GetMaximalIconSize(favicon_base::IconType icon_type) { | |
252 return FaviconHandler::GetMaximalIconSize(icon_type); | |
253 } | |
254 | |
255 TestFaviconHandler(FaviconHandler::Delegate* delegate, | |
256 FaviconDriverObserver::NotificationIconType handler_type) | |
257 : FaviconHandler(nullptr, delegate, handler_type) {} | |
258 | |
259 ~TestFaviconHandler() override {} | |
260 | |
261 HistoryRequestHandler* history_handler() { | |
262 return history_handler_.get(); | |
263 } | |
264 | |
265 // This method will take the ownership of the given handler. | |
266 void set_history_handler(HistoryRequestHandler* handler) { | |
267 history_handler_.reset(handler); | |
268 } | |
269 | |
270 FaviconURL* current_candidate() { | |
271 return FaviconHandler::current_candidate(); | |
272 } | |
273 | |
274 size_t current_candidate_index() const { | |
275 return current_candidate_index_; | |
276 } | |
277 | |
278 const FaviconCandidate& best_favicon_candidate() { | |
279 return best_favicon_candidate_; | |
280 } | |
281 | |
282 protected: | |
283 void UpdateFaviconMappingAndFetch( | |
284 const GURL& page_url, | |
285 const GURL& icon_url, | |
286 favicon_base::IconType icon_type, | |
287 const favicon_base::FaviconResultsCallback& callback, | |
288 base::CancelableTaskTracker* tracker) override { | |
289 history_handler_.reset(new HistoryRequestHandler(page_url, icon_url, | |
290 icon_type, callback)); | |
291 } | |
292 | |
293 void GetFaviconFromFaviconService( | |
294 const GURL& icon_url, | |
295 favicon_base::IconType icon_type, | |
296 const favicon_base::FaviconResultsCallback& callback, | |
297 base::CancelableTaskTracker* tracker) override { | |
298 history_handler_.reset(new HistoryRequestHandler(GURL(), icon_url, | |
299 icon_type, callback)); | |
300 } | |
301 | |
302 void GetFaviconForURLFromFaviconService( | |
303 const GURL& page_url, | |
304 int icon_types, | |
305 const favicon_base::FaviconResultsCallback& callback, | |
306 base::CancelableTaskTracker* tracker) override { | |
307 history_handler_.reset(new HistoryRequestHandler(page_url, GURL(), | |
308 icon_types, callback)); | |
309 } | |
310 | |
311 void SetHistoryFavicons(const GURL& page_url, | |
312 const GURL& icon_url, | |
313 favicon_base::IconType icon_type, | |
314 const gfx::Image& image) override { | |
315 scoped_refptr<base::RefCountedMemory> bytes = image.As1xPNGBytes(); | |
316 std::vector<unsigned char> bitmap_data(bytes->front(), | |
317 bytes->front() + bytes->size()); | |
318 history_handler_.reset(new HistoryRequestHandler( | |
319 page_url, icon_url, icon_type, bitmap_data, image.Size())); | |
320 } | |
321 | |
322 bool ShouldSaveFavicon() override { return true; } | |
323 | |
324 GURL page_url_; | |
325 | |
326 private: | |
327 std::unique_ptr<HistoryRequestHandler> history_handler_; | |
328 | |
329 DISALLOW_COPY_AND_ASSIGN(TestFaviconHandler); | |
330 }; | |
331 | |
332 namespace { | |
333 | |
334 void HistoryRequestHandler::InvokeCallback() { | |
335 if (!callback_.is_null()) { | |
336 callback_.Run(history_results_); | |
337 } | |
338 } | |
339 | |
340 void DownloadHandler::InvokeCallback() { | |
341 if (callback_invoked_) | |
342 return; | |
343 | |
344 std::vector<gfx::Size> original_bitmap_sizes; | |
345 std::vector<SkBitmap> bitmaps; | |
346 if (should_fail_download_icon_urls_.count(download_->image_url)) { | |
347 failed_download_icon_urls_.insert(download_->image_url); | |
348 } else { | |
349 for (std::vector<int>::const_iterator i = download_->image_sizes.begin(); | |
350 i != download_->image_sizes.end(); ++i) { | |
351 int original_size = (*i > 0) ? *i : gfx::kFaviconSize; | |
352 int downloaded_size = original_size; | |
353 if (download_->max_image_size != 0 && | |
354 downloaded_size > download_->max_image_size) { | |
355 downloaded_size = download_->max_image_size; | |
356 } | |
357 SkBitmap bitmap; | |
358 FillDataToBitmap(downloaded_size, downloaded_size, &bitmap); | |
359 bitmaps.push_back(bitmap); | |
360 original_bitmap_sizes.push_back(gfx::Size(original_size, original_size)); | |
361 } | |
362 } | |
363 download_->callback.Run(download_->download_id, | |
364 /*=status_code=*/200, download_->image_url, bitmaps, | |
365 original_bitmap_sizes); | |
366 callback_invoked_ = true; | |
367 } | |
368 | |
369 class FaviconHandlerTest : public testing::Test { | 206 class FaviconHandlerTest : public testing::Test { |
370 protected: | 207 protected: |
208 const std::vector<gfx::Size> kEmptySizes; | |
209 const std::vector<SkBitmap> kEmptyBitmaps; | |
210 const std::vector<FaviconRawBitmapResult> kEmptyRawBitmapResult; | |
211 | |
212 // Some known icons for which download will succeed. | |
213 const GURL kPageURL = GURL("http://www.google.com"); | |
214 const GURL kIconURL10x10 = GURL("http://www.google.com/favicon10x10"); | |
215 const GURL kIconURL12x12 = GURL("http://www.google.com/favicon12x12"); | |
216 const GURL kIconURL16x16 = GURL("http://www.google.com/favicon16x16"); | |
217 const GURL kIconURL64x64 = GURL("http://www.google.com/favicon64x64"); | |
218 | |
371 FaviconHandlerTest() { | 219 FaviconHandlerTest() { |
372 } | 220 // Emulate the cache being initially empty, unless overriden in tests. |
373 | 221 ON_CALL(favicon_service_, GetFaviconForPageURL(_, _, _, _, _)) |
374 ~FaviconHandlerTest() override {} | 222 .WillByDefault(PostReply<5>(kEmptyRawBitmapResult)); |
223 ON_CALL(favicon_service_, GetFavicon(_, _, _, _, _)) | |
224 .WillByDefault(PostReply<5>(kEmptyRawBitmapResult)); | |
225 ON_CALL(favicon_service_, UpdateFaviconMappingsAndFetch(_, _, _, _, _, _)) | |
226 .WillByDefault(PostReply<6>(kEmptyRawBitmapResult)); | |
227 // Let's be "nice" about reads, to avoid boilerplate in tests. | |
228 EXPECT_CALL(favicon_service_, GetFaviconForPageURL(_, _, _, _, _)) | |
229 .Times(AnyNumber()); | |
230 EXPECT_CALL(favicon_service_, GetFavicon(_, _, _, _, _)).Times(AnyNumber()); | |
231 EXPECT_CALL(favicon_service_, WasUnableToDownloadFavicon(_)) | |
232 .Times(AnyNumber()); | |
233 // Let's be "strict" about image downloads, unless explicitly listed in | |
234 // test. | |
235 EXPECT_CALL(delegate_, DownloadImage(_, _, _)).Times(0); | |
pkotwicz
2017/03/09 02:15:09
Each test which wants to check that there has been
mastiz
2017/03/09 10:40:08
Done, reverted.
| |
236 // Delegate image downloading to FakeImageDownloader. | |
237 ON_CALL(delegate_, DownloadImage(_, _, _)) | |
238 .WillByDefault(Invoke(&fake_image_downloader_, | |
239 &FakeImageDownloader::DownloadImage)); | |
pkotwicz
2017/03/09 02:15:08
Can we move this ON_CALL to the MockDelegate const
mastiz
2017/03/09 10:40:08
Done, although I see no benefit.
| |
240 // Register various known icon URLs. | |
241 fake_image_downloader_.Add(kIconURL10x10, IntVector{10}); | |
242 fake_image_downloader_.Add(kIconURL12x12, IntVector{12}); | |
243 fake_image_downloader_.Add(kIconURL16x16, IntVector{16}); | |
244 fake_image_downloader_.Add(kIconURL64x64, IntVector{64}); | |
245 // The score computed by SelectFaviconFrames() is dependent on the supported | |
246 // scale factors of the platform. It is used for determining the goodness of | |
247 // a downloaded bitmap in FaviconHandler::OnDidDownloadFavicon(). | |
248 // Force the values of the scale factors so that the tests produce the same | |
249 // results on all platforms. | |
250 scoped_set_supported_scale_factors_.reset( | |
251 new ui::test::ScopedSetSupportedScaleFactors({ui::SCALE_FACTOR_100P})); | |
252 } | |
253 | |
254 // Creates a new handler and feeds in the page URL and the candidates. | |
255 // Returns the handler in case tests want to exercise further steps. | |
256 std::unique_ptr<FaviconHandler> RunHandlerWithCandidates( | |
257 FaviconDriverObserver::NotificationIconType handler_type, | |
258 const std::vector<favicon::FaviconURL>& candidates, | |
259 bool flush_events_before_candidates = true) { | |
260 auto handler = base::MakeUnique<FaviconHandler>(&favicon_service_, | |
261 &delegate_, handler_type); | |
262 handler->FetchFavicon(kPageURL); | |
263 // The first RunUntilIdle() causes the FaviconService lookups be faster than | |
264 // OnUpdateFaviconURL(), which is the most likely scenario. | |
265 if (flush_events_before_candidates) | |
266 base::RunLoop().RunUntilIdle(); | |
267 handler->OnUpdateFaviconURL(kPageURL, candidates); | |
268 base::RunLoop().RunUntilIdle(); | |
269 return handler; | |
270 } | |
375 | 271 |
376 // Simulates requesting a favicon for |page_url| given: | 272 // Simulates requesting a favicon for |page_url| given: |
377 // - We have not previously cached anything in history for |page_url| or for | 273 // - We have not previously cached anything in history for |page_url| or for |
378 // any of |candidates|. | 274 // any of |candidates|. |
379 // - The page provides favicons at |candidate_icons|. | 275 // - The page provides favicons at |candidate_icons|. |
380 // - The favicons at |candidate_icons| have edge pixel sizes of | 276 // - The favicons at |candidate_icons| have edge pixel sizes of |
381 // |candidate_icon_sizes|. | 277 // |candidate_icon_sizes|. |
382 void DownloadTillDoneIgnoringHistory( | 278 // |
383 TestDelegate* delegate, | 279 // Returns the chosen size among |candidate_icon_sizes| or -1 if none was |
384 TestFaviconHandler* favicon_handler, | 280 // chosen. |
385 const GURL& page_url, | 281 int DownloadTillDoneIgnoringHistory( |
386 const std::vector<FaviconURL>& candidate_icons, | 282 const std::vector<FaviconURL>& candidate_icons, |
387 const int* candidate_icon_sizes) { | 283 const IntVector& candidate_icon_sizes) { |
388 size_t old_num_notifications = delegate->num_notifications(); | 284 DCHECK_EQ(candidate_icons.size(), candidate_icon_sizes.size()); |
389 | 285 // Set up 200 responses for all images, and the corresponding size. |
390 UpdateFaviconURL(delegate, favicon_handler, page_url, candidate_icons); | |
391 EXPECT_EQ(candidate_icons.size(), favicon_handler->image_urls().size()); | |
392 | |
393 DownloadHandler* download_handler = delegate->download_handler(); | |
394 for (size_t i = 0; i < candidate_icons.size(); ++i) { | 286 for (size_t i = 0; i < candidate_icons.size(); ++i) { |
395 favicon_handler->history_handler()->history_results_.clear(); | 287 const FaviconURL& candidate_icon = candidate_icons[i]; |
396 favicon_handler->history_handler()->InvokeCallback(); | 288 const GURL& icon_url = candidate_icon.icon_url; |
397 ASSERT_TRUE(download_handler->HasDownload()); | 289 const int icon_size = candidate_icon_sizes[i]; |
398 EXPECT_EQ(download_handler->GetImageUrl(), | 290 fake_image_downloader_.Add(icon_url, IntVector{icon_size}); |
399 candidate_icons[i].icon_url); | |
400 std::vector<int> sizes; | |
401 sizes.push_back(candidate_icon_sizes[i]); | |
402 download_handler->SetImageSizes(sizes); | |
403 download_handler->InvokeCallback(); | |
404 | |
405 download_handler->Reset(); | |
406 | |
407 if (delegate->num_notifications() > old_num_notifications) | |
408 return; | |
409 } | 291 } |
410 } | 292 |
411 | 293 EXPECT_CALL(delegate_, DownloadImage(_, _, _)) |
412 void UpdateFaviconURL(TestDelegate* delegate, | 294 .Times(AtMost(candidate_icon_sizes.size())); |
413 TestFaviconHandler* favicon_handler, | 295 EXPECT_CALL(favicon_service_, |
414 const GURL& page_url, | 296 UpdateFaviconMappingsAndFetch(_, _, _, _, _, _)) |
415 const std::vector<FaviconURL>& candidate_icons) { | 297 .Times(AtMost(candidate_icon_sizes.size())); |
416 delegate->ResetNumNotifications(); | 298 EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, _, FAVICON, _)) |
417 | 299 .Times(AtMost(1)); |
418 favicon_handler->FetchFavicon(page_url); | 300 |
419 favicon_handler->history_handler()->InvokeCallback(); | 301 GURL chosen_icon_url; |
420 | 302 ON_CALL(delegate_, OnFaviconUpdated( |
421 favicon_handler->OnUpdateFaviconURL(page_url, candidate_icons); | 303 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, _, |
422 } | 304 /*icon_url_changed=*/true, _)) |
423 | 305 .WillByDefault(SaveArg<2>(&chosen_icon_url)); |
424 void SetUp() override { | 306 |
425 // The score computed by SelectFaviconFrames() is dependent on the supported | 307 RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, |
426 // scale factors of the platform. It is used for determining the goodness of | 308 candidate_icons); |
427 // a downloaded bitmap in FaviconHandler::OnDidDownloadFavicon(). | 309 for (size_t i = 0; i < candidate_icons.size(); ++i) { |
428 // Force the values of the scale factors so that the tests produce the same | 310 if (candidate_icons[i].icon_url == chosen_icon_url) |
429 // results on all platforms. | 311 return candidate_icon_sizes[i]; |
430 std::vector<ui::ScaleFactor> scale_factors; | 312 } |
431 scale_factors.push_back(ui::SCALE_FACTOR_100P); | 313 return -1; |
432 scoped_set_supported_scale_factors_.reset( | 314 } |
433 new ui::test::ScopedSetSupportedScaleFactors(scale_factors)); | 315 |
434 testing::Test::SetUp(); | 316 base::MessageLoopForUI message_loop_; |
435 } | |
436 | |
437 std::unique_ptr<ui::test::ScopedSetSupportedScaleFactors> | 317 std::unique_ptr<ui::test::ScopedSetSupportedScaleFactors> |
438 scoped_set_supported_scale_factors_; | 318 scoped_set_supported_scale_factors_; |
319 testing::StrictMock<MockFaviconService> favicon_service_; | |
320 FakeImageDownloader fake_image_downloader_; | |
321 testing::NiceMock<MockDelegate> delegate_; | |
439 }; | 322 }; |
440 | 323 |
324 // Test that FaviconHandler process finishes when: | |
325 // - The icon URL used by the page has changed. | |
326 // AND | |
327 // - FaviconService::GetFaviconForPageURL() callback returns before | |
328 // FaviconHandler::OnUpdateFaviconURL() is called. | |
441 TEST_F(FaviconHandlerTest, GetFaviconFromHistory) { | 329 TEST_F(FaviconHandlerTest, GetFaviconFromHistory) { |
442 const GURL page_url("http://www.google.com"); | 330 const GURL kIconURL("http://www.google.com/favicon"); |
443 const GURL icon_url("http://www.google.com/favicon"); | 331 |
444 | 332 ON_CALL(favicon_service_, GetFaviconForPageURL(kPageURL, _, _, _, _)) |
445 TestDelegate delegate; | 333 .WillByDefault(PostReply<5>( |
446 TestFaviconHandler helper(&delegate, FaviconDriverObserver::NON_TOUCH_16_DIP); | 334 CreateRawBitmapResult(kIconURL, FAVICON, /*expired=*/false))); |
447 | 335 |
448 helper.FetchFavicon(page_url); | 336 // Shouldn't request to download icon. |
449 HistoryRequestHandler* history_handler = helper.history_handler(); | 337 EXPECT_CALL(delegate_, DownloadImage(_, _, _)).Times(0); |
450 // Ensure the data given to history is correct. | 338 EXPECT_CALL(delegate_, OnFaviconUpdated( |
451 ASSERT_TRUE(history_handler); | 339 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, |
452 EXPECT_EQ(page_url, history_handler->page_url_); | 340 kIconURL, /*icon_url_changed=*/true, _)); |
453 EXPECT_EQ(GURL(), history_handler->icon_url_); | 341 |
454 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); | 342 RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, |
455 | 343 {FaviconURL(kIconURL, FAVICON, kEmptySizes)}); |
456 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_); | 344 } |
457 | 345 |
458 // Send history response. | 346 // Test that OnFaviconUpdated() is called to update the UI when the initial DB |
459 history_handler->InvokeCallback(); | 347 // request completes if there is matching data in the database. This is nice |
460 // Verify FaviconHandler status | 348 // because we only get the icon URLs associated with the page once the page |
461 EXPECT_EQ(1u, delegate.num_notifications()); | 349 // loading stops which can take a while. |
462 EXPECT_EQ(icon_url, delegate.icon_url()); | 350 TEST_F(FaviconHandlerTest, GetFaviconFromHistoryBeforeCandidates) { |
463 | 351 const GURL kIconURL("http://www.google.com/favicon"); |
464 // Simulates update favicon url. | 352 |
465 std::vector<FaviconURL> urls; | 353 ON_CALL(favicon_service_, GetFaviconForPageURL(kPageURL, _, _, _, _)) |
466 urls.push_back( | 354 .WillByDefault(PostReply<5>( |
467 FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>())); | 355 CreateRawBitmapResult(kIconURL, FAVICON, /*expired=*/false))); |
468 helper.OnUpdateFaviconURL(page_url, urls); | 356 |
469 | 357 EXPECT_CALL(delegate_, OnFaviconUpdated( |
470 // Verify FaviconHandler status | 358 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, |
471 EXPECT_EQ(1u, helper.image_urls().size()); | 359 kIconURL, /*icon_url_changed=*/true, _)); |
472 ASSERT_TRUE(helper.current_candidate()); | 360 |
473 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url); | 361 FaviconHandler handler(&favicon_service_, &delegate_, |
474 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type); | 362 FaviconDriverObserver::NON_TOUCH_16_DIP); |
475 | 363 handler.FetchFavicon(kPageURL); |
476 // Favicon shouldn't request to download icon. | 364 base::RunLoop().RunUntilIdle(); |
477 EXPECT_FALSE(delegate.download_handler()->HasDownload()); | 365 } |
478 } | 366 |
479 | 367 TEST_F(FaviconHandlerTest, DownloadUnknownFavicon) { |
480 TEST_F(FaviconHandlerTest, DownloadFavicon) { | 368 InSequence seq; |
481 const GURL page_url("http://www.google.com"); | 369 EXPECT_CALL(favicon_service_, |
482 const GURL icon_url("http://www.google.com/favicon"); | 370 UpdateFaviconMappingsAndFetch(kPageURL, URLVector{kIconURL16x16}, |
483 | 371 FAVICON, _, _, _)); |
484 TestDelegate delegate; | 372 EXPECT_CALL(delegate_, DownloadImage(kIconURL16x16, _, _)); |
485 TestFaviconHandler helper(&delegate, FaviconDriverObserver::NON_TOUCH_16_DIP); | 373 EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, FAVICON, |
486 | 374 ImageSizeIs(16, 16))); |
487 helper.FetchFavicon(page_url); | 375 EXPECT_CALL(delegate_, OnFaviconUpdated( |
488 HistoryRequestHandler* history_handler = helper.history_handler(); | 376 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, |
489 // Ensure the data given to history is correct. | 377 kIconURL16x16, /*icon_url_changed=*/true, _)); |
490 ASSERT_TRUE(history_handler); | 378 |
491 EXPECT_EQ(page_url, history_handler->page_url_); | 379 RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, |
492 EXPECT_EQ(GURL(), history_handler->icon_url_); | 380 {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}); |
493 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); | 381 } |
494 | 382 |
495 // Set icon data expired | 383 TEST_F(FaviconHandlerTest, DownloadUnknownFaviconInIncognito) { |
496 SetFaviconRawBitmapResult(icon_url, | 384 ON_CALL(delegate_, IsOffTheRecord()).WillByDefault(Return(true)); |
497 favicon_base::FAVICON, | 385 |
498 true /* expired */, | 386 // No writes expected. |
499 &history_handler->history_results_); | 387 EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch(_, _, _, _, _, _)) |
500 // Send history response. | 388 .Times(0); |
501 history_handler->InvokeCallback(); | 389 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)).Times(0); |
502 // Verify FaviconHandler status | 390 |
503 EXPECT_EQ(1u, delegate.num_notifications()); | 391 InSequence seq; |
504 EXPECT_EQ(icon_url, delegate.icon_url()); | 392 EXPECT_CALL(delegate_, DownloadImage(kIconURL16x16, _, _)); |
505 | 393 EXPECT_CALL(delegate_, OnFaviconUpdated( |
506 // Simulates update favicon url. | 394 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, |
507 std::vector<FaviconURL> urls; | 395 kIconURL16x16, /*icon_url_changed=*/true, _)); |
508 urls.push_back( | 396 |
509 FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>())); | 397 RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, |
510 helper.OnUpdateFaviconURL(page_url, urls); | 398 {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}); |
511 | 399 } |
512 // Verify FaviconHandler status | 400 |
513 EXPECT_EQ(1u, helper.image_urls().size()); | 401 // Test that FaviconHandler process finishes when: |
514 ASSERT_TRUE(helper.current_candidate()); | 402 // - The icon URL used by the page has changed. |
515 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url); | 403 // AND |
516 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type); | 404 // - FaviconService::GetFaviconForPageURL() callback returns after |
517 | 405 // FaviconHandler::OnUpdateFaviconURL() is called. |
518 // Favicon should request to download icon now. | 406 TEST_F(FaviconHandlerTest, DownloadUnknownFaviconIfCandidatesFaster) { |
519 DownloadHandler* download_handler = delegate.download_handler(); | 407 InSequence seq; |
520 EXPECT_TRUE(download_handler->HasDownload()); | 408 EXPECT_CALL(favicon_service_, |
521 | 409 UpdateFaviconMappingsAndFetch(kPageURL, URLVector{kIconURL16x16}, |
522 // Verify the download request. | 410 FAVICON, _, _, _)); |
523 EXPECT_EQ(icon_url, download_handler->GetImageUrl()); | 411 EXPECT_CALL(delegate_, DownloadImage(kIconURL16x16, _, _)); |
524 | 412 EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, FAVICON, |
525 // Reset the history_handler to verify whether favicon is set. | 413 ImageSizeIs(16, 16))); |
526 helper.set_history_handler(nullptr); | 414 EXPECT_CALL(delegate_, OnFaviconUpdated( |
527 | 415 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, |
528 // Smulates download done. | 416 kIconURL16x16, /*icon_url_changed=*/true, _)); |
529 download_handler->InvokeCallback(); | 417 |
530 | 418 RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, |
531 // New icon should be saved to history backend and navigation entry. | 419 {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}, |
532 history_handler = helper.history_handler(); | 420 /*flush_events_before_candidates=*/false); |
533 ASSERT_TRUE(history_handler); | 421 } |
534 EXPECT_EQ(icon_url, history_handler->icon_url_); | 422 |
535 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); | 423 // Test that the icon is redownloaded if the icon cached for the page URL has |
536 EXPECT_LT(0U, history_handler->bitmap_data_.size()); | 424 // expired. |
537 EXPECT_EQ(page_url, history_handler->page_url_); | 425 TEST_F(FaviconHandlerTest, RedownloadExpiredFavicon) { |
538 | 426 ON_CALL(favicon_service_, GetFaviconForPageURL(kPageURL, _, _, _, _)) |
539 // Verify NavigationEntry. | 427 .WillByDefault(PostReply<5>( |
540 EXPECT_EQ(2u, delegate.num_notifications()); | 428 CreateRawBitmapResult(kIconURL16x16, FAVICON, /*expired=*/true))); |
pkotwicz
2017/03/09 02:15:08
TestFaviconService::Store(kPageURL, kIconURL16x16,
mastiz
2017/03/09 10:40:08
I personally disagree this is better because the b
| |
541 EXPECT_EQ(icon_url, delegate.icon_url()); | 429 |
pkotwicz
2017/03/09 02:15:08
We want to check that UpdateFaviconMappingsAndFetc
mastiz
2017/03/09 10:40:08
Done.
| |
542 EXPECT_FALSE(delegate.image().IsEmpty()); | 430 InSequence seq; |
543 EXPECT_EQ(gfx::kFaviconSize, delegate.image().Width()); | 431 EXPECT_CALL(delegate_, OnFaviconUpdated( |
432 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, | |
433 kIconURL16x16, /*icon_url_changed=*/true, _)); | |
pkotwicz
2017/03/09 02:15:08
We don't care about the values of any of the param
mastiz
2017/03/09 10:40:07
Done, except for icon_url_changed which I think we
pkotwicz
2017/03/13 05:16:31
I'd rather have separate tests which test the |ico
mastiz
2017/03/13 12:46:02
Done.
| |
434 EXPECT_CALL(delegate_, DownloadImage(kIconURL16x16, _, _)); | |
435 EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, FAVICON, | |
436 ImageSizeIs(16, 16))); | |
437 EXPECT_CALL(delegate_, OnFaviconUpdated( | |
438 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, | |
439 kIconURL16x16, /*icon_url_changed=*/false, _)); | |
pkotwicz
2017/03/09 02:15:08
It would be nice if we could check whether the two
mastiz
2017/03/09 10:40:08
Added TODO, since I believe the former tests didn'
pkotwicz
2017/03/13 05:16:31
Please file a bug to do this :)
mastiz
2017/03/13 12:46:03
Done.
| |
440 | |
441 RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, | |
442 {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}); | |
pkotwicz
2017/03/09 02:15:08
Can you add RunHandlerWithGURLCandidates() which t
mastiz
2017/03/09 10:40:07
Done.
| |
443 } | |
444 | |
445 // Test that an icon is not redownloaded if a previous attempt returned a 404. | |
446 TEST_F(FaviconHandlerTest, NotRedownloadForPrevious404) { | |
447 ON_CALL(favicon_service_, WasUnableToDownloadFavicon(kIconURL16x16)) | |
448 .WillByDefault(Return(true)); | |
449 | |
450 EXPECT_CALL(delegate_, DownloadImage(_, _, _)).Times(0); | |
451 | |
452 EXPECT_CALL(favicon_service_, | |
453 UpdateFaviconMappingsAndFetch(kPageURL, URLVector{kIconURL16x16}, | |
454 _, _, _, _)); | |
455 | |
456 RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, | |
457 {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}); | |
458 } | |
459 | |
460 TEST_F(FaviconHandlerTest, Report404) { | |
461 const GURL k404IconURL("http://www.google.com/404.png"); | |
462 | |
463 EXPECT_CALL(favicon_service_, | |
464 UpdateFaviconMappingsAndFetch(_, _, _, _, _, _)); | |
465 EXPECT_CALL(delegate_, DownloadImage(k404IconURL, _, _)); | |
466 EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(k404IconURL)); | |
467 | |
468 RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, | |
469 {FaviconURL(k404IconURL, FAVICON, kEmptySizes)}); | |
470 } | |
471 | |
472 // Test that WasUnableToDownloadFavicon() is not called if a download returns | |
473 // HTTP status 503. | |
474 TEST_F(FaviconHandlerTest, NotReport503) { | |
475 const GURL k503IconURL("http://www.google.com/503.png"); | |
476 | |
477 fake_image_downloader_.AddError(k503IconURL, 503); | |
478 | |
479 EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(k503IconURL)).Times(0); | |
480 | |
481 EXPECT_CALL(favicon_service_, | |
482 UpdateFaviconMappingsAndFetch(_, _, _, _, _, _)); | |
483 EXPECT_CALL(delegate_, DownloadImage(k503IconURL, _, _)); | |
484 | |
485 RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, | |
486 {FaviconURL(k503IconURL, FAVICON, kEmptySizes)}); | |
544 } | 487 } |
545 | 488 |
546 TEST_F(FaviconHandlerTest, UpdateAndDownloadFavicon) { | 489 TEST_F(FaviconHandlerTest, UpdateAndDownloadFavicon) { |
547 const GURL page_url("http://www.google.com"); | 490 const GURL kOldIconURL("http://www.google.com/old_favicon"); |
548 const GURL icon_url("http://www.google.com/favicon"); | 491 ON_CALL(favicon_service_, GetFaviconForPageURL(kPageURL, _, _, _, _)) |
549 const GURL new_icon_url("http://www.google.com/new_favicon"); | 492 .WillByDefault(PostReply<5>(CreateRawBitmapResult(kOldIconURL, FAVICON, |
550 | 493 /*expired=*/false))); |
551 TestDelegate delegate; | 494 |
552 TestFaviconHandler helper(&delegate, FaviconDriverObserver::NON_TOUCH_16_DIP); | 495 InSequence seq; |
553 | 496 EXPECT_CALL(delegate_, OnFaviconUpdated( |
554 helper.FetchFavicon(page_url); | 497 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, |
555 HistoryRequestHandler* history_handler = helper.history_handler(); | 498 kOldIconURL, /*icon_url_changed=*/true, _)); |
556 // Ensure the data given to history is correct. | 499 EXPECT_CALL(favicon_service_, |
557 ASSERT_TRUE(history_handler); | 500 UpdateFaviconMappingsAndFetch(kPageURL, URLVector{kIconURL16x16}, |
558 EXPECT_EQ(page_url, history_handler->page_url_); | 501 FAVICON, _, _, _)); |
559 EXPECT_EQ(GURL(), history_handler->icon_url_); | 502 EXPECT_CALL(delegate_, DownloadImage(kIconURL16x16, _, _)); |
560 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); | 503 EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, FAVICON, |
561 | 504 ImageSizeIs(16, 16))); |
562 // Set valid icon data. | 505 EXPECT_CALL(delegate_, OnFaviconUpdated( |
563 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_); | 506 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, |
564 | 507 kIconURL16x16, /*icon_url_changed=*/true, _)); |
565 // Send history response. | 508 |
566 history_handler->InvokeCallback(); | 509 RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, |
567 // Verify FaviconHandler status. | 510 {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}); |
568 EXPECT_EQ(1u, delegate.num_notifications()); | 511 } |
569 EXPECT_EQ(icon_url, delegate.icon_url()); | 512 |
570 | 513 // If there is data for the page URL in history which is invalid, test that: |
571 // Reset the history_handler to verify whether new icon is requested from | 514 // - the invalid data is not sent to the UI. |
572 // history. | 515 // - the icon is redownloaded. |
573 helper.set_history_handler(nullptr); | |
574 | |
575 // Simulates update with the different favicon url. | |
576 std::vector<FaviconURL> urls; | |
577 urls.push_back(FaviconURL( | |
578 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>())); | |
579 helper.OnUpdateFaviconURL(page_url, urls); | |
580 | |
581 // Verify FaviconHandler status. | |
582 EXPECT_EQ(1u, helper.image_urls().size()); | |
583 ASSERT_TRUE(helper.current_candidate()); | |
584 ASSERT_EQ(new_icon_url, helper.current_candidate()->icon_url); | |
585 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type); | |
586 | |
587 // Favicon should be requested from history. | |
588 history_handler = helper.history_handler(); | |
589 ASSERT_TRUE(history_handler); | |
590 EXPECT_EQ(new_icon_url, history_handler->icon_url_); | |
591 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); | |
592 EXPECT_EQ(page_url, history_handler->page_url_); | |
593 | |
594 // Simulate not find icon. | |
595 history_handler->history_results_.clear(); | |
596 history_handler->InvokeCallback(); | |
597 | |
598 // Favicon should request to download icon now. | |
599 DownloadHandler* download_handler = delegate.download_handler(); | |
600 EXPECT_TRUE(download_handler->HasDownload()); | |
601 | |
602 // Verify the download request. | |
603 EXPECT_EQ(new_icon_url, download_handler->GetImageUrl()); | |
604 | |
605 // Reset the history_handler to verify whether favicon is set. | |
606 helper.set_history_handler(nullptr); | |
607 | |
608 // Smulates download done. | |
609 download_handler->InvokeCallback(); | |
610 | |
611 // New icon should be saved to history backend and navigation entry. | |
612 history_handler = helper.history_handler(); | |
613 ASSERT_TRUE(history_handler); | |
614 EXPECT_EQ(new_icon_url, history_handler->icon_url_); | |
615 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); | |
616 EXPECT_LT(0U, history_handler->bitmap_data_.size()); | |
617 EXPECT_EQ(page_url, history_handler->page_url_); | |
618 | |
619 // Verify NavigationEntry. | |
620 EXPECT_EQ(2u, delegate.num_notifications()); | |
621 EXPECT_EQ(new_icon_url, delegate.icon_url()); | |
622 EXPECT_FALSE(delegate.image().IsEmpty()); | |
623 EXPECT_EQ(gfx::kFaviconSize, delegate.image().Width()); | |
624 } | |
625 | |
626 TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) { | 516 TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) { |
627 const GURL page_url("http://www.google.com"); | |
628 const GURL icon_url("http://www.google.com/favicon"); | |
629 | |
630 TestDelegate delegate; | |
631 TestFaviconHandler helper(&delegate, FaviconDriverObserver::NON_TOUCH_16_DIP); | |
632 | |
633 helper.FetchFavicon(page_url); | |
634 HistoryRequestHandler* history_handler = helper.history_handler(); | |
635 // Ensure the data given to history is correct. | |
636 ASSERT_TRUE(history_handler); | |
637 EXPECT_EQ(page_url, history_handler->page_url_); | |
638 EXPECT_EQ(GURL(), history_handler->icon_url_); | |
639 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); | |
640 | |
641 // Set non empty but invalid data. | 517 // Set non empty but invalid data. |
642 favicon_base::FaviconRawBitmapResult bitmap_result; | 518 FaviconRawBitmapResult bitmap_result; |
643 bitmap_result.expired = false; | 519 bitmap_result.expired = false; |
644 // Empty bitmap data is invalid. | 520 // Empty bitmap data is invalid. |
645 bitmap_result.bitmap_data = new base::RefCountedBytes(); | 521 bitmap_result.bitmap_data = new base::RefCountedBytes(); |
646 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize); | 522 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize); |
647 bitmap_result.icon_type = favicon_base::FAVICON; | 523 bitmap_result.icon_type = FAVICON; |
648 bitmap_result.icon_url = icon_url; | 524 bitmap_result.icon_url = kIconURL16x16; |
649 history_handler->history_results_.clear(); | 525 |
650 history_handler->history_results_.push_back(bitmap_result); | 526 ON_CALL(favicon_service_, GetFaviconForPageURL(kPageURL, _, _, _, _)) |
651 | 527 .WillByDefault( |
652 // Send history response. | 528 PostReply<5>(std::vector<FaviconRawBitmapResult>{bitmap_result})); |
653 history_handler->InvokeCallback(); | 529 |
654 // The NavigationEntry should not be set yet as the history data is invalid. | 530 InSequence seq; |
655 EXPECT_EQ(0u, delegate.num_notifications()); | 531 EXPECT_CALL(delegate_, DownloadImage(kIconURL16x16, _, _)); |
656 EXPECT_EQ(GURL(), delegate.icon_url()); | 532 EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, _, _)); |
657 | 533 EXPECT_CALL(delegate_, OnFaviconUpdated( |
658 // Reset the history_handler to verify whether new icon is requested from | 534 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, |
659 // history. | 535 kIconURL16x16, /*icon_url_changed=*/true, _)); |
660 helper.set_history_handler(nullptr); | 536 |
661 | 537 RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, |
662 // Simulates update with matching favicon URL. | 538 {FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}); |
663 std::vector<FaviconURL> urls; | 539 } |
664 urls.push_back( | 540 |
665 FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>())); | 541 // Test that no downloads are done if a user visits a page which changed its |
666 helper.OnUpdateFaviconURL(page_url, urls); | 542 // favicon URL to a favicon URL which is already cached in the database. |
667 | |
668 // A download for the favicon should be requested, and we should not do | |
669 // another history request. | |
670 DownloadHandler* download_handler = delegate.download_handler(); | |
671 EXPECT_TRUE(download_handler->HasDownload()); | |
672 EXPECT_EQ(nullptr, helper.history_handler()); | |
673 | |
674 // Verify the download request. | |
675 EXPECT_EQ(icon_url, download_handler->GetImageUrl()); | |
676 | |
677 // Simulates download done. | |
678 download_handler->InvokeCallback(); | |
679 | |
680 // New icon should be saved to history backend and navigation entry. | |
681 history_handler = helper.history_handler(); | |
682 ASSERT_TRUE(history_handler); | |
683 EXPECT_EQ(icon_url, history_handler->icon_url_); | |
684 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); | |
685 EXPECT_LT(0U, history_handler->bitmap_data_.size()); | |
686 EXPECT_EQ(page_url, history_handler->page_url_); | |
687 | |
688 // Verify NavigationEntry. | |
689 EXPECT_EQ(1u, delegate.num_notifications()); | |
690 EXPECT_EQ(icon_url, delegate.icon_url()); | |
691 EXPECT_FALSE(delegate.image().IsEmpty()); | |
692 EXPECT_EQ(gfx::kFaviconSize, delegate.image().Width()); | |
693 } | |
694 | |
695 TEST_F(FaviconHandlerTest, UpdateFavicon) { | 543 TEST_F(FaviconHandlerTest, UpdateFavicon) { |
696 const GURL page_url("http://www.google.com"); | 544 const GURL kIconURL("http://www.google.com/favicon"); |
697 const GURL icon_url("http://www.google.com/favicon"); | 545 const GURL kNewIconURL("http://www.google.com/new_favicon"); |
698 const GURL new_icon_url("http://www.google.com/new_favicon"); | 546 |
699 | 547 ON_CALL(favicon_service_, GetFaviconForPageURL(kPageURL, FAVICON, _, _, _)) |
700 TestDelegate delegate; | 548 .WillByDefault(PostReply<5>( |
701 TestFaviconHandler helper(&delegate, FaviconDriverObserver::NON_TOUCH_16_DIP); | 549 CreateRawBitmapResult(kIconURL, FAVICON, /*expired=*/false))); |
702 | 550 |
703 helper.FetchFavicon(page_url); | 551 // Shouldn't request to download icon. |
704 HistoryRequestHandler* history_handler = helper.history_handler(); | 552 EXPECT_CALL(delegate_, DownloadImage(_, _, _)).Times(0); |
705 // Ensure the data given to history is correct. | 553 |
706 ASSERT_TRUE(history_handler); | 554 InSequence seq; |
707 EXPECT_EQ(page_url, history_handler->page_url_); | 555 EXPECT_CALL(delegate_, OnFaviconUpdated( |
708 EXPECT_EQ(GURL(), history_handler->icon_url_); | 556 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, |
709 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); | 557 kIconURL, /*icon_url_changed=*/true, _)); |
710 | 558 EXPECT_CALL(favicon_service_, |
711 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_); | 559 UpdateFaviconMappingsAndFetch(kPageURL, URLVector{kNewIconURL}, |
712 | 560 FAVICON, _, _, _)) |
pkotwicz
2017/03/09 02:15:08
We don't need to check whether UpdateFaviconMappin
mastiz
2017/03/09 10:40:08
Needed unless we adopt NiceMock for FaviconService
| |
713 // Send history response. | 561 .WillOnce(PostReply<6>( |
714 history_handler->InvokeCallback(); | 562 CreateRawBitmapResult(kNewIconURL, FAVICON, /*expired=*/false))); |
715 // Verify FaviconHandler status. | 563 EXPECT_CALL(delegate_, OnFaviconUpdated( |
716 EXPECT_EQ(1u, delegate.num_notifications()); | 564 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, |
717 EXPECT_EQ(icon_url, delegate.icon_url()); | 565 kNewIconURL, /*icon_url_changed=*/true, _)); |
pkotwicz
2017/03/09 02:15:08
For the sake of completeness we should check that
mastiz
2017/03/09 10:40:08
Done.
| |
718 | 566 |
719 // Reset the history_handler to verify whether new icon is requested from | 567 RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, |
720 // history. | 568 {FaviconURL(kNewIconURL, FAVICON, kEmptySizes)}); |
721 helper.set_history_handler(nullptr); | |
722 | |
723 // Simulates update with the different favicon url. | |
724 std::vector<FaviconURL> urls; | |
725 urls.push_back(FaviconURL( | |
726 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>())); | |
727 helper.OnUpdateFaviconURL(page_url, urls); | |
728 | |
729 // Verify FaviconHandler status. | |
730 EXPECT_EQ(1u, helper.image_urls().size()); | |
731 ASSERT_TRUE(helper.current_candidate()); | |
732 ASSERT_EQ(new_icon_url, helper.current_candidate()->icon_url); | |
733 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type); | |
734 | |
735 // Favicon should be requested from history. | |
736 history_handler = helper.history_handler(); | |
737 ASSERT_TRUE(history_handler); | |
738 EXPECT_EQ(new_icon_url, history_handler->icon_url_); | |
739 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); | |
740 EXPECT_EQ(page_url, history_handler->page_url_); | |
741 | |
742 // Simulate find icon. | |
743 SetFaviconRawBitmapResult(new_icon_url, &history_handler->history_results_); | |
744 history_handler->InvokeCallback(); | |
745 | |
746 // Shouldn't request download favicon | |
747 EXPECT_FALSE(delegate.download_handler()->HasDownload()); | |
748 | |
749 // Verify the favicon status. | |
750 EXPECT_EQ(2u, delegate.num_notifications()); | |
751 EXPECT_EQ(new_icon_url, delegate.icon_url()); | |
752 EXPECT_FALSE(delegate.image().IsEmpty()); | |
753 } | 569 } |
754 | 570 |
755 TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) { | 571 TEST_F(FaviconHandlerTest, Download2ndFaviconURLCandidate) { |
756 const GURL page_url("http://www.google.com"); | 572 const GURL kIconURLReturning500("http://www.google.com/500.png"); |
757 const GURL icon_url("http://www.google.com/favicon"); | 573 fake_image_downloader_.AddError(kIconURLReturning500, 500); |
758 const GURL new_icon_url("http://www.google.com/new_favicon"); | 574 |
759 | 575 // First download will fail, second will succeed. |
760 TestDelegate delegate; | 576 EXPECT_CALL(delegate_, DownloadImage(kIconURLReturning500, _, _)); |
761 TestFaviconHandler helper(&delegate, FaviconDriverObserver::TOUCH_LARGEST); | 577 EXPECT_CALL(delegate_, DownloadImage(kIconURL64x64, _, _)); |
762 std::set<GURL> fail_downloads; | 578 |
763 fail_downloads.insert(icon_url); | 579 InSequence seq; |
764 delegate.download_handler()->FailDownloadForIconURLs(fail_downloads); | 580 EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch( |
765 | 581 kPageURL, URLVector{kIconURLReturning500}, |
766 helper.FetchFavicon(page_url); | 582 TOUCH_PRECOMPOSED_ICON, _, _, _)); |
767 HistoryRequestHandler* history_handler = helper.history_handler(); | 583 // Simulates getting an expired icon from history. |
768 // Ensure the data given to history is correct. | 584 EXPECT_CALL(favicon_service_, |
769 ASSERT_TRUE(history_handler); | 585 UpdateFaviconMappingsAndFetch(kPageURL, URLVector{kIconURL64x64}, |
770 EXPECT_EQ(page_url, history_handler->page_url_); | 586 TOUCH_ICON, _, _, _)) |
771 EXPECT_EQ(GURL(), history_handler->icon_url_); | 587 .WillOnce(PostReply<6>( |
772 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON, | 588 CreateRawBitmapResult(kIconURL64x64, TOUCH_ICON, /*expired=*/true))); |
773 history_handler->icon_type_); | 589 EXPECT_CALL(delegate_, |
774 | 590 OnFaviconUpdated(kPageURL, FaviconDriverObserver::TOUCH_LARGEST, |
775 // Icon not found. | 591 kIconURL64x64, /*icon_url_changed=*/true, _)); |
776 history_handler->history_results_.clear(); | 592 // New icon should be saved to favicon service. |
777 // Send history response. | 593 EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL64x64, TOUCH_ICON, |
778 history_handler->InvokeCallback(); | 594 ImageSizeIs(64, 64))); |
779 // Verify FaviconHandler status. | 595 EXPECT_CALL(delegate_, |
780 EXPECT_EQ(0u, delegate.num_notifications()); | 596 OnFaviconUpdated(kPageURL, FaviconDriverObserver::TOUCH_LARGEST, |
781 EXPECT_EQ(GURL(), delegate.icon_url()); | 597 kIconURL64x64, /*icon_url_changed=*/false, _)); |
782 | 598 |
783 // Reset the history_handler to verify whether new icon is requested from | 599 RunHandlerWithCandidates( |
784 // history. | 600 FaviconDriverObserver::TOUCH_LARGEST, |
785 helper.set_history_handler(nullptr); | 601 { |
786 | 602 FaviconURL(kIconURLReturning500, TOUCH_PRECOMPOSED_ICON, kEmptySizes), |
787 // Simulates update with the different favicon url. | 603 FaviconURL(kIconURL64x64, TOUCH_ICON, kEmptySizes), |
788 std::vector<FaviconURL> urls; | 604 }); |
789 urls.push_back(FaviconURL(icon_url, | 605 } |
790 favicon_base::TOUCH_PRECOMPOSED_ICON, | 606 |
791 std::vector<gfx::Size>())); | 607 // Test that download data for icon URLs other than the current favicon |
792 urls.push_back(FaviconURL( | 608 // candidate URLs is ignored. This test tests the scenario where a download is |
793 new_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>())); | 609 // in flight when FaviconHandler::OnUpdateFaviconURL() is called. |
794 urls.push_back(FaviconURL( | |
795 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>())); | |
796 helper.OnUpdateFaviconURL(page_url, urls); | |
797 | |
798 // Verify FaviconHandler status. | |
799 EXPECT_EQ(2u, helper.image_urls().size()); | |
800 EXPECT_EQ(0u, helper.current_candidate_index()); | |
801 ASSERT_TRUE(helper.current_candidate()); | |
802 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url); | |
803 ASSERT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON, | |
804 helper.current_candidate()->icon_type); | |
805 | |
806 // Favicon should be requested from history. | |
807 history_handler = helper.history_handler(); | |
808 ASSERT_TRUE(history_handler); | |
809 EXPECT_EQ(icon_url, history_handler->icon_url_); | |
810 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON, history_handler->icon_type_); | |
811 EXPECT_EQ(page_url, history_handler->page_url_); | |
812 | |
813 // Simulate not find icon. | |
814 history_handler->history_results_.clear(); | |
815 history_handler->InvokeCallback(); | |
816 | |
817 // Should request download favicon. | |
818 DownloadHandler* download_handler = delegate.download_handler(); | |
819 EXPECT_TRUE(download_handler->HasDownload()); | |
820 | |
821 // Verify the download request. | |
822 EXPECT_EQ(icon_url, download_handler->GetImageUrl()); | |
823 | |
824 // Reset the history_handler to verify whether favicon is request from | |
825 // history. | |
826 helper.set_history_handler(nullptr); | |
827 download_handler->InvokeCallback(); | |
828 | |
829 // Left 1 url. | |
830 EXPECT_EQ(1u, helper.current_candidate_index()); | |
831 ASSERT_TRUE(helper.current_candidate()); | |
832 EXPECT_EQ(new_icon_url, helper.current_candidate()->icon_url); | |
833 EXPECT_EQ(favicon_base::TOUCH_ICON, helper.current_candidate()->icon_type); | |
834 | |
835 // Favicon should be requested from history. | |
836 history_handler = helper.history_handler(); | |
837 ASSERT_TRUE(history_handler); | |
838 EXPECT_EQ(new_icon_url, history_handler->icon_url_); | |
839 EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_); | |
840 EXPECT_EQ(page_url, history_handler->page_url_); | |
841 | |
842 // Reset download handler | |
843 download_handler->Reset(); | |
844 | |
845 // Simulates getting a expired icon from history. | |
846 SetFaviconRawBitmapResult(new_icon_url, | |
847 favicon_base::TOUCH_ICON, | |
848 true /* expired */, | |
849 &history_handler->history_results_); | |
850 history_handler->InvokeCallback(); | |
851 | |
852 // Verify the download request. | |
853 EXPECT_TRUE(delegate.download_handler()->HasDownload()); | |
854 EXPECT_EQ(new_icon_url, download_handler->GetImageUrl()); | |
855 | |
856 helper.set_history_handler(nullptr); | |
857 | |
858 // Simulates icon being downloaded. | |
859 download_handler->InvokeCallback(); | |
860 | |
861 // New icon should be saved to history backend. | |
862 history_handler = helper.history_handler(); | |
863 ASSERT_TRUE(history_handler); | |
864 EXPECT_EQ(new_icon_url, history_handler->icon_url_); | |
865 EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_); | |
866 EXPECT_LT(0U, history_handler->bitmap_data_.size()); | |
867 EXPECT_EQ(page_url, history_handler->page_url_); | |
868 } | |
869 | |
870 TEST_F(FaviconHandlerTest, UpdateDuringDownloading) { | 610 TEST_F(FaviconHandlerTest, UpdateDuringDownloading) { |
pkotwicz
2017/03/09 02:15:09
We want to:
- set initial state
- test the initial
mastiz
2017/03/09 10:40:08
Done.
FYI, I've used VerifyAndClearExpectations i
| |
871 const GURL page_url("http://www.google.com"); | 611 const GURL kIconURL("http://www.google.com/favicon"); |
872 const GURL icon_url("http://www.google.com/favicon"); | 612 const GURL kNewIconURL("http://www.google.com/new_favicon"); |
873 const GURL new_icon_url("http://www.google.com/new_favicon"); | 613 const GURL kLatestIconURL("http://www.google.com/latest_favicon"); |
874 | 614 |
875 TestDelegate delegate; | 615 // Defer the download completion such that RunUntilIdle() doesn't complete |
876 TestFaviconHandler helper(&delegate, FaviconDriverObserver::TOUCH_LARGEST); | 616 // the download. |
877 | 617 fake_image_downloader_.SetRunCallbackManuallyForUrl(kIconURL); |
878 helper.FetchFavicon(page_url); | 618 fake_image_downloader_.Add(kIconURL, IntVector{16}); |
879 HistoryRequestHandler* history_handler = helper.history_handler(); | 619 EXPECT_CALL(delegate_, DownloadImage(kIconURL, _, _)); |
880 // Ensure the data given to history is correct. | 620 |
881 ASSERT_TRUE(history_handler); | 621 // Make sure kIconURL isn't saved, although StrictMock does it implicitly. |
882 EXPECT_EQ(page_url, history_handler->page_url_); | 622 EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL, _, _)).Times(0); |
pkotwicz
2017/03/09 02:15:08
We don't want SetFavicons() to be called at all fo
mastiz
2017/03/09 10:40:07
Done.
| |
883 EXPECT_EQ(GURL(), history_handler->icon_url_); | 623 |
884 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON, | 624 InSequence seq; |
885 history_handler->icon_type_); | 625 EXPECT_CALL(favicon_service_, |
886 | 626 UpdateFaviconMappingsAndFetch(kPageURL, URLVector{kIconURL}, |
887 // Icon not found. | 627 TOUCH_PRECOMPOSED_ICON, _, _, _)); |
888 history_handler->history_results_.clear(); | 628 EXPECT_CALL(favicon_service_, |
889 // Send history response. | 629 UpdateFaviconMappingsAndFetch(kPageURL, URLVector{kLatestIconURL}, |
890 history_handler->InvokeCallback(); | 630 TOUCH_ICON, _, _, _)) |
891 // Verify FaviconHandler status. | 631 .WillOnce(PostReply<6>(CreateRawBitmapResult(kLatestIconURL, TOUCH_ICON, |
892 EXPECT_EQ(0u, delegate.num_notifications()); | 632 /*expired=*/false))); |
pkotwicz
2017/03/09 02:15:08
We don't care about the UpdateFaviconMappingsAndFe
mastiz
2017/03/09 10:40:07
Needed unless we adopt NiceMock for FaviconService
| |
893 EXPECT_EQ(GURL(), delegate.icon_url()); | 633 EXPECT_CALL(delegate_, |
894 | 634 OnFaviconUpdated(kPageURL, FaviconDriverObserver::TOUCH_LARGEST, |
895 // Reset the history_handler to verify whether new icon is requested from | 635 kLatestIconURL, /*icon_url_changed=*/true, _)); |
pkotwicz
2017/03/09 02:15:09
kLatestIconUrl is the only parameter that we care
mastiz
2017/03/09 10:40:08
Done. Note that my tests we covering the same expe
| |
896 // history. | 636 |
897 helper.set_history_handler(nullptr); | 637 std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates( |
pkotwicz
2017/03/09 02:15:08
1) Some of the old tests were testing too many thi
mastiz
2017/03/09 10:40:08
Adopted FAVICON and added TODO for the rest. I pro
pkotwicz
2017/03/13 05:16:31
Adding new tests in a follow up CL sounds good to
| |
898 | 638 FaviconDriverObserver::TOUCH_LARGEST, |
899 // Simulates update with the different favicon url. | 639 { |
900 std::vector<FaviconURL> urls; | 640 FaviconURL(kIconURL, TOUCH_PRECOMPOSED_ICON, kEmptySizes), |
901 urls.push_back(FaviconURL(icon_url, | 641 FaviconURL(kNewIconURL, TOUCH_ICON, kEmptySizes), |
902 favicon_base::TOUCH_PRECOMPOSED_ICON, | 642 }); |
pkotwicz
2017/03/09 02:15:08
For the "verify the final state" part of this test
mastiz
2017/03/09 10:40:08
Done, I added similar expectations but not exactly
| |
903 std::vector<gfx::Size>())); | 643 |
904 urls.push_back(FaviconURL( | 644 // Favicon update (should invalidate the ongoing download). |
905 new_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>())); | 645 EXPECT_TRUE(fake_image_downloader_.HasPendingManualCallback()); |
906 urls.push_back(FaviconURL( | 646 handler->OnUpdateFaviconURL( |
907 new_icon_url, favicon_base::FAVICON, std::vector<gfx::Size>())); | 647 kPageURL, {FaviconURL(kLatestIconURL, TOUCH_ICON, kEmptySizes)}); |
908 helper.OnUpdateFaviconURL(page_url, urls); | 648 // Finalizes download, which should be thrown away as there is favicon update. |
909 | 649 EXPECT_TRUE(fake_image_downloader_.RunCallbackManually()); |
910 // Verify FaviconHandler status. | 650 base::RunLoop().RunUntilIdle(); |
911 EXPECT_EQ(2u, helper.image_urls().size()); | 651 } |
912 ASSERT_EQ(0u, helper.current_candidate_index()); | 652 |
913 ASSERT_EQ(icon_url, helper.current_candidate()->icon_url); | 653 // Test that calling OnUpdateFaviconUrl() with the same icon URLs as the |
914 ASSERT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON, | 654 // previous call to OnUpdateFaviconUrl() while the FaviconHandler process is in |
915 helper.current_candidate()->icon_type); | 655 // progresss does not restart the process from the beginning. |
916 | 656 TEST_F(FaviconHandlerTest, UpdateSameIconURLsWhileProcessing) { |
917 // Favicon should be requested from history. | 657 const GURL kSlowLoadingIconURL("http://www.google.com/slow_favicon"); |
918 history_handler = helper.history_handler(); | 658 |
919 ASSERT_TRUE(history_handler); | 659 const std::vector<FaviconURL> favicon_urls = { |
920 EXPECT_EQ(icon_url, history_handler->icon_url_); | 660 FaviconURL(kIconURL64x64, FAVICON, kEmptySizes), |
921 EXPECT_EQ(favicon_base::TOUCH_PRECOMPOSED_ICON, history_handler->icon_type_); | 661 FaviconURL(kSlowLoadingIconURL, FAVICON, kEmptySizes), |
922 EXPECT_EQ(page_url, history_handler->page_url_); | 662 }; |
923 | 663 |
924 // Simulate not find icon. | 664 // Defer the download completion such that RunUntilIdle() doesn't complete |
925 history_handler->history_results_.clear(); | 665 // the download. |
926 history_handler->InvokeCallback(); | 666 fake_image_downloader_.SetRunCallbackManuallyForUrl(kSlowLoadingIconURL); |
927 | 667 fake_image_downloader_.Add(kSlowLoadingIconURL, IntVector{16}); |
928 // Should request download favicon. | 668 |
929 DownloadHandler* download_handler = delegate.download_handler(); | 669 EXPECT_CALL(delegate_, DownloadImage(kIconURL64x64, _, _)); |
930 EXPECT_TRUE(download_handler->HasDownload()); | 670 EXPECT_CALL(delegate_, DownloadImage(kSlowLoadingIconURL, _, _)); |
931 | 671 |
932 // Verify the download request. | 672 EXPECT_CALL(favicon_service_, |
933 EXPECT_EQ(icon_url, download_handler->GetImageUrl()); | 673 UpdateFaviconMappingsAndFetch(kPageURL, URLVector{kIconURL64x64}, |
934 | 674 _, _, _, _)); |
935 // Reset the history_handler to verify whether favicon is request from | 675 EXPECT_CALL(favicon_service_, |
936 // history. | 676 UpdateFaviconMappingsAndFetch( |
937 helper.set_history_handler(nullptr); | 677 kPageURL, URLVector{kSlowLoadingIconURL}, _, _, _, _)); |
938 const GURL latest_icon_url("http://www.google.com/latest_favicon"); | 678 |
939 std::vector<FaviconURL> latest_urls; | 679 std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates( |
940 latest_urls.push_back(FaviconURL( | 680 FaviconDriverObserver::NON_TOUCH_16_DIP, favicon_urls); |
941 latest_icon_url, favicon_base::TOUCH_ICON, std::vector<gfx::Size>())); | 681 |
942 helper.OnUpdateFaviconURL(page_url, latest_urls); | 682 // Calling OnUpdateFaviconURL() with the same icon URLs should have no effect, |
943 | 683 // despite the ongoing download. |
944 EXPECT_EQ(1u, helper.image_urls().size()); | 684 EXPECT_TRUE(fake_image_downloader_.HasPendingManualCallback()); |
945 EXPECT_EQ(0u, helper.current_candidate_index()); | 685 handler->OnUpdateFaviconURL(kPageURL, favicon_urls); |
946 EXPECT_EQ(latest_icon_url, helper.current_candidate()->icon_url); | 686 base::RunLoop().RunUntilIdle(); |
947 EXPECT_EQ(favicon_base::TOUCH_ICON, helper.current_candidate()->icon_type); | 687 |
948 | 688 // Complete the download. |
949 // Whether new icon is requested from history | 689 InSequence seq; |
950 history_handler = helper.history_handler(); | 690 EXPECT_CALL(favicon_service_, SetFavicons(_, _, _, _)); |
951 ASSERT_TRUE(history_handler); | 691 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)); |
952 EXPECT_EQ(latest_icon_url, history_handler->icon_url_); | 692 EXPECT_TRUE(fake_image_downloader_.RunCallbackManually()); |
953 EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_); | 693 base::RunLoop().RunUntilIdle(); |
954 EXPECT_EQ(page_url, history_handler->page_url_); | 694 } |
955 | 695 |
956 // Reset the history_handler to verify whether favicon is request from | 696 // Test that calling OnUpdateFaviconUrl() with the same icon URLs as before is a |
957 // history. | 697 // no-op. This is important because OnUpdateFaviconUrl() is called when the page |
958 // Save the callback for late use. | 698 // finishes loading. This can occur several for pages with iframes. |
959 favicon_base::FaviconResultsCallback callback = history_handler->callback_; | 699 TEST_F(FaviconHandlerTest, UpdateSameIconURLsAfterFinished) { |
960 helper.set_history_handler(nullptr); | 700 const std::vector<FaviconURL> favicon_urls = { |
961 | 701 FaviconURL(kIconURL10x10, FAVICON, kEmptySizes), |
962 // Simulates download succeed. | 702 FaviconURL(kIconURL16x16, FAVICON, kEmptySizes), |
963 download_handler->InvokeCallback(); | 703 }; |
964 // The downloaded icon should be thrown away as there is favicon update. | 704 |
965 EXPECT_FALSE(helper.history_handler()); | 705 EXPECT_CALL(delegate_, DownloadImage(kIconURL10x10, _, _)); |
966 | 706 EXPECT_CALL(delegate_, DownloadImage(kIconURL16x16, _, _)); |
967 download_handler->Reset(); | 707 EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch( |
968 | 708 _, URLVector{kIconURL10x10}, _, _, _, _)); |
969 // Simulates getting the icon from history. | 709 EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch( |
970 std::unique_ptr<HistoryRequestHandler> handler; | 710 _, URLVector{kIconURL16x16}, _, _, _, _)); |
971 handler.reset(new HistoryRequestHandler( | 711 EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL16x16, _, _)); |
972 page_url, latest_icon_url, favicon_base::TOUCH_ICON, callback)); | 712 |
973 SetFaviconRawBitmapResult(latest_icon_url, | 713 std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates( |
974 favicon_base::TOUCH_ICON, | 714 FaviconDriverObserver::NON_TOUCH_16_DIP, favicon_urls); |
975 false /* expired */, | 715 |
pkotwicz
2017/03/09 02:15:08
You should call VerifyExpectCalls() and have new e
mastiz
2017/03/09 10:40:08
Done.
| |
976 &handler->history_results_); | 716 // Calling OnUpdateFaviconURL() with identical data should be a no-op. |
977 handler->InvokeCallback(); | 717 handler->OnUpdateFaviconURL(kPageURL, favicon_urls); |
978 | 718 base::RunLoop().RunUntilIdle(); |
979 // No download request. | |
980 EXPECT_FALSE(download_handler->HasDownload()); | |
981 } | |
982 | |
983 // Test that sending an icon URL update identical to the previous icon URL | |
984 // update is a no-op. | |
985 TEST_F(FaviconHandlerTest, UpdateSameIconURLs) { | |
986 const GURL page_url("http://www.google.com"); | |
987 const GURL icon_url1("http://www.google.com/favicon1"); | |
988 const GURL icon_url2("http://www.google.com/favicon2"); | |
989 std::vector<FaviconURL> favicon_urls; | |
990 favicon_urls.push_back(FaviconURL(GURL("http://www.google.com/favicon1"), | |
991 favicon_base::FAVICON, | |
992 std::vector<gfx::Size>())); | |
993 favicon_urls.push_back(FaviconURL(GURL("http://www.google.com/favicon2"), | |
994 favicon_base::FAVICON, | |
995 std::vector<gfx::Size>())); | |
996 | |
997 TestDelegate delegate; | |
998 TestFaviconHandler helper(&delegate, FaviconDriverObserver::NON_TOUCH_16_DIP); | |
999 | |
1000 // Initiate a request for favicon data for |page_url|. History does not know | |
1001 // about the page URL or the icon URLs. | |
1002 helper.FetchFavicon(page_url); | |
1003 helper.history_handler()->InvokeCallback(); | |
1004 helper.set_history_handler(nullptr); | |
1005 | |
1006 // Got icon URLs. | |
1007 helper.OnUpdateFaviconURL(page_url, favicon_urls); | |
1008 | |
1009 // There should be an ongoing history request for |icon_url1|. | |
1010 ASSERT_EQ(2u, helper.image_urls().size()); | |
1011 ASSERT_EQ(0u, helper.current_candidate_index()); | |
1012 HistoryRequestHandler* history_handler = helper.history_handler(); | |
1013 ASSERT_TRUE(history_handler); | |
1014 | |
1015 // Calling OnUpdateFaviconURL() with the same icon URLs should have no effect. | |
1016 helper.OnUpdateFaviconURL(page_url, favicon_urls); | |
1017 EXPECT_EQ(history_handler, helper.history_handler()); | |
1018 | |
1019 // Complete history request for |icon_url1| and do download. | |
1020 helper.history_handler()->InvokeCallback(); | |
1021 helper.set_history_handler(nullptr); | |
1022 delegate.download_handler()->SetImageSizes(std::vector<int>(1u, 10)); | |
1023 delegate.download_handler()->InvokeCallback(); | |
1024 delegate.download_handler()->Reset(); | |
1025 | |
1026 // There should now be an ongoing history request for |icon_url2|. | |
1027 ASSERT_EQ(1u, helper.current_candidate_index()); | |
1028 history_handler = helper.history_handler(); | |
1029 ASSERT_TRUE(history_handler); | |
1030 | |
1031 // Calling OnUpdateFaviconURL() with the same icon URLs should have no effect. | |
1032 helper.OnUpdateFaviconURL(page_url, favicon_urls); | |
1033 EXPECT_EQ(history_handler, helper.history_handler()); | |
1034 } | 719 } |
1035 | 720 |
1036 // Fixes crbug.com/544560 | 721 // Fixes crbug.com/544560 |
722 // Tests that Delegate::OnFaviconUpdated() is called if: | |
723 // - The best icon on the initial page is not the last icon. | |
724 // - All of the initial page's icons are downloaded. | |
725 // AND | |
726 // - JavaScript modifies the page's <link rel="icon"> tags to contain only the | |
727 // last icon. | |
1037 TEST_F(FaviconHandlerTest, | 728 TEST_F(FaviconHandlerTest, |
1038 OnFaviconAvailableNotificationSentAfterIconURLChange) { | 729 OnFaviconAvailableNotificationSentAfterIconURLChange) { |
1039 const GURL kPageURL("http://www.page_which_animates_favicon.com"); | 730 const GURL kIconURL1( |
1040 const GURL kIconURL1("http://wwww.page_which_animates_favicon.com/frame1.png") ; | 731 "http://wwww.page_which_animates_favicon.com/frame1.png"); |
1041 const GURL kIconURL2("http://wwww.page_which_animates_favicon.com/frame2.png") ; | 732 const GURL kIconURL2( |
1042 | 733 "http://wwww.page_which_animates_favicon.com/frame2.png"); |
1043 TestDelegate delegate; | |
1044 TestFaviconHandler helper(&delegate, FaviconDriverObserver::NON_TOUCH_16_DIP); | |
1045 | 734 |
1046 // Initial state: | 735 // Initial state: |
1047 // - The database does not know about |kPageURL|. | 736 // - The database does not know about |kPageURL|. |
1048 // - The page uses |kIconURL1| and |kIconURL2|. | 737 // - The page uses |kIconURL1| and |kIconURL2|. |
1049 // - The database knows about both |kIconURL1| and |kIconURl2|. Both icons | 738 // - The database knows about both |kIconURL1| and |kIconURl2|. Both icons |
1050 // are expired in the database. | 739 // are expired in the database. |
1051 helper.FetchFavicon(kPageURL); | 740 |
1052 ASSERT_TRUE(helper.history_handler()); | 741 // FaviconHandler should download |kIconURL1| and |kIconURL2|. |kIconURL1| is |
1053 helper.history_handler()->InvokeCallback(); | 742 // the better match. |
1054 { | 743 fake_image_downloader_.Add(kIconURL1, IntVector{15}); |
1055 std::vector<FaviconURL> icon_urls; | 744 fake_image_downloader_.Add(kIconURL2, IntVector{10}); |
1056 icon_urls.push_back( | 745 |
1057 FaviconURL(kIconURL1, favicon_base::FAVICON, std::vector<gfx::Size>())); | 746 EXPECT_CALL(delegate_, DownloadImage(kIconURL1, _, _)); |
1058 icon_urls.push_back( | 747 EXPECT_CALL(delegate_, DownloadImage(kIconURL2, _, _)).Times(2); |
pkotwicz
2017/03/09 02:15:08
- We only care about the downloads which occur in
mastiz
2017/03/09 10:40:08
Done.
| |
1059 FaviconURL(kIconURL2, favicon_base::FAVICON, std::vector<gfx::Size>())); | 748 |
1060 helper.OnUpdateFaviconURL(kPageURL, icon_urls); | 749 // FaviconHandler should ask for the mappings and fetch expired icons. |
1061 } | 750 EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch( |
1062 | 751 _, URLVector{kIconURL1}, FAVICON, _, _, _)) |
1063 // FaviconHandler should request from history and download |kIconURL1| and | 752 .WillOnce(PostReply<6>( |
1064 // |kIconURL2|. |kIconURL1| is the better match. A | 753 CreateRawBitmapResult(kIconURL1, FAVICON, /*expired=*/true))); |
pkotwicz
2017/03/09 02:15:08
It is unimportant for there to be data in the data
mastiz
2017/03/09 10:40:07
Done. Please file a bug that describes the repeate
| |
754 EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch( | |
755 _, URLVector{kIconURL2}, _, _, _, _)) | |
756 .WillOnce(PostReply<6>( | |
757 CreateRawBitmapResult(kIconURL2, FAVICON, /*expired=*/true))); | |
758 | |
759 // Two FaviconDriver::OnFaviconUpdated() notifications should be sent for | |
760 // |kIconURL1|, one before and one after the download. | |
761 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL1, _, _)).Times(2); | |
1065 // FaviconDriver::OnFaviconUpdated() notification should be sent for | 762 // FaviconDriver::OnFaviconUpdated() notification should be sent for |
1066 // |kIconURL1|. | 763 // |kIconURL2|. |
1067 ASSERT_EQ(0u, delegate.num_notifications()); | 764 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL2, _, _)); |
1068 ASSERT_TRUE(helper.history_handler()); | 765 EXPECT_CALL(favicon_service_, |
1069 SetFaviconRawBitmapResult(kIconURL1, | 766 SetFavicons(_, kIconURL1, _, ImageSizeIs(16, 16))); |
1070 favicon_base::FAVICON, | 767 |
1071 true /* expired */, | 768 std::unique_ptr<FaviconHandler> handler = |
1072 &helper.history_handler()->history_results_); | 769 RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_16_DIP, |
1073 helper.history_handler()->InvokeCallback(); | 770 { |
1074 helper.set_history_handler(nullptr); | 771 FaviconURL(kIconURL1, FAVICON, kEmptySizes), |
1075 ASSERT_TRUE(delegate.download_handler()->HasDownload()); | 772 FaviconURL(kIconURL2, FAVICON, kEmptySizes), |
1076 delegate.download_handler()->SetImageSizes(std::vector<int>(1u, 15)); | 773 }); |
pkotwicz
2017/03/09 02:15:08
We want to:
- set initial state
- test the initial
mastiz
2017/03/09 10:40:08
Done.
| |
1077 delegate.download_handler()->InvokeCallback(); | |
1078 delegate.download_handler()->Reset(); | |
1079 | |
1080 ASSERT_TRUE(helper.history_handler()); | |
1081 helper.history_handler()->InvokeCallback(); | |
1082 SetFaviconRawBitmapResult(kIconURL2, | |
1083 favicon_base::FAVICON, | |
1084 true /* expired */, | |
1085 &helper.history_handler()->history_results_); | |
1086 helper.history_handler()->InvokeCallback(); | |
1087 helper.set_history_handler(nullptr); | |
1088 ASSERT_TRUE(delegate.download_handler()->HasDownload()); | |
1089 delegate.download_handler()->SetImageSizes(std::vector<int>(1u, 10)); | |
1090 delegate.download_handler()->InvokeCallback(); | |
1091 delegate.download_handler()->Reset(); | |
1092 | |
1093 ASSERT_LT(0u, delegate.num_notifications()); | |
1094 ASSERT_EQ(kIconURL1, delegate.icon_url()); | |
1095 | |
1096 // Clear the history handler because SetHistoryFavicons() sets it. | |
1097 helper.set_history_handler(nullptr); | |
1098 | 774 |
1099 // Simulate the page changing it's icon URL to just |kIconURL2| via | 775 // Simulate the page changing it's icon URL to just |kIconURL2| via |
1100 // Javascript. | 776 // Javascript. |
1101 helper.OnUpdateFaviconURL( | 777 InSequence seq; |
1102 kPageURL, | 778 EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch( |
1103 std::vector<FaviconURL>(1u, FaviconURL(kIconURL2, favicon_base::FAVICON, | 779 _, URLVector{kIconURL2}, _, _, _, _)) |
1104 std::vector<gfx::Size>()))); | 780 .WillOnce(PostReply<6>( |
1105 | 781 CreateRawBitmapResult(kIconURL2, FAVICON, /*expired=*/true))); |
1106 // FaviconHandler should request from history and download |kIconURL2|. A | 782 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL2, |
1107 // FaviconDriver::OnFaviconUpdated() notification should be sent for | 783 /*icon_url_changed=*/true, _)); |
1108 // |kIconURL2|. | 784 EXPECT_CALL(favicon_service_, |
1109 delegate.ResetNumNotifications(); | 785 SetFavicons(_, kIconURL2, _, ImageSizeIs(16, 16))); |
1110 ASSERT_TRUE(helper.history_handler()); | 786 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL2, _, _)); |
1111 SetFaviconRawBitmapResult(kIconURL2, | 787 |
1112 favicon_base::FAVICON, | 788 handler->OnUpdateFaviconURL(kPageURL, |
1113 true /* expired */, | 789 {FaviconURL(kIconURL2, FAVICON, kEmptySizes)}); |
1114 &helper.history_handler()->history_results_); | 790 base::RunLoop().RunUntilIdle(); |
1115 helper.history_handler()->InvokeCallback(); | 791 } |
1116 helper.set_history_handler(nullptr); | 792 |
1117 ASSERT_TRUE(delegate.download_handler()->HasDownload()); | 793 // The goal of these tests is to be more of an integration test than |
1118 delegate.download_handler()->InvokeCallback(); | 794 // SelectFaviconFramesTest.*. They test which favicon is selected when the web |
1119 delegate.download_handler()->Reset(); | 795 // page provides several favicons and none are cached in history. |
1120 ASSERT_LT(0u, delegate.num_notifications()); | 796 class FaviconHandlerMultipleFaviconsTest : public FaviconHandlerTest { |
1121 EXPECT_EQ(kIconURL2, delegate.icon_url()); | 797 protected: |
1122 } | 798 const std::vector<FaviconURL> kSourceIconURLs = { |
1123 | 799 FaviconURL(GURL("http://www.google.com/a"), FAVICON, kEmptySizes), |
1124 // Test the favicon which is selected when the web page provides several | 800 FaviconURL(GURL("http://www.google.com/b"), FAVICON, kEmptySizes), |
1125 // favicons and none of the favicons are cached in history. | 801 FaviconURL(GURL("http://www.google.com/c"), FAVICON, kEmptySizes), |
1126 // The goal of this test is to be more of an integration test than | 802 FaviconURL(GURL("http://www.google.com/d"), FAVICON, kEmptySizes), |
1127 // SelectFaviconFramesTest.*. | 803 FaviconURL(GURL("http://www.google.com/e"), FAVICON, kEmptySizes)}; |
1128 TEST_F(FaviconHandlerTest, MultipleFavicons) { | 804 |
1129 const GURL kPageURL("http://www.google.com"); | 805 FaviconHandlerMultipleFaviconsTest() { |
1130 const FaviconURL kSourceIconURLs[] = { | 806 scoped_set_supported_scale_factors_.reset( |
1131 FaviconURL(GURL("http://www.google.com/a"), | 807 new ui::test::ScopedSetSupportedScaleFactors( |
1132 favicon_base::FAVICON, | 808 {ui::SCALE_FACTOR_100P, ui::SCALE_FACTOR_200P})); |
1133 std::vector<gfx::Size>()), | 809 } |
1134 FaviconURL(GURL("http://www.google.com/b"), | 810 |
1135 favicon_base::FAVICON, | 811 // Same as from the base class but with fixed FaviconURLs. |
1136 std::vector<gfx::Size>()), | 812 int DownloadTillDoneIgnoringHistory(const IntVector& candidate_icon_sizes) { |
1137 FaviconURL(GURL("http://www.google.com/c"), | 813 return FaviconHandlerTest::DownloadTillDoneIgnoringHistory( |
1138 favicon_base::FAVICON, | 814 std::vector<FaviconURL>( |
1139 std::vector<gfx::Size>()), | 815 kSourceIconURLs.begin(), |
1140 FaviconURL(GURL("http://www.google.com/d"), | 816 kSourceIconURLs.begin() + candidate_icon_sizes.size()), |
1141 favicon_base::FAVICON, | 817 candidate_icon_sizes); |
1142 std::vector<gfx::Size>()), | 818 } |
1143 FaviconURL(GURL("http://www.google.com/e"), | 819 }; |
1144 favicon_base::FAVICON, | 820 |
1145 std::vector<gfx::Size>())}; | 821 // Test that if there are several single resolution favicons to choose from |
1146 | 822 // that the largest exact match is chosen. |
1147 // Set the supported scale factors to 1x and 2x. This affects the behavior of | 823 TEST_F(FaviconHandlerMultipleFaviconsTest, ChooseLargestExactMatch) { |
1148 // SelectFaviconFrames(). | 824 EXPECT_EQ(32, DownloadTillDoneIgnoringHistory( |
1149 std::vector<ui::ScaleFactor> scale_factors; | 825 std::vector<int>{16, 24, 32, 48, 256})); |
1150 scale_factors.push_back(ui::SCALE_FACTOR_100P); | 826 } |
1151 scale_factors.push_back(ui::SCALE_FACTOR_200P); | 827 |
1152 ui::test::ScopedSetSupportedScaleFactors scoped_supported(scale_factors); | 828 // Test that if there are several single resolution favicons to choose |
1153 | 829 // from, the exact match is preferred even if it results in upsampling. |
1154 // 1) Test that if there are several single resolution favicons to choose from | 830 TEST_F(FaviconHandlerMultipleFaviconsTest, ChooseExactMatchDespiteUpsampling) { |
1155 // that the largest exact match is chosen. | 831 EXPECT_EQ(16, |
1156 TestDelegate delegate1; | 832 DownloadTillDoneIgnoringHistory(std::vector<int>{16, 24, 48, 256})); |
1157 TestFaviconHandler handler1(&delegate1, | 833 } |
1158 FaviconDriverObserver::NON_TOUCH_16_DIP); | 834 |
1159 | 835 // Test that favicons which need to be upsampled a little or downsampled |
1160 const int kSizes1[] = { 16, 24, 32, 48, 256 }; | 836 // a little are preferred over huge favicons. |
1161 std::vector<FaviconURL> urls1(kSourceIconURLs, | 837 TEST_F(FaviconHandlerMultipleFaviconsTest, |
1162 kSourceIconURLs + arraysize(kSizes1)); | 838 ChooseMinorResamplingOverHugeFavicons) { |
1163 DownloadTillDoneIgnoringHistory(&delegate1, &handler1, kPageURL, urls1, | 839 EXPECT_EQ(48, DownloadTillDoneIgnoringHistory(std::vector<int>{256, 48})); |
1164 kSizes1); | 840 } |
1165 | 841 |
1166 EXPECT_EQ(nullptr, handler1.current_candidate()); | 842 TEST_F(FaviconHandlerMultipleFaviconsTest, |
1167 EXPECT_EQ(1u, delegate1.num_notifications()); | 843 ChooseMinorResamplingOverHugeFavicons2) { |
1168 EXPECT_FALSE(delegate1.image().IsEmpty()); | 844 EXPECT_EQ(17, DownloadTillDoneIgnoringHistory(std::vector<int>{17, 256})); |
1169 EXPECT_EQ(gfx::kFaviconSize, delegate1.image().Width()); | |
1170 | |
1171 size_t expected_index = 2u; | |
1172 EXPECT_EQ(32, kSizes1[expected_index]); | |
1173 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url, delegate1.icon_url()); | |
1174 | |
1175 // 2) Test that if there are several single resolution favicons to choose | |
1176 // from, the exact match is preferred even if it results in upsampling. | |
1177 TestDelegate delegate2; | |
1178 TestFaviconHandler handler2(&delegate2, | |
1179 FaviconDriverObserver::NON_TOUCH_16_DIP); | |
1180 | |
1181 const int kSizes2[] = { 16, 24, 48, 256 }; | |
1182 std::vector<FaviconURL> urls2(kSourceIconURLs, | |
1183 kSourceIconURLs + arraysize(kSizes2)); | |
1184 DownloadTillDoneIgnoringHistory(&delegate2, &handler2, kPageURL, urls2, | |
1185 kSizes2); | |
1186 EXPECT_EQ(1u, delegate2.num_notifications()); | |
1187 expected_index = 0u; | |
1188 EXPECT_EQ(16, kSizes2[expected_index]); | |
1189 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url, delegate2.icon_url()); | |
1190 | |
1191 // 3) Test that favicons which need to be upsampled a little or downsampled | |
1192 // a little are preferred over huge favicons. | |
1193 TestDelegate delegate3; | |
1194 TestFaviconHandler handler3(&delegate3, | |
1195 FaviconDriverObserver::NON_TOUCH_16_DIP); | |
1196 | |
1197 const int kSizes3[] = { 256, 48 }; | |
1198 std::vector<FaviconURL> urls3(kSourceIconURLs, | |
1199 kSourceIconURLs + arraysize(kSizes3)); | |
1200 DownloadTillDoneIgnoringHistory(&delegate3, &handler3, kPageURL, urls3, | |
1201 kSizes3); | |
1202 EXPECT_EQ(1u, delegate3.num_notifications()); | |
1203 expected_index = 1u; | |
1204 EXPECT_EQ(48, kSizes3[expected_index]); | |
1205 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url, delegate3.icon_url()); | |
1206 | |
1207 TestDelegate delegate4; | |
1208 TestFaviconHandler handler4(&delegate4, | |
1209 FaviconDriverObserver::NON_TOUCH_16_DIP); | |
1210 | |
1211 const int kSizes4[] = { 17, 256 }; | |
1212 std::vector<FaviconURL> urls4(kSourceIconURLs, | |
1213 kSourceIconURLs + arraysize(kSizes4)); | |
1214 DownloadTillDoneIgnoringHistory(&delegate4, &handler4, kPageURL, urls4, | |
1215 kSizes4); | |
1216 EXPECT_EQ(1u, delegate4.num_notifications()); | |
1217 expected_index = 0u; | |
1218 EXPECT_EQ(17, kSizes4[expected_index]); | |
1219 EXPECT_EQ(kSourceIconURLs[expected_index].icon_url, delegate4.icon_url()); | |
1220 } | 845 } |
1221 | 846 |
1222 // Test that the best favicon is selected when: | 847 // Test that the best favicon is selected when: |
1223 // - The page provides several favicons. | 848 // - The page provides several favicons. |
1224 // - Downloading one of the page's icon URLs previously returned a 404. | 849 // - Downloading one of the page's icon URLs previously returned a 404. |
1225 // - None of the favicons are cached in the Favicons database. | 850 // - None of the favicons are cached in the Favicons database. |
1226 TEST_F(FaviconHandlerTest, MultipleFavicons404) { | 851 TEST_F(FaviconHandlerTest, MultipleFavicons404) { |
1227 const GURL kPageURL("http://www.google.com"); | 852 ON_CALL(favicon_service_, WasUnableToDownloadFavicon(kIconURL64x64)) |
1228 const GURL k404IconURL("http://www.google.com/404.png"); | 853 .WillByDefault(Return(true)); |
1229 const FaviconURL k404FaviconURL( | |
1230 k404IconURL, favicon_base::FAVICON, std::vector<gfx::Size>()); | |
1231 const FaviconURL kFaviconURLs[] = { | |
1232 FaviconURL(GURL("http://www.google.com/a"), | |
1233 favicon_base::FAVICON, | |
1234 std::vector<gfx::Size>()), | |
1235 k404FaviconURL, | |
1236 FaviconURL(GURL("http://www.google.com/c"), | |
1237 favicon_base::FAVICON, | |
1238 std::vector<gfx::Size>()), | |
1239 }; | |
1240 | 854 |
1241 TestDelegate delegate; | 855 EXPECT_EQ(16, DownloadTillDoneIgnoringHistory( |
1242 TestFaviconHandler handler(&delegate, | 856 { |
1243 FaviconDriverObserver::NON_TOUCH_16_DIP); | 857 FaviconURL(kIconURL16x16, FAVICON, kEmptySizes), |
1244 DownloadHandler* download_handler = delegate.download_handler(); | 858 FaviconURL(kIconURL64x64, FAVICON, kEmptySizes), |
859 }, | |
860 IntVector{16, 64})); | |
861 } | |
1245 | 862 |
1246 std::set<GURL> k404URLs; | 863 // Test that the best favicon is selected when: |
1247 k404URLs.insert(k404IconURL); | 864 // - The page provides several favicons. |
1248 download_handler->FailDownloadForIconURLs(k404URLs); | 865 // - Downloading the last page icon URL previously returned a 404. |
866 // - None of the favicons are cached in the Favicons database. | |
867 // - Size hints are misleading and cause the 404 icon to be processed last. | |
868 TEST_F(FaviconHandlerTest, MultipleFaviconsLast404) { | |
869 ON_CALL(favicon_service_, WasUnableToDownloadFavicon(kIconURL64x64)) | |
870 .WillByDefault(Return(true)); | |
1249 | 871 |
1250 // Make the initial download for |k404IconURL| fail. | 872 EXPECT_EQ(10, DownloadTillDoneIgnoringHistory( |
1251 const int kSizes1[] = { 0 }; | 873 { |
1252 std::vector<FaviconURL> urls1(1u, k404FaviconURL); | 874 // Sizes intentionally wrong to reproduce a corner case. |
1253 DownloadTillDoneIgnoringHistory(&delegate, &handler, kPageURL, urls1, | 875 FaviconURL(kIconURL10x10, FAVICON, {gfx::Size(16, 16)}), |
1254 kSizes1); | 876 FaviconURL(kIconURL64x64, FAVICON, {gfx::Size(15, 15)}), |
1255 EXPECT_TRUE(download_handler->DidFailDownloadForIconURL(k404IconURL)); | 877 }, |
1256 | 878 IntVector{10, 64})); |
1257 // Do a fetch now that the initial download for |k404IconURL| has failed. The | |
1258 // behavior is different because OnDidDownloadFavicon() is invoked | |
1259 // synchronously from DownloadFavicon(). | |
1260 const int kSizes2[] = { 10, 0, 16 }; | |
1261 std::vector<FaviconURL> urls2(kFaviconURLs, | |
1262 kFaviconURLs + arraysize(kFaviconURLs)); | |
1263 DownloadTillDoneIgnoringHistory(&delegate, &handler, kPageURL, urls2, | |
1264 kSizes2); | |
1265 | |
1266 EXPECT_EQ(nullptr, handler.current_candidate()); | |
1267 EXPECT_EQ(1u, delegate.num_notifications()); | |
1268 EXPECT_FALSE(delegate.image().IsEmpty()); | |
1269 int expected_index = 2u; | |
1270 EXPECT_EQ(16, kSizes2[expected_index]); | |
1271 EXPECT_EQ(kFaviconURLs[expected_index].icon_url, delegate.icon_url()); | |
1272 } | 879 } |
1273 | 880 |
1274 // Test that no favicon is selected when: | 881 // Test that no favicon is selected when: |
1275 // - The page provides several favicons. | 882 // - The page provides several favicons. |
1276 // - Downloading the page's icons has previously returned a 404. | 883 // - Downloading the page's icons has previously returned a 404. |
1277 // - None of the favicons are cached in the Favicons database. | 884 // - None of the favicons are cached in the Favicons database. |
1278 TEST_F(FaviconHandlerTest, MultipleFaviconsAll404) { | 885 TEST_F(FaviconHandlerTest, MultipleFaviconsAll404) { |
1279 const GURL kPageURL("http://www.google.com"); | 886 ON_CALL(favicon_service_, WasUnableToDownloadFavicon(kIconURL16x16)) |
1280 const GURL k404IconURL1("http://www.google.com/4041.png"); | 887 .WillByDefault(Return(true)); |
1281 const GURL k404IconURL2("http://www.google.com/4042.png"); | 888 ON_CALL(favicon_service_, WasUnableToDownloadFavicon(kIconURL64x64)) |
1282 const FaviconURL kFaviconURLs[] = { | 889 .WillByDefault(Return(true)); |
1283 FaviconURL(k404IconURL1, | |
1284 favicon_base::FAVICON, | |
1285 std::vector<gfx::Size>()), | |
1286 FaviconURL(k404IconURL2, | |
1287 favicon_base::FAVICON, | |
1288 std::vector<gfx::Size>()), | |
1289 }; | |
1290 | 890 |
1291 TestDelegate delegate; | 891 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)).Times(0); |
1292 TestFaviconHandler handler(&delegate, | |
1293 FaviconDriverObserver::NON_TOUCH_16_DIP); | |
1294 DownloadHandler* download_handler = delegate.download_handler(); | |
1295 | 892 |
1296 std::set<GURL> k404URLs; | 893 EXPECT_EQ(-1, DownloadTillDoneIgnoringHistory( |
1297 k404URLs.insert(k404IconURL1); | 894 { |
1298 k404URLs.insert(k404IconURL2); | 895 FaviconURL(kIconURL16x16, FAVICON, kEmptySizes), |
1299 download_handler->FailDownloadForIconURLs(k404URLs); | 896 FaviconURL(kIconURL64x64, FAVICON, kEmptySizes), |
1300 | 897 }, |
1301 // Make the initial downloads for |kFaviconURLs| fail. | 898 IntVector{16, 64})); |
1302 for (const FaviconURL& favicon_url : kFaviconURLs) { | |
1303 const int kSizes[] = { 0 }; | |
1304 std::vector<FaviconURL> urls(1u, favicon_url); | |
1305 DownloadTillDoneIgnoringHistory(&delegate, &handler, kPageURL, urls, | |
1306 kSizes); | |
1307 } | |
1308 EXPECT_TRUE(download_handler->DidFailDownloadForIconURL(k404IconURL1)); | |
1309 EXPECT_TRUE(download_handler->DidFailDownloadForIconURL(k404IconURL2)); | |
1310 | |
1311 // Do a fetch now that the initial downloads for |kFaviconURLs| have failed. | |
1312 // The behavior is different because OnDidDownloadFavicon() is invoked | |
1313 // synchronously from DownloadFavicon(). | |
1314 const int kSizes[] = { 0, 0 }; | |
1315 std::vector<FaviconURL> urls(kFaviconURLs, | |
1316 kFaviconURLs + arraysize(kFaviconURLs)); | |
1317 DownloadTillDoneIgnoringHistory(&delegate, &handler, kPageURL, urls, kSizes); | |
1318 | |
1319 EXPECT_EQ(nullptr, handler.current_candidate()); | |
1320 EXPECT_EQ(0u, delegate.num_notifications()); | |
1321 EXPECT_TRUE(delegate.image().IsEmpty()); | |
1322 } | 899 } |
1323 | 900 |
1324 // Test that no favicon is selected when the page's only icon uses an invalid | 901 // Test that no favicon is selected when the page's only icon uses an invalid |
1325 // URL syntax. | 902 // URL syntax. |
1326 TEST_F(FaviconHandlerTest, FaviconInvalidURL) { | 903 TEST_F(FaviconHandlerTest, FaviconInvalidURL) { |
1327 const GURL kPageURL("http://www.google.com"); | |
1328 const GURL kInvalidFormatURL("invalid"); | 904 const GURL kInvalidFormatURL("invalid"); |
1329 ASSERT_TRUE(kInvalidFormatURL.is_empty()); | 905 ASSERT_TRUE(kInvalidFormatURL.is_empty()); |
1330 | 906 |
1331 FaviconURL favicon_url(kInvalidFormatURL, favicon_base::FAVICON, | 907 // Shouldn't request to download icon. |
1332 std::vector<gfx::Size>()); | 908 EXPECT_CALL(delegate_, DownloadImage(_, _, _)).Times(0); |
909 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, _, _, _)).Times(0); | |
1333 | 910 |
1334 TestDelegate delegate; | 911 RunHandlerWithCandidates( |
1335 TestFaviconHandler handler(&delegate, | 912 FaviconDriverObserver::NON_TOUCH_16_DIP, |
1336 FaviconDriverObserver::NON_TOUCH_16_DIP); | 913 {FaviconURL(kInvalidFormatURL, FAVICON, kEmptySizes)}); |
1337 UpdateFaviconURL(&delegate, &handler, kPageURL, | |
1338 std::vector<FaviconURL>(1u, favicon_url)); | |
1339 EXPECT_EQ(0u, handler.image_urls().size()); | |
1340 } | 914 } |
1341 | 915 |
1342 TEST_F(FaviconHandlerTest, TestSortFavicon) { | 916 TEST_F(FaviconHandlerTest, TestSortFavicon) { |
1343 const GURL kPageURL("http://www.google.com"); | 917 const std::vector<favicon::FaviconURL> kSourceIconURLs{ |
1344 std::vector<gfx::Size> icon1; | 918 FaviconURL(GURL("http://www.google.com/b"), FAVICON, |
1345 icon1.push_back(gfx::Size(1024, 1024)); | 919 {gfx::Size(15, 15), gfx::Size(16, 16)}), |
1346 icon1.push_back(gfx::Size(512, 512)); | 920 FaviconURL(GURL("http://www.google.com/a"), FAVICON, |
921 {gfx::Size(1024, 1024), gfx::Size(512, 512)}), | |
922 FaviconURL(GURL("http://www.google.com/c"), FAVICON, | |
923 {gfx::Size(16, 16), gfx::Size(14, 14)}), | |
924 FaviconURL(GURL("http://www.google.com/d"), FAVICON, kEmptySizes), | |
925 FaviconURL(GURL("http://www.google.com/e"), FAVICON, kEmptySizes)}; | |
1347 | 926 |
1348 std::vector<gfx::Size> icon2; | 927 EXPECT_CALL(favicon_service_, |
1349 icon2.push_back(gfx::Size(15, 15)); | 928 UpdateFaviconMappingsAndFetch(_, _, _, _, _, _)); |
1350 icon2.push_back(gfx::Size(16, 16)); | 929 EXPECT_CALL(delegate_, DownloadImage(_, _, _)).WillOnce(Return(1)); |
1351 | 930 |
1352 std::vector<gfx::Size> icon3; | 931 std::unique_ptr<FaviconHandler> handler = RunHandlerWithCandidates( |
1353 icon3.push_back(gfx::Size(16, 16)); | 932 FaviconDriverObserver::NON_TOUCH_LARGEST, kSourceIconURLs); |
1354 icon3.push_back(gfx::Size(14, 14)); | |
1355 | |
1356 const FaviconURL kSourceIconURLs[] = { | |
1357 FaviconURL(GURL("http://www.google.com/a"), favicon_base::FAVICON, icon1), | |
1358 FaviconURL(GURL("http://www.google.com/b"), favicon_base::FAVICON, icon2), | |
1359 FaviconURL(GURL("http://www.google.com/c"), favicon_base::FAVICON, icon3), | |
1360 FaviconURL(GURL("http://www.google.com/d"), | |
1361 favicon_base::FAVICON, | |
1362 std::vector<gfx::Size>()), | |
1363 FaviconURL(GURL("http://www.google.com/e"), | |
1364 favicon_base::FAVICON, | |
1365 std::vector<gfx::Size>())}; | |
1366 | |
1367 TestDelegate delegate1; | |
1368 TestFaviconHandler handler1(&delegate1, | |
1369 FaviconDriverObserver::NON_TOUCH_LARGEST); | |
1370 std::vector<FaviconURL> urls1(kSourceIconURLs, | |
1371 kSourceIconURLs + arraysize(kSourceIconURLs)); | |
1372 UpdateFaviconURL(&delegate1, &handler1, kPageURL, urls1); | |
1373 | 933 |
1374 struct ExpectedResult { | 934 struct ExpectedResult { |
1375 // The favicon's index in kSourceIconURLs. | 935 // The favicon's index in kSourceIconURLs. |
1376 size_t favicon_index; | 936 size_t favicon_index; |
1377 // Width of largest bitmap. | 937 // Width of largest bitmap. |
1378 int width; | 938 int width; |
1379 } results[] = { | 939 } results[] = { |
1380 // First is icon1, though its size larger than maximal. | 940 // First is icon2, though its size larger than maximal. |
1381 {0, 1024}, | 941 {1, 1024}, |
1382 // Second is icon2 | 942 // Second is icon1 |
1383 // The 16x16 is largest. | 943 // The 16x16 is largest. |
1384 {1, 16}, | 944 {0, 16}, |
1385 // Third is icon3 though it has same size as icon2. | 945 // Third is icon3 though it has same size as icon1. |
1386 // The 16x16 is largest. | 946 // The 16x16 is largest. |
1387 {2, 16}, | 947 {2, 16}, |
1388 // The rest of bitmaps come in order, there is no sizes attribute. | 948 // The rest of bitmaps come in order, there is no sizes attribute. |
1389 {3, -1}, | 949 {3, -1}, |
1390 {4, -1}, | 950 {4, -1}, |
1391 }; | 951 }; |
1392 const std::vector<FaviconURL>& icons = handler1.image_urls(); | 952 const std::vector<FaviconURL>& icons = handler->image_urls(); |
1393 ASSERT_EQ(5u, icons.size()); | 953 ASSERT_EQ(5u, icons.size()); |
1394 for (size_t i = 0; i < icons.size(); ++i) { | 954 for (size_t i = 0; i < icons.size(); ++i) { |
1395 EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url, | 955 EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url, |
1396 icons[i].icon_url); | 956 icons[i].icon_url); |
1397 if (results[i].width != -1) | 957 if (results[i].width != -1) |
1398 EXPECT_EQ(results[i].width, icons[i].icon_sizes[0].width()); | 958 EXPECT_EQ(results[i].width, icons[i].icon_sizes[0].width()); |
1399 } | 959 } |
1400 } | 960 } |
1401 | 961 |
1402 TEST_F(FaviconHandlerTest, TestDownloadLargestFavicon) { | 962 TEST_F(FaviconHandlerTest, TestDownloadLargestFavicon) { |
1403 const GURL kPageURL("http://www.google.com"); | 963 { |
pkotwicz
2017/03/09 02:15:08
I think that it is easy to have bugs with this tes
mastiz
2017/03/09 10:40:07
Done, went ahead with the second.
| |
1404 std::vector<gfx::Size> icon1; | 964 InSequence seq; |
1405 icon1.push_back(gfx::Size(1024, 1024)); | 965 for (const GURL& icon_url : std::vector<GURL>{ |
1406 icon1.push_back(gfx::Size(512, 512)); | 966 GURL("http://www.google.com/a"), GURL("http://www.google.com/c"), |
967 GURL("http://www.google.com/b"), | |
968 // The rest of bitmaps come in order, there is no sizes attribute. | |
969 GURL("http://www.google.com/d"), | |
970 GURL("http://www.google.com/e")}) { | |
971 // Icon URLs are not registered and hence 404s will be produced, which | |
972 // allows checking whether the icons were requested according to their | |
973 // size. | |
974 EXPECT_CALL(delegate_, DownloadImage(icon_url, _, _)); | |
975 } | |
976 } | |
1407 | 977 |
1408 std::vector<gfx::Size> icon2; | 978 EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch(_, _, _, _, _, _)) |
1409 icon2.push_back(gfx::Size(15, 15)); | 979 .Times(5); |
pkotwicz
2017/03/09 02:15:08
We don't care about calls to UpdateFaviconMappings
mastiz
2017/03/09 10:40:08
Needed unless we adopt a NiceMock for FaviconServi
| |
1410 icon2.push_back(gfx::Size(14, 14)); | 980 EXPECT_CALL(favicon_service_, UnableToDownloadFavicon(_)).Times(5); |
1411 | 981 |
1412 std::vector<gfx::Size> icon3; | 982 RunHandlerWithCandidates( |
1413 icon3.push_back(gfx::Size(16, 16)); | 983 FaviconDriverObserver::NON_TOUCH_LARGEST, |
1414 icon3.push_back(gfx::Size(512, 512)); | 984 {FaviconURL(GURL("http://www.google.com/a"), FAVICON, |
1415 | 985 {gfx::Size(1024, 1024), gfx::Size(512, 512)}), |
1416 const FaviconURL kSourceIconURLs[] = { | 986 FaviconURL(GURL("http://www.google.com/b"), FAVICON, |
1417 FaviconURL( | 987 {gfx::Size(15, 15), gfx::Size(14, 14)}), |
1418 GURL("http://www.google.com/a"), favicon_base::FAVICON, icon1), | 988 FaviconURL(GURL("http://www.google.com/c"), FAVICON, |
1419 FaviconURL( | 989 {gfx::Size(16, 16), gfx::Size(512, 512)}), |
1420 GURL("http://www.google.com/b"), favicon_base::FAVICON, icon2), | 990 FaviconURL(GURL("http://www.google.com/d"), FAVICON, kEmptySizes), |
1421 FaviconURL( | 991 FaviconURL(GURL("http://www.google.com/e"), FAVICON, kEmptySizes)}); |
1422 GURL("http://www.google.com/c"), favicon_base::FAVICON, icon3), | |
1423 FaviconURL(GURL("http://www.google.com/d"), | |
1424 favicon_base::FAVICON, | |
1425 std::vector<gfx::Size>()), | |
1426 FaviconURL(GURL("http://www.google.com/e"), | |
1427 favicon_base::FAVICON, | |
1428 std::vector<gfx::Size>())}; | |
1429 | |
1430 TestDelegate delegate1; | |
1431 TestFaviconHandler handler1(&delegate1, | |
1432 FaviconDriverObserver::NON_TOUCH_LARGEST); | |
1433 | |
1434 std::set<GURL> fail_icon_urls; | |
1435 for (size_t i = 0; i < arraysize(kSourceIconURLs); ++i) { | |
1436 fail_icon_urls.insert(kSourceIconURLs[i].icon_url); | |
1437 } | |
1438 delegate1.download_handler()->FailDownloadForIconURLs(fail_icon_urls); | |
1439 | |
1440 std::vector<FaviconURL> urls1(kSourceIconURLs, | |
1441 kSourceIconURLs + arraysize(kSourceIconURLs)); | |
1442 UpdateFaviconURL(&delegate1, &handler1, kPageURL, urls1); | |
1443 | |
1444 // Simulate the download failed, to check whether the icons were requested | |
1445 // to download according their size. | |
1446 struct ExpectedResult { | |
1447 // The favicon's index in kSourceIconURLs. | |
1448 size_t favicon_index; | |
1449 // Width of largest bitmap. | |
1450 int width; | |
1451 } results[] = { | |
1452 {0, 1024}, | |
1453 {2, 512}, | |
1454 {1, 15}, | |
1455 // The rest of bitmaps come in order. | |
1456 {3, -1}, | |
1457 {4, -1}, | |
1458 }; | |
1459 | |
1460 for (int i = 0; i < 5; ++i) { | |
1461 EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url, | |
1462 handler1.current_candidate()->icon_url); | |
1463 if (results[i].width != -1) { | |
1464 EXPECT_EQ(results[i].width, handler1.current_candidate()-> | |
1465 icon_sizes[0].width()); | |
1466 } | |
1467 | |
1468 // Simulate no favicon from history. | |
1469 handler1.history_handler()->history_results_.clear(); | |
1470 handler1.history_handler()->InvokeCallback(); | |
1471 | |
1472 // Verify download request | |
1473 ASSERT_TRUE(delegate1.download_handler()->HasDownload()); | |
1474 EXPECT_EQ(kSourceIconURLs[results[i].favicon_index].icon_url, | |
1475 delegate1.download_handler()->GetImageUrl()); | |
1476 | |
1477 delegate1.download_handler()->InvokeCallback(); | |
1478 delegate1.download_handler()->Reset(); | |
1479 } | |
1480 } | 992 } |
1481 | 993 |
1482 TEST_F(FaviconHandlerTest, TestSelectLargestFavicon) { | 994 TEST_F(FaviconHandlerTest, TestSelectLargestFavicon) { |
1483 const GURL kPageURL("http://www.google.com"); | 995 const GURL kIconURL1("http://www.google.com/b"); |
996 const GURL kIconURL2("http://www.google.com/c"); | |
1484 | 997 |
1485 std::vector<gfx::Size> one_icon; | 998 fake_image_downloader_.Add(kIconURL2, IntVector{14, 16}); |
1486 one_icon.push_back(gfx::Size(15, 15)); | 999 EXPECT_CALL(delegate_, DownloadImage(kIconURL2, _, _)); |
1487 | |
1488 std::vector<gfx::Size> two_icons; | |
1489 two_icons.push_back(gfx::Size(14, 14)); | |
1490 two_icons.push_back(gfx::Size(16, 16)); | |
1491 | |
1492 const FaviconURL kSourceIconURLs[] = { | |
1493 FaviconURL( | |
1494 GURL("http://www.google.com/b"), favicon_base::FAVICON, one_icon), | |
1495 FaviconURL( | |
1496 GURL("http://www.google.com/c"), favicon_base::FAVICON, two_icons)}; | |
1497 | |
1498 TestDelegate delegate1; | |
1499 TestFaviconHandler handler1(&delegate1, | |
1500 FaviconDriverObserver::NON_TOUCH_LARGEST); | |
1501 std::vector<FaviconURL> urls1(kSourceIconURLs, | |
1502 kSourceIconURLs + arraysize(kSourceIconURLs)); | |
1503 UpdateFaviconURL(&delegate1, &handler1, kPageURL, urls1); | |
1504 | |
1505 ASSERT_EQ(2u, handler1.image_urls().size()); | |
1506 | |
1507 // Index of largest favicon in kSourceIconURLs. | |
1508 size_t i = 1; | |
1509 // The largest bitmap's index in Favicon . | |
1510 int b = 1; | |
1511 | |
1512 // Verify the icon_bitmaps_ was initialized correctly. | |
1513 EXPECT_EQ(kSourceIconURLs[i].icon_url, | |
1514 handler1.current_candidate()->icon_url); | |
1515 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b], | |
1516 handler1.current_candidate()->icon_sizes[0]); | |
1517 | |
1518 // Simulate no favicon from history. | |
1519 handler1.history_handler()->history_results_.clear(); | |
1520 handler1.history_handler()->InvokeCallback(); | |
1521 | |
1522 // Verify download request | |
1523 ASSERT_TRUE(delegate1.download_handler()->HasDownload()); | |
1524 EXPECT_EQ(kSourceIconURLs[i].icon_url, | |
1525 delegate1.download_handler()->GetImageUrl()); | |
1526 | |
1527 // Give the correct download result. | |
1528 std::vector<int> sizes; | |
1529 for (std::vector<gfx::Size>::const_iterator j = | |
1530 kSourceIconURLs[i].icon_sizes.begin(); | |
1531 j != kSourceIconURLs[i].icon_sizes.end(); ++j) | |
1532 sizes.push_back(j->width()); | |
1533 | |
1534 delegate1.download_handler()->SetImageSizes(sizes); | |
1535 delegate1.download_handler()->InvokeCallback(); | |
1536 | 1000 |
1537 // Verify the largest bitmap has been saved into history. | 1001 // Verify the largest bitmap has been saved into history. |
1538 EXPECT_EQ(kSourceIconURLs[i].icon_url, handler1.history_handler()->icon_url_); | 1002 EXPECT_CALL(favicon_service_, |
1539 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b], | 1003 UpdateFaviconMappingsAndFetch(kPageURL, URLVector{kIconURL2}, _, |
1540 handler1.history_handler()->size_); | 1004 _, _, _)); |
1005 EXPECT_CALL(favicon_service_, | |
1006 SetFavicons(kPageURL, kIconURL2, FAVICON, ImageSizeIs(16, 16))); | |
1541 // Verify NotifyFaviconAvailable(). | 1007 // Verify NotifyFaviconAvailable(). |
1542 EXPECT_EQ(1u, delegate1.num_notifications()); | 1008 EXPECT_CALL(delegate_, OnFaviconUpdated( |
1543 EXPECT_EQ(kSourceIconURLs[i].icon_url, delegate1.icon_url()); | 1009 kPageURL, FaviconDriverObserver::NON_TOUCH_LARGEST, |
1544 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b], delegate1.image().Size()); | 1010 kIconURL2, /*icon_url_changed=*/true, _)); |
1011 | |
1012 RunHandlerWithCandidates( | |
1013 FaviconDriverObserver::NON_TOUCH_LARGEST, | |
1014 {FaviconURL(kIconURL1, FAVICON, {gfx::Size(15, 15)}), | |
1015 FaviconURL(kIconURL2, FAVICON, {gfx::Size(14, 14), gfx::Size(16, 16)})}); | |
1545 } | 1016 } |
1546 | 1017 |
1547 TEST_F(FaviconHandlerTest, TestFaviconWasScaledAfterDownload) { | 1018 TEST_F(FaviconHandlerTest, TestFaviconWasScaledAfterDownload) { |
1548 const GURL kPageURL("http://www.google.com"); | 1019 const int kMaximalSize = FaviconHandler::GetMaximalIconSize(FAVICON); |
1549 const int kMaximalSize = | |
1550 TestFaviconHandler::GetMaximalIconSize(favicon_base::FAVICON); | |
1551 | 1020 |
1552 std::vector<gfx::Size> icon1; | 1021 const GURL kIconURL1("http://www.google.com/b"); |
1553 icon1.push_back(gfx::Size(kMaximalSize + 1, kMaximalSize + 1)); | 1022 const GURL kIconURL2("http://www.google.com/c"); |
1554 | 1023 |
1555 std::vector<gfx::Size> icon2; | 1024 const int kOriginalSize1 = kMaximalSize + 1; |
1556 icon2.push_back(gfx::Size(kMaximalSize + 2, kMaximalSize + 2)); | 1025 const int kOriginalSize2 = kMaximalSize + 2; |
1557 | 1026 |
1558 const FaviconURL kSourceIconURLs[] = { | 1027 fake_image_downloader_.AddWithOriginalSizes( |
1559 FaviconURL( | 1028 kIconURL2, IntVector{kMaximalSize}, IntVector{kOriginalSize2}); |
1560 GURL("http://www.google.com/b"), favicon_base::FAVICON, icon1), | 1029 EXPECT_CALL(delegate_, DownloadImage(kIconURL2, _, _)); |
1561 FaviconURL( | |
1562 GURL("http://www.google.com/c"), favicon_base::FAVICON, icon2)}; | |
1563 | |
1564 TestDelegate delegate1; | |
1565 TestFaviconHandler handler1(&delegate1, | |
1566 FaviconDriverObserver::NON_TOUCH_LARGEST); | |
1567 std::vector<FaviconURL> urls1(kSourceIconURLs, | |
1568 kSourceIconURLs + arraysize(kSourceIconURLs)); | |
1569 UpdateFaviconURL(&delegate1, &handler1, kPageURL, urls1); | |
1570 | |
1571 ASSERT_EQ(2u, handler1.image_urls().size()); | |
1572 | |
1573 // Index of largest favicon in kSourceIconURLs. | |
1574 size_t i = 1; | |
1575 // The largest bitmap's index in Favicon . | |
1576 int b = 0; | |
1577 | |
1578 // Verify the icon_bitmaps_ was initialized correctly. | |
1579 EXPECT_EQ(kSourceIconURLs[i].icon_url, | |
1580 handler1.current_candidate()->icon_url); | |
1581 EXPECT_EQ(kSourceIconURLs[i].icon_sizes[b], | |
1582 handler1.current_candidate()->icon_sizes[0]); | |
1583 | |
1584 // Simulate no favicon from history. | |
1585 handler1.history_handler()->history_results_.clear(); | |
1586 handler1.history_handler()->InvokeCallback(); | |
1587 | |
1588 // Verify download request | |
1589 ASSERT_TRUE(delegate1.download_handler()->HasDownload()); | |
1590 EXPECT_EQ(kSourceIconURLs[i].icon_url, | |
1591 delegate1.download_handler()->GetImageUrl()); | |
1592 | |
1593 // Give the scaled download bitmap. | |
1594 std::vector<int> sizes; | |
1595 sizes.push_back(kMaximalSize); | |
1596 | |
1597 delegate1.download_handler()->SetImageSizes(sizes); | |
1598 delegate1.download_handler()->InvokeCallback(); | |
1599 | 1030 |
1600 // Verify the largest bitmap has been saved into history though it was | 1031 // Verify the largest bitmap has been saved into history though it was |
1601 // scaled down to maximal size and smaller than icon1 now. | 1032 // scaled down to maximal size and smaller than |kIconURL1| now. |
1602 EXPECT_EQ(kSourceIconURLs[i].icon_url, handler1.history_handler()->icon_url_); | 1033 EXPECT_CALL(favicon_service_, |
1603 EXPECT_EQ(gfx::Size(kMaximalSize, kMaximalSize), | 1034 UpdateFaviconMappingsAndFetch(kPageURL, URLVector{kIconURL2}, _, |
1604 handler1.history_handler()->size_); | 1035 _, _, _)); |
1036 EXPECT_CALL(favicon_service_, | |
1037 SetFavicons(kPageURL, kIconURL2, FAVICON, | |
1038 ImageSizeIs(kMaximalSize, kMaximalSize))); | |
1039 | |
1040 RunHandlerWithCandidates( | |
1041 FaviconDriverObserver::NON_TOUCH_LARGEST, | |
1042 {FaviconURL(kIconURL1, FAVICON, | |
1043 SizeVector{gfx::Size(kOriginalSize1, kOriginalSize1)}), | |
1044 FaviconURL(kIconURL2, FAVICON, | |
1045 SizeVector{gfx::Size(kOriginalSize2, kOriginalSize2)})}); | |
1605 } | 1046 } |
1606 | 1047 |
1607 TEST_F(FaviconHandlerTest, TestKeepDownloadedLargestFavicon) { | 1048 TEST_F(FaviconHandlerTest, TestKeepDownloadedLargestFavicon) { |
1608 const GURL kPageURL("http://www.google.com"); | 1049 { |
1050 InSequence seq; | |
1051 EXPECT_CALL(favicon_service_, | |
1052 UpdateFaviconMappingsAndFetch( | |
1053 kPageURL, URLVector{kIconURL10x10}, _, _, _, _)); | |
1054 // Very the best candidate is icon 2. | |
1055 EXPECT_CALL(favicon_service_, | |
1056 UpdateFaviconMappingsAndFetch( | |
1057 kPageURL, URLVector{kIconURL12x12}, _, _, _, _)); | |
1058 } | |
pkotwicz
2017/03/09 02:15:08
We don't care about the UpdateFaviconMappingsAndFe
mastiz
2017/03/09 10:40:08
Ditto.
| |
1609 | 1059 |
1610 std::vector<gfx::Size> icon1; | 1060 EXPECT_CALL(delegate_, DownloadImage(kIconURL10x10, _, _)); |
1611 icon1.push_back(gfx::Size(16, 16)); | 1061 EXPECT_CALL(delegate_, DownloadImage(kIconURL12x12, _, _)); |
1612 const int actual_size1 = 10; | 1062 EXPECT_CALL(favicon_service_, SetFavicons(kPageURL, kIconURL12x12, FAVICON, |
1063 ImageSizeIs(12, 12))); | |
pkotwicz
2017/03/09 02:15:08
In my CL I have made all of the tests check for th
mastiz
2017/03/09 10:40:08
Ditto: while FaviconService uses StrictMock, it's
| |
1613 | 1064 |
1614 std::vector<gfx::Size> icon2; | 1065 RunHandlerWithCandidates( |
1615 icon2.push_back(gfx::Size(15, 15)); | 1066 FaviconDriverObserver::NON_TOUCH_LARGEST, |
1616 const int actual_size2 = 12; | 1067 {FaviconURL(kIconURL10x10, FAVICON, SizeVector{gfx::Size(16, 16)}), |
1617 | 1068 FaviconURL(kIconURL12x12, FAVICON, SizeVector{gfx::Size(15, 15)}), |
1618 const FaviconURL kSourceIconURLs[] = { | 1069 FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}); |
1619 FaviconURL(GURL("http://www.google.com/b"), favicon_base::FAVICON, icon1), | |
1620 FaviconURL(GURL("http://www.google.com/c"), favicon_base::FAVICON, icon2), | |
1621 FaviconURL(GURL("http://www.google.com/d"), | |
1622 favicon_base::FAVICON, | |
1623 std::vector<gfx::Size>())}; | |
1624 | |
1625 TestDelegate delegate1; | |
1626 TestFaviconHandler handler1(&delegate1, | |
1627 FaviconDriverObserver::NON_TOUCH_LARGEST); | |
1628 std::vector<FaviconURL> urls1(kSourceIconURLs, | |
1629 kSourceIconURLs + arraysize(kSourceIconURLs)); | |
1630 UpdateFaviconURL(&delegate1, &handler1, kPageURL, urls1); | |
1631 ASSERT_EQ(3u, handler1.image_urls().size()); | |
1632 | |
1633 // Simulate no favicon from history. | |
1634 handler1.history_handler()->history_results_.clear(); | |
1635 handler1.history_handler()->InvokeCallback(); | |
1636 | |
1637 // Verify the first icon was request to download | |
1638 ASSERT_TRUE(delegate1.download_handler()->HasDownload()); | |
1639 EXPECT_EQ(kSourceIconURLs[0].icon_url, | |
1640 delegate1.download_handler()->GetImageUrl()); | |
1641 | |
1642 // Give the incorrect size. | |
1643 std::vector<int> sizes; | |
1644 sizes.push_back(actual_size1); | |
1645 delegate1.download_handler()->SetImageSizes(sizes); | |
1646 delegate1.download_handler()->InvokeCallback(); | |
1647 delegate1.download_handler()->Reset(); | |
1648 | |
1649 // Simulate no favicon from history. | |
1650 handler1.history_handler()->history_results_.clear(); | |
1651 handler1.history_handler()->InvokeCallback(); | |
1652 | |
1653 // Verify the 2nd icon was request to download | |
1654 ASSERT_TRUE(delegate1.download_handler()->HasDownload()); | |
1655 EXPECT_EQ(kSourceIconURLs[1].icon_url, | |
1656 delegate1.download_handler()->GetImageUrl()); | |
1657 | |
1658 // Very the best candidate is icon1 | |
1659 EXPECT_EQ(kSourceIconURLs[0].icon_url, | |
1660 handler1.best_favicon_candidate().image_url); | |
1661 EXPECT_EQ(gfx::Size(actual_size1, actual_size1), | |
1662 handler1.best_favicon_candidate().image.Size()); | |
1663 | |
1664 // Give the incorrect size. | |
1665 sizes.clear(); | |
1666 sizes.push_back(actual_size2); | |
1667 delegate1.download_handler()->SetImageSizes(sizes); | |
1668 delegate1.download_handler()->InvokeCallback(); | |
1669 delegate1.download_handler()->Reset(); | |
1670 | |
1671 // Verify icon2 has been saved into history. | |
1672 EXPECT_EQ(kSourceIconURLs[1].icon_url, handler1.history_handler()->icon_url_); | |
1673 EXPECT_EQ(gfx::Size(actual_size2, actual_size2), | |
1674 handler1.history_handler()->size_); | |
1675 } | 1070 } |
1676 | 1071 |
1677 } // namespace | 1072 } // namespace |
1678 } // namespace favicon | 1073 } // namespace favicon |
OLD | NEW |