| Index: components/ntp_snippets/category_rankers/click_based_category_ranker_unittest.cc
|
| diff --git a/components/ntp_snippets/category_rankers/click_based_category_ranker_unittest.cc b/components/ntp_snippets/category_rankers/click_based_category_ranker_unittest.cc
|
| index 0f14faaacf8d094a7ae8eacc0bfad60ea2315065..a37e30cb3fd07d8f52f9badfc6ca194d3fc6c200 100644
|
| --- a/components/ntp_snippets/category_rankers/click_based_category_ranker_unittest.cc
|
| +++ b/components/ntp_snippets/category_rankers/click_based_category_ranker_unittest.cc
|
| @@ -5,6 +5,9 @@
|
| #include "components/ntp_snippets/category_rankers/click_based_category_ranker.h"
|
|
|
| #include "base/memory/ptr_util.h"
|
| +#include "base/test/simple_test_clock.h"
|
| +#include "base/time/default_clock.h"
|
| +#include "base/time/time.h"
|
| #include "components/ntp_snippets/category.h"
|
| #include "components/ntp_snippets/category_rankers/constant_category_ranker.h"
|
| #include "components/prefs/testing_pref_service.h"
|
| @@ -21,7 +24,8 @@ class ClickBasedCategoryRankerTest : public testing::Test {
|
| static_cast<int>(KnownCategories::LAST_KNOWN_REMOTE_CATEGORY) + 1) {
|
| ClickBasedCategoryRanker::RegisterProfilePrefs(pref_service_->registry());
|
|
|
| - ranker_ = base::MakeUnique<ClickBasedCategoryRanker>(pref_service_.get());
|
| + ranker_ = base::MakeUnique<ClickBasedCategoryRanker>(
|
| + pref_service_.get(), base::MakeUnique<base::DefaultClock>());
|
| }
|
|
|
| int GetUnusedRemoteCategoryID() { return unused_remote_category_id_++; }
|
| @@ -46,8 +50,9 @@ class ClickBasedCategoryRankerTest : public testing::Test {
|
| }
|
| }
|
|
|
| - void ResetRanker() {
|
| - ranker_ = base::MakeUnique<ClickBasedCategoryRanker>(pref_service_.get());
|
| + void ResetRanker(std::unique_ptr<base::Clock> clock) {
|
| + ranker_ = base::MakeUnique<ClickBasedCategoryRanker>(pref_service_.get(),
|
| + std::move(clock));
|
| }
|
|
|
| void NotifyOnSuggestionOpened(int times, Category category) {
|
| @@ -219,7 +224,7 @@ TEST_F(ClickBasedCategoryRankerTest, ShouldPersistOrderAndClicksWhenRestarted) {
|
| ASSERT_TRUE(CompareCategories(first, third));
|
|
|
| // Simulate Chrome restart.
|
| - ResetRanker();
|
| + ResetRanker(base::MakeUnique<base::DefaultClock>());
|
|
|
| // The old order must be preserved.
|
| EXPECT_TRUE(CompareCategories(third, second));
|
| @@ -230,6 +235,94 @@ TEST_F(ClickBasedCategoryRankerTest, ShouldPersistOrderAndClicksWhenRestarted) {
|
| EXPECT_TRUE(CompareCategories(third, first));
|
| }
|
|
|
| +TEST_F(ClickBasedCategoryRankerTest, ShouldDecayClickCountsWithTime) {
|
| + // Add dummy remote categories to ensure that the following categories are not
|
| + // in the top anymore.
|
| + AddUnusedRemoteCategories(
|
| + ClickBasedCategoryRanker::GetNumTopCategoriesWithExtraMargin());
|
| +
|
| + // Non-top categories are added.
|
| + Category first = AddUnusedRemoteCategory();
|
| + Category second = AddUnusedRemoteCategory();
|
| +
|
| + const int first_clicks = 10 * ClickBasedCategoryRanker::GetPassingMargin();
|
| +
|
| + // Simulate the user using the first category for a long time (and not using
|
| + // anything else).
|
| + NotifyOnSuggestionOpened(/*times=*/first_clicks, first);
|
| +
|
| + // Let multiple years pass by.
|
| + auto test_clock = base::MakeUnique<base::SimpleTestClock>();
|
| + base::SimpleTestClock* raw_test_clock = test_clock.get();
|
| + raw_test_clock->SetNow(base::Time::Now() + base::TimeDelta::FromDays(1000));
|
| + // Reset the ranker to pick up the new clock.
|
| + ResetRanker(std::move(test_clock));
|
| +
|
| + // The user behavior changes and they start using the second category instead.
|
| + // According to our requirenments after such a long time it should take less
|
| + // than |first_clicks| for the second category to outperfom the first one.
|
| + int second_clicks = 0;
|
| + while (CompareCategories(first, second) && second_clicks < first_clicks) {
|
| + NotifyOnSuggestionOpened(/*times=*/1, second);
|
| + second_clicks++;
|
| + }
|
| + EXPECT_THAT(second_clicks, testing::Lt(first_clicks));
|
| +}
|
| +
|
| +TEST_F(ClickBasedCategoryRankerTest, ShouldDecayAfterClearHistory) {
|
| + std::vector<KnownCategories> default_order =
|
| + ConstantCategoryRanker::GetKnownCategoriesDefaultOrder();
|
| + Category first = Category::FromKnownCategory(default_order[0]);
|
| + Category second = Category::FromKnownCategory(default_order[1]);
|
| +
|
| + // The user clears entire history.
|
| + ranker()->ClearHistory(/*begin=*/base::Time(),
|
| + /*end=*/base::Time::Max());
|
| +
|
| + // Check whether decay happens by clicking on the first category and
|
| + // waiting.
|
| + const int first_clicks = 10 * ClickBasedCategoryRanker::GetPassingMargin();
|
| + NotifyOnSuggestionOpened(/*times=*/first_clicks, first);
|
| +
|
| + // Let multiple years pass by.
|
| + auto test_clock = base::MakeUnique<base::SimpleTestClock>();
|
| + base::SimpleTestClock* raw_test_clock = test_clock.get();
|
| + raw_test_clock->SetNow(base::Time::Now() + base::TimeDelta::FromDays(1000));
|
| + // Reset the ranker to pick up the new clock.
|
| + ResetRanker(std::move(test_clock));
|
| +
|
| + // It should take less than |first_clicks| for the second category to
|
| + // overtake because of decays.
|
| + int second_clicks = 0;
|
| + while (CompareCategories(first, second) && second_clicks < first_clicks) {
|
| + NotifyOnSuggestionOpened(/*times=*/1, second);
|
| + second_clicks++;
|
| + }
|
| + EXPECT_THAT(second_clicks, testing::Lt(first_clicks));
|
| +}
|
| +
|
| +TEST_F(ClickBasedCategoryRankerTest, ShouldRemoveLastDecayTimeOnClearHistory) {
|
| + ASSERT_NE(ranker()->GetLastDecayTime(), base::Time::FromInternalValue(0));
|
| +
|
| + // The user clears entire history.
|
| + ranker()->ClearHistory(/*begin=*/base::Time(),
|
| + /*end=*/base::Time::Max());
|
| +
|
| + EXPECT_EQ(ranker()->GetLastDecayTime(), base::Time::FromInternalValue(0));
|
| +}
|
| +
|
| +TEST_F(ClickBasedCategoryRankerTest, ShouldPersistLastDecayTimeWhenRestarted) {
|
| + base::Time before = ranker()->GetLastDecayTime();
|
| + ASSERT_NE(before, base::Time::FromInternalValue(0));
|
| +
|
| + // Ensure that |Now()| is different from |before| by injecting our clock.
|
| + auto test_clock = base::MakeUnique<base::SimpleTestClock>();
|
| + test_clock->SetNow(base::Time::Now() + base::TimeDelta::FromSeconds(10));
|
| + ResetRanker(std::move(test_clock));
|
| +
|
| + EXPECT_EQ(before, ranker()->GetLastDecayTime());
|
| +}
|
| +
|
| TEST_F(ClickBasedCategoryRankerTest, ShouldMoveCategoryDownWhenDismissed) {
|
| // Take top categories.
|
| std::vector<KnownCategories> default_order =
|
|
|