blob: e86be600d87a25483b5bc111c3df24168e2ad563 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/android/favicon_helper.h"
#include <vector>
#include "base/test/task_environment.h"
#include "components/favicon/core/test/mock_favicon_service.h"
#include "components/favicon_base/favicon_callback.h"
#include "components/favicon_base/favicon_types.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/codec/png_codec.h"
#include "url/gurl.h"
using ::testing::_;
const int kDummyTaskId = 1;
favicon_base::FaviconRawBitmapResult
CreateTestBitmapResult(GURL url, int size, SkColor color = SK_ColorRED) {
favicon_base::FaviconRawBitmapResult result;
result.expired = false;
// Create bitmap and fill with |color|.
scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes());
SkBitmap bitmap;
bitmap.allocN32Pixels(size, size);
bitmap.eraseColor(color);
gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &data->data());
result.bitmap_data = data;
result.pixel_size = gfx::Size(size, size);
result.icon_url = url;
result.icon_type = favicon_base::IconType::kFavicon;
CHECK(result.is_valid());
return result;
}
class FaviconHelperTest : public testing::Test {
public:
FaviconHelperTest() {
ON_CALL(mock_favicon_service_, GetRawFaviconForPageURL(_, _, _, _, _, _))
.WillByDefault([](const GURL& url, auto, int size, auto,
favicon_base::FaviconRawBitmapCallback callback,
auto) {
std::move(callback).Run(CreateTestBitmapResult(url, size));
return kDummyTaskId;
});
get_composed_favicon_raw_results_callback_ = base::BindOnce(
&FaviconHelperTest::onNativeGetComposedFaviconImageFinished,
base::Unretained(this));
}
~FaviconHelperTest() override { favicon_helper_->Destroy(nullptr); }
void onNativeGetComposedFaviconImageFinished(
const std::vector<favicon_base::FaviconRawBitmapResult>& result) {
raw_bitmap_results_ = result;
}
protected:
base::test::TaskEnvironment task_environment_;
favicon::MockFaviconService mock_favicon_service_;
FaviconHelper* favicon_helper_ = new FaviconHelper();
std::vector<favicon_base::FaviconRawBitmapResult> raw_bitmap_results_;
favicon_base::FaviconResultsCallback
get_composed_favicon_raw_results_callback_;
};
TEST_F(FaviconHelperTest, GetLargestSizeIndex) {
std::vector<gfx::Size> sizes;
gfx::Size size1 = gfx::Size(INT_MAX, INT_MAX);
sizes.push_back(size1);
gfx::Size size2 = gfx::Size(16, 16);
sizes.push_back(size2);
gfx::Size size3 = gfx::Size(32, 32);
sizes.push_back(size3);
EXPECT_EQ(2u, FaviconHelper::GetLargestSizeIndex(sizes));
sizes.clear();
sizes.push_back(size1);
sizes.push_back(size1);
EXPECT_EQ(0u, FaviconHelper::GetLargestSizeIndex(sizes));
}
TEST_F(FaviconHelperTest, GetComposedFaviconImage) {
raw_bitmap_results_.clear();
std::vector<std::string> urls = {"http://www.tab1.com",
"http://www.tab2.com"};
GURL url1 = GURL(urls[0]);
GURL url2 = GURL(urls[1]);
EXPECT_CALL(mock_favicon_service_,
GetRawFaviconForPageURL(url1, _, _, 16, _, _))
.Times(1);
EXPECT_CALL(mock_favicon_service_,
GetRawFaviconForPageURL(url2, _, _, 16, _, _))
.Times(1);
favicon_helper_->GetComposedFaviconImageInternal(
&mock_favicon_service_, urls, 16,
std::move(get_composed_favicon_raw_results_callback_));
task_environment_.RunUntilIdle();
EXPECT_EQ(2, (int)raw_bitmap_results_.size());
}
TEST_F(FaviconHelperTest, GetComposedFaviconImageWithOneFaviconFailed) {
raw_bitmap_results_.clear();
std::vector<std::string> urls = {"http://www.tab1.com", "http://www.tab2.com",
"http://www.tab3.com"};
GURL url1 = GURL(urls[0]);
GURL url2 = GURL(urls[1]);
GURL url3 = GURL(urls[2]);
EXPECT_CALL(mock_favicon_service_,
GetRawFaviconForPageURL(url1, _, _, 16, _, _))
.Times(1);
EXPECT_CALL(mock_favicon_service_,
GetRawFaviconForPageURL(url2, _, _, 16, _, _))
.Times(1);
// With one favicon failed.
EXPECT_CALL(mock_favicon_service_,
GetRawFaviconForPageURL(url3, _, _, 16, _, _))
.WillOnce([](auto, auto, auto, auto,
favicon_base::FaviconRawBitmapCallback callback, auto) {
std::move(callback).Run(favicon_base::FaviconRawBitmapResult());
return kDummyTaskId;
});
favicon_helper_->GetComposedFaviconImageInternal(
&mock_favicon_service_, urls, 16,
std::move(get_composed_favicon_raw_results_callback_));
task_environment_.RunUntilIdle();
EXPECT_EQ(2, (int)raw_bitmap_results_.size());
}
TEST_F(FaviconHelperTest, GetComposedFaviconImageOrderMatchesInput) {
raw_bitmap_results_.clear();
std::vector<std::string> urls = {"http://www.tab1.com", "http://www.tab2.com",
"http://www.tab3.com"};
GURL url1 = GURL(urls[0]);
GURL url2 = GURL(urls[1]);
GURL url3 = GURL(urls[2]);
EXPECT_CALL(mock_favicon_service_,
GetRawFaviconForPageURL(url1, _, _, 16, _, _))
.Times(1);
EXPECT_CALL(mock_favicon_service_,
GetRawFaviconForPageURL(url2, _, _, 16, _, _))
.WillOnce([](const GURL& url, auto, int size, auto,
favicon_base::FaviconRawBitmapCallback callback,
base::CancelableTaskTracker* tracker) {
tracker->PostTask(
base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
base::BindOnce(
[](favicon_base::FaviconRawBitmapCallback callback, GURL url,
int size) {
sleep(5);
std::move(callback).Run(CreateTestBitmapResult(url, size));
},
std::move(callback), url, size));
return kDummyTaskId;
});
EXPECT_CALL(mock_favicon_service_,
GetRawFaviconForPageURL(url3, _, _, 16, _, _))
.Times(1);
favicon_helper_->GetComposedFaviconImageInternal(
&mock_favicon_service_, urls, 16,
std::move(get_composed_favicon_raw_results_callback_));
task_environment_.RunUntilIdle();
EXPECT_EQ(3, (int)raw_bitmap_results_.size());
EXPECT_EQ(url1, raw_bitmap_results_[0].icon_url);
EXPECT_EQ(url2, raw_bitmap_results_[1].icon_url);
EXPECT_EQ(url3, raw_bitmap_results_[2].icon_url);
}