chromium/ash/system/phonehub/quick_actions_view_unittest.cc

// Copyright 2020 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/phonehub/quick_actions_view.h"

#include "ash/constants/ash_features.h"
#include "ash/system/phonehub/quick_action_item.h"
#include "ash/test/ash_test_base.h"
#include "base/test/scoped_feature_list.h"
#include "chromeos/ash/components/phonehub/fake_phone_hub_manager.h"
#include "ui/events/test/test_event.h"
#include "ui/views/test/button_test_api.h"

namespace ash {

namespace {

using FindMyDeviceController = phonehub::FindMyDeviceController;
using TetherController = phonehub::TetherController;

constexpr base::TimeDelta kWaitForRequestTimeout = base::Seconds(10);

}  // namespace

class QuickActionsViewTest : public AshTestBase {
 public:
  QuickActionsViewTest()
      : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
  ~QuickActionsViewTest() override = default;

  // AshTestBase:
  void SetUp() override {
    feature_list_.InitAndEnableFeature(features::kPhoneHub);
    AshTestBase::SetUp();

    quick_actions_view_ =
        std::make_unique<QuickActionsView>(&phone_hub_manager_);
  }

  void TearDown() override {
    quick_actions_view_.reset();
    AshTestBase::TearDown();
  }

 protected:
  QuickActionsView* actions_view() { return quick_actions_view_.get(); }
  phonehub::FakeTetherController* tether_controller() {
    return phone_hub_manager_.fake_tether_controller();
  }
  phonehub::FakeDoNotDisturbController* dnd_controller() {
    return phone_hub_manager_.fake_do_not_disturb_controller();
  }
  phonehub::FakeFindMyDeviceController* find_my_device_controller() {
    return phone_hub_manager_.fake_find_my_device_controller();
  }

 private:
  std::unique_ptr<QuickActionsView> quick_actions_view_;
  phonehub::FakePhoneHubManager phone_hub_manager_;
  base::test::ScopedFeatureList feature_list_;
};

TEST_F(QuickActionsViewTest, EnableHotspotVisibility) {
  tether_controller()->SetStatus(
      TetherController::Status::kIneligibleForFeature);

  // Enable Hotspot button should not be shown if the feature is ineligible.
  EXPECT_FALSE(actions_view()->GetEnableHotspotQuickActionItem()->GetVisible());

  tether_controller()->SetStatus(
      TetherController::Status::kConnectionAvailable);
  // Enable Hotspot button should be shown if the feature is available.
  EXPECT_TRUE(actions_view()->GetEnableHotspotQuickActionItem()->GetVisible());
}

TEST_F(QuickActionsViewTest, EnableHotspotToggle) {
  tether_controller()->SetStatus(
      TetherController::Status::kConnectionAvailable);

  // Simulate a toggle press. Status should be connecting.
  views::test::ButtonTestApi test_api(
      actions_view()->GetEnableHotspotQuickActionItem()->icon_button());
  test_api.NotifyClick(ui::test::TestEvent());
  // The color provider is null in tests causing toggle to not be set
  // so setting here.
  actions_view()->GetEnableHotspotQuickActionItem()->SetToggled(true);
  EXPECT_EQ(TetherController::Status::kConnecting,
            tether_controller()->GetStatus());

  tether_controller()->SetStatus(TetherController::Status::kConnected);
  // Toggling again will change the state.
  test_api.NotifyClick(ui::test::TestEvent());
  EXPECT_EQ(TetherController::Status::kConnecting,
            tether_controller()->GetStatus());
}

TEST_F(QuickActionsViewTest, SilencePhoneToggle) {
  // Allow silence phone to be toggle-able.
  dnd_controller()->SetDoNotDisturbStateInternal(
      /*is_dnd_enabled=*/false,
      /*can_request_new_dnd_state=*/true);

  // Initially, silence phone is not enabled.
  EXPECT_FALSE(dnd_controller()->IsDndEnabled());

  // Toggling the button will enable the feature.
  views::test::ButtonTestApi test_api(
      actions_view()->silence_phone_for_testing()->icon_button());
  test_api.NotifyClick(ui::test::TestEvent());
  EXPECT_TRUE(dnd_controller()->IsDndEnabled());

  // Toggle again to disable.
  test_api.NotifyClick(ui::test::TestEvent());
  EXPECT_FALSE(dnd_controller()->IsDndEnabled());

  // Test the error state.
  dnd_controller()->SetShouldRequestFail(true);
  test_api.NotifyClick(ui::test::TestEvent());

  // In error state, do not disturb is disabled but the button should still be
  // on after being pressed.
  EXPECT_FALSE(dnd_controller()->IsDndEnabled());
  EXPECT_TRUE(actions_view()->silence_phone_for_testing()->IsToggled());

  // After a certain time, the button should be corrected to be off.
  task_environment()->FastForwardBy(kWaitForRequestTimeout);
  EXPECT_FALSE(actions_view()->silence_phone_for_testing()->IsToggled());

  dnd_controller()->SetShouldRequestFail(false);
}

TEST_F(QuickActionsViewTest, LocatePhoneToggle) {
  // Initially, locate phone is not enabled.
  EXPECT_EQ(FindMyDeviceController::Status::kRingingOff,
            find_my_device_controller()->GetPhoneRingingStatus());

  // Toggling the button will enable the feature.
  views::test::ButtonTestApi test_api(
      actions_view()->locate_phone_for_testing()->icon_button());
  test_api.NotifyClick(ui::test::TestEvent());
  EXPECT_EQ(FindMyDeviceController::Status::kRingingOn,
            find_my_device_controller()->GetPhoneRingingStatus());

  // Toggle again to disable.
  test_api.NotifyClick(ui::test::TestEvent());
  EXPECT_EQ(FindMyDeviceController::Status::kRingingOff,
            find_my_device_controller()->GetPhoneRingingStatus());

  // Test the error state.
  find_my_device_controller()->SetShouldRequestFail(true);
  test_api.NotifyClick(ui::test::TestEvent());

  // In error state, find my device is disabled but the button should still be
  // on after being pressed.
  EXPECT_EQ(FindMyDeviceController::Status::kRingingOff,
            find_my_device_controller()->GetPhoneRingingStatus());
  EXPECT_TRUE(actions_view()->locate_phone_for_testing()->IsToggled());

  // After a certain time, the button should be corrected to be off.
  task_environment()->FastForwardBy(kWaitForRequestTimeout);
  EXPECT_FALSE(actions_view()->locate_phone_for_testing()->IsToggled());

  find_my_device_controller()->SetShouldRequestFail(false);
}

}  // namespace ash