| 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
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fc1cb55d57a69efadfb8076f1298a5621c3c7e7b
|
| --- /dev/null
|
| +++ b/components/ntp_snippets/category_rankers/click_based_category_ranker_unittest.cc
|
| @@ -0,0 +1,229 @@
|
| +// Copyright 2016 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/ntp_snippets/category_rankers/click_based_category_ranker.h"
|
| +
|
| +#include "base/memory/ptr_util.h"
|
| +#include "components/ntp_snippets/category.h"
|
| +#include "components/ntp_snippets/category_rankers/constant_category_ranker.h"
|
| +#include "components/prefs/testing_pref_service.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace ntp_snippets {
|
| +
|
| +class ClickBasedCategoryRankerTest : public testing::Test {
|
| + public:
|
| + ClickBasedCategoryRankerTest()
|
| + : pref_service_(base::MakeUnique<TestingPrefServiceSimple>()),
|
| + unused_remote_category_id_(
|
| + static_cast<int>(KnownCategories::LAST_KNOWN_REMOTE_CATEGORY) + 1) {
|
| + ClickBasedCategoryRanker::RegisterProfilePrefs(pref_service_->registry());
|
| +
|
| + ranker_ = base::MakeUnique<ClickBasedCategoryRanker>(pref_service_.get());
|
| + }
|
| +
|
| + int GetUnusedRemoteCategoryID() { return unused_remote_category_id_++; }
|
| +
|
| + Category GetUnusedRemoteCategory() {
|
| + return Category::FromIDValue(GetUnusedRemoteCategoryID());
|
| + }
|
| +
|
| + bool CompareCategories(const Category& left, const Category& right) {
|
| + return ranker()->Compare(left, right);
|
| + }
|
| +
|
| + Category AddUnusedRemoteCategory() {
|
| + Category category = GetUnusedRemoteCategory();
|
| + ranker()->AppendCategoryIfNecessary(category);
|
| + return category;
|
| + }
|
| +
|
| + void AddUnusedRemoteCategories(int quantity) {
|
| + for (int i = 0; i < quantity; ++i) {
|
| + AddUnusedRemoteCategory();
|
| + }
|
| + }
|
| +
|
| + void ResetRanker() {
|
| + ranker_ = base::MakeUnique<ClickBasedCategoryRanker>(pref_service_.get());
|
| + }
|
| +
|
| + void NotifyOnSuggestionOpened(int times, Category category) {
|
| + for (int i = 0; i < times; ++i) {
|
| + ranker()->OnSuggestionOpened(category);
|
| + }
|
| + }
|
| +
|
| + ClickBasedCategoryRanker* ranker() { return ranker_.get(); }
|
| +
|
| + private:
|
| + std::unique_ptr<TestingPrefServiceSimple> pref_service_;
|
| + int unused_remote_category_id_;
|
| + std::unique_ptr<ClickBasedCategoryRanker> ranker_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ClickBasedCategoryRankerTest);
|
| +};
|
| +
|
| +TEST_F(ClickBasedCategoryRankerTest, ShouldSortRemoteCategoriesByWhenAdded) {
|
| + const Category first = GetUnusedRemoteCategory();
|
| + const Category second = GetUnusedRemoteCategory();
|
| + // Categories are added in decreasing id order to test that they are not
|
| + // compared by id.
|
| + ranker()->AppendCategoryIfNecessary(second);
|
| + ranker()->AppendCategoryIfNecessary(first);
|
| + EXPECT_TRUE(CompareCategories(second, first));
|
| + EXPECT_FALSE(CompareCategories(first, second));
|
| +}
|
| +
|
| +TEST_F(ClickBasedCategoryRankerTest, ShouldSortLocalCategoriesBeforeRemote) {
|
| + const Category remote_category = AddUnusedRemoteCategory();
|
| + const Category local_category =
|
| + Category::FromKnownCategory(KnownCategories::BOOKMARKS);
|
| + EXPECT_TRUE(CompareCategories(local_category, remote_category));
|
| + EXPECT_FALSE(CompareCategories(remote_category, local_category));
|
| +}
|
| +
|
| +TEST_F(ClickBasedCategoryRankerTest,
|
| + CompareShouldReturnFalseForSameCategories) {
|
| + const Category remote_category = AddUnusedRemoteCategory();
|
| + EXPECT_FALSE(CompareCategories(remote_category, remote_category));
|
| +
|
| + const Category local_category =
|
| + Category::FromKnownCategory(KnownCategories::BOOKMARKS);
|
| + EXPECT_FALSE(CompareCategories(local_category, local_category));
|
| +}
|
| +
|
| +TEST_F(ClickBasedCategoryRankerTest,
|
| + AddingMoreRemoteCategoriesShouldNotChangePreviousOrder) {
|
| + AddUnusedRemoteCategories(3);
|
| +
|
| + Category first = AddUnusedRemoteCategory();
|
| + Category second = AddUnusedRemoteCategory();
|
| +
|
| + ASSERT_TRUE(CompareCategories(first, second));
|
| + ASSERT_FALSE(CompareCategories(second, first));
|
| +
|
| + AddUnusedRemoteCategories(3);
|
| +
|
| + EXPECT_TRUE(CompareCategories(first, second));
|
| + EXPECT_FALSE(CompareCategories(second, first));
|
| +}
|
| +
|
| +TEST_F(ClickBasedCategoryRankerTest, ShouldChangeOrderOfNonTopCategories) {
|
| + // Add dummy remote categories to ensure that the following categories are not
|
| + // in the top anymore.
|
| + AddUnusedRemoteCategories(
|
| + ClickBasedCategoryRanker::GetNumTopCategoriesWithExtraMargin());
|
| +
|
| + Category first = AddUnusedRemoteCategory();
|
| + Category second = AddUnusedRemoteCategory();
|
| +
|
| + ASSERT_TRUE(CompareCategories(first, second));
|
| + ASSERT_FALSE(CompareCategories(second, first));
|
| +
|
| + NotifyOnSuggestionOpened(
|
| + /*times=*/ClickBasedCategoryRanker::GetPassingMargin(), second);
|
| +
|
| + EXPECT_TRUE(CompareCategories(second, first));
|
| + EXPECT_FALSE(CompareCategories(first, second));
|
| +}
|
| +
|
| +TEST_F(ClickBasedCategoryRankerTest,
|
| + ShouldNotChangeOrderRightAfterOrderChange) {
|
| + // Add dummy remote categories to ensure that the following categories are not
|
| + // in the top anymore.
|
| + AddUnusedRemoteCategories(
|
| + ClickBasedCategoryRanker::GetNumTopCategoriesWithExtraMargin());
|
| +
|
| + // Two non-top categories are added.
|
| + Category first = AddUnusedRemoteCategory();
|
| + Category second = AddUnusedRemoteCategory();
|
| + ASSERT_TRUE(CompareCategories(first, second));
|
| + ASSERT_FALSE(CompareCategories(second, first));
|
| + // Their order is changed.
|
| + NotifyOnSuggestionOpened(
|
| + /*times=*/ClickBasedCategoryRanker::GetPassingMargin(), second);
|
| + ASSERT_TRUE(CompareCategories(second, first));
|
| + ASSERT_FALSE(CompareCategories(first, second));
|
| +
|
| + // Click on the lower category.
|
| + NotifyOnSuggestionOpened(/*times=*/1, first);
|
| +
|
| + // Order should not change.
|
| + EXPECT_TRUE(CompareCategories(second, first));
|
| + EXPECT_FALSE(CompareCategories(first, second));
|
| +}
|
| +
|
| +TEST_F(ClickBasedCategoryRankerTest,
|
| + ShouldNotMoveCategoryMoreThanOncePerClick) {
|
| + // 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();
|
| + Category third = AddUnusedRemoteCategory();
|
| +
|
| + // Move the third category up.
|
| + NotifyOnSuggestionOpened(
|
| + /*times=*/ClickBasedCategoryRanker::GetPassingMargin(), third);
|
| + EXPECT_TRUE(CompareCategories(third, second));
|
| + // But only on one position even though the first category has low counts.
|
| + EXPECT_TRUE(CompareCategories(first, third));
|
| + // However, another click must move it further.
|
| + NotifyOnSuggestionOpened(/*times=*/1, third);
|
| + EXPECT_TRUE(CompareCategories(third, first));
|
| +}
|
| +
|
| +TEST_F(ClickBasedCategoryRankerTest,
|
| + ShouldNotMoveTopCategoryRightAfterThreshold) {
|
| + ASSERT_GE(ClickBasedCategoryRanker::GetNumTopCategoriesWithExtraMargin(), 1);
|
| +
|
| + // At least one top category is added from the default order.
|
| + std::vector<KnownCategories> default_order =
|
| + ConstantCategoryRanker::GetKnownCategoriesDefaultOrder();
|
| + Category first = Category::FromKnownCategory(default_order[0]);
|
| + Category second = Category::FromKnownCategory(default_order[1]);
|
| +
|
| + // Try to move the second category up as if the first category was non-top.
|
| + NotifyOnSuggestionOpened(
|
| + /*times=*/ClickBasedCategoryRanker::GetPassingMargin(), second);
|
| +
|
| + // Nothing should change, because the first category is top.
|
| + EXPECT_TRUE(CompareCategories(first, second));
|
| +}
|
| +
|
| +TEST_F(ClickBasedCategoryRankerTest, ShouldPersistOrderAndClicksWhenRestarted) {
|
| + // 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();
|
| + Category third = AddUnusedRemoteCategory();
|
| +
|
| + // Change the order.
|
| + NotifyOnSuggestionOpened(
|
| + /*times=*/ClickBasedCategoryRanker::GetPassingMargin(), third);
|
| + ASSERT_TRUE(CompareCategories(third, second));
|
| + ASSERT_TRUE(CompareCategories(first, third));
|
| +
|
| + // Simulate Chrome restart.
|
| + ResetRanker();
|
| +
|
| + // The old order must be preserved.
|
| + EXPECT_TRUE(CompareCategories(third, second));
|
| +
|
| + // Clicks must be preserved as well.
|
| + NotifyOnSuggestionOpened(
|
| + /*times=*/1, third);
|
| + EXPECT_TRUE(CompareCategories(third, first));
|
| +}
|
| +
|
| +} // namespace ntp_snippets
|
|
|