chromium/chrome/browser/ui/safety_hub/menu_notification_service_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 "chrome/browser/ui/safety_hub/menu_notification_service.h"

#include <ctime>
#include <memory>
#include <optional>
#include <string>

#include "base/time/time.h"
#include "base/values.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/extensions/cws_info_service_factory.h"
#include "chrome/browser/password_manager/password_manager_test_util.h"
#include "chrome/browser/permissions/notifications_engagement_service_factory.h"
#include "chrome/browser/ui/safety_hub/menu_notification.h"
#include "chrome/browser/ui/safety_hub/menu_notification_service_factory.h"
#include "chrome/browser/ui/safety_hub/notification_permission_review_service_factory.h"
#include "chrome/browser/ui/safety_hub/safety_hub_constants.h"
#include "chrome/browser/ui/safety_hub/safety_hub_prefs.h"
#include "chrome/browser/ui/safety_hub/safety_hub_test_util.h"
#include "chrome/browser/ui/safety_hub/unused_site_permissions_service_factory.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/permissions/constants.h"
#include "components/permissions/pref_names.h"
#include "components/safe_browsing/core/common/features.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"

#if !BUILDFLAG(IS_ANDROID)
#include "chrome/browser/password_manager/password_manager_test_util.h"
#include "chrome/browser/ui/safety_hub/password_status_check_service.h"
#include "chrome/browser/ui/safety_hub/password_status_check_service_factory.h"
#include "components/password_manager/core/browser/password_store/test_password_store.h"
#endif  // BUILDFLAG(IS_ANDROID)

class SafetyHubMenuNotificationServiceTest
    : public ChromeRenderViewHostTestHarness {};

TEST_F(SafetyHubMenuNotificationServiceTest, GetNotificationToShowNoResult) {}

TEST_F(SafetyHubMenuNotificationServiceTest, SingleNotificationToShow) {}

TEST_F(SafetyHubMenuNotificationServiceTest, TwoNotificationsIncremental) {}

TEST_F(SafetyHubMenuNotificationServiceTest, TwoNotificationsSequentially) {}

TEST_F(SafetyHubMenuNotificationServiceTest, TwoNotificationsNoOverride) {}

TEST_F(SafetyHubMenuNotificationServiceTest, SafeBrowsingOverride) {}

TEST_F(SafetyHubMenuNotificationServiceTest, SafeBrowsingTriggerLogic) {}

#if BUILDFLAG(IS_ANDROID)
TEST_F(SafetyHubMenuNotificationServiceTest, PasswordOverride) {
  std::optional<MenuNotificationEntry> notification;
  // Show Safe Browsing notification.
  prefs()->SetBoolean(prefs::kSafeBrowsingEnabled, false);
  notification = menu_notification_service()->GetNotificationToShow();
  AdvanceClockBy(base::Days(1));
  notification = menu_notification_service()->GetNotificationToShow();
  EXPECT_TRUE(notification.has_value());
  EXPECT_EQ(
      menu_notification_service()->GetLastShownNotificationModule().value(),
      safety_hub::SafetyHubModuleType::SAFE_BROWSING);

  // A leaked password warning should override the Safe Browsing notification.
  prefs()->SetInteger(prefs::kBreachedCredentialsCount, 1);
  notification = menu_notification_service()->GetNotificationToShow();
  EXPECT_TRUE(notification.has_value());
  ExpectPluralString(
      IDS_SETTINGS_SAFETY_HUB_COMPROMISED_PASSWORDS_MENU_NOTIFICATION, 1,
      notification.value().label);
  EXPECT_TRUE(menu_notification_service()
                  ->GetLastShownNotificationModule()
                  .has_value());
  EXPECT_EQ(
      menu_notification_service()->GetLastShownNotificationModule().value(),
      safety_hub::SafetyHubModuleType::PASSWORDS);

  // Fixing the leaked password will clear notification. Because the safe
  // browsing notification was dismissed, it will not be shown either.
  prefs()->SetInteger(prefs::kBreachedCredentialsCount, 0);
  notification = menu_notification_service()->GetNotificationToShow();
  EXPECT_FALSE(notification.has_value());

  // The last shown menu notification remains the same even when it has been
  // dismissed.
  EXPECT_TRUE(menu_notification_service()
                  ->GetLastShownNotificationModule()
                  .has_value());
  EXPECT_EQ(
      menu_notification_service()->GetLastShownNotificationModule().value(),
      safety_hub::SafetyHubModuleType::PASSWORDS);
}

TEST_F(SafetyHubMenuNotificationServiceTest, PasswordTrigger) {
  // If the leaked password count is not yet fetched or the user is signed out,
  // no notification should be displayed.
  std::optional<MenuNotificationEntry> notification;
  prefs()->SetInteger(prefs::kBreachedCredentialsCount, -1);
  notification = menu_notification_service()->GetNotificationToShow();
  EXPECT_FALSE(notification.has_value());

  // A leaked password warning should create a password notification.
  prefs()->SetInteger(prefs::kBreachedCredentialsCount, 2);
  notification = menu_notification_service()->GetNotificationToShow();
  EXPECT_TRUE(notification.has_value());
  ExpectPluralString(
      IDS_SETTINGS_SAFETY_HUB_COMPROMISED_PASSWORDS_MENU_NOTIFICATION, 2,
      notification.value().label);

  // The notification should no longer appear after it has been dismissed.
  menu_notification_service()->DismissActiveNotificationOfModule(
      safety_hub::SafetyHubModuleType::PASSWORDS);
  notification = menu_notification_service()->GetNotificationToShow();
  EXPECT_FALSE(notification.has_value());
  EXPECT_TRUE(menu_notification_service()
                  ->GetLastShownNotificationModule()
                  .has_value());

  // A leaked password count of lower value should NOT create a new password
  // notification.
  prefs()->SetInteger(prefs::kBreachedCredentialsCount, 1);
  notification = menu_notification_service()->GetNotificationToShow();
  EXPECT_FALSE(notification.has_value());
  EXPECT_TRUE(menu_notification_service()
                  ->GetLastShownNotificationModule()
                  .has_value());

  // A leaked password count of higher value should create a new password
  // notification.
  prefs()->SetInteger(prefs::kBreachedCredentialsCount, 3);
  notification = menu_notification_service()->GetNotificationToShow();
  EXPECT_TRUE(notification.has_value());
  ExpectPluralString(
      IDS_SETTINGS_SAFETY_HUB_COMPROMISED_PASSWORDS_MENU_NOTIFICATION, 3,
      notification.value().label);

  // Fixing the leaked passwords should clear notification.
  prefs()->SetInteger(prefs::kBreachedCredentialsCount, 0);
  notification = menu_notification_service()->GetNotificationToShow();
  EXPECT_FALSE(notification.has_value());
}
#endif

TEST_F(SafetyHubMenuNotificationServiceTest, DismissNotifications) {}

// TODO(crbug.com/328773301): Remove after
// SafetyHubAbusiveNotificationRevocation is launched.
class
    SafetyHubMenuNotificationServiceTestDisableAutoAbusiveNotificationRevocation
    : public SafetyHubMenuNotificationServiceTest {};

TEST_F(
    SafetyHubMenuNotificationServiceTestDisableAutoAbusiveNotificationRevocation,
    TwoNotificationsSequentially) {}

#if !BUILDFLAG(IS_ANDROID)
// TODO(crbug.com/328773301): Remove after
// SafetyHubAbusiveNotificationRevocation is launched.
class SafetyHubMenuNotificationServiceDesktopOnlyTest
    : public SafetyHubMenuNotificationServiceTest {};

TEST_F(SafetyHubMenuNotificationServiceDesktopOnlyTest,
       ExtensionsMenuNotification) {}

TEST_F(SafetyHubMenuNotificationServiceDesktopOnlyTest, PasswordOverride) {}

TEST_F(SafetyHubMenuNotificationServiceDesktopOnlyTest, PasswordTrigger) {}

TEST_F(SafetyHubMenuNotificationServiceDesktopOnlyTest,
       DismissPasswordNotification) {}

TEST_F(SafetyHubMenuNotificationServiceDesktopOnlyTest, PasswordMigration) {}
#endif  // BUILDFLAG(IS_ANDROID)