chromium/chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl_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 <string>

#include "chromeos/ash/components/nearby/presence/credentials/local_device_data_provider_impl.h"

#include "base/strings/utf_string_conversions.h"
#include "base/test/gtest_util.h"
#include "base/test/task_environment.h"
#include "chromeos/ash/components/nearby/presence/credentials/local_device_data_provider.h"
#include "chromeos/ash/components/nearby/presence/credentials/prefs.h"
#include "chromeos/strings/grit/chromeos_strings.h"
#include "components/prefs/pref_registry.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/identity_test_environment.h"
#include "components/signin/public/identity_manager/identity_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/strings/ascii.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/chromeos/devicetype_utils.h"

namespace {

const std::string kUserEmail = "[email protected]";
const std::string kCanocalizedUserEmail = "[email protected]";
const std::string kGivenName = "Test";
const std::string kUserName = "Test Tester";
const std::string kProfileUrl = "https://example.com";
constexpr int64_t kId1 = 111;
constexpr int64_t kId2 = 222;
constexpr int64_t kId3 = 333;
constexpr int64_t kId4 = 444;
constexpr int64_t kId5 = 555;
constexpr int64_t kId6 = 666;

}  // namespace

namespace ash::nearby::presence {

class LocalDeviceDataProviderImplTest : public testing::Test {
 public:
  void SetUp() override {
    RegisterNearbyPresenceCredentialPrefs(pref_service_.registry());
    account_info_ = identity_test_env_.MakePrimaryAccountAvailable(
        kUserEmail, signin::ConsentLevel::kSignin);
  }

  void CreateDataProvider() {
    local_device_data_provider_ = std::make_unique<LocalDeviceDataProviderImpl>(
        &pref_service_, identity_test_env_.identity_manager());
  }

  void DestroyDataProvider() { local_device_data_provider_.reset(); }

 protected:
  AccountInfo account_info_;
  base::test::TaskEnvironment task_environment_;
  TestingPrefServiceSimple pref_service_;
  signin::IdentityTestEnvironment identity_test_env_;
  std::unique_ptr<LocalDeviceDataProvider> local_device_data_provider_;
};

TEST_F(LocalDeviceDataProviderImplTest, DeviceId) {
  CreateDataProvider();

  std::string id = local_device_data_provider_->GetDeviceId();
  EXPECT_EQ(16u, id.size());

  // Ensure the ID is persisted.
  DestroyDataProvider();
  CreateDataProvider();
  EXPECT_EQ(id, local_device_data_provider_->GetDeviceId());
}

TEST_F(LocalDeviceDataProviderImplTest, AccountName) {
  CreateDataProvider();
  EXPECT_EQ(kCanocalizedUserEmail,
            local_device_data_provider_->GetAccountName());
}

TEST_F(LocalDeviceDataProviderImplTest, SaveUserRegistrationInfo) {
  CreateDataProvider();

  // Simulate first time registration has occurred.
  local_device_data_provider_->SaveUserRegistrationInfo(kUserName, kProfileUrl);
  local_device_data_provider_->SetRegistrationComplete(/*complete=*/true);

  EXPECT_TRUE(
      local_device_data_provider_->IsRegistrationCompleteAndUserInfoSaved());
}

TEST_F(LocalDeviceDataProviderImplTest, Metadata) {
  CreateDataProvider();

  // Simulate first time registration has occurred.
  local_device_data_provider_->SaveUserRegistrationInfo(kUserName, kProfileUrl);

  // Assume that without the given name, the device name is just the
  // device type.
  ::nearby::internal::DeviceIdentityMetaData metadata =
      local_device_data_provider_->GetDeviceMetadata();
  EXPECT_EQ(base::UTF16ToUTF8(ui::GetChromeOSDeviceName()),
            metadata.device_name());

  // Populate the account information and expect the device name to include the
  // user's given name.
  account_info_.given_name = kGivenName;
  identity_test_env_.UpdateAccountInfoForAccount(account_info_);
  metadata = local_device_data_provider_->GetDeviceMetadata();
  EXPECT_EQ(l10n_util::GetStringFUTF8(IDS_NEARBY_PRESENCE_DEVICE_NAME,
                                      base::UTF8ToUTF16(kGivenName),
                                      ui::GetChromeOSDeviceName()),
            metadata.device_name());

  // Confirm the other fields are expected.
  EXPECT_EQ(::nearby::internal::DeviceType::DEVICE_TYPE_CHROMEOS,
            metadata.device_type());
  EXPECT_EQ(std::string(), metadata.bluetooth_mac_address());
}

TEST_F(LocalDeviceDataProviderImplTest, PersistCredentialIds) {
  CreateDataProvider();

  // Mock a list of shared credentials. These credentials can be empty except
  // for the secret id field for unit test purposes since only the secret id is
  // persisted and checked for changes.
  ::nearby::internal::SharedCredential shared_credential_1;
  shared_credential_1.set_id(kId1);
  ::nearby::internal::SharedCredential shared_credential_2;
  shared_credential_2.set_id(kId2);
  ::nearby::internal::SharedCredential shared_credential_3;
  shared_credential_3.set_id(kId3);

  // Persist the list of shared credentials ids, and expect that the same list
  // passed to `HavePublicCredentialsChanged` returns false.
  local_device_data_provider_->UpdatePersistedSharedCredentials(
      {shared_credential_1, shared_credential_2, shared_credential_3});
  EXPECT_FALSE(local_device_data_provider_->HaveSharedCredentialsChanged(
      {shared_credential_1, shared_credential_2, shared_credential_3}));

  // Send in a changed list of shared credential ids to
  // `HavePublicCredentialsChanged` and expect it returns true.
  ::nearby::internal::SharedCredential shared_credential_4;
  shared_credential_4.set_id(kId4);
  ::nearby::internal::SharedCredential shared_credential_5;
  shared_credential_5.set_id(kId5);
  ::nearby::internal::SharedCredential shared_credential_6;
  shared_credential_6.set_id(kId6);
  EXPECT_TRUE(local_device_data_provider_->HaveSharedCredentialsChanged(
      {shared_credential_4, shared_credential_5, shared_credential_6}));

  // Send in a changed list of shared credential ids with one removed, and
  // expect it to return true.
  EXPECT_TRUE(local_device_data_provider_->HaveSharedCredentialsChanged(
      {shared_credential_1, shared_credential_2}));

  // Send in a changed list of shared credential ids with one added, and
  // expect it to return true.
  EXPECT_TRUE(local_device_data_provider_->HaveSharedCredentialsChanged(
      {shared_credential_1, shared_credential_2, shared_credential_3,
       shared_credential_4}));
}

}  // namespace ash::nearby::presence