chromium/components/user_manager/account_id_util_unittest.cc

// Copyright 2024 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/account_id_util.h"

#include <memory>
#include <optional>
#include <utility>

#include "base/values.h"
#include "components/account_id/account_id.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace user_manager {

namespace {
constexpr char kUserEmail[] = "[email protected]";
constexpr char kOtherEmail[] = "[email protected]";
constexpr char kGaiaID[] = "fake-gaia-id";
// Active directory users are deprecated, but full cleanup is not finished yet.
constexpr char kObjGuid[] = "fake-obj-guid";
}  // namespace

// Base class for tests of known_user.
// Sets up global objects necessary for known_user to be able to access
// local_state.
class AccountIdUtilTest : public testing::Test {
 public:
  AccountIdUtilTest() {}
  ~AccountIdUtilTest() override = default;

  AccountIdUtilTest(const AccountIdUtilTest& other) = delete;
  AccountIdUtilTest& operator=(const AccountIdUtilTest& other) = delete;

 protected:
  const AccountId kDefaultAccountId =
      AccountId::FromUserEmailGaiaId(kUserEmail, kGaiaID);
};

TEST_F(AccountIdUtilTest, LoadGoogleAccountWithGaiaId) {
  base::Value::Dict dict = base::Value::Dict()
                               .Set("account_type", "google")
                               .Set("email", kUserEmail)
                               .Set("gaia_id", kGaiaID)
                               .Set("obj_guid", kObjGuid);
  std::optional<AccountId> result = LoadAccountId(dict);
  ASSERT_TRUE(result);
  ASSERT_TRUE(result->is_valid());
  EXPECT_EQ(result->GetAccountType(), AccountType::GOOGLE);
  EXPECT_EQ(result->GetUserEmail(), kUserEmail);
  ASSERT_TRUE(result->HasAccountIdKey());
  ASSERT_EQ(result->GetGaiaId(), kGaiaID);
}

TEST_F(AccountIdUtilTest, LoadGoogleAccountWithoutGaiaId) {
  base::Value::Dict dict = base::Value::Dict()
                               .Set("account_type", "google")
                               .Set("email", kUserEmail)
                               .Set("obj_guid", kObjGuid);
  std::optional<AccountId> result = LoadAccountId(dict);
  ASSERT_TRUE(result);
  ASSERT_TRUE(result->is_valid());
  EXPECT_EQ(result->GetAccountType(), AccountType::GOOGLE);
  EXPECT_EQ(result->GetUserEmail(), kUserEmail);
  ASSERT_FALSE(result->HasAccountIdKey());
}

// Death test for some reason fails on MSAN bots.
// TODO(b/325904498): Investigate how DEATH tests should be used.
TEST_F(AccountIdUtilTest, DISABLED_LoadUnknownAccount) {
  base::Value::Dict dict = base::Value::Dict()
                               .Set("account_type", "unknown")
                               .Set("email", kUserEmail)
                               .Set("gaia_id", kGaiaID)
                               .Set("obj_guid", kObjGuid);
  ASSERT_DEATH({ LoadAccountId(dict); }, "Unknown account type");
}

TEST_F(AccountIdUtilTest, LoadAccountEmailOnly) {
  base::Value::Dict dict = base::Value::Dict().Set("email", kUserEmail);
  std::optional<AccountId> result = LoadAccountId(dict);
  ASSERT_TRUE(result);
  ASSERT_TRUE(result->is_valid());
  // Assume that accounts are Google accounts by default.
  EXPECT_EQ(result->GetAccountType(), AccountType::GOOGLE);
  EXPECT_EQ(result->GetUserEmail(), kUserEmail);
  ASSERT_FALSE(result->HasAccountIdKey());
}

TEST_F(AccountIdUtilTest, LoadDeprecatedActiveDirectoryUser) {
  base::Value::Dict dict = base::Value::Dict()
                               .Set("account_type", "ad")
                               .Set("email", kUserEmail)
                               .Set("obj_guid", kObjGuid);
  std::optional<AccountId> result = LoadAccountId(dict);
  ASSERT_TRUE(result);
  ASSERT_TRUE(result->is_valid());
  EXPECT_EQ(result->GetAccountType(), AccountType::ACTIVE_DIRECTORY);
  EXPECT_EQ(result->GetUserEmail(), kUserEmail);
  ASSERT_TRUE(result->HasAccountIdKey());
  EXPECT_EQ(result->GetObjGuid(), kObjGuid);
}

TEST_F(AccountIdUtilTest, MatchByCorrectEmail) {
  base::Value::Dict dict = base::Value::Dict()
                               .Set("account_type", "google")
                               .Set("email", kUserEmail)
                               .Set("gaia_id", kGaiaID);
  AccountId id = AccountId::FromUserEmail(kUserEmail);
  ASSERT_TRUE(AccountIdMatches(id, dict));
}

TEST_F(AccountIdUtilTest, MatchByIncorrectEmail) {
  base::Value::Dict dict = base::Value::Dict()
                               .Set("account_type", "google")
                               .Set("email", kUserEmail)
                               .Set("gaia_id", kGaiaID);
  AccountId id = AccountId::FromUserEmail(kOtherEmail);
  ASSERT_FALSE(AccountIdMatches(id, dict));
}

TEST_F(AccountIdUtilTest, MatchByGaiaIdSameEmail) {
  base::Value::Dict dict = base::Value::Dict()
                               .Set("account_type", "google")
                               .Set("email", kUserEmail)
                               .Set("gaia_id", kGaiaID);
  AccountId id = AccountId::FromUserEmailGaiaId(kUserEmail, kGaiaID);
  ASSERT_TRUE(AccountIdMatches(id, dict));
}

TEST_F(AccountIdUtilTest, MatchByGaiaIdOtherEmail) {
  base::Value::Dict dict = base::Value::Dict()
                               .Set("account_type", "google")
                               .Set("email", kUserEmail)
                               .Set("gaia_id", kGaiaID);
  AccountId id = AccountId::FromUserEmailGaiaId(kOtherEmail, kGaiaID);
  ASSERT_TRUE(AccountIdMatches(id, dict));
}

TEST_F(AccountIdUtilTest, MatchByEmailOnly) {
  base::Value::Dict dict = base::Value::Dict().Set("email", kUserEmail);
  AccountId id = AccountId::FromUserEmail(kUserEmail);
  ASSERT_TRUE(AccountIdMatches(id, dict));
}

TEST_F(AccountIdUtilTest, StoreEmailOnly) {
  AccountId id = AccountId::FromUserEmail(kUserEmail);
  base::Value::Dict dict;
  StoreAccountId(id, dict);
  EXPECT_EQ(dict.Find("account_type"), nullptr);
  EXPECT_EQ(dict.Find("email")->GetString(), kUserEmail);
  EXPECT_EQ(dict.Find("gaia_id"), nullptr);
}

TEST_F(AccountIdUtilTest, StoreGoogleAccount) {
  AccountId id = AccountId::FromUserEmailGaiaId(kUserEmail, kGaiaID);
  base::Value::Dict dict;
  StoreAccountId(id, dict);
  EXPECT_EQ(dict.Find("account_type")->GetString(), "google");
  EXPECT_EQ(dict.Find("email")->GetString(), kUserEmail);
  EXPECT_EQ(dict.Find("gaia_id")->GetString(), kGaiaID);
}

TEST_F(AccountIdUtilTest, StoreDeprecatedADAccount) {
  AccountId id = AccountId::AdFromUserEmailObjGuid(kUserEmail, kObjGuid);
  base::Value::Dict dict;
  StoreAccountId(id, dict);
  EXPECT_EQ(dict.Find("account_type")->GetString(), "ad");
  EXPECT_EQ(dict.Find("email")->GetString(), kUserEmail);
  EXPECT_EQ(dict.Find("obj_guid")->GetString(), kObjGuid);
}

}  // namespace user_manager