123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616 |
- // Copyright 2022 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/browsing_topics/browsing_topics_state.h"
- #include "base/base64.h"
- #include "base/callback_helpers.h"
- #include "base/files/file_util.h"
- #include "base/files/scoped_temp_dir.h"
- #include "base/json/json_file_value_serializer.h"
- #include "base/json/values_util.h"
- #include "base/strings/strcat.h"
- #include "base/test/metrics/histogram_tester.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/test/task_environment.h"
- #include "components/browsing_topics/util.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/blink/public/common/features.h"
- namespace browsing_topics {
- namespace {
- constexpr base::Time kTime1 =
- base::Time::FromDeltaSinceWindowsEpoch(base::Days(1));
- constexpr base::Time kTime2 =
- base::Time::FromDeltaSinceWindowsEpoch(base::Days(2));
- constexpr base::Time kTime3 =
- base::Time::FromDeltaSinceWindowsEpoch(base::Days(3));
- constexpr base::Time kTime4 =
- base::Time::FromDeltaSinceWindowsEpoch(base::Days(4));
- constexpr base::Time kTime5 =
- base::Time::FromDeltaSinceWindowsEpoch(base::Days(5));
- constexpr browsing_topics::HmacKey kZeroKey = {};
- constexpr browsing_topics::HmacKey kTestKey = {1};
- constexpr browsing_topics::HmacKey kTestKey2 = {2};
- constexpr size_t kTaxonomySize = 349;
- constexpr int kTaxonomyVersion = 1;
- constexpr int64_t kModelVersion = 2;
- constexpr size_t kPaddedTopTopicsStartIndex = 3;
- EpochTopics CreateTestEpochTopics(base::Time calculation_time) {
- std::vector<TopicAndDomains> top_topics_and_observing_domains;
- top_topics_and_observing_domains.emplace_back(
- TopicAndDomains(Topic(1), {HashedDomain(1)}));
- top_topics_and_observing_domains.emplace_back(
- TopicAndDomains(Topic(2), {HashedDomain(1), HashedDomain(2)}));
- top_topics_and_observing_domains.emplace_back(
- TopicAndDomains(Topic(3), {HashedDomain(1), HashedDomain(3)}));
- top_topics_and_observing_domains.emplace_back(
- TopicAndDomains(Topic(4), {HashedDomain(2), HashedDomain(3)}));
- top_topics_and_observing_domains.emplace_back(
- TopicAndDomains(Topic(5), {HashedDomain(1)}));
- EpochTopics epoch_topics(std::move(top_topics_and_observing_domains),
- kPaddedTopTopicsStartIndex, kTaxonomySize,
- kTaxonomyVersion, kModelVersion, calculation_time);
- return epoch_topics;
- }
- } // namespace
- class BrowsingTopicsStateTest : public testing::Test {
- public:
- BrowsingTopicsStateTest()
- : task_environment_(new base::test::TaskEnvironment(
- base::test::TaskEnvironment::TimeSource::MOCK_TIME)) {
- feature_list_.InitAndEnableFeatureWithParameters(
- blink::features::kBrowsingTopics, {{"config_version", "123"}});
- OverrideHmacKeyForTesting(kTestKey);
- EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
- }
- base::FilePath TestFilePath() {
- return temp_dir_.GetPath().Append(FILE_PATH_LITERAL("BrowsingTopicsState"));
- }
- std::string GetTestFileContent() {
- JSONFileValueDeserializer deserializer(TestFilePath());
- std::unique_ptr<base::Value> value = deserializer.Deserialize(
- /*error_code=*/nullptr,
- /*error_message=*/nullptr);
- EXPECT_TRUE(value);
- return base::CollapseWhitespaceASCII(value->DebugString(), true);
- }
- void CreateOrOverrideTestFile(std::vector<EpochTopics> epochs,
- base::Time next_scheduled_calculation_time,
- std::string hex_encoded_hmac_key,
- int config_version) {
- base::Value::List epochs_list;
- for (const EpochTopics& epoch : epochs) {
- epochs_list.Append(epoch.ToDictValue());
- }
- base::Value::Dict dict;
- dict.Set("epochs", std::move(epochs_list));
- dict.Set("next_scheduled_calculation_time",
- base::TimeToValue(next_scheduled_calculation_time));
- dict.Set("hex_encoded_hmac_key", std::move(hex_encoded_hmac_key));
- dict.Set("config_version", config_version);
- JSONFileValueSerializer(TestFilePath()).Serialize(dict);
- }
- void OnBrowsingTopicsStateLoaded() { observed_state_loaded_ = true; }
- bool observed_state_loaded() const { return observed_state_loaded_; }
- protected:
- base::test::ScopedFeatureList feature_list_;
- std::unique_ptr<base::test::TaskEnvironment> task_environment_;
- base::ScopedTempDir temp_dir_;
- bool observed_state_loaded_ = false;
- };
- TEST_F(BrowsingTopicsStateTest, InitFromNoFile_SaveToDiskAfterDelay) {
- base::HistogramTester histograms;
- BrowsingTopicsState state(
- temp_dir_.GetPath(),
- base::BindOnce(&BrowsingTopicsStateTest::OnBrowsingTopicsStateLoaded,
- base::Unretained(this)));
- EXPECT_FALSE(state.HasScheduledSaveForTesting());
- EXPECT_FALSE(observed_state_loaded());
- // UMA should not be recorded yet.
- histograms.ExpectTotalCount(
- "BrowsingTopics.BrowsingTopicsState.LoadFinishStatus", 0);
- // Let the backend file read task finish.
- task_environment_->RunUntilIdle();
- histograms.ExpectUniqueSample(
- "BrowsingTopics.BrowsingTopicsState.LoadFinishStatus", true,
- /*expected_bucket_count=*/1);
- EXPECT_TRUE(state.epochs().empty());
- EXPECT_TRUE(state.next_scheduled_calculation_time().is_null());
- EXPECT_TRUE(std::equal(state.hmac_key().begin(), state.hmac_key().end(),
- kTestKey.begin()));
- EXPECT_TRUE(state.HasScheduledSaveForTesting());
- EXPECT_TRUE(observed_state_loaded());
- // Advance clock until immediately before saving takes place.
- task_environment_->FastForwardBy(base::Milliseconds(2499));
- EXPECT_TRUE(state.HasScheduledSaveForTesting());
- EXPECT_FALSE(base::PathExists(TestFilePath()));
- // Advance clock past the saving moment.
- task_environment_->FastForwardBy(base::Milliseconds(1));
- EXPECT_FALSE(state.HasScheduledSaveForTesting());
- EXPECT_TRUE(base::PathExists(TestFilePath()));
- EXPECT_EQ(
- GetTestFileContent(),
- "{\"config_version\": 123,\"epochs\": [ ],\"hex_encoded_hmac_key\": "
- "\"0100000000000000000000000000000000000000000000000000000000000000\","
- "\"next_scheduled_calculation_time\": \"0\"}");
- }
- TEST_F(BrowsingTopicsStateTest,
- UpdateNextScheduledCalculationTime_SaveToDiskAfterDelay) {
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->FastForwardBy(base::Milliseconds(3000));
- EXPECT_FALSE(state.HasScheduledSaveForTesting());
- state.UpdateNextScheduledCalculationTime();
- EXPECT_TRUE(state.epochs().empty());
- EXPECT_EQ(state.next_scheduled_calculation_time(),
- base::Time::Now() + base::Days(7));
- EXPECT_TRUE(std::equal(state.hmac_key().begin(), state.hmac_key().end(),
- kTestKey.begin()));
- EXPECT_TRUE(state.HasScheduledSaveForTesting());
- task_environment_->FastForwardBy(base::Milliseconds(2499));
- EXPECT_TRUE(state.HasScheduledSaveForTesting());
- task_environment_->FastForwardBy(base::Milliseconds(1));
- EXPECT_FALSE(state.HasScheduledSaveForTesting());
- std::string expected_content = base::StrCat(
- {"{\"config_version\": 123,\"epochs\": [ ],\"hex_encoded_hmac_key\": "
- "\"0100000000000000000000000000000000000000000000000000000000000000"
- "\",\"next_scheduled_calculation_time\": \"",
- base::NumberToString(state.next_scheduled_calculation_time()
- .ToDeltaSinceWindowsEpoch()
- .InMicroseconds()),
- "\"}"});
- EXPECT_EQ(GetTestFileContent(), expected_content);
- }
- TEST_F(BrowsingTopicsStateTest, AddEpoch) {
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- // Successful topics calculation at `kTime1`.
- state.AddEpoch(CreateTestEpochTopics(kTime1));
- EXPECT_EQ(state.epochs().size(), 1u);
- EXPECT_FALSE(state.epochs()[0].empty());
- EXPECT_EQ(state.epochs()[0].calculation_time(), kTime1);
- // Successful topics calculation at `kTime2`.
- state.AddEpoch(CreateTestEpochTopics(kTime2));
- EXPECT_EQ(state.epochs().size(), 2u);
- EXPECT_FALSE(state.epochs()[0].empty());
- EXPECT_EQ(state.epochs()[0].calculation_time(), kTime1);
- EXPECT_FALSE(state.epochs()[1].empty());
- EXPECT_EQ(state.epochs()[1].calculation_time(), kTime2);
- // Failed topics calculation.
- state.AddEpoch(EpochTopics(kTime3));
- EXPECT_EQ(state.epochs().size(), 3u);
- EXPECT_FALSE(state.epochs()[0].empty());
- EXPECT_EQ(state.epochs()[0].calculation_time(), kTime1);
- EXPECT_FALSE(state.epochs()[1].empty());
- EXPECT_EQ(state.epochs()[1].calculation_time(), kTime2);
- EXPECT_TRUE(state.epochs()[2].empty());
- EXPECT_EQ(state.epochs()[2].calculation_time(), kTime3);
- // Successful topics calculation at `kTime4`.
- state.AddEpoch(CreateTestEpochTopics(kTime4));
- EXPECT_EQ(state.epochs().size(), 4u);
- EXPECT_FALSE(state.epochs()[0].empty());
- EXPECT_EQ(state.epochs()[0].calculation_time(), kTime1);
- EXPECT_FALSE(state.epochs()[1].empty());
- EXPECT_EQ(state.epochs()[1].calculation_time(), kTime2);
- EXPECT_TRUE(state.epochs()[2].empty());
- EXPECT_FALSE(state.epochs()[3].empty());
- EXPECT_EQ(state.epochs()[3].calculation_time(), kTime4);
- // Successful topics calculation at `kTime5`. When this epoch is added, the
- // first one should be evicted.
- state.AddEpoch(CreateTestEpochTopics(kTime5));
- EXPECT_EQ(state.epochs().size(), 4u);
- EXPECT_FALSE(state.epochs()[0].empty());
- EXPECT_EQ(state.epochs()[0].calculation_time(), kTime2);
- EXPECT_TRUE(state.epochs()[1].empty());
- EXPECT_FALSE(state.epochs()[2].empty());
- EXPECT_EQ(state.epochs()[2].calculation_time(), kTime4);
- EXPECT_FALSE(state.epochs()[3].empty());
- EXPECT_EQ(state.epochs()[3].calculation_time(), kTime5);
- // The `next_scheduled_calculation_time` and `hmac_key` are unaffected.
- EXPECT_EQ(state.next_scheduled_calculation_time(), base::Time());
- EXPECT_TRUE(std::equal(state.hmac_key().begin(), state.hmac_key().end(),
- kTestKey.begin()));
- }
- TEST_F(BrowsingTopicsStateTest, EpochsForSite_Empty) {
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- EXPECT_TRUE(state.EpochsForSite(/*top_domain=*/"foo.com").empty());
- }
- TEST_F(BrowsingTopicsStateTest, EpochsForSite_OneEpoch_SwitchTimeNotArrived) {
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- state.AddEpoch(CreateTestEpochTopics(kTime1));
- state.UpdateNextScheduledCalculationTime();
- ASSERT_LT(state.CalculateSiteStickyTimeDelta("foo.com") + base::Hours(1),
- base::Days(7));
- task_environment_->FastForwardBy(base::Hours(1));
- EXPECT_TRUE(state.EpochsForSite(/*top_domain=*/"foo.com").empty());
- }
- TEST_F(BrowsingTopicsStateTest, EpochsForSite_OneEpoch_SwitchTimeArrived) {
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- state.AddEpoch(CreateTestEpochTopics(kTime1));
- state.UpdateNextScheduledCalculationTime();
- ASSERT_GT(state.CalculateSiteStickyTimeDelta("foo.com") + base::Days(1),
- base::Days(7));
- task_environment_->FastForwardBy(base::Days(1));
- std::vector<const EpochTopics*> epochs_for_site =
- state.EpochsForSite(/*top_domain=*/"foo.com");
- EXPECT_EQ(epochs_for_site.size(), 1u);
- EXPECT_EQ(epochs_for_site[0], &state.epochs()[0]);
- }
- TEST_F(BrowsingTopicsStateTest,
- EpochsForSite_ThreeEpochs_SwitchTimeNotArrived) {
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- state.AddEpoch(CreateTestEpochTopics(kTime1));
- state.AddEpoch(CreateTestEpochTopics(kTime2));
- state.AddEpoch(CreateTestEpochTopics(kTime3));
- state.UpdateNextScheduledCalculationTime();
- task_environment_->FastForwardBy(base::Hours(1));
- std::vector<const EpochTopics*> epochs_for_site =
- state.EpochsForSite(/*top_domain=*/"foo.com");
- EXPECT_EQ(epochs_for_site.size(), 2u);
- EXPECT_EQ(epochs_for_site[0], &state.epochs()[0]);
- EXPECT_EQ(epochs_for_site[1], &state.epochs()[1]);
- }
- TEST_F(BrowsingTopicsStateTest, EpochsForSite_ThreeEpochs_SwitchTimeArrived) {
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- state.AddEpoch(CreateTestEpochTopics(kTime1));
- state.AddEpoch(CreateTestEpochTopics(kTime2));
- state.AddEpoch(CreateTestEpochTopics(kTime3));
- state.UpdateNextScheduledCalculationTime();
- task_environment_->FastForwardBy(base::Days(1));
- std::vector<const EpochTopics*> epochs_for_site =
- state.EpochsForSite(/*top_domain=*/"foo.com");
- EXPECT_EQ(epochs_for_site.size(), 3u);
- EXPECT_EQ(epochs_for_site[0], &state.epochs()[0]);
- EXPECT_EQ(epochs_for_site[1], &state.epochs()[1]);
- EXPECT_EQ(epochs_for_site[2], &state.epochs()[2]);
- }
- TEST_F(BrowsingTopicsStateTest, EpochsForSite_FourEpochs_SwitchTimeNotArrived) {
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- state.AddEpoch(CreateTestEpochTopics(kTime1));
- state.AddEpoch(CreateTestEpochTopics(kTime2));
- state.AddEpoch(CreateTestEpochTopics(kTime3));
- state.AddEpoch(CreateTestEpochTopics(kTime4));
- state.UpdateNextScheduledCalculationTime();
- task_environment_->FastForwardBy(base::Hours(1));
- std::vector<const EpochTopics*> epochs_for_site =
- state.EpochsForSite(/*top_domain=*/"foo.com");
- EXPECT_EQ(epochs_for_site.size(), 3u);
- EXPECT_EQ(epochs_for_site[0], &state.epochs()[0]);
- EXPECT_EQ(epochs_for_site[1], &state.epochs()[1]);
- EXPECT_EQ(epochs_for_site[2], &state.epochs()[2]);
- }
- TEST_F(BrowsingTopicsStateTest, EpochsForSite_FourEpochs_SwitchTimeArrived) {
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- state.AddEpoch(CreateTestEpochTopics(kTime1));
- state.AddEpoch(CreateTestEpochTopics(kTime2));
- state.AddEpoch(CreateTestEpochTopics(kTime3));
- state.AddEpoch(CreateTestEpochTopics(kTime4));
- state.UpdateNextScheduledCalculationTime();
- task_environment_->FastForwardBy(base::Days(1));
- std::vector<const EpochTopics*> epochs_for_site =
- state.EpochsForSite(/*top_domain=*/"foo.com");
- EXPECT_EQ(epochs_for_site.size(), 3u);
- EXPECT_EQ(epochs_for_site[0], &state.epochs()[1]);
- EXPECT_EQ(epochs_for_site[1], &state.epochs()[2]);
- EXPECT_EQ(epochs_for_site[2], &state.epochs()[3]);
- }
- TEST_F(BrowsingTopicsStateTest, InitFromPreexistingFile_CorruptedHmacKey) {
- base::HistogramTester histograms;
- std::vector<EpochTopics> epochs;
- epochs.emplace_back(CreateTestEpochTopics(kTime1));
- CreateOrOverrideTestFile(std::move(epochs),
- /*next_scheduled_calculation_time=*/kTime2,
- /*hex_encoded_hmac_key=*/"123",
- /*config_version=*/123);
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- EXPECT_EQ(state.epochs().size(), 0u);
- EXPECT_TRUE(state.next_scheduled_calculation_time().is_null());
- EXPECT_TRUE(std::equal(state.hmac_key().begin(), state.hmac_key().end(),
- kZeroKey.begin()));
- histograms.ExpectUniqueSample(
- "BrowsingTopics.BrowsingTopicsState.LoadFinishStatus", false,
- /*expected_bucket_count=*/1);
- }
- TEST_F(BrowsingTopicsStateTest, InitFromPreexistingFile_SameConfigVersion) {
- base::HistogramTester histograms;
- std::vector<EpochTopics> epochs;
- epochs.emplace_back(CreateTestEpochTopics(kTime1));
- CreateOrOverrideTestFile(std::move(epochs),
- /*next_scheduled_calculation_time=*/kTime2,
- /*hex_encoded_hmac_key=*/base::HexEncode(kTestKey2),
- /*config_version=*/123);
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- EXPECT_EQ(state.epochs().size(), 1u);
- EXPECT_FALSE(state.epochs()[0].empty());
- EXPECT_EQ(state.epochs()[0].model_version(), kModelVersion);
- EXPECT_EQ(state.next_scheduled_calculation_time(), kTime2);
- EXPECT_TRUE(std::equal(state.hmac_key().begin(), state.hmac_key().end(),
- kTestKey2.begin()));
- histograms.ExpectUniqueSample(
- "BrowsingTopics.BrowsingTopicsState.LoadFinishStatus", true,
- /*expected_bucket_count=*/1);
- }
- TEST_F(BrowsingTopicsStateTest,
- InitFromPreexistingFile_DifferentConfigVersion) {
- base::HistogramTester histograms;
- std::vector<EpochTopics> epochs;
- epochs.emplace_back(CreateTestEpochTopics(kTime1));
- CreateOrOverrideTestFile(std::move(epochs),
- /*next_scheduled_calculation_time=*/kTime2,
- /*hex_encoded_hmac_key=*/base::HexEncode(kTestKey2),
- /*config_version=*/100);
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- EXPECT_TRUE(state.epochs().empty());
- EXPECT_TRUE(state.next_scheduled_calculation_time().is_null());
- EXPECT_TRUE(std::equal(state.hmac_key().begin(), state.hmac_key().end(),
- kTestKey2.begin()));
- histograms.ExpectUniqueSample(
- "BrowsingTopics.BrowsingTopicsState.LoadFinishStatus", true,
- /*expected_bucket_count=*/1);
- }
- TEST_F(BrowsingTopicsStateTest, ClearOneEpoch) {
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- state.AddEpoch(CreateTestEpochTopics(kTime1));
- EXPECT_EQ(state.epochs().size(), 1u);
- EXPECT_FALSE(state.epochs()[0].empty());
- EXPECT_EQ(state.epochs()[0].calculation_time(), kTime1);
- state.AddEpoch(CreateTestEpochTopics(kTime2));
- EXPECT_EQ(state.epochs().size(), 2u);
- EXPECT_FALSE(state.epochs()[0].empty());
- EXPECT_EQ(state.epochs()[0].calculation_time(), kTime1);
- EXPECT_FALSE(state.epochs()[1].empty());
- EXPECT_EQ(state.epochs()[1].calculation_time(), kTime2);
- state.ClearOneEpoch(/*epoch_index=*/0);
- EXPECT_EQ(state.epochs().size(), 2u);
- EXPECT_TRUE(state.epochs()[0].empty());
- EXPECT_FALSE(state.epochs()[1].empty());
- EXPECT_EQ(state.epochs()[1].calculation_time(), kTime2);
- state.UpdateNextScheduledCalculationTime();
- EXPECT_EQ(state.next_scheduled_calculation_time(),
- base::Time::Now() + base::Days(7));
- EXPECT_TRUE(std::equal(state.hmac_key().begin(), state.hmac_key().end(),
- kTestKey.begin()));
- }
- TEST_F(BrowsingTopicsStateTest, ClearAllTopics) {
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- state.AddEpoch(CreateTestEpochTopics(kTime1));
- EXPECT_EQ(state.epochs().size(), 1u);
- EXPECT_FALSE(state.epochs()[0].empty());
- EXPECT_EQ(state.epochs()[0].calculation_time(), kTime1);
- state.AddEpoch(CreateTestEpochTopics(kTime2));
- EXPECT_EQ(state.epochs().size(), 2u);
- EXPECT_FALSE(state.epochs()[0].empty());
- EXPECT_EQ(state.epochs()[0].calculation_time(), kTime1);
- EXPECT_FALSE(state.epochs()[1].empty());
- EXPECT_EQ(state.epochs()[1].calculation_time(), kTime2);
- state.UpdateNextScheduledCalculationTime();
- state.ClearAllTopics();
- EXPECT_EQ(state.epochs().size(), 0u);
- EXPECT_EQ(state.next_scheduled_calculation_time(),
- base::Time::Now() + base::Days(7));
- EXPECT_TRUE(std::equal(state.hmac_key().begin(), state.hmac_key().end(),
- kTestKey.begin()));
- }
- TEST_F(BrowsingTopicsStateTest, ClearTopic) {
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- state.AddEpoch(CreateTestEpochTopics(kTime1));
- state.AddEpoch(CreateTestEpochTopics(kTime2));
- state.UpdateNextScheduledCalculationTime();
- state.ClearTopic(Topic(3), kTaxonomyVersion);
- EXPECT_EQ(state.epochs().size(), 2u);
- EXPECT_EQ(state.epochs()[0].top_topics_and_observing_domains()[0].topic(),
- Topic(1));
- EXPECT_EQ(state.epochs()[0].top_topics_and_observing_domains()[1].topic(),
- Topic(2));
- EXPECT_FALSE(
- state.epochs()[0].top_topics_and_observing_domains()[2].IsValid());
- EXPECT_EQ(state.epochs()[0].top_topics_and_observing_domains()[3].topic(),
- Topic(4));
- EXPECT_EQ(state.epochs()[0].top_topics_and_observing_domains()[4].topic(),
- Topic(5));
- EXPECT_EQ(state.epochs()[1].top_topics_and_observing_domains()[0].topic(),
- Topic(1));
- EXPECT_EQ(state.epochs()[1].top_topics_and_observing_domains()[1].topic(),
- Topic(2));
- EXPECT_FALSE(
- state.epochs()[1].top_topics_and_observing_domains()[2].IsValid());
- EXPECT_EQ(state.epochs()[1].top_topics_and_observing_domains()[3].topic(),
- Topic(4));
- EXPECT_EQ(state.epochs()[1].top_topics_and_observing_domains()[4].topic(),
- Topic(5));
- }
- TEST_F(BrowsingTopicsStateTest, ClearContextDomain) {
- BrowsingTopicsState state(temp_dir_.GetPath(), base::DoNothing());
- task_environment_->RunUntilIdle();
- state.AddEpoch(CreateTestEpochTopics(kTime1));
- state.AddEpoch(CreateTestEpochTopics(kTime2));
- state.UpdateNextScheduledCalculationTime();
- state.ClearContextDomain(HashedDomain(1));
- EXPECT_EQ(
- state.epochs()[0].top_topics_and_observing_domains()[0].hashed_domains(),
- std::set<HashedDomain>{});
- EXPECT_EQ(
- state.epochs()[0].top_topics_and_observing_domains()[1].hashed_domains(),
- std::set<HashedDomain>({HashedDomain(2)}));
- EXPECT_EQ(
- state.epochs()[0].top_topics_and_observing_domains()[2].hashed_domains(),
- std::set<HashedDomain>({HashedDomain(3)}));
- EXPECT_EQ(
- state.epochs()[0].top_topics_and_observing_domains()[3].hashed_domains(),
- std::set<HashedDomain>({HashedDomain(2), HashedDomain(3)}));
- EXPECT_EQ(
- state.epochs()[0].top_topics_and_observing_domains()[4].hashed_domains(),
- std::set<HashedDomain>{});
- EXPECT_EQ(
- state.epochs()[1].top_topics_and_observing_domains()[0].hashed_domains(),
- std::set<HashedDomain>{});
- EXPECT_EQ(
- state.epochs()[1].top_topics_and_observing_domains()[1].hashed_domains(),
- std::set<HashedDomain>({HashedDomain(2)}));
- EXPECT_EQ(
- state.epochs()[1].top_topics_and_observing_domains()[2].hashed_domains(),
- std::set<HashedDomain>({HashedDomain(3)}));
- EXPECT_EQ(
- state.epochs()[1].top_topics_and_observing_domains()[3].hashed_domains(),
- std::set<HashedDomain>({HashedDomain(2), HashedDomain(3)}));
- EXPECT_EQ(
- state.epochs()[1].top_topics_and_observing_domains()[4].hashed_domains(),
- std::set<HashedDomain>{});
- }
- TEST_F(BrowsingTopicsStateTest, ShouldSaveFileDespiteShutdownWhileScheduled) {
- auto state = std::make_unique<BrowsingTopicsState>(temp_dir_.GetPath(),
- base::DoNothing());
- task_environment_->RunUntilIdle();
- ASSERT_TRUE(state->HasScheduledSaveForTesting());
- EXPECT_FALSE(base::PathExists(TestFilePath()));
- state.reset();
- task_environment_.reset();
- // TaskEnvironment and BrowsingTopicsState both have been destroyed, mimic-ing
- // a browser shutdown.
- EXPECT_TRUE(base::PathExists(TestFilePath()));
- EXPECT_EQ(
- GetTestFileContent(),
- "{\"config_version\": 123,\"epochs\": [ ],\"hex_encoded_hmac_key\": "
- "\"0100000000000000000000000000000000000000000000000000000000000000\","
- "\"next_scheduled_calculation_time\": \"0\"}");
- }
- } // namespace browsing_topics
|