tile_utils_unittest.cc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/query_tiles/internal/tile_utils.h"
  5. #include "base/test/scoped_feature_list.h"
  6. #include "components/query_tiles/internal/tile_config.h"
  7. #include "components/query_tiles/internal/tile_group.h"
  8. #include "components/query_tiles/switches.h"
  9. #include "components/query_tiles/test/test_utils.h"
  10. #include "testing/gtest/include/gtest/gtest.h"
  11. namespace query_tiles {
  12. namespace {
  13. // Class to reverse shuffle a list of tiles, starting at a given position.
  14. class ReverseTileShuffler : public TileShuffler {
  15. public:
  16. void Shuffle(std::vector<Tile>* tiles, int start) const override {
  17. std::reverse(tiles->begin() + start, tiles->end());
  18. }
  19. };
  20. // Tests that nothing happens when sorting an empty TileGroup.
  21. TEST(TileUtilsTest, SortEmptyTileGroup) {
  22. TileGroup group;
  23. std::map<std::string, TileStats> tile_stats;
  24. tile_stats["guid-1-3"] = TileStats(group.last_updated_ts, 0.7);
  25. tile_stats["guid-1-4"] = TileStats(group.last_updated_ts, 0.4);
  26. SortTilesAndClearUnusedStats(&group.tiles, &tile_stats);
  27. EXPECT_EQ(tile_stats["guid-1-3"].score, 0.7);
  28. EXPECT_EQ(tile_stats["guid-1-4"].score, 0.4);
  29. }
  30. TEST(TileUtilsTest, Sort) {
  31. TileGroup group;
  32. test::ResetTestGroup(&group);
  33. SortTilesAndClearUnusedStats(&group.tiles, &group.tile_stats);
  34. EXPECT_EQ(group.tiles[0]->id, "guid-1-3");
  35. EXPECT_EQ(group.tiles[1]->id, "guid-1-1");
  36. EXPECT_EQ(group.tiles[2]->id, "guid-1-2");
  37. EXPECT_EQ(group.tiles[1]->sub_tiles[0]->id, "guid-2-2");
  38. EXPECT_EQ(group.tiles[1]->sub_tiles[1]->id, "guid-2-1");
  39. EXPECT_EQ(group.tiles[0]->sub_tiles[0]->id, "guid-1-4");
  40. EXPECT_EQ(group.tiles[1]->sub_tiles[1]->sub_tiles[0]->id, "guid-3-1");
  41. }
  42. TEST(TileUtilsTest, SortWithEmptyTileStats) {
  43. TileGroup group;
  44. test::ResetTestGroup(&group);
  45. std::map<std::string, TileStats> tile_stats;
  46. SortTilesAndClearUnusedStats(&group.tiles, &tile_stats);
  47. EXPECT_EQ(group.tiles[0]->id, "guid-1-1");
  48. EXPECT_EQ(group.tiles[1]->id, "guid-1-2");
  49. EXPECT_EQ(group.tiles[2]->id, "guid-1-3");
  50. EXPECT_EQ(group.tiles[0]->sub_tiles[0]->id, "guid-2-1");
  51. EXPECT_EQ(group.tiles[0]->sub_tiles[1]->id, "guid-2-2");
  52. }
  53. // If new tiles are at the front, tile ordering should be kept after
  54. // sort.
  55. TEST(TileUtilsTest, SortWithNewTilesAtTheFront) {
  56. TileGroup group;
  57. test::ResetTestGroup(&group);
  58. std::map<std::string, TileStats> tile_stats;
  59. tile_stats["guid-1-3"] = TileStats(group.last_updated_ts, 0.7);
  60. tile_stats["guid-1-4"] = TileStats(group.last_updated_ts, 0.4);
  61. tile_stats["guid-2-2"] = TileStats(group.last_updated_ts, 0.6);
  62. SortTilesAndClearUnusedStats(&group.tiles, &tile_stats);
  63. EXPECT_EQ(group.tiles[0]->id, "guid-1-1");
  64. EXPECT_EQ(group.tiles[1]->id, "guid-1-2");
  65. EXPECT_EQ(group.tiles[2]->id, "guid-1-3");
  66. EXPECT_EQ(group.tiles[0]->sub_tiles[0]->id, "guid-2-1");
  67. EXPECT_EQ(group.tiles[0]->sub_tiles[1]->id, "guid-2-2");
  68. // Front tiles should have the minimum score.
  69. EXPECT_EQ(tile_stats["guid-1-1"].score,
  70. TileConfig::GetMinimumScoreForNewFrontTiles());
  71. EXPECT_EQ(tile_stats["guid-1-2"].score,
  72. TileConfig::GetMinimumScoreForNewFrontTiles());
  73. EXPECT_EQ(tile_stats["guid-2-1"].score,
  74. TileConfig::GetMinimumScoreForNewFrontTiles());
  75. }
  76. // If new tiles are at the end, tile ordering should be kept after
  77. // sort.
  78. TEST(TileUtilsTest, SortWithNewTilesAtTheEnd) {
  79. TileGroup group;
  80. test::ResetTestGroup(&group);
  81. std::map<std::string, TileStats> tile_stats;
  82. tile_stats["guid-1-1"] = TileStats(group.last_updated_ts, 0.5);
  83. tile_stats["guid-1-2"] = TileStats(group.last_updated_ts, 0.2);
  84. tile_stats["guid-2-1"] = TileStats(group.last_updated_ts, 0.3);
  85. SortTilesAndClearUnusedStats(&group.tiles, &tile_stats);
  86. EXPECT_EQ(group.tiles[0]->id, "guid-1-1");
  87. EXPECT_EQ(group.tiles[1]->id, "guid-1-2");
  88. EXPECT_EQ(group.tiles[2]->id, "guid-1-3");
  89. EXPECT_EQ(group.tiles[0]->sub_tiles[0]->id, "guid-2-1");
  90. EXPECT_EQ(group.tiles[0]->sub_tiles[1]->id, "guid-2-2");
  91. EXPECT_EQ(tile_stats["guid-1-3"].score, 0);
  92. EXPECT_EQ(tile_stats["guid-2-2"].score, 0);
  93. }
  94. // Test the case that new tiles are in the middle.
  95. TEST(TileUtilsTest, SortWithNewTilesInTheMiddle) {
  96. TileGroup group;
  97. test::ResetTestGroup(&group);
  98. std::map<std::string, TileStats> tile_stats;
  99. tile_stats["guid-1-1"] = TileStats(group.last_updated_ts, 0.5);
  100. tile_stats["guid-1-3"] = TileStats(group.last_updated_ts, 0.7);
  101. SortTilesAndClearUnusedStats(&group.tiles, &tile_stats);
  102. EXPECT_EQ(group.tiles[0]->id, "guid-1-3");
  103. EXPECT_EQ(group.tiles[1]->id, "guid-1-1");
  104. EXPECT_EQ(group.tiles[2]->id, "guid-1-2");
  105. EXPECT_EQ(tile_stats["guid-1-2"].score, 0.5);
  106. EXPECT_EQ(tile_stats["guid-1-2"].last_clicked_time, group.last_updated_ts);
  107. }
  108. // Tiles that are not clicked recently should be placed to the end.
  109. TEST(TileUtilsTest, SortWithTilesNotClickedRecently) {
  110. TileGroup group;
  111. test::ResetTestGroup(&group);
  112. base::Time past_time = base::Time::Now() - base::Days(30);
  113. std::map<std::string, TileStats> tile_stats;
  114. tile_stats["guid-1-1"] = TileStats(group.last_updated_ts, 0.5);
  115. tile_stats["guid-1-2"] = TileStats(past_time, 0.5);
  116. tile_stats["guid-1-3"] = TileStats(group.last_updated_ts, 0.2);
  117. tile_stats["guid-2-1"] = TileStats(past_time, 0.3);
  118. tile_stats["guid-2-2"] = TileStats(group.last_updated_ts, 0.3);
  119. SortTilesAndClearUnusedStats(&group.tiles, &tile_stats);
  120. EXPECT_EQ(group.tiles[0]->id, "guid-1-1");
  121. EXPECT_EQ(group.tiles[1]->id, "guid-1-3");
  122. EXPECT_EQ(group.tiles[2]->id, "guid-1-2");
  123. EXPECT_EQ(group.tiles[0]->sub_tiles[0]->id, "guid-2-2");
  124. EXPECT_EQ(group.tiles[0]->sub_tiles[1]->id, "guid-2-1");
  125. }
  126. // Test the case that stats for unused tiles are cleared.
  127. TEST(TileUtilsTest, UnusedTilesCleared) {
  128. TileGroup group;
  129. test::ResetTestGroup(&group);
  130. std::string recently_unsed_tile_id = "guid-x-recent";
  131. std::string unsed_tile_id = "guid-x";
  132. std::map<std::string, TileStats> tile_stats;
  133. tile_stats["guid-1-1"] = TileStats(group.last_updated_ts, 0.5);
  134. tile_stats["guid-1-3"] = TileStats(group.last_updated_ts, 0.7);
  135. // Stats for tiles that no longer appear in group.tiles.
  136. tile_stats[unsed_tile_id] =
  137. TileStats(group.last_updated_ts - base::Days(30), 0.1);
  138. tile_stats[recently_unsed_tile_id] = TileStats(group.last_updated_ts, 0.1);
  139. SortTilesAndClearUnusedStats(&group.tiles, &tile_stats);
  140. EXPECT_EQ(group.tiles[0]->id, "guid-1-3");
  141. EXPECT_EQ(group.tiles[1]->id, "guid-1-1");
  142. EXPECT_EQ(group.tiles[2]->id, "guid-1-2");
  143. // Only tiles that are no longer clicked recently will be cleared.
  144. EXPECT_TRUE(tile_stats.find(recently_unsed_tile_id) != tile_stats.end());
  145. EXPECT_TRUE(tile_stats.find(unsed_tile_id) == tile_stats.end());
  146. }
  147. TEST(TileUtilsTest, CalculateTileScore) {
  148. base::Time now_time = base::Time::Now();
  149. EXPECT_EQ(CalculateTileScore(TileStats(now_time, 0.7), now_time), 0.7);
  150. EXPECT_EQ(
  151. CalculateTileScore(TileStats(now_time, 1.0), now_time + base::Hours(18)),
  152. 1.0);
  153. EXPECT_EQ(
  154. CalculateTileScore(TileStats(now_time, 1.0), now_time + base::Days(1)),
  155. exp(-0.099));
  156. EXPECT_EQ(
  157. CalculateTileScore(TileStats(now_time, 1.0), now_time + base::Days(30)),
  158. 0);
  159. }
  160. TEST(TileUtilsTest, IsTrendingTile) {
  161. EXPECT_TRUE(IsTrendingTile("trending_news"));
  162. EXPECT_FALSE(IsTrendingTile("Trending_news"));
  163. EXPECT_FALSE(IsTrendingTile("trendingnews"));
  164. EXPECT_FALSE(IsTrendingTile("news"));
  165. }
  166. TEST(TileUtilsTest, ShuffleTiles) {
  167. std::vector<Tile> tiles;
  168. Tile tile1;
  169. tile1.id = "t1";
  170. Tile tile2;
  171. tile2.id = "t2";
  172. Tile tile3;
  173. tile3.id = "t3";
  174. Tile tile4;
  175. tile4.id = "t4";
  176. tiles.push_back(tile1);
  177. tiles.push_back(tile2);
  178. tiles.push_back(tile3);
  179. tiles.push_back(tile4);
  180. ShuffleTiles(&tiles, ReverseTileShuffler());
  181. EXPECT_EQ(tiles[0].id, "t1");
  182. EXPECT_EQ(tiles[1].id, "t2");
  183. EXPECT_EQ(tiles[2].id, "t4");
  184. EXPECT_EQ(tiles[3].id, "t3");
  185. }
  186. } // namespace
  187. } // namespace query_tiles