chromium/chrome/browser/web_applications/web_app_icon_manager_unittest.cc

// Copyright 2018 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/web_applications/web_app_icon_manager.h"

#include <algorithm>
#include <memory>
#include <optional>
#include <string>
#include <utility>

#include "base/containers/contains.h"
#include "base/files/file_enumerator.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "base/time/time.h"
#include "chrome/browser/web_applications/test/fake_web_app_database_factory.h"
#include "chrome/browser/web_applications/test/fake_web_app_provider.h"
#include "chrome/browser/web_applications/test/test_file_utils.h"
#include "chrome/browser/web_applications/test/web_app_icon_test_utils.h"
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/test/web_app_test.h"
#include "chrome/browser/web_applications/test/web_app_test_utils.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_constants.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
#include "chrome/browser/web_applications/web_app_icon_generator.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/browser/web_applications/web_app_install_manager.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_registry_update.h"
#include "chrome/browser/web_applications/web_app_sync_bridge.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/testing_profile.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/base/resource/resource_scale_factor.h"
#include "ui/gfx/favicon_size.h"

namespace web_app {

namespace {

IconSizeAndPurpose;
const int kMinimumHomeTabIconSizeInPx =;

// Returns a vector of item infos for the shortcuts menu. Each item is empty
// except `downloaded_icon_sizes` is set to `icon_sizes`.
std::vector<WebAppShortcutsMenuItemInfo> CreateShortcutsMenuItemInfos(
    int num_menu_items,
    const IconSizes& icon_sizes) {}

}  // namespace

class WebAppIconManagerTest : public WebAppTest {};

TEST_F(WebAppIconManagerTest, WriteAndReadIcons_AnyOnly) {}

TEST_F(WebAppIconManagerTest, WriteAndReadIcons_MaskableOnly) {}

TEST_F(WebAppIconManagerTest, WriteAndReadIcons_MonochromeOnly) {}

TEST_F(WebAppIconManagerTest, WriteAndReadIcons_AnyAndMaskable) {}

TEST_F(WebAppIconManagerTest, WriteAndReadIcons_AnyAndMonochrome) {}

TEST_F(WebAppIconManagerTest, OverwriteIcons) {}

TEST_F(WebAppIconManagerTest, ReadAllIcons_AnyOnly) {}

TEST_F(WebAppIconManagerTest, ReadAllIconsLastUpdateTime) {}

TEST_F(WebAppIconManagerTest, ReadAllShortcutMenuIconsWithTimestamp) {}

TEST_F(WebAppIconManagerTest, NoHomeTabIcons) {}

TEST_F(WebAppIconManagerTest, ReadAllIcons_AnyAndMaskable) {}

TEST_F(WebAppIconManagerTest, ReadShortcutsMenuIconsFailed) {}

TEST_F(WebAppIconManagerTest, WriteAndReadAllShortcutsMenuIcons) {}

TEST_F(WebAppIconManagerTest, WriteNonProductIconsEmptyMaps) {}

TEST_F(WebAppIconManagerTest, WriteOtherIconsToDisk) {}

TEST_F(WebAppIconManagerTest, ReadIconsFailed) {}

TEST_F(WebAppIconManagerTest, FindExact) {}

// Simple struct doesn't have an operator==.
bool operator==(const IconSizeAndPurpose& a, const IconSizeAndPurpose& b) {}

TEST_F(WebAppIconManagerTest, FindSmallest) {}

TEST_F(WebAppIconManagerTest, DeleteData_Success) {}

TEST_F(WebAppIconManagerTest, DeleteData_Failure) {}

TEST_F(WebAppIconManagerTest, ReadSmallestCompressedIcon_Success_AnyOnly) {}

TEST_F(WebAppIconManagerTest, ReadSmallestCompressedIcon_Success) {}

TEST_F(WebAppIconManagerTest, ReadSmallestCompressedIcon_Failure) {}

TEST_F(WebAppIconManagerTest, ReadIconAndResize_Success_AnyOnly) {}

TEST_F(WebAppIconManagerTest, ReadIconAndResize_Success_AnyAndMaskable) {}

TEST_F(WebAppIconManagerTest, ReadIconAndResize_Failure) {}

TEST_F(WebAppIconManagerTest, CacheExistingAppFavicon) {}

TEST_F(WebAppIconManagerTest, CacheAppFaviconWithResize) {}

TEST_F(WebAppIconManagerTest, CacheNewAppFavicon) {}

TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_NoMissingIcons) {}

TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_DownsizingIcons) {}

TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_NoIcons) {}

TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_NoMatchSmaller) {}

TEST_F(WebAppIconManagerTest,
       CacheAppFavicon_UiScaleFactors_DownsizingFromSingleIcon) {}

TEST_F(WebAppIconManagerTest,
       CacheAppFavicon_UiScaleFactors_BiggerUiScaleFactorIconMissing) {}

#if BUILDFLAG(IS_CHROMEOS)
using WebAppIconManagerTest_NotificationIconAndTitle = WebAppIconManagerTest;

// TODO(b/321111988): Reenable this test.
TEST_F(WebAppIconManagerTest_NotificationIconAndTitle,
       DISABLED_CacheAppMonochromeFavicon_NoMissingIcons) {
  std::unique_ptr<WebApp> web_app = test::CreateWebApp();
  web_app->SetThemeColor(std::make_optional(SK_ColorBLUE));

  const webapps::AppId app_id = web_app->app_id();

  // App declares icons precisely matching suspported UI scale factors.
  const std::vector<int> sizes_px{icon_size::k16, icon_size::k32,
                                  icon_size::k64};
  ASSERT_TRUE(base::Contains(sizes_px, gfx::kFaviconSize));

  const std::vector<SkColor> colors{SK_ColorYELLOW, SK_ColorTRANSPARENT,
                                    SK_ColorRED};
  IconManagerWriteGeneratedIcons(icon_manager(), app_id,
                                 {{IconPurpose::MONOCHROME, sizes_px, colors}});

  web_app->SetDownloadedIconSizes(IconPurpose::MONOCHROME, sizes_px);

  AwaitReadFaviconMonochromeOnAddingWebApp(std::move(web_app));

  gfx::ImageSkia monochrome_image = icon_manager().GetMonochromeFavicon(app_id);
  ASSERT_FALSE(monochrome_image.isNull());

  EXPECT_EQ(gfx::kFaviconSize, monochrome_image.width());
  EXPECT_EQ(gfx::kFaviconSize, monochrome_image.height());
  {
    SCOPED_TRACE(icon_size::k16);
    ExpectImageSkiaRep(monochrome_image, /*scale=*/1.0f,
                       /*size_px=*/icon_size::k16, SK_ColorBLUE);
  }
  {
    SCOPED_TRACE(icon_size::k32);
    ExpectImageSkiaRep(monochrome_image, /*scale=*/2.0f,
                       /*size_px=*/icon_size::k32, SK_ColorTRANSPARENT);
  }
  {
    SCOPED_TRACE(icon_size::k64);
    ExpectImageSkiaRep(monochrome_image, /*scale=*/4.0f,
                       /*size_px=*/icon_size::k64, SK_ColorBLUE);
  }
}

TEST_F(WebAppIconManagerTest_NotificationIconAndTitle,
       CacheAppMonochromeFavicon_CacheAfterAppInstall) {
  std::unique_ptr<WebApp> web_app = test::CreateWebApp();
  web_app->SetThemeColor(std::make_optional(SK_ColorGREEN));

  const webapps::AppId app_id = web_app->app_id();

  // App declares only one jumbo icon.
  const std::vector<int> sizes_px{icon_size::k512};
  const std::vector<SkColor> colors{SK_ColorRED};
  IconManagerWriteGeneratedIcons(icon_manager(), app_id,
                                 {{IconPurpose::MONOCHROME, sizes_px, colors}});
  web_app->SetDownloadedIconSizes(IconPurpose::MONOCHROME, sizes_px);

  AwaitReadFaviconMonochromeOnAddingWebApp(std::move(web_app));

  gfx::ImageSkia monochrome_image = icon_manager().GetMonochromeFavicon(app_id);
  ASSERT_FALSE(monochrome_image.isNull());

  EXPECT_EQ(gfx::kFaviconSize, monochrome_image.width());
  EXPECT_EQ(gfx::kFaviconSize, monochrome_image.height());
  {
    SCOPED_TRACE(icon_size::k16);
    ExpectImageSkiaRep(monochrome_image, /*scale=*/1.0f,
                       /*size_px=*/icon_size::k16, SK_ColorGREEN);
  }
  {
    SCOPED_TRACE(icon_size::k64);
    ExpectImageSkiaRep(monochrome_image, /*scale=*/4.0f,
                       /*size_px=*/icon_size::k64, SK_ColorGREEN);
  }
  EXPECT_FALSE(monochrome_image.HasRepresentation(2.0f));
  EXPECT_FALSE(monochrome_image.HasRepresentation(3.0f));
  EXPECT_FALSE(monochrome_image.HasRepresentation(32.0f));
}

TEST_F(WebAppIconManagerTest_NotificationIconAndTitle,
       CacheAppMonochromeFavicon_NoThemeColor) {
  std::unique_ptr<WebApp> web_app = test::CreateWebApp();
  web_app->SetThemeColor(std::nullopt);

  const webapps::AppId app_id = web_app->app_id();

  // Provides only k200Percent icon.
  const std::vector<int> sizes_px{icon_size::k32};
  const std::vector<SkColor> colors{SK_ColorRED};
  IconManagerWriteGeneratedIcons(icon_manager(), app_id,
                                 {{IconPurpose::MONOCHROME, sizes_px, colors}});
  web_app->SetDownloadedIconSizes(IconPurpose::MONOCHROME, sizes_px);

  AwaitReadFaviconMonochromeOnAddingWebApp(std::move(web_app));

  gfx::ImageSkia monochrome_image = icon_manager().GetMonochromeFavicon(app_id);
  ASSERT_FALSE(monochrome_image.isNull());

  EXPECT_EQ(gfx::kFaviconSize, monochrome_image.width());
  EXPECT_EQ(gfx::kFaviconSize, monochrome_image.height());
  {
    SCOPED_TRACE(icon_size::k16);
    ExpectImageSkiaRep(monochrome_image, /*scale=*/1.0f,
                       /*size_px=*/icon_size::k16, SK_ColorDKGRAY);
  }
  {
    SCOPED_TRACE(icon_size::k32);
    ExpectImageSkiaRep(monochrome_image, /*scale=*/2.0f,
                       /*size_px=*/icon_size::k32, SK_ColorDKGRAY);
  }
  EXPECT_FALSE(monochrome_image.HasRepresentation(3.0));
}

TEST_F(WebAppIconManagerTest_NotificationIconAndTitle,
       CacheAppMonochromeFavicon_NoIcons) {
  std::unique_ptr<WebApp> web_app = test::CreateWebApp();
  const webapps::AppId app_id = web_app->app_id();
  AwaitReadFaviconMonochromeOnAddingWebApp(std::move(web_app));

  gfx::ImageSkia monochrome_image = icon_manager().GetMonochromeFavicon(app_id);
  EXPECT_TRUE(monochrome_image.isNull());
}
#endif  // BUILDFLAG(IS_CHROMEOS)

}  // namespace web_app