chromium/chrome/browser/extensions/api/passwords_private/password_check_delegate_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 "chrome/browser/extensions/api/passwords_private/password_check_delegate.h"

#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>

#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/gmock_move_support.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_callback.h"
#include "base/time/time.h"
#include "chrome/browser/extensions/api/passwords_private/passwords_private_event_router.h"
#include "chrome/browser/extensions/api/passwords_private/passwords_private_event_router_factory.h"
#include "chrome/browser/password_manager/account_password_store_factory.h"
#include "chrome/browser/password_manager/bulk_leak_check_service_factory.h"
#include "chrome/browser/password_manager/password_manager_test_util.h"
#include "chrome/browser/password_manager/profile_password_store_factory.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
#include "chrome/browser/sync/sync_service_factory.h"
#include "chrome/common/extensions/api/passwords_private.h"
#include "chrome/test/base/testing_profile.h"
#include "components/affiliations/core/browser/fake_affiliation_service.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/password_manager/core/browser/leak_detection/bulk_leak_check.h"
#include "components/password_manager/core/browser/leak_detection/bulk_leak_check_service.h"
#include "components/password_manager/core/browser/leak_detection/leak_detection_delegate_interface.h"
#include "components/password_manager/core/browser/password_form.h"
#include "components/password_manager/core/browser/password_manager_metrics_util.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/password_store/test_password_store.h"
#include "components/password_manager/core/browser/ui/credential_ui_entry.h"
#include "components/password_manager/core/browser/ui/saved_passwords_presenter.h"
#include "components/password_manager/core/browser/well_known_change_password/well_known_change_password_util.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/identity_test_environment.h"
#include "components/sync/service/sync_service.h"
#include "components/sync/test/test_sync_service.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/browser/browser_context.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_event_histogram_value.h"
#include "extensions/browser/test_event_router.h"
#include "extensions/browser/test_event_router_observer.h"
#include "services/network/test/test_shared_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/origin.h"

namespace extensions {

namespace {

constexpr char kExampleCom[] =;
constexpr char kExampleOrg[] =;
constexpr char kExampleApp[] =;

constexpr char kTestEmail[] =;

constexpr char16_t kUsername1[] =;
constexpr char16_t kUsername2[] =;
constexpr char16_t kUsername3[] =;

constexpr char16_t kPassword1[] =;
constexpr char16_t kPassword2[] =;
constexpr char16_t kWeakPassword1[] =;
constexpr char16_t kWeakPassword2[] =;

constexpr char kGoogleAccounts[] =;

CompromisedInfo;
DomainInfo;
PasswordCheckStatus;
PasswordUiEntry;
BulkLeakCheckDelegateInterface;
BulkLeakCheckService;
InsecureType;
InsecurityMetadata;
IsLeaked;
IsMuted;
LeakCheckCredential;
PasswordForm;
SavedPasswordsPresenter;
TestPasswordStore;
TriggerBackendNotification;
kLastTimePasswordCheckCompleted;
IdentityTestEnvironment;
AllOf;
AtLeast;
ElementsAre;
Eq;
Field;
IsEmpty;
IsNull;
Mock;
Optional;
Pair;
Pointee;
Return;
UnorderedElementsAre;

MockStartPasswordCheckCallback;

PasswordForm MakeSavedPassword(
    std::string_view signon_realm,
    std::u16string_view username,
    std::u16string_view password = kPassword1,
    std::u16string_view username_element = u"",
    PasswordForm::Store store = PasswordForm::Store::kProfileStore) {}

PasswordForm MakeSavedFederatedCredential(
    std::string_view signon_realm,
    std::u16string_view username,
    std::string_view provider = kGoogleAccounts,
    PasswordForm::Store store = PasswordForm::Store::kProfileStore) {}

void AddIssueToForm(PasswordForm* form,
                    InsecureType type,
                    base::TimeDelta time_since_creation = base::TimeDelta(),
                    const bool is_muted = false) {}

std::string MakeAndroidRealm(std::string_view package_name) {}

PasswordForm MakeSavedAndroidPassword(
    std::string_view package_name,
    std::u16string_view username,
    std::string_view app_display_name = "",
    std::string_view affiliated_web_realm = "",
    std::u16string_view password = kPassword1) {}

// Creates matcher for a given compromised info.
auto ExpectCompromisedInfo(
    base::TimeDelta elapsed_time_since_compromise,
    const std::string& elapsed_time_since_compromise_str,
    std::vector<api::passwords_private::CompromiseType> compromise_types) {}

// Creates matcher for a given compromised credential
auto ExpectCredential(const std::optional<std::string>& change_password_url,
                      const std::u16string& username) {}

// Creates matcher for a given compromised credential
auto ExpectCompromisedCredential(
    const std::optional<std::string>& change_password_url,
    const std::u16string& username,
    base::TimeDelta elapsed_time_since_compromise,
    const std::string& elapsed_time_since_compromise_str,
    std::vector<api::passwords_private::CompromiseType> compromise_types) {}

std::unique_ptr<TestingProfile> CreateTestingProfile() {}

class PasswordCheckDelegateTest : public ::testing::Test {};

}  // namespace

// Verify that GetInsecureCredentials() correctly represents weak credentials.
TEST_F(PasswordCheckDelegateTest, GetInsecureCredentialsFillsFieldsCorrectly) {}

// Verify that computation of weak credentials notifies observers.
TEST_F(PasswordCheckDelegateTest, WeakCheckNotifiesObservers) {}

// Verifies that the weak check will be run if the user is signed out.
TEST_F(PasswordCheckDelegateTest, WeakCheckWhenUserSignedOut) {}

// Verifies that the formatted timestamp associated with a compromised
// credential covers the "Just now" cases (less than a minute ago), as well as
// months and years.
TEST_F(PasswordCheckDelegateTest, GetInsecureCredentialsHandlesTimes) {}

// Verifies that both leaked and phished credentials are ordered correctly
// within the list of compromised credentials. These credentials should be
// listed before just leaked ones and have a timestamp that corresponds to the
// most recent compromise.
TEST_F(PasswordCheckDelegateTest,
       GetInsecureCredentialsDedupesLeakedAndCompromised) {}

TEST_F(PasswordCheckDelegateTest, GetInsecureCredentialsInjectsAndroid) {}

// Test that a change to compromised credential notifies observers.
TEST_F(PasswordCheckDelegateTest, OnGetInsecureCredentials) {}

// Test that muting a insecure password succeeds.
TEST_F(PasswordCheckDelegateTest, MuteInsecureCredentialSuccess) {}

// Test that muting a insecure password fails if the underlying insecure
// credential no longer exists.
TEST_F(PasswordCheckDelegateTest, MuteInsecureCredentialStaleData) {}

// Test that muting a insecure password fails if the ids don't match.
TEST_F(PasswordCheckDelegateTest, MuteInsecureCredentialIdMismatch) {}

// Test that unmuting a muted insecure password succeeds.
TEST_F(PasswordCheckDelegateTest, UnmuteInsecureCredentialSuccess) {}

// Test that unmuting a insecure password fails if the underlying insecure
// credential no longer exists.
TEST_F(PasswordCheckDelegateTest, UnmuteInsecureCredentialStaleData) {}

// Test that unmuting a insecure password fails if the ids don't match.
TEST_F(PasswordCheckDelegateTest, UnmuteInsecureCredentialIdMismatch) {}

// Tests that we don't create an entry in the database if there is no matching
// saved password.
TEST_F(PasswordCheckDelegateTest, OnLeakFoundDoesNotCreateCredential) {}

// Test that we don't create an entry in the password store if IsLeaked is
// false.
TEST_F(PasswordCheckDelegateTest, NoLeakedFound) {}

// Test that a found leak creates a compromised credential in the password
// store.
TEST_F(PasswordCheckDelegateTest, OnLeakFoundCreatesCredential) {}

// Test that a found leak creates a compromised credential in the password
// store for each combination of the same canonicalized username and password.
TEST_F(PasswordCheckDelegateTest, OnLeakFoundCreatesMultipleCredential) {}

// Verifies that the case where the user has no saved passwords is reported
// correctly.
TEST_F(PasswordCheckDelegateTest, GetPasswordCheckStatusNoPasswords) {}

// Verifies that the case where the check is idle is reported correctly.
TEST_F(PasswordCheckDelegateTest, GetPasswordCheckStatusIdle) {}

// Verifies that the case where the user is signed out is reported correctly.
TEST_F(PasswordCheckDelegateTest, GetPasswordCheckStatusSignedOut) {}

// Verifies that the case where the check is running is reported correctly and
// the progress indicator matches expectations.
TEST_F(PasswordCheckDelegateTest, GetPasswordCheckStatusRunning) {}

// Verifies that the total password count is reported accurately.
// Regression test for crbug.com/1432734.
TEST_F(PasswordCheckDelegateTest, GetPasswordCheckStatusCount) {}

// Verifies that the case where the user is offline is reported correctly.
TEST_F(PasswordCheckDelegateTest, GetPasswordCheckStatusOffline) {}

// Verifies that the case where the user hits another error (e.g. invalid
// credentials) is reported correctly.
TEST_F(PasswordCheckDelegateTest, GetPasswordCheckStatusOther) {}

// Test that a change to the saved passwords notifies observers.
TEST_F(PasswordCheckDelegateTest,
       NotifyPasswordCheckStatusChangedAfterPasswordChange) {}

// Test that a change to the bulk leak check notifies observers.
TEST_F(PasswordCheckDelegateTest,
       NotifyPasswordCheckStatusChangedAfterStateChange) {}

// Checks that the default kLastTimePasswordCheckCompleted pref value is
// treated as no completed run yet.
TEST_F(PasswordCheckDelegateTest, LastTimePasswordCheckCompletedNotSet) {}

// Checks that a non-default kLastTimePasswordCheckCompleted pref value is
// treated as a completed run, and formatted accordingly.
TEST_F(PasswordCheckDelegateTest, LastTimePasswordCheckCompletedIsSet) {}

// Checks that a transition into the idle state after starting a check results
// in resetting the kLastTimePasswordCheckCompleted pref to the current time.
TEST_F(PasswordCheckDelegateTest, LastTimePasswordCheckCompletedReset) {}

// Checks that processing a credential by the leak check updates the progress
// correctly and raises the expected event.
TEST_F(PasswordCheckDelegateTest, OnCredentialDoneUpdatesProgress) {}

// Tests that pending callbacks get invoked once initialization finishes.
TEST_F(PasswordCheckDelegateTest,
       StartPasswordCheckRunsCallbacksAfterInitialization) {}

TEST_F(PasswordCheckDelegateTest, WellKnownChangePasswordUrl) {}

TEST_F(PasswordCheckDelegateTest, WellKnownChangePasswordUrl_androidrealm) {}

// Verify that GetCredentialsWithReusedPassword() correctly represents reused
// credentials.
TEST_F(PasswordCheckDelegateTest,
       GetCredentialsWithReusedPasswordFillsFieldsCorrectly) {}

TEST_F(PasswordCheckDelegateTest,
       GetCredentialsWithReusedPasswordAvoidsSingleReuse) {}

// Verify that computation of weak credentials notifies observers.
TEST_F(PasswordCheckDelegateTest, NoNotificationsWithoutRouter) {}

}  // namespace extensions