chromium/ash/system/focus_mode/focus_mode_countdown_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/focus_mode/focus_mode_countdown_view.h"

#include "ash/constants/ash_features.h"
#include "ash/style/pill_button.h"
#include "ash/system/focus_mode/focus_mode_controller.h"
#include "ash/system/focus_mode/focus_mode_histogram_names.h"
#include "ash/system/focus_mode/focus_mode_task_test_utils.h"
#include "ash/system/focus_mode/focus_mode_tray.h"
#include "ash/system/focus_mode/focus_mode_util.h"
#include "ash/system/status_area_widget_test_helper.h"
#include "ash/test/ash_test_base.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "components/account_id/account_id.h"

namespace ash {

class FocusModeCountdownViewTest : public AshTestBase {
 public:
  FocusModeCountdownViewTest() : scoped_feature_(features::kFocusMode) {}
  ~FocusModeCountdownViewTest() override = default;

  // AshTestBase:
  void SetUp() override {
    AshTestBase::SetUp();

    // Prepare a TaskClient for FocusModeController.
    AccountId account = AccountId::FromUserEmail("[email protected]");
    CreateFakeTasksClient(account);
    SimulateUserLogin(account);

    focus_mode_tray_ =
        StatusAreaWidgetTestHelper::GetStatusAreaWidget()->focus_mode_tray();
  }

  void TearDown() override {
    focus_mode_tray_ = nullptr;
    AshTestBase::TearDown();
  }

  PillButton* GetExtendTimeButton() {
    return focus_mode_tray_->countdown_view_for_testing()
        ->extend_session_duration_button_;
  }

  views::Label* GetTimeRemainingLabel() {
    return focus_mode_tray_->countdown_view_for_testing()
        ->time_remaining_label_;
  }

  PillButton* GetEndButton() {
    return focus_mode_tray_->countdown_view_for_testing()->end_button_;
  }

 protected:
  base::test::ScopedFeatureList scoped_feature_;
  raw_ptr<FocusModeTray> focus_mode_tray_ = nullptr;
};

// Tests that the bubble is not visible until the tray is activated, and the
// bubble goes away when the tray is deactivated or focus mode ends.
TEST_F(FocusModeCountdownViewTest, ToggleVisibility) {
  ASSERT_TRUE(focus_mode_tray_);
  EXPECT_FALSE(focus_mode_tray_->GetBubbleView());

  // Start the focus session and activate the tray.
  FocusModeController* controller = FocusModeController::Get();
  controller->ToggleFocusMode();
  EXPECT_FALSE(focus_mode_tray_->GetBubbleView());
  LeftClickOn(focus_mode_tray_);
  EXPECT_TRUE(focus_mode_tray_->GetBubbleView());

  // Click the tray again to toggle the bubble.
  LeftClickOn(focus_mode_tray_);
  EXPECT_FALSE(focus_mode_tray_->GetBubbleView());

  // Bring the bubble back, then end focus mode to toggle the bubble.
  LeftClickOn(focus_mode_tray_);
  EXPECT_TRUE(focus_mode_tray_->GetBubbleView());
  controller->ToggleFocusMode();
  EXPECT_FALSE(focus_mode_tray_->GetBubbleView());
}

// Tests that in an active focus session, the user clicks the `+10 min` button
// while the valid time to extend is less than 10 minutes. Check if the `+10
// min` button is disabled and the text of the remaining time label in the
// progress bar should be equal to the maximum session duration.
TEST_F(FocusModeCountdownViewTest, ExtendSessionDurationUntilUpperBound) {
  FocusModeController* controller = FocusModeController::Get();
  controller->SetInactiveSessionDuration(focus_mode_util::kMaximumDuration -
                                         base::Minutes(1));
  controller->ToggleFocusMode();

  LeftClickOn(focus_mode_tray_);
  EXPECT_TRUE(focus_mode_tray_->GetBubbleView());

  auto* button = GetExtendTimeButton();
  EXPECT_TRUE(button->GetEnabled());

  auto* label = GetTimeRemainingLabel();
  EXPECT_EQ(u"4:59:00", label->GetText());

  // Extend the session duration.
  LeftClickOn(button);

  EXPECT_FALSE(button->GetEnabled());
  EXPECT_EQ(u"5:00:00", label->GetText());
  EXPECT_EQ(focus_mode_util::kMaximumDuration,
            controller->GetSessionDuration());
}

// Tests that when clicking the `End` button from the contextual panel, the
// histogram will record it.
TEST_F(FocusModeCountdownViewTest, ToogleEndButton) {
  base::HistogramTester histogram_tester;

  auto* controller = FocusModeController::Get();
  EXPECT_FALSE(controller->in_focus_session());
  controller->SetInactiveSessionDuration(focus_mode_util::kMaximumDuration -
                                         base::Minutes(1));

  // Start a focus session.
  controller->ToggleFocusMode();

  LeftClickOn(focus_mode_tray_);
  EXPECT_TRUE(focus_mode_tray_->GetBubbleView());
  // Toggle `End` button on the contextual panel and check the histogram.
  auto* button = GetEndButton();
  EXPECT_TRUE(button);
  LeftClickOn(button);
  EXPECT_FALSE(controller->in_focus_session());
  histogram_tester.ExpectBucketCount(
      /*name=*/focus_mode_histogram_names::
          kToggleEndButtonDuringSessionHistogramName,
      /*sample=*/focus_mode_histogram_names::ToggleSource::kContextualPanel,
      /*expected_count=*/1);
}

}  // namespace ash