chromium/chrome/browser/ash/app_list/search/ranking/mrfu_ranker_unittest.cc

// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/app_list/search/ranking/mrfu_ranker.h"

#include "chrome/browser/ash/app_list/search/chrome_search_result.h"
#include "chrome/browser/ash/app_list/search/ranking/ranker.h"
#include "chrome/browser/ash/app_list/search/search_controller.h"
#include "chrome/browser/ash/app_list/search/test/ranking_test_util.h"
#include "chrome/browser/ash/app_list/search/types.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace app_list::test {
namespace {

using testing::ElementsAre;

}  // namespace

// MrfuResultRanker ------------------------------------------------------------

class MrfuResultRankerTest : public RankerTestBase {};

TEST_F(MrfuResultRankerTest, TrainAndRank) {
  MrfuResultRanker ranker(MrfuCache::Params(),
                          MrfuCache::Proto(GetPath(), base::Seconds(0)));
  Wait();

  // Train on some results.
  ranker.Train(MakeLaunchData("a"));
  ranker.Train(MakeLaunchData("b"));
  ranker.Train(MakeLaunchData("c"));
  ranker.Train(MakeLaunchData("a"));

  ResultsMap results;
  results[ResultType::kInstalledApp] = MakeResults({"a", "b"});
  results[ResultType::kOsSettings] = MakeResults({"c", "d"});
  CategoriesList categories;

  // Rank them, expecting ordering a > c > b > d.
  ranker.Start(u"query", categories);
  auto ab_scores = ranker.GetResultRanks(results, ResultType::kInstalledApp);
  auto cd_scores = ranker.GetResultRanks(results, ResultType::kOsSettings);
  EXPECT_GT(ab_scores[0], cd_scores[0]);
  EXPECT_GT(cd_scores[0], ab_scores[1]);
  EXPECT_GT(ab_scores[1], cd_scores[1]);
}

// MrfuCategoryRanker ----------------------------------------------------------

class MrfuCategoryRankerTest : public RankerTestBase {};

TEST_F(MrfuCategoryRankerTest, DefaultCategoryScores) {
  MrfuCategoryRanker ranker(MrfuCache::Params(),
                            MrfuCache::Proto(GetPath(), base::Seconds(0)));
  Wait();

  ResultsMap results;
  // The following categories of results have default category scores.
  results[ResultType::kInstalledApp] =
      MakeResults({"apps"}, ResultType::kInstalledApp, Category::kApps);
  results[ResultType::kPlayStoreApp] = MakeResults(
      {"playstore"}, ResultType::kPlayStoreApp, Category::kPlayStore);
  results[ResultType::kOsSettings] =
      MakeResults({"settings"}, ResultType::kOsSettings, Category::kSettings);
  results[ResultType::kOmnibox] =
      MakeResults({"omnibox"}, ResultType::kOmnibox, Category::kWeb);
  results[ResultType::kFileSearch] =
      MakeResults({"files"}, ResultType::kFileSearch, Category::kFiles);
  results[ResultType::kKeyboardShortcut] = MakeResults(
      {"shortcuts"}, ResultType::kKeyboardShortcut, Category::kHelp);

  // The following categories of results do not have default category scores.
  results[ResultType::kAssistantText] = MakeResults(
      {"g"}, ResultType::kAssistantText, Category::kSearchAndAssistant);
  results[ResultType::kArcAppShortcut] =
      MakeResults({"h"}, ResultType::kArcAppShortcut, Category::kAppShortcuts);

  CategoriesList categories({{.category = Category::kApps},
                             {.category = Category::kPlayStore},
                             {.category = Category::kSettings},
                             {.category = Category::kWeb},
                             {.category = Category::kFiles},
                             {.category = Category::kHelp},
                             {.category = Category::kSearchAndAssistant},
                             {.category = Category::kAppShortcuts}});
  ranker.Start(u"query", categories);
  auto scores =
      ranker.GetCategoryRanks(results, categories, ResultType::kInstalledApp);
  ASSERT_EQ(scores.size(), 8u);

  // Expect the first six categories of |categories| to be ranked in descending
  // order.
  EXPECT_GT(scores[0], scores[1]);
  EXPECT_GT(scores[1], scores[2]);
  EXPECT_GT(scores[2], scores[3]);
  EXPECT_GT(scores[3], scores[4]);
  EXPECT_GT(scores[4], scores[5]);

  // Expect the remaining two categories to be ranked below the first six. Note
  // that the default ranking between these two is not defined.
  EXPECT_GT(scores[5], scores[6]);
  EXPECT_GT(scores[5], scores[7]);
}

TEST_F(MrfuCategoryRankerTest, TrainAndRank) {
  MrfuCategoryRanker ranker(MrfuCache::Params(),
                            MrfuCache::Proto(GetPath(), base::Seconds(0)));
  Wait();

  // Train so that settings should be first, followed by apps.
  ranker.Train(MakeLaunchData("a", Category::kApps));
  ranker.Train(MakeLaunchData("c", Category::kSettings));
  ranker.Train(MakeLaunchData("d", Category::kSettings));
  ranker.Train(MakeLaunchData("b", Category::kApps));

  ResultsMap results;
  results[ResultType::kInstalledApp] =
      MakeResults({"a", "b"}, ResultType::kInstalledApp, Category::kApps);
  results[ResultType::kOsSettings] =
      MakeResults({"c", "d"}, ResultType::kOsSettings, Category::kSettings);
  results[ResultType::kFileSearch] =
      MakeResults({"e", "f"}, ResultType::kFileSearch, Category::kFiles);
  CategoriesList categories({{.category = Category::kApps},
                             {.category = Category::kSettings},
                             {.category = Category::kFiles}});

  // Expect a ranking of kInstalledApp > kOsSettings > kFileSearch.
  ranker.Start(u"query", categories);
  auto scores =
      ranker.GetCategoryRanks(results, categories, ResultType::kInstalledApp);
  ASSERT_EQ(scores.size(), 3u);
  EXPECT_GT(scores[0], scores[1]);
  EXPECT_GT(scores[1], scores[2]);
}

}  // namespace app_list::test