blob: 62c5677345328868e90a05926ce5e7eaef96a770 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/favicon/favicon_utils.h"
#include "content/public/browser/navigation_entry.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/color/color_id.h"
#include "ui/color/color_provider.h"
#include "ui/color/color_provider_key.h"
#include "ui/color/color_provider_manager.h"
#include "ui/color/color_recipe.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/resources/grit/ui_resources.h"
namespace favicon {
namespace {
constexpr SkColor kLightColor = SK_ColorWHITE;
constexpr SkColor kDarkColor = SK_ColorBLACK;
} // namespace
TEST(FaviconUtilsTest, ShouldThemifyFavicon) {
std::unique_ptr<content::NavigationEntry> entry =
content::NavigationEntry::Create();
const GURL unthemeable_url("http://mail.google.com");
const GURL themeable_virtual_url("chrome://feedback/");
const GURL themeable_url("chrome://new-tab-page/");
entry->SetVirtualURL(themeable_virtual_url);
entry->SetURL(themeable_url);
// Entry should be themefied if both its virtual and actual URLs are
// themeable.
EXPECT_TRUE(ShouldThemifyFaviconForEntry(entry.get()));
entry->SetVirtualURL(unthemeable_url);
// Entry should be themefied if only its actual URL is themeable.
EXPECT_TRUE(ShouldThemifyFaviconForEntry(entry.get()));
entry->SetURL(unthemeable_url);
// Entry should not be themefied if both its virtual and actual URLs are
// not themeable.
EXPECT_FALSE(ShouldThemifyFaviconForEntry(entry.get()));
entry->SetVirtualURL(themeable_virtual_url);
// Entry should be themefied if only its virtual URL is themeable.
EXPECT_TRUE(ShouldThemifyFaviconForEntry(entry.get()));
}
class DefaultFaviconModelTest : public ::testing::Test {
protected:
using InitializerType =
ui::ColorProviderManager::ColorProviderInitializerList::CallbackType;
// testing::Test:
void SetUp() override {
Test::SetUp();
AddDefaultInitializer();
}
void TearDown() override {
ui::ColorProviderManager::ResetForTesting();
Test::TearDown();
}
void AddDefaultInitializer() {
const auto initializer = [&](ui::ColorProvider* provider,
const ui::ColorProviderKey& key) {
ui::ColorMixer& mixer = provider->AddMixer();
mixer[ui::kColorWindowBackground] = {
key.color_mode == ui::ColorProviderKey::ColorMode::kDark
? kDarkColor
: kLightColor};
};
AddInitializer(base::BindRepeating(initializer));
}
void AddInitializer(InitializerType initializer) {
ui::ColorProviderManager& manager =
ui::ColorProviderManager::GetForTesting();
manager.AppendColorProviderInitializer(base::BindRepeating(initializer));
}
ui::ColorProvider* GetColorProvider(
ui::ColorProviderKey::ColorMode color_mode) {
ui::ColorProviderKey key;
key.color_mode = color_mode;
return ui::ColorProviderManager::GetForTesting().GetColorProviderFor(key);
}
gfx::ImageSkia GetDefaultFaviconForColorScheme(bool is_dark) {
const int resource_id =
is_dark ? IDR_DEFAULT_FAVICON_DARK : IDR_DEFAULT_FAVICON;
return ui::ResourceBundle::GetSharedInstance()
.GetNativeImageNamed(resource_id)
.AsImageSkia();
}
};
TEST_F(DefaultFaviconModelTest, UsesCorrectIcon_LightBackground) {
auto* color_provider =
GetColorProvider(ui::ColorProviderKey::ColorMode::kLight);
const auto favicon_image = GetDefaultFaviconModel().Rasterize(color_provider);
EXPECT_TRUE(GetDefaultFaviconForColorScheme(/*is_dark=*/false)
.BackedBySameObjectAs(favicon_image));
}
TEST_F(DefaultFaviconModelTest, UsesCorrectIcon_DarkBackground) {
auto* color_provider =
GetColorProvider(ui::ColorProviderKey::ColorMode::kDark);
const auto favicon_image = GetDefaultFaviconModel().Rasterize(color_provider);
EXPECT_TRUE(GetDefaultFaviconForColorScheme(/*is_dark=*/true)
.BackedBySameObjectAs(favicon_image));
}
TEST_F(DefaultFaviconModelTest, UsesCorrectIcon_LightBackground_Custom) {
// Flip the background for a new color id such that it is light in dark mode
// and vice versa.
const auto initializer = [&](ui::ColorProvider* provider,
const ui::ColorProviderKey& key) {
ui::ColorMixer& mixer = provider->AddMixer();
mixer[ui::kColorBubbleBackground] = {
key.color_mode == ui::ColorProviderKey::ColorMode::kDark ? kLightColor
: kDarkColor};
};
AddInitializer(base::BindRepeating(initializer));
// Even if the color provider is configured for light mode the default favicon
// model should match the dark variant when rasterized.
auto* color_provider =
GetColorProvider(ui::ColorProviderKey::ColorMode::kLight);
const auto favicon_image = GetDefaultFaviconModel(ui::kColorBubbleBackground)
.Rasterize(color_provider);
EXPECT_TRUE(GetDefaultFaviconForColorScheme(/*is_dark=*/true)
.BackedBySameObjectAs(favicon_image));
}
TEST_F(DefaultFaviconModelTest, UsesCorrectIcon_DarkBackground_Custom) {
// Flip the background for a new color id such that it is light in dark mode
// and vice versa.
const auto initializer = [&](ui::ColorProvider* provider,
const ui::ColorProviderKey& key) {
ui::ColorMixer& mixer = provider->AddMixer();
mixer[ui::kColorBubbleBackground] = {
key.color_mode == ui::ColorProviderKey::ColorMode::kDark ? kLightColor
: kDarkColor};
};
AddInitializer(base::BindRepeating(initializer));
// Even if the color provider is configured for dark mode the default favicon
// model should match the light variant when rasterized.
auto* color_provider =
GetColorProvider(ui::ColorProviderKey::ColorMode::kDark);
const auto favicon_image = GetDefaultFaviconModel(ui::kColorBubbleBackground)
.Rasterize(color_provider);
EXPECT_TRUE(GetDefaultFaviconForColorScheme(/*is_dark=*/false)
.BackedBySameObjectAs(favicon_image));
}
} // namespace favicon