123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- // Copyright 2019 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/metrics/demographics/user_demographics.h"
- #include <utility>
- #include "base/time/time.h"
- #include "components/sync_preferences/testing_pref_service_syncable.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/metrics_proto/user_demographics.pb.h"
- namespace metrics {
- namespace {
- // Gets the now time used for testing demographics.
- base::Time GetNowTime() {
- constexpr char kNowTimeInStringFormat[] = "22 Jul 2019 00:00:00 UDT";
- base::Time now;
- bool result = base::Time::FromString(kNowTimeInStringFormat, &now);
- DCHECK(result);
- return now;
- }
- } // namespace
- TEST(UserDemographicsTest, UserDemographicsResult_ForValue) {
- int user_birth_year = 1982;
- UserDemographicsProto_Gender user_gender = UserDemographicsProto::GENDER_MALE;
- UserDemographics user_demographics;
- user_demographics.birth_year = user_birth_year;
- user_demographics.gender = user_gender;
- UserDemographicsResult user_demographics_result =
- UserDemographicsResult::ForValue(std::move(user_demographics));
- EXPECT_TRUE(user_demographics_result.IsSuccess());
- EXPECT_EQ(UserDemographicsStatus::kSuccess,
- user_demographics_result.status());
- EXPECT_EQ(user_birth_year, user_demographics_result.value().birth_year);
- EXPECT_EQ(user_gender, user_demographics_result.value().gender);
- }
- TEST(UserDemographicsTest, UserDemographicsResult_ForStatus) {
- UserDemographicsStatus error_status =
- UserDemographicsStatus::kIneligibleDemographicsData;
- UserDemographicsResult user_demographics_result =
- UserDemographicsResult::ForStatus(error_status);
- EXPECT_FALSE(user_demographics_result.IsSuccess());
- EXPECT_EQ(error_status, user_demographics_result.status());
- }
- class UserDemographicsPrefsTest : public testing::Test {
- protected:
- UserDemographicsPrefsTest() {
- RegisterDemographicsProfilePrefs(pref_service_.registry());
- }
- void SetDemographics(int birth_year, UserDemographicsProto::Gender gender) {
- base::DictionaryValue dict;
- dict.SetIntPath(kSyncDemographicsBirthYearPath, birth_year);
- dict.SetIntPath(kSyncDemographicsGenderPath, static_cast<int>(gender));
- pref_service_.Set(kSyncDemographicsPrefName, dict);
- }
- sync_preferences::TestingPrefServiceSyncable pref_service_;
- };
- TEST_F(UserDemographicsPrefsTest, ReadDemographicsWithRandomOffset) {
- int user_demographics_birth_year = 1983;
- UserDemographicsProto_Gender user_demographics_gender =
- UserDemographicsProto::GENDER_MALE;
- // Set user demographic prefs.
- SetDemographics(user_demographics_birth_year, user_demographics_gender);
- int provided_birth_year;
- {
- UserDemographicsResult demographics_result =
- GetUserNoisedBirthYearAndGenderFromPrefs(GetNowTime(), &pref_service_);
- ASSERT_TRUE(demographics_result.IsSuccess());
- EXPECT_EQ(user_demographics_gender, demographics_result.value().gender);
- // Verify that the provided birth year is within the range.
- provided_birth_year = demographics_result.value().birth_year;
- int delta = provided_birth_year - user_demographics_birth_year;
- EXPECT_LE(delta, kUserDemographicsBirthYearNoiseOffsetRange);
- EXPECT_GE(delta, -kUserDemographicsBirthYearNoiseOffsetRange);
- }
- // Verify that the offset is cached and that the randomized birth year is the
- // same when doing more that one read of the birth year.
- {
- ASSERT_TRUE(
- pref_service_.HasPrefPath(kSyncDemographicsBirthYearOffsetPrefName));
- UserDemographicsResult demographics_result =
- GetUserNoisedBirthYearAndGenderFromPrefs(GetNowTime(), &pref_service_);
- ASSERT_TRUE(demographics_result.IsSuccess());
- EXPECT_EQ(provided_birth_year, demographics_result.value().birth_year);
- }
- }
- TEST_F(UserDemographicsPrefsTest, ReadAndClearUserDemographicPreferences) {
- // Verify demographic prefs are not available when there is nothing set.
- ASSERT_FALSE(
- GetUserNoisedBirthYearAndGenderFromPrefs(GetNowTime(), &pref_service_)
- .IsSuccess());
- // Set demographic prefs directly from the pref service interface because
- // demographic prefs will only be set on the server-side. The SyncPrefs
- // interface cannot set demographic prefs.
- SetDemographics(1983, UserDemographicsProto::GENDER_FEMALE);
- // Set birth year noise offset to not have it randomized.
- pref_service_.SetInteger(kSyncDemographicsBirthYearOffsetPrefName, 2);
- // Verify that demographics are provided.
- {
- UserDemographicsResult demographics_result =
- GetUserNoisedBirthYearAndGenderFromPrefs(GetNowTime(), &pref_service_);
- ASSERT_TRUE(demographics_result.IsSuccess());
- }
- ClearDemographicsPrefs(&pref_service_);
- // Verify that demographics are not provided and kSyncDemographics is cleared.
- // Note that we retain kSyncDemographicsBirthYearOffset. If the user resumes
- // syncing, causing these prefs to be recreated, we don't want them to start
- // reporting a different randomized birth year as this could narrow down or
- // even reveal their true birth year.
- EXPECT_FALSE(
- GetUserNoisedBirthYearAndGenderFromPrefs(GetNowTime(), &pref_service_)
- .IsSuccess());
- EXPECT_FALSE(pref_service_.HasPrefPath(kSyncDemographicsPrefName));
- EXPECT_TRUE(
- pref_service_.HasPrefPath(kSyncDemographicsBirthYearOffsetPrefName));
- }
- struct DemographicsTestParam {
- // Birth year of the user.
- int birth_year = kUserDemographicsBirthYearDefaultValue;
- // Non-random offset to apply to |birth_year| as noise.
- int birth_year_offset = kUserDemographicsBirthYearNoiseOffsetDefaultValue;
- // Gender of the user.
- UserDemographicsProto_Gender gender = kUserDemographicGenderDefaultEnumValue;
- // Status of the retrieval of demographics.
- UserDemographicsStatus status = UserDemographicsStatus::kMaxValue;
- };
- // Extend UserDemographicsPrefsTest fixture for parameterized tests on
- // demographics.
- class UserDemographicsPrefsTestWithParam
- : public UserDemographicsPrefsTest,
- public testing::WithParamInterface<DemographicsTestParam> {};
- TEST_P(UserDemographicsPrefsTestWithParam, ReadDemographics_OffsetIsNotRandom) {
- DemographicsTestParam param = GetParam();
- // Set user demographic prefs.
- SetDemographics(param.birth_year, param.gender);
- // Set birth year noise offset to not have it randomized.
- pref_service_.SetInteger(kSyncDemographicsBirthYearOffsetPrefName,
- param.birth_year_offset);
- // Verify provided demographics for the different parameterized test cases.
- UserDemographicsResult demographics_result =
- GetUserNoisedBirthYearAndGenderFromPrefs(GetNowTime(), &pref_service_);
- if (param.status == UserDemographicsStatus::kSuccess) {
- ASSERT_TRUE(demographics_result.IsSuccess());
- EXPECT_EQ(param.birth_year + param.birth_year_offset,
- demographics_result.value().birth_year);
- EXPECT_EQ(param.gender, demographics_result.value().gender);
- } else {
- ASSERT_FALSE(demographics_result.IsSuccess());
- EXPECT_EQ(param.status, demographics_result.status());
- }
- }
- // Test suite composed of different test cases of getting user demographics.
- // The now time in each test case is "22 Jul 2019 00:00:00 UDT" which falls into
- // the year bucket of 2018. Users need at most a |birth_year| +
- // |birth_year_offset| of 1998 to be able to provide demographics.
- INSTANTIATE_TEST_SUITE_P(
- All,
- UserDemographicsPrefsTestWithParam,
- ::testing::Values(
- // Test where birth year should not be provided because |birth_year| + 2
- // > 1998.
- DemographicsTestParam{
- /*birth_year=*/1997,
- /*birth_year_offset=*/2,
- /*gender=*/UserDemographicsProto::GENDER_FEMALE,
- /*status=*/UserDemographicsStatus::kIneligibleDemographicsData},
- // Test where birth year should not be provided because |birth_year| - 2
- // > 1998.
- DemographicsTestParam{
- /*birth_year=*/2001,
- /*birth_year_offset=*/-2,
- /*gender=*/UserDemographicsProto::GENDER_FEMALE,
- /*status=*/UserDemographicsStatus::kIneligibleDemographicsData},
- // Test where birth year should not be provided because age of user is
- // |kUserDemographicsMaxAge| + 1, which is over the max age.
- DemographicsTestParam{
- /*birth_year=*/1933,
- /*birth_year_offset=*/0,
- /*gender=*/UserDemographicsProto::GENDER_FEMALE,
- /*status=*/UserDemographicsStatus::kIneligibleDemographicsData},
- // Test where gender should not be provided because it has a low
- // population that can have their privacy compromised because of high
- // entropy.
- DemographicsTestParam{
- /*birth_year=*/1986,
- /*birth_year_offset=*/0,
- /*gender=*/UserDemographicsProto::GENDER_CUSTOM_OR_OTHER,
- /*status=*/UserDemographicsStatus::kIneligibleDemographicsData},
- // Test where birth year can be provided because |birth_year| + 2 ==
- // 1998.
- DemographicsTestParam{/*birth_year=*/1996,
- /*birth_year_offset=*/2,
- /*gender=*/UserDemographicsProto::GENDER_FEMALE,
- /*status=*/UserDemographicsStatus::kSuccess},
- // Test where birth year can be provided because |birth_year| - 2 ==
- // 1998.
- DemographicsTestParam{/*birth_year=*/2000,
- /*birth_year_offset=*/-2,
- /*gender=*/UserDemographicsProto::GENDER_MALE,
- /*status=*/UserDemographicsStatus::kSuccess},
- // Test where birth year can be provided because |birth_year| + 2 <
- // 1998.
- DemographicsTestParam{/*birth_year=*/1995,
- /*birth_year_offset=*/2,
- /*gender=*/UserDemographicsProto::GENDER_FEMALE,
- /*status=*/UserDemographicsStatus::kSuccess},
- // Test where birth year can be provided because |birth_year| - 2 <
- // 1998.
- DemographicsTestParam{/*birth_year=*/1999,
- /*birth_year_offset=*/-2,
- /*gender=*/UserDemographicsProto::GENDER_MALE,
- /*status=*/UserDemographicsStatus::kSuccess},
- // Test where gender can be provided because it is part of a large
- // population with a low entropy.
- DemographicsTestParam{/*birth_year=*/1986,
- /*birth_year_offset=*/0,
- /*gender=*/UserDemographicsProto::GENDER_FEMALE,
- /*status=*/UserDemographicsStatus::kSuccess},
- // Test where gender can be provided because it is part of a large
- // population with a low entropy.
- DemographicsTestParam{/*birth_year=*/1986,
- /*birth_year_offset=*/0,
- /*gender=*/UserDemographicsProto::GENDER_MALE,
- /*status=*/UserDemographicsStatus::kSuccess}));
- } // namespace metrics
|