chromium/ash/picker/views/picker_image_item_grid_view_unittest.cc

// Copyright 2024 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/picker/views/picker_image_item_grid_view.h"

#include <memory>
#include <string>
#include <utility>

#include "ash/picker/views/picker_gif_view.h"
#include "ash/picker/views/picker_image_item_view.h"
#include "base/functional/callback_helpers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/size.h"
#include "ui/views/view.h"

namespace ash {
namespace {

using ::testing::ElementsAre;
using ::testing::IsEmpty;
using ::testing::Pointee;
using ::testing::Property;

constexpr int kDefaultGridWidth = 320;

int GetAspectRatio(const gfx::Size& size) {
  return size.height() / size.width();
}

std::unique_ptr<PickerImageItemView> CreateGifItem(
    const gfx::Size& gif_dimensions) {
  return std::make_unique<PickerImageItemView>(
      base::DoNothing(),
      std::make_unique<PickerGifView>(
          /*frames_fetcher=*/base::DoNothing(),
          /*preview_image_fetcher=*/base::DoNothing(), gif_dimensions,
          /*accessible_name=*/u""));
}

TEST(PickerImageItemGridViewTest, OneGifItem) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);

  const PickerItemView* item =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 100)));

  // Two columns, one item in the first column.
  EXPECT_THAT(
      item_grid.children(),
      ElementsAre(Pointee(Property(&views::View::children, ElementsAre(item))),
                  Pointee(Property(&views::View::children, IsEmpty()))));
}

TEST(PickerImageItemGridViewTest, TwoGifItems) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);

  const PickerItemView* item1 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 100)));
  const PickerItemView* item2 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 100)));

  // Two columns, one item in each column.
  EXPECT_THAT(
      item_grid.children(),
      ElementsAre(
          Pointee(Property(&views::View::children, ElementsAre(item1))),
          Pointee(Property(&views::View::children, ElementsAre(item2)))));
}

TEST(PickerImageItemGridViewTest, GifItemsWithVaryingHeight) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);

  const PickerItemView* item1 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 120)));
  const PickerItemView* item2 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 20)));
  const PickerItemView* item3 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 30)));
  const PickerItemView* item4 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 20)));

  // One item in first column, three items in second column.
  EXPECT_THAT(
      item_grid.children(),
      ElementsAre(Pointee(Property(&views::View::children, ElementsAre(item1))),
                  Pointee(Property(&views::View::children,
                                   ElementsAre(item2, item3, item4)))));
}

// TODO: b/357146181 - Re-enable once Gifs are used again.
TEST(PickerImageItemGridViewTest, DISABLED_GifItemsAreResizedToSameWidth) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);

  const PickerItemView* item1 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 100)));
  const PickerItemView* item2 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(80, 160)));

  EXPECT_EQ(item1->GetPreferredSize().width(),
            item2->GetPreferredSize().width());
}

TEST(PickerImageItemGridViewTest, PreservesAspectRatioOfGifItems) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);

  constexpr gfx::Size kGifDimensions(100, 200);
  const PickerItemView* item =
      item_grid.AddImageItem(CreateGifItem(kGifDimensions));

  EXPECT_EQ(GetAspectRatio(item->GetPreferredSize()),
            GetAspectRatio(kGifDimensions));
}

TEST(PickerImageItemGridViewTest, GetsTopItem) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);

  PickerItemView* item1 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 100)));
  PickerItemView* item2 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 110)));
  PickerItemView* item3 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 120)));

  EXPECT_THAT(
      item_grid.children(),
      ElementsAre(
          Pointee(Property(&views::View::children, ElementsAre(item1, item3))),
          Pointee(Property(&views::View::children, ElementsAre(item2)))));
  EXPECT_EQ(item_grid.GetTopItem(), item1);
}

TEST(PickerImageItemGridViewTest, EmptyGridHasNoTopItem) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);

  EXPECT_EQ(item_grid.GetTopItem(), nullptr);
}

TEST(PickerImageItemGridViewTest, GetsBottomItem) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);

  PickerItemView* item1 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 100)));
  PickerItemView* item2 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 110)));
  PickerItemView* item3 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 120)));

  EXPECT_THAT(
      item_grid.children(),
      ElementsAre(
          Pointee(Property(&views::View::children, ElementsAre(item1, item3))),
          Pointee(Property(&views::View::children, ElementsAre(item2)))));
  EXPECT_EQ(item_grid.GetBottomItem(), item3);
}

TEST(PickerImageItemGridViewTest, EmptyGridHasNoBottomItem) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);

  EXPECT_EQ(item_grid.GetBottomItem(), nullptr);
}

TEST(PickerImageItemGridViewTest, GetsItemAbove) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);

  PickerItemView* item1 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 100)));
  PickerItemView* item2 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 110)));
  PickerItemView* item3 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 120)));
  PickerItemView* item4 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 130)));

  EXPECT_THAT(item_grid.children(),
              ElementsAre(Pointee(Property(&views::View::children,
                                           ElementsAre(item1, item3))),
                          Pointee(Property(&views::View::children,
                                           ElementsAre(item2, item4)))));
  EXPECT_EQ(item_grid.GetItemAbove(item1), nullptr);
  EXPECT_EQ(item_grid.GetItemAbove(item2), nullptr);
  EXPECT_EQ(item_grid.GetItemAbove(item3), item1);
  EXPECT_EQ(item_grid.GetItemAbove(item4), item2);
}

TEST(PickerImageItemGridViewTest, ItemNotInGridHasNoItemAbove) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);
  std::unique_ptr<PickerImageItemView> item_not_in_grid =
      CreateGifItem(gfx::Size(100, 100));

  EXPECT_EQ(item_grid.GetItemAbove(item_not_in_grid.get()), nullptr);
}

TEST(PickerImageItemGridViewTest, GetsItemBelow) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);

  PickerItemView* item1 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 100)));
  PickerItemView* item2 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 110)));
  PickerItemView* item3 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 120)));
  PickerItemView* item4 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 130)));

  EXPECT_THAT(item_grid.children(),
              ElementsAre(Pointee(Property(&views::View::children,
                                           ElementsAre(item1, item3))),
                          Pointee(Property(&views::View::children,
                                           ElementsAre(item2, item4)))));
  EXPECT_EQ(item_grid.GetItemBelow(item1), item3);
  EXPECT_EQ(item_grid.GetItemBelow(item2), item4);
  EXPECT_EQ(item_grid.GetItemBelow(item3), nullptr);
  EXPECT_EQ(item_grid.GetItemBelow(item4), nullptr);
}

TEST(PickerImageItemGridViewTest, ItemNotInGridHasNoItemBelow) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);
  std::unique_ptr<PickerImageItemView> item_not_in_grid =
      CreateGifItem(gfx::Size(100, 100));

  EXPECT_EQ(item_grid.GetItemBelow(item_not_in_grid.get()), nullptr);
}

TEST(PickerImageItemGridViewTest, GetsItemLeftOf) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);

  PickerItemView* item1 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 100)));
  PickerItemView* item2 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 110)));
  PickerItemView* item3 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 120)));
  PickerItemView* item4 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 130)));

  EXPECT_THAT(item_grid.children(),
              ElementsAre(Pointee(Property(&views::View::children,
                                           ElementsAre(item1, item3))),
                          Pointee(Property(&views::View::children,
                                           ElementsAre(item2, item4)))));
  EXPECT_EQ(item_grid.GetItemLeftOf(item1), nullptr);
  EXPECT_EQ(item_grid.GetItemLeftOf(item2), item1);
  EXPECT_EQ(item_grid.GetItemLeftOf(item3), nullptr);
  EXPECT_EQ(item_grid.GetItemLeftOf(item4), item3);
}

TEST(PickerImageItemGridViewTest, GetsItemLeftOfWithUnbalancedColumns) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);

  PickerItemView* item1 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 300)));
  PickerItemView* item2 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 110)));
  PickerItemView* item3 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 120)));

  EXPECT_THAT(
      item_grid.children(),
      ElementsAre(Pointee(Property(&views::View::children, ElementsAre(item1))),
                  Pointee(Property(&views::View::children,
                                   ElementsAre(item2, item3)))));
  EXPECT_EQ(item_grid.GetItemLeftOf(item1), nullptr);
  EXPECT_EQ(item_grid.GetItemLeftOf(item2), item1);
  EXPECT_EQ(item_grid.GetItemLeftOf(item3), item1);
}

TEST(PickerImageItemGridViewTest, ItemNotInGridHasNoItemLeftOf) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);
  std::unique_ptr<PickerImageItemView> item_not_in_grid =
      CreateGifItem(gfx::Size(100, 100));

  EXPECT_EQ(item_grid.GetItemLeftOf(item_not_in_grid.get()), nullptr);
}

TEST(PickerImageItemGridViewTest, GetsItemRightOf) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);

  PickerItemView* item1 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 100)));
  PickerItemView* item2 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 110)));
  PickerItemView* item3 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 120)));
  PickerItemView* item4 =
      item_grid.AddImageItem(CreateGifItem(gfx::Size(100, 130)));

  EXPECT_THAT(item_grid.children(),
              ElementsAre(Pointee(Property(&views::View::children,
                                           ElementsAre(item1, item3))),
                          Pointee(Property(&views::View::children,
                                           ElementsAre(item2, item4)))));
  EXPECT_EQ(item_grid.GetItemRightOf(item1), item2);
  EXPECT_EQ(item_grid.GetItemRightOf(item2), nullptr);
  EXPECT_EQ(item_grid.GetItemRightOf(item3), item4);
  EXPECT_EQ(item_grid.GetItemRightOf(item4), nullptr);
}

TEST(PickerImageItemGridViewTest, ItemNotInGridHasNoItemRightOf) {
  PickerImageItemGridView item_grid(kDefaultGridWidth);
  std::unique_ptr<PickerImageItemView> item_not_in_grid =
      CreateGifItem(gfx::Size(100, 100));

  EXPECT_EQ(item_grid.GetItemRightOf(item_not_in_grid.get()), nullptr);
}

}  // namespace
}  // namespace ash