chromium/ash/system/holding_space/holding_space_item_screen_capture_view_unittest.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/holding_space/holding_space_item_screen_capture_view.h"

#include <memory>
#include <set>

#include "ash/public/cpp/holding_space/holding_space_constants.h"
#include "ash/public/cpp/holding_space/holding_space_file.h"
#include "ash/public/cpp/holding_space/holding_space_image.h"
#include "ash/public/cpp/holding_space/holding_space_item.h"
#include "ash/public/cpp/holding_space/holding_space_section.h"
#include "ash/public/cpp/holding_space/holding_space_util.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/shell.h"
#include "ash/style/ash_color_id.h"
#include "ash/style/color_util.h"
#include "ash/system/holding_space/holding_space_ash_test_base.h"
#include "ash/system/holding_space/holding_space_view_delegate.h"
#include "components/vector_icons/vector_icons.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/image/image_unittest_util.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/view_utils.h"

namespace ash {
namespace {

// Helpers ---------------------------------------------------------------------

// Returns the set of all holding space item types which are screen captures.
std::set<HoldingSpaceItem::Type> GetHoldingSpaceItemScreenCaptureTypes() {
  std::set<HoldingSpaceItem::Type> types;
  if (const HoldingSpaceSection* section =
          GetHoldingSpaceSection(HoldingSpaceSectionId::kScreenCaptures)) {
    for (const HoldingSpaceItem::Type& supported_type :
         section->supported_types) {
      DCHECK(HoldingSpaceItem::IsScreenCaptureType(supported_type));
      types.insert(supported_type);
    }
  }
  DCHECK_GT(types.size(), 0u);
  return types;
}

}  // namespace

// HoldingSpaceItemScreenCaptureViewTest ---------------------------------------

// Base class for tests of `HoldingSpaceItemScreenCaptureView`.
class HoldingSpaceItemScreenCaptureViewTest
    : public HoldingSpaceAshTestBase,
      public testing::WithParamInterface<HoldingSpaceItem::Type> {
 public:
  const HoldingSpaceItem* item() const { return item_.get(); }
  const views::View* view() const { return view_.get(); }

 private:
  // HoldingSpaceAshTestBase:
  void SetUp() override {
    HoldingSpaceAshTestBase::SetUp();

    HoldingSpaceItem::Type type = GetParam();
    ASSERT_TRUE(HoldingSpaceItem::IsScreenCaptureType(type));

    item_ = HoldingSpaceItem::CreateFileBackedItem(
        type,
        HoldingSpaceFile(base::FilePath("file_path"),
                         HoldingSpaceFile::FileSystemType::kTest,
                         GURL("filesystem:file_system_url")),
        base::BindOnce(
            [](HoldingSpaceItem::Type type, const base::FilePath& file_path)
                -> std::unique_ptr<HoldingSpaceImage> {
              return std::make_unique<HoldingSpaceImage>(
                  holding_space_util::GetMaxImageSizeForType(type), file_path,
                  /*async_bitmap_resolver=*/base::DoNothing());
            }));

    delegate_ = std::make_unique<HoldingSpaceViewDelegate>(/*bubble=*/nullptr);
    view_ = std::make_unique<HoldingSpaceItemScreenCaptureView>(delegate_.get(),
                                                                item_.get());
  }

  void TearDown() override {
    view_.reset();
    delegate_.reset();
    item_.reset();

    HoldingSpaceAshTestBase::TearDown();
  }

  std::unique_ptr<HoldingSpaceItem> item_;
  std::unique_ptr<HoldingSpaceViewDelegate> delegate_;
  std::unique_ptr<HoldingSpaceItemScreenCaptureView> view_;
};

INSTANTIATE_TEST_SUITE_P(
    All,
    HoldingSpaceItemScreenCaptureViewTest,
    testing::ValuesIn(GetHoldingSpaceItemScreenCaptureTypes()));

// Tests -----------------------------------------------------------------------

// Verifies absence/presence of overlay icon depending on item type.
TEST_P(HoldingSpaceItemScreenCaptureViewTest, OverlayIcon) {
  const views::View* overlay_icon =
      view()->GetViewByID(kHoldingSpaceScreenCaptureOverlayIconId);

  if (item()->type() == HoldingSpaceItem::Type::kScreenshot) {
    EXPECT_FALSE(overlay_icon);
    return;
  }

  ASSERT_TRUE(overlay_icon);

  auto* color_provider_source =
      ColorUtil::GetColorProviderSourceForWindow(Shell::GetPrimaryRootWindow());
  ASSERT_TRUE(color_provider_source);
  auto* color_provider = color_provider_source->GetColorProvider();
  ASSERT_TRUE(color_provider);

  // NOTE: The below compares rasterized bitmaps instead of directly comparing
  // image models due to the fact that vector icons have different memory
  // addresses in production code than in test code, resulting in inequality.
  EXPECT_TRUE(gfx::test::AreBitmapsEqual(
      *views::AsViewClass<views::ImageView>(overlay_icon)
           ->GetImageModel()
           .Rasterize(color_provider)
           .bitmap(),
      *ui::ImageModel::FromVectorIcon(
           item()->type() == HoldingSpaceItem::Type::kScreenRecordingGif
               ? kGifIcon
               : vector_icons::kPlayArrowIcon,
           kColorAshButtonIconColor, kHoldingSpaceIconSize)
           .Rasterize(color_provider)
           .bitmap()));
}

}  // namespace ash