chromium/ash/system/network/network_list_tether_hosts_header_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/network/network_list_tether_hosts_header_view.h"

#include <memory>

#include "ash/constants/ash_features.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/network/network_list_header_view.h"
#include "ash/system/tray/hover_highlight_view.h"
#include "ash/system/tray/tri_view.h"
#include "ash/test/ash_test_base.h"
#include "base/functional/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/image_model.h"
#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/vector_icon_types.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"

namespace ash {

class NetworkListTetherHostsHeaderViewTest : public AshTestBase {
 public:
  ~NetworkListTetherHostsHeaderViewTest() override = default;

  // AshTestBase:
  void SetUp() override {
    AshTestBase::SetUp();
    std::vector<base::test::FeatureRef> enabled_features;
    std::vector<base::test::FeatureRef> disabled_features;
    enabled_features.push_back(features::kInstantHotspotRebrand);
    feature_list_.InitWithFeatures(enabled_features, disabled_features);
    std::unique_ptr<NetworkListTetherHostsHeaderView>
        network_list_tether_hosts_header_view =
            std::make_unique<NetworkListTetherHostsHeaderView>(
                base::BindRepeating(
                    &NetworkListTetherHostsHeaderViewTest::OnHeaderClicked,
                    weak_ptr_factory_.GetWeakPtr()));

    widget_ = CreateFramelessTestWidget();
    widget_->SetFullscreen(true);
    network_list_tether_hosts_header_view_ = widget_->SetContentsView(
        std::move(network_list_tether_hosts_header_view));

    // Wait for network state and device change events to be handled.
    base::RunLoop().RunUntilIdle();
  }

  void TearDown() override {
    widget_.reset();

    AshTestBase::TearDown();
  }

  HoverHighlightView* GetEntryRow() {
    return FindViewById<HoverHighlightView*>(static_cast<int>(
        NetworkListTetherHostsHeaderView::
            NetworkListTetherHostsHeaderViewChildId::kEntryRow));
  }

  bool ChevronHasIcon(const gfx::VectorIcon& icon) {
    auto* chevron_view = FindViewById<views::ImageView*>(static_cast<int>(
        NetworkListTetherHostsHeaderView::
            NetworkListTetherHostsHeaderViewChildId::kChevron));
    const SkBitmap* actual_bitmap = chevron_view->GetImage().bitmap();

    auto expected_icon =
        ui::ImageModel::FromVectorIcon(icon, cros_tokens::kCrosSysOnSurface);

    const SkBitmap* expected_bitmap =
        expected_icon.Rasterize(chevron_view->GetColorProvider()).bitmap();

    return gfx::BitmapsAreEqual(*actual_bitmap, *expected_bitmap);
  }

  int get_expanded_callback_execution_count() {
    return expanded_callback_call_count_;
  }

  NetworkListTetherHostsHeaderView* get_header() {
    return network_list_tether_hosts_header_view_;
  }

 private:
  template <class T>
  T FindViewById(int id) {
    return static_cast<T>(
        network_list_tether_hosts_header_view_->GetViewByID(id));
  }
  void OnHeaderClicked() { expanded_callback_call_count_++; }

  size_t expanded_callback_call_count_ = 0u;

  base::test::ScopedFeatureList feature_list_;

  std::unique_ptr<views::Widget> widget_;
  raw_ptr<NetworkListTetherHostsHeaderView, DanglingUntriaged>
      network_list_tether_hosts_header_view_;

  base::WeakPtrFactory<NetworkListTetherHostsHeaderViewTest> weak_ptr_factory_{
      this};
};

TEST_F(NetworkListTetherHostsHeaderViewTest,
       ClickingEntryRowTogglesExpandedValue) {
  // Expect the header starts expanded.
  EXPECT_TRUE(get_header()->is_expanded());
  EXPECT_TRUE(ChevronHasIcon(kChevronUpIcon));

  // Click once - expect it is no longer expanded.
  auto* entry_row = GetEntryRow();
  LeftClickOn(entry_row);
  EXPECT_EQ(get_expanded_callback_execution_count(), 1);
  EXPECT_FALSE(get_header()->is_expanded());
  EXPECT_TRUE(ChevronHasIcon(kChevronDownIcon));

  // Click again - expect it is expanded.
  LeftClickOn(entry_row);
  EXPECT_EQ(get_expanded_callback_execution_count(), 2);
  EXPECT_TRUE(get_header()->is_expanded());
  EXPECT_TRUE(ChevronHasIcon(kChevronUpIcon));
}

// TODO(b/298254852): check for correct label ID and icon.
// TODO(b/300155715): parameterize test suite on whether kQsRevamp is
// enabled/disabled.

}  // namespace ash