// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/user_manager/known_user.h"
#include <memory>
#include <optional>
#include <utility>
#include "base/json/values_util.h"
#include "base/memory/raw_ptr.h"
#include "base/test/task_environment.h"
#include "base/values.h"
#include "components/account_id/account_id.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/prefs/testing_pref_service.h"
#include "components/user_manager/fake_user_manager.h"
#include "components/user_manager/scoped_user_manager.h"
#include "components/user_manager/user_manager_base.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace user_manager {
namespace {
std::optional<std::string> GetStringPrefValue(KnownUser* known_user,
const AccountId& account_id,
const char* pref_name) {
if (const std::string* value =
known_user->FindStringPath(account_id, pref_name)) {
return *value;
}
return std::nullopt;
}
} // namespace
// Base class for tests of known_user.
// Sets up global objects necessary for known_user to be able to access
// local_state.
class KnownUserTest : public testing::Test {
public:
KnownUserTest() {
auto fake_user_manager = std::make_unique<FakeUserManager>();
fake_user_manager_ = fake_user_manager.get();
scoped_user_manager_ =
std::make_unique<ScopedUserManager>(std::move(fake_user_manager));
UserManagerBase::RegisterPrefs(local_state_.registry());
}
~KnownUserTest() override = default;
KnownUserTest(const KnownUserTest& other) = delete;
KnownUserTest& operator=(const KnownUserTest& other) = delete;
protected:
const AccountId kDefaultAccountId =
AccountId::FromUserEmailGaiaId("[email protected]",
"fake-gaia-id");
FakeUserManager* fake_user_manager() { return fake_user_manager_; }
PrefService* local_state() { return &local_state_; }
const base::Value::Dict* FindPrefs(const AccountId& account_id) {
return KnownUser(local_state()).FindPrefs(account_id);
}
private:
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::MainThreadType::UI};
// Owned by |scoped_user_manager_|.
raw_ptr<FakeUserManager, DanglingUntriaged> fake_user_manager_ = nullptr;
std::unique_ptr<ScopedUserManager> scoped_user_manager_;
TestingPrefServiceSimple local_state_;
};
TEST_F(KnownUserTest, FindPrefsNonExisting) {
EXPECT_FALSE(FindPrefs(kDefaultAccountId));
}
TEST_F(KnownUserTest, FindPrefsExisting) {
KnownUser known_user(local_state());
const std::string kCustomPrefName = "custom_pref";
known_user.SetStringPref(kDefaultAccountId, kCustomPrefName, "value");
const base::Value::Dict* value = FindPrefs(kDefaultAccountId);
ASSERT_TRUE(value);
const std::string* pref_value = value->FindString(kCustomPrefName);
ASSERT_TRUE(pref_value);
EXPECT_EQ(*pref_value, "value");
}
TEST_F(KnownUserTest, FindPrefsIgnoresEphemeralGaiaUsers) {
KnownUser known_user(local_state());
const AccountId kAccountIdEphemeralGaia =
AccountId::FromUserEmailGaiaId("[email protected]", "gaia_id_2");
const AccountId kAccountIdEphemeralAd =
AccountId::AdFromUserEmailObjGuid("[email protected]", "guid_4");
fake_user_manager()->SetUserNonCryptohomeDataEphemeral(
kAccountIdEphemeralGaia,
/*is_ephemeral=*/true);
fake_user_manager()->SetUserNonCryptohomeDataEphemeral(kAccountIdEphemeralAd,
/*is_ephemeral=*/true);
const std::string kCustomPrefName = "custom_pref";
known_user.SetStringPref(kAccountIdEphemeralGaia, kCustomPrefName, "value");
known_user.SetStringPref(kAccountIdEphemeralAd, kCustomPrefName, "value");
EXPECT_FALSE(FindPrefs(kAccountIdEphemeralGaia));
EXPECT_TRUE(FindPrefs(kAccountIdEphemeralAd));
}
TEST_F(KnownUserTest, FindPrefsMatchForUnknownAccountType) {
KnownUser known_user(local_state());
// All account ids have the same e-mail
const AccountId kAccountIdUnknown =
AccountId::FromUserEmail("[email protected]");
const AccountId kAccountIdGaia =
AccountId::FromUserEmailGaiaId("[email protected]", "gaia_id_2");
const AccountId kAccountIdAd =
AccountId::AdFromUserEmailObjGuid("[email protected]", "guid");
known_user.SetStringPref(kAccountIdUnknown, "some_pref", "some_value");
EXPECT_TRUE(FindPrefs(kAccountIdUnknown));
EXPECT_TRUE(FindPrefs(kAccountIdGaia));
EXPECT_TRUE(FindPrefs(kAccountIdAd));
}
TEST_F(KnownUserTest, FindPrefsMatchForGaiaAccountWithEmail) {
KnownUser known_user(local_state());
const char* kEmailA = "[email protected]";
const char* kEmailB = "[email protected]";
const char* kGaiaIdA = "a";
const char* kGaiaIdB = "b";
known_user.SaveKnownUser(AccountId::FromUserEmailGaiaId(kEmailA, kGaiaIdA));
// Finding by itself should work
EXPECT_TRUE(FindPrefs(AccountId::FromUserEmailGaiaId(kEmailA, kGaiaIdA)));
// Finding by gaia id should also work even if the e-mail doesn't match.
EXPECT_TRUE(FindPrefs(AccountId::FromUserEmailGaiaId(kEmailB, kGaiaIdA)));
// Finding by e-mail should also work even if the gaia id doesn't match.
// TODO(https://crbug.com/1190902): This should likely be EXPECT_FALSE going
// forward.
EXPECT_TRUE(FindPrefs(AccountId::FromUserEmailGaiaId(kEmailA, kGaiaIdB)));
// An unrelated gaia AccountId with the same Account Type doesn't find
// anything.
EXPECT_FALSE(FindPrefs(AccountId::FromUserEmailGaiaId(kEmailB, kGaiaIdB)));
// Looking up an AccountId stored as gaia by an unknown-type AccountId with
// the same e-mail address succeeds.
EXPECT_TRUE(FindPrefs(AccountId::FromUserEmail(kEmailA)));
// Looking up an AccountId stored as gaia by an AccountId with type Ad fails.
EXPECT_FALSE(FindPrefs(AccountId::AdFromUserEmailObjGuid(kEmailA, "guid")));
}
TEST_F(KnownUserTest, FindPrefsMatchForAdAccountWithEmail) {
KnownUser known_user(local_state());
const std::string kEmailA = "[email protected]";
const std::string kEmailB = "[email protected]";
known_user.SaveKnownUser(AccountId::AdFromUserEmailObjGuid(kEmailA, "a"));
// Finding by itself should work
EXPECT_TRUE(FindPrefs(AccountId::AdFromUserEmailObjGuid(kEmailA, "a")));
// Finding by guid should also work even if the e-mail doesn't match.
EXPECT_TRUE(FindPrefs(AccountId::AdFromUserEmailObjGuid(kEmailB, "a")));
// Finding by e-mail should also work even if the guid doesn't match.
EXPECT_TRUE(FindPrefs(AccountId::AdFromUserEmailObjGuid(kEmailA, "b")));
// An unrelated AD AccountId with the same Account Type doesn't find
// anything.
EXPECT_FALSE(FindPrefs(AccountId::AdFromUserEmailObjGuid(kEmailB, "b")));
// Looking up an AccountId stored as AD by an unknown-type AccountId with
// the same e-mail address succeeds.
EXPECT_TRUE(FindPrefs(AccountId::FromUserEmail(kEmailA)));
// Looking up an AccountId stored as AD by an AccountId with type gaia fails.
EXPECT_FALSE(FindPrefs(AccountId::FromUserEmailGaiaId(kEmailA, "gaia_id")));
}
TEST_F(KnownUserTest, UpdatePrefsWithoutClear) {
KnownUser known_user(local_state());
constexpr char kPrefName1[] = "pref1";
constexpr char kPrefName2[] = "pref2";
known_user.SetPath(kDefaultAccountId, kPrefName1,
base::Value("pref1_value1"));
known_user.SetPath(kDefaultAccountId, kPrefName1,
base::Value("pref1_value2"));
known_user.SetPath(kDefaultAccountId, kPrefName2,
base::Value("pref2_value1"));
EXPECT_EQ(std::make_optional(std::string("pref1_value2")),
GetStringPrefValue(&known_user, kDefaultAccountId, kPrefName1));
EXPECT_EQ(std::make_optional(std::string("pref2_value1")),
GetStringPrefValue(&known_user, kDefaultAccountId, kPrefName2));
}
TEST_F(KnownUserTest, UpdatePrefsWithClear) {
KnownUser known_user(local_state());
constexpr char kPrefName1[] = "pref1";
constexpr char kPrefName2[] = "pref2";
known_user.SetPath(kDefaultAccountId, kPrefName1,
base::Value("pref1_value1"));
known_user.SetPath(kDefaultAccountId, kPrefName2,
base::Value("pref2_value1"));
known_user.SetPath(kDefaultAccountId, kPrefName1, std::nullopt);
EXPECT_EQ(std::nullopt,
GetStringPrefValue(&known_user, kDefaultAccountId, kPrefName1));
EXPECT_EQ(std::make_optional(std::string("pref2_value1")),
GetStringPrefValue(&known_user, kDefaultAccountId, kPrefName2));
}
TEST_F(KnownUserTest, GetKnownAccountIdsNoAccounts) {
KnownUser known_user(local_state());
EXPECT_THAT(known_user.GetKnownAccountIds(), testing::IsEmpty());
}
TEST_F(KnownUserTest, GetKnownAccountIdsWithAccounts) {
KnownUser known_user(local_state());
const AccountId kAccountIdGaia =
AccountId::FromUserEmailGaiaId("[email protected]", "gaia_id");
const AccountId kAccountIdAd =
AccountId::AdFromUserEmailObjGuid("[email protected]", "obj_guid");
known_user.SaveKnownUser(kAccountIdGaia);
known_user.SaveKnownUser(kAccountIdAd);
EXPECT_THAT(known_user.GetKnownAccountIds(),
testing::UnorderedElementsAre(kAccountIdGaia, kAccountIdAd));
}
TEST_F(KnownUserTest, SaveKnownUserIgnoresUnknownType) {
KnownUser known_user(local_state());
const AccountId kAccountIdUnknown =
AccountId::FromUserEmail("[email protected]");
known_user.SaveKnownUser(kAccountIdUnknown);
EXPECT_THAT(known_user.GetKnownAccountIds(), testing::IsEmpty());
}
TEST_F(KnownUserTest, SaveKnownUserIgnoresEphemeralGaiaUsers) {
KnownUser known_user(local_state());
const AccountId kAccountIdNonEphemeralGaia =
AccountId::FromUserEmailGaiaId("[email protected]", "gaia_id_1");
const AccountId kAccountIdEphemeralGaia =
AccountId::FromUserEmailGaiaId("[email protected]", "gaia_id_2");
const AccountId kAccountIdNonEphemeralAd =
AccountId::AdFromUserEmailObjGuid("[email protected]", "guid_3");
const AccountId kAccountIdEphemeralAd =
AccountId::AdFromUserEmailObjGuid("[email protected]", "guid_4");
fake_user_manager()->SetUserNonCryptohomeDataEphemeral(
kAccountIdEphemeralGaia,
/*is_ephemeral=*/true);
fake_user_manager()->SetUserNonCryptohomeDataEphemeral(kAccountIdEphemeralAd,
/*is_ephemeral=*/true);
known_user.SaveKnownUser(kAccountIdNonEphemeralGaia);
known_user.SaveKnownUser(kAccountIdEphemeralGaia);
known_user.SaveKnownUser(kAccountIdNonEphemeralAd);
known_user.SaveKnownUser(kAccountIdEphemeralAd);
EXPECT_THAT(known_user.GetKnownAccountIds(),
testing::UnorderedElementsAre(kAccountIdNonEphemeralGaia,
kAccountIdNonEphemeralAd,
kAccountIdEphemeralAd));
}
TEST_F(KnownUserTest, UpdateIdForGaiaAccount) {
KnownUser known_user(local_state());
const AccountId kAccountIdUnknown =
AccountId::FromUserEmail("[email protected]");
known_user.SetStringPref(kAccountIdUnknown, "some_pref", "some_value");
EXPECT_THAT(known_user.GetKnownAccountIds(),
testing::UnorderedElementsAre(kAccountIdUnknown));
const AccountId kAccountIdGaia =
AccountId::FromUserEmailGaiaId("[email protected]", "gaia_id");
known_user.UpdateId(kAccountIdGaia);
EXPECT_THAT(known_user.GetKnownAccountIds(),
testing::UnorderedElementsAre(kAccountIdGaia));
}
TEST_F(KnownUserTest, UpdateIdForAdAccount) {
KnownUser known_user(local_state());
const AccountId kAccountIdUnknown =
AccountId::FromUserEmail("[email protected]");
known_user.SetStringPref(kAccountIdUnknown, "some_pref", "some_value");
EXPECT_THAT(known_user.GetKnownAccountIds(),
testing::UnorderedElementsAre(kAccountIdUnknown));
const AccountId kAccountIdAd =
AccountId::AdFromUserEmailObjGuid("[email protected]", "guid");
known_user.UpdateId(kAccountIdAd);
EXPECT_THAT(known_user.GetKnownAccountIds(),
testing::UnorderedElementsAre(kAccountIdAd));
}
TEST_F(KnownUserTest, FindGaiaIdForGaiaAccount) {
KnownUser known_user(local_state());
const AccountId kAccountIdGaia =
AccountId::FromUserEmailGaiaId("[email protected]", "gaia_id");
known_user.SaveKnownUser(kAccountIdGaia);
const std::string* gaia_id = known_user.FindGaiaID(kAccountIdGaia);
ASSERT_TRUE(gaia_id);
EXPECT_EQ(*gaia_id, "gaia_id");
}
TEST_F(KnownUserTest, FindGaiaIdForAdAccount) {
KnownUser known_user(local_state());
const AccountId kAccountIdAd =
AccountId::AdFromUserEmailObjGuid("[email protected]", "guid");
known_user.SaveKnownUser(kAccountIdAd);
EXPECT_FALSE(known_user.FindGaiaID(kAccountIdAd));
}
// TODO(crbug.com/40731309): Add tests for GetAccountId.
TEST_F(KnownUserTest, RemovePrefOnCustomPref) {
KnownUser known_user(local_state());
const std::string kCustomPrefName = "custom_pref";
known_user.SetStringPref(kDefaultAccountId, kCustomPrefName, "value");
EXPECT_TRUE(known_user.FindStringPath(kDefaultAccountId, kCustomPrefName));
known_user.RemovePref(kDefaultAccountId, kCustomPrefName);
EXPECT_FALSE(known_user.FindStringPath(kDefaultAccountId, kCustomPrefName));
}
TEST_F(KnownUserTest, RemovePrefOnReservedPref) {
KnownUser known_user(local_state());
const std::string kReservedPrefName = "device_id";
known_user.SetStringPref(kDefaultAccountId, kReservedPrefName, "value");
// Don't verify the message because on some builds CHECK failures do not print
// debug messages (https://crbug.com/1198519).
ASSERT_DEATH(known_user.RemovePref(kDefaultAccountId, kReservedPrefName), "");
}
TEST_F(KnownUserTest, DeviceId) {
KnownUser known_user(local_state());
EXPECT_EQ(known_user.GetDeviceId(kDefaultAccountId), std::string());
known_user.SetDeviceId(kDefaultAccountId, "test");
EXPECT_EQ(known_user.GetDeviceId(kDefaultAccountId), "test");
}
TEST_F(KnownUserTest, GAPSCookie) {
KnownUser known_user(local_state());
EXPECT_EQ(known_user.GetGAPSCookie(kDefaultAccountId), std::string());
known_user.SetGAPSCookie(kDefaultAccountId, "test");
EXPECT_EQ(known_user.GetGAPSCookie(kDefaultAccountId), "test");
}
TEST_F(KnownUserTest, UsingSAML) {
KnownUser known_user(local_state());
EXPECT_FALSE(known_user.IsUsingSAML(kDefaultAccountId));
known_user.UpdateUsingSAML(kDefaultAccountId, /*using_saml=*/true);
EXPECT_TRUE(known_user.IsUsingSAML(kDefaultAccountId));
}
TEST_F(KnownUserTest, UsingSAMLPrincipalsAPI) {
KnownUser known_user(local_state());
EXPECT_FALSE(known_user.GetIsUsingSAMLPrincipalsAPI(kDefaultAccountId));
known_user.UpdateIsUsingSAMLPrincipalsAPI(kDefaultAccountId,
/*using_saml=*/true);
EXPECT_TRUE(known_user.GetIsUsingSAMLPrincipalsAPI(kDefaultAccountId));
}
TEST_F(KnownUserTest, ProfileRequiresPolicy) {
KnownUser known_user(local_state());
EXPECT_EQ(known_user.GetProfileRequiresPolicy(kDefaultAccountId),
ProfileRequiresPolicy::kUnknown);
known_user.SetProfileRequiresPolicy(kDefaultAccountId,
ProfileRequiresPolicy::kPolicyRequired);
EXPECT_EQ(known_user.GetProfileRequiresPolicy(kDefaultAccountId),
ProfileRequiresPolicy::kPolicyRequired);
known_user.SetProfileRequiresPolicy(kDefaultAccountId,
ProfileRequiresPolicy::kNoPolicyRequired);
EXPECT_EQ(known_user.GetProfileRequiresPolicy(kDefaultAccountId),
ProfileRequiresPolicy::kNoPolicyRequired);
known_user.ClearProfileRequiresPolicy(kDefaultAccountId);
EXPECT_EQ(known_user.GetProfileRequiresPolicy(kDefaultAccountId),
ProfileRequiresPolicy::kUnknown);
}
TEST_F(KnownUserTest, ReauthReason) {
KnownUser known_user(local_state());
EXPECT_FALSE(known_user.FindReauthReason(kDefaultAccountId).has_value());
known_user.UpdateReauthReason(kDefaultAccountId, 3);
EXPECT_EQ(known_user.FindReauthReason(kDefaultAccountId), 3);
}
TEST_F(KnownUserTest, ChallengeResponseKeys) {
KnownUser known_user(local_state());
EXPECT_TRUE(known_user.GetChallengeResponseKeys(kDefaultAccountId).empty());
base::Value::List challenge_response_keys;
challenge_response_keys.Append("key1");
known_user.SetChallengeResponseKeys(kDefaultAccountId,
challenge_response_keys.Clone());
EXPECT_EQ(known_user.GetChallengeResponseKeys(kDefaultAccountId),
challenge_response_keys);
}
TEST_F(KnownUserTest, LastOnlineSignin) {
KnownUser known_user(local_state());
EXPECT_TRUE(known_user.GetLastOnlineSignin(kDefaultAccountId).is_null());
base::Time last_online_signin = base::Time::Now();
known_user.SetLastOnlineSignin(kDefaultAccountId, last_online_signin);
EXPECT_EQ(known_user.GetLastOnlineSignin(kDefaultAccountId),
last_online_signin);
}
TEST_F(KnownUserTest, OfflineSigninLimit) {
KnownUser known_user(local_state());
EXPECT_FALSE(known_user.GetOfflineSigninLimit(kDefaultAccountId).has_value());
base::TimeDelta offline_signin_limit = base::Minutes(80);
known_user.SetOfflineSigninLimit(kDefaultAccountId, offline_signin_limit);
EXPECT_EQ(known_user.GetOfflineSigninLimit(kDefaultAccountId).value(),
offline_signin_limit);
}
TEST_F(KnownUserTest, IsEnterpriseManaged) {
KnownUser known_user(local_state());
EXPECT_FALSE(known_user.GetIsEnterpriseManaged(kDefaultAccountId));
known_user.SetIsEnterpriseManaged(kDefaultAccountId, true);
EXPECT_TRUE(known_user.GetIsEnterpriseManaged(kDefaultAccountId));
}
TEST_F(KnownUserTest, AccountManager) {
KnownUser known_user(local_state());
EXPECT_FALSE(known_user.GetAccountManager(kDefaultAccountId));
known_user.SetAccountManager(kDefaultAccountId, "test");
EXPECT_TRUE(known_user.GetAccountManager(kDefaultAccountId));
}
TEST_F(KnownUserTest, UserLastLoginInputMethodId) {
KnownUser known_user(local_state());
EXPECT_FALSE(known_user.GetUserLastInputMethodId(kDefaultAccountId));
known_user.SetUserLastLoginInputMethodId(kDefaultAccountId, "test");
EXPECT_TRUE(known_user.GetUserLastInputMethodId(kDefaultAccountId));
}
TEST_F(KnownUserTest, UserPinLength) {
KnownUser known_user(local_state());
EXPECT_EQ(known_user.GetUserPinLength(kDefaultAccountId), 0);
known_user.SetUserPinLength(kDefaultAccountId, 8);
EXPECT_EQ(known_user.GetUserPinLength(kDefaultAccountId), 8);
}
TEST_F(KnownUserTest, PinAutosubmitBackfillNeeded) {
KnownUser known_user(local_state());
// If the pref is not set, returns true.
EXPECT_TRUE(known_user.PinAutosubmitIsBackfillNeeded(kDefaultAccountId));
known_user.PinAutosubmitSetBackfillNotNeeded(kDefaultAccountId);
EXPECT_FALSE(known_user.PinAutosubmitIsBackfillNeeded(kDefaultAccountId));
known_user.PinAutosubmitSetBackfillNeededForTests(kDefaultAccountId);
EXPECT_TRUE(known_user.PinAutosubmitIsBackfillNeeded(kDefaultAccountId));
}
TEST_F(KnownUserTest, PasswordSyncToken) {
KnownUser known_user(local_state());
EXPECT_FALSE(known_user.GetPasswordSyncToken(kDefaultAccountId));
known_user.SetPasswordSyncToken(kDefaultAccountId, "test");
EXPECT_EQ(*known_user.GetPasswordSyncToken(kDefaultAccountId), "test");
}
TEST_F(KnownUserTest, CleanEphemeralUsersRemovesEphemeralAdOnly) {
KnownUser known_user(local_state());
const AccountId kAccountIdNonEphemeralGaia =
AccountId::FromUserEmailGaiaId("[email protected]", "gaia_id_1");
const AccountId kAccountIdEphemeralGaia =
AccountId::FromUserEmailGaiaId("[email protected]", "gaia_id_2");
const AccountId kAccountIdNonEphemeralAd =
AccountId::AdFromUserEmailObjGuid("[email protected]", "guid_3");
const AccountId kAccountIdEphemeralAd =
AccountId::AdFromUserEmailObjGuid("[email protected]", "guid_4");
known_user.SaveKnownUser(kAccountIdNonEphemeralGaia);
known_user.SaveKnownUser(kAccountIdEphemeralGaia);
known_user.SaveKnownUser(kAccountIdNonEphemeralAd);
known_user.SaveKnownUser(kAccountIdEphemeralAd);
known_user.SetIsEphemeralUser(kAccountIdEphemeralGaia,
/*is_ephemeral=*/true);
known_user.SetIsEphemeralUser(kAccountIdEphemeralAd, /*is_ephemeral=*/true);
EXPECT_THAT(known_user.GetKnownAccountIds(),
testing::UnorderedElementsAre(
kAccountIdNonEphemeralGaia, kAccountIdEphemeralGaia,
kAccountIdNonEphemeralAd, kAccountIdEphemeralAd));
known_user.CleanEphemeralUsers();
EXPECT_THAT(known_user.GetKnownAccountIds(),
testing::UnorderedElementsAre(kAccountIdNonEphemeralGaia,
kAccountIdEphemeralGaia,
kAccountIdNonEphemeralAd));
}
TEST_F(KnownUserTest, CleanObsoletePrefs) {
KnownUser known_user(local_state());
const std::string kObsoletePrefName = "minimal_migration_attempted";
const std::string kCustomPrefName = "custom_pref";
// Set an obsolete pref.
known_user.SetBooleanPref(kDefaultAccountId, kObsoletePrefName, true);
// Set a custom pref.
known_user.SetBooleanPref(kDefaultAccountId, kCustomPrefName, true);
// Set a reserved, non-obsolete pref.
known_user.SetIsEnterpriseManaged(kDefaultAccountId, true);
known_user.CleanObsoletePrefs();
// Verify that only the obsolete pref has been removed.
EXPECT_FALSE(known_user.FindBoolPath(kDefaultAccountId, kObsoletePrefName)
.has_value());
std::optional<bool> custom_pref_value =
known_user.FindBoolPath(kDefaultAccountId, kCustomPrefName);
EXPECT_TRUE(custom_pref_value.has_value());
EXPECT_TRUE(custom_pref_value.value());
EXPECT_TRUE(known_user.GetIsEnterpriseManaged(kDefaultAccountId));
}
//
// =============================================================================
// Type-parametrized unittests for Set{String,Boolean,Integer,}Pref and
// Get{String,Boolean,Integer,}Pref.
// For every type (string, boolean, integer, raw base::Value) a PrefTypeInfo
// struct is declared which is then referenced in the generic test code.
// Test type holder for known_user string prefs.
struct PrefTypeInfoString {
using PrefType = std::string;
using PrefTypeForReading = std::string;
static constexpr auto SetFunc = &KnownUser::SetStringPref;
static constexpr auto GetFunc = &KnownUser::GetStringPrefForTest;
static PrefType CreatePrefValue() { return std::string("test"); }
static bool CheckPrefValue(PrefTypeForReading read_value) {
return read_value == "test";
}
static bool CheckPrefValueAsBaseValue(const base::Value& read_value) {
return read_value.is_string() && read_value.GetString() == "test";
}
};
// Test type holder for known_user integer prefs.
struct PrefTypeInfoInteger {
using PrefType = int;
using PrefTypeForReading = int;
static constexpr auto SetFunc = &KnownUser::SetIntegerPref;
static constexpr auto GetFunc = &KnownUser::GetIntegerPrefForTest;
static PrefType CreatePrefValue() { return 7; }
static bool CheckPrefValue(PrefTypeForReading read_value) {
return read_value == 7;
}
static bool CheckPrefValueAsBaseValue(const base::Value& read_value) {
return read_value.is_int() && read_value.GetInt() == 7;
}
};
// Test type holder for known_user boolean prefs.
struct PrefTypeInfoBoolean {
using PrefType = bool;
using PrefTypeForReading = bool;
static constexpr auto SetFunc = &KnownUser::SetBooleanPref;
static constexpr auto GetFunc = &KnownUser::GetBooleanPrefForTest;
static PrefType CreatePrefValue() { return true; }
static bool CheckPrefValue(PrefTypeForReading read_value) {
return read_value == true;
}
static bool CheckPrefValueAsBaseValue(const base::Value& read_value) {
return read_value.is_bool() && read_value.GetBool() == true;
}
};
// Test type holder for known_user base::Value prefs.
struct PrefTypeInfoValue {
using PrefType = base::Value;
using PrefTypeForReading = const base::Value*;
static constexpr auto SetFunc = &KnownUser::SetPath;
static constexpr auto GetFunc = &KnownUser::GetPrefForTest;
static PrefType CreatePrefValue() { return base::Value("test"); }
static bool CheckPrefValue(PrefTypeForReading read_value) {
return *read_value == CreatePrefValue();
}
static bool CheckPrefValueAsBaseValue(const base::Value& read_value) {
return read_value == CreatePrefValue();
}
};
template <typename PrefTypeInfo>
class KnownUserWithPrefTypeTest : public KnownUserTest {
public:
KnownUserWithPrefTypeTest() = default;
~KnownUserWithPrefTypeTest() = default;
};
TYPED_TEST_SUITE_P(KnownUserWithPrefTypeTest);
TYPED_TEST_P(KnownUserWithPrefTypeTest, ReadOnNonExistingUser) {
KnownUser known_user(KnownUserTest::local_state());
constexpr char kPrefName[] = "some_pref";
const AccountId kNonExistingUser =
AccountId::FromUserEmail("[email protected]");
typename TypeParam::PrefTypeForReading read_result;
bool read_success = (known_user.*TypeParam::GetFunc)(kNonExistingUser,
kPrefName, &read_result);
EXPECT_FALSE(read_success);
}
TYPED_TEST_P(KnownUserWithPrefTypeTest, ReadMissingPrefOnExistingUser) {
KnownUser known_user(KnownUserTest::local_state());
constexpr char kPrefName[] = "some_pref";
const AccountId kUser = AccountId::FromUserEmail("[email protected]");
known_user.SaveKnownUser(kUser);
typename TypeParam::PrefTypeForReading read_result;
bool read_success =
(known_user.*TypeParam::GetFunc)(kUser, kPrefName, &read_result);
EXPECT_FALSE(read_success);
}
TYPED_TEST_P(KnownUserWithPrefTypeTest, ReadExistingPref) {
KnownUser known_user(KnownUserTest::local_state());
constexpr char kPrefName[] = "some_pref";
const AccountId kUser = AccountId::FromUserEmail("[email protected]");
// Set* implicitly creates the known_user user entry.
(known_user.*TypeParam::SetFunc)(kUser, kPrefName,
TypeParam::CreatePrefValue());
typename TypeParam::PrefTypeForReading read_result;
bool read_success =
(known_user.*TypeParam::GetFunc)(kUser, kPrefName, &read_result);
EXPECT_TRUE(read_success);
TypeParam::CheckPrefValue(read_result);
}
TYPED_TEST_P(KnownUserWithPrefTypeTest, ReadExistingPrefAsValue) {
KnownUser known_user(KnownUserTest::local_state());
constexpr char kPrefName[] = "some_pref";
const AccountId kUser = AccountId::FromUserEmail("[email protected]");
// Set* implicitly creates the known_user user entry.
(known_user.*TypeParam::SetFunc)(kUser, kPrefName,
TypeParam::CreatePrefValue());
const base::Value* read_result;
bool read_success = known_user.GetPrefForTest(kUser, kPrefName, &read_result);
EXPECT_TRUE(read_success);
ASSERT_TRUE(read_result);
TypeParam::CheckPrefValueAsBaseValue(*read_result);
}
REGISTER_TYPED_TEST_SUITE_P(KnownUserWithPrefTypeTest,
// All test functions must be listed:
ReadOnNonExistingUser,
ReadMissingPrefOnExistingUser,
ReadExistingPref,
ReadExistingPrefAsValue);
// This must be an alias because the preprocessor does not understand <> so if
// it was directly embedded in the INSTANTIATE_TYPED_TEST_SUITE_P macro the
// prepocessor would be confused on the comma.
using AllTypeInfos = testing::Types<PrefTypeInfoString,
PrefTypeInfoInteger,
PrefTypeInfoBoolean,
PrefTypeInfoValue>;
INSTANTIATE_TYPED_TEST_SUITE_P(AllTypes,
KnownUserWithPrefTypeTest,
AllTypeInfos);
} // namespace user_manager