custom_links_manager_impl_unittest.cc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. // Copyright 2018 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/ntp_tiles/custom_links_manager_impl.h"
  5. #include <stdint.h>
  6. #include <memory>
  7. #include "base/files/scoped_temp_dir.h"
  8. #include "base/strings/utf_string_conversions.h"
  9. #include "base/test/mock_callback.h"
  10. #include "base/test/task_environment.h"
  11. #include "components/history/core/test/history_service_test_util.h"
  12. #include "components/ntp_tiles/pref_names.h"
  13. #include "components/sync_preferences/testing_pref_service_syncable.h"
  14. #include "extensions/buildflags/buildflags.h"
  15. #include "testing/gtest/include/gtest/gtest.h"
  16. using Link = ntp_tiles::CustomLinksManager::Link;
  17. using sync_preferences::TestingPrefServiceSyncable;
  18. namespace ntp_tiles {
  19. namespace {
  20. struct TestCaseItem {
  21. const char* url;
  22. const char16_t* title;
  23. };
  24. const TestCaseItem kTestCase1[] = {{"http://foo1.com/", u"Foo1"}};
  25. const TestCaseItem kTestCase2[] = {
  26. {"http://foo1.com/", u"Foo1"},
  27. {"http://foo2.com/", u"Foo2"},
  28. };
  29. const TestCaseItem kTestCase3[] = {
  30. {"http://foo1.com/", u"Foo1"},
  31. {"http://foo2.com/", u"Foo2"},
  32. {"http://foo3.com/", u"Foo3"},
  33. };
  34. const TestCaseItem kTestCaseMax[] = {
  35. {"http://foo1.com/", u"Foo1"}, {"http://foo2.com/", u"Foo2"},
  36. {"http://foo3.com/", u"Foo3"}, {"http://foo4.com/", u"Foo4"},
  37. {"http://foo5.com/", u"Foo5"}, {"http://foo6.com/", u"Foo6"},
  38. {"http://foo7.com/", u"Foo7"}, {"http://foo8.com/", u"Foo8"},
  39. {"http://foo9.com/", u"Foo9"}, {"http://foo10.com/", u"Foo10"},
  40. };
  41. const char kTestTitle[] = "Test";
  42. const char16_t kTestTitle16[] = u"Test";
  43. const char kTestUrl[] = "http://test.com/";
  44. #if BUILDFLAG(ENABLE_EXTENSIONS)
  45. const char16_t kTestGmail16[] = u"Gmail";
  46. const char kTestGmailURL[] =
  47. "chrome-extension://pjkljhegncpnkpknbcohdijeoejaedia/index.html";
  48. #endif
  49. base::Value::List FillTestList(const char* url,
  50. const char* title,
  51. const bool is_most_visited) {
  52. base::Value::List new_link_list;
  53. base::Value::Dict new_link;
  54. new_link.Set("url", url);
  55. new_link.Set("title", title);
  56. new_link.Set("isMostVisited", is_most_visited);
  57. new_link_list.Append(std::move(new_link));
  58. return new_link_list;
  59. }
  60. void AddTile(NTPTilesVector* tiles, const char* url, const char16_t* title) {
  61. NTPTile tile;
  62. tile.url = GURL(url);
  63. tile.title = title;
  64. tiles->push_back(std::move(tile));
  65. }
  66. NTPTilesVector FillTestTiles(base::span<const TestCaseItem> test_cases) {
  67. NTPTilesVector tiles;
  68. for (const auto& test_case : test_cases) {
  69. AddTile(&tiles, test_case.url, test_case.title);
  70. }
  71. return tiles;
  72. }
  73. std::vector<Link> FillTestLinks(base::span<const TestCaseItem> test_cases) {
  74. std::vector<Link> links;
  75. for (const auto& test_case : test_cases) {
  76. links.emplace_back(Link{GURL(test_case.url), test_case.title, true});
  77. }
  78. return links;
  79. }
  80. } // namespace
  81. class CustomLinksManagerImplTest : public testing::Test {
  82. public:
  83. CustomLinksManagerImplTest() {
  84. CustomLinksManagerImpl::RegisterProfilePrefs(prefs_.registry());
  85. base::Value::List defaults;
  86. defaults.Append("pjkljhegncpnkpknbcohdijeoejaedia");
  87. prefs_.registry()->RegisterListPref(
  88. webapps::kWebAppsMigratedPreinstalledApps,
  89. base::Value(std::move(defaults)));
  90. }
  91. CustomLinksManagerImplTest(const CustomLinksManagerImplTest&) = delete;
  92. CustomLinksManagerImplTest& operator=(const CustomLinksManagerImplTest&) =
  93. delete;
  94. void SetUp() override {
  95. ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
  96. history_service_ = history::CreateHistoryService(scoped_temp_dir_.GetPath(),
  97. /*create_db=*/false);
  98. custom_links_ = std::make_unique<CustomLinksManagerImpl>(
  99. &prefs_, history_service_.get());
  100. }
  101. protected:
  102. base::ScopedTempDir scoped_temp_dir_;
  103. base::test::TaskEnvironment task_environment_;
  104. sync_preferences::TestingPrefServiceSyncable prefs_;
  105. std::unique_ptr<history::HistoryService> history_service_;
  106. std::unique_ptr<CustomLinksManagerImpl> custom_links_;
  107. };
  108. TEST_F(CustomLinksManagerImplTest, InitializeOnlyOnce) {
  109. ASSERT_FALSE(custom_links_->IsInitialized());
  110. ASSERT_TRUE(custom_links_->GetLinks().empty());
  111. // Initialize.
  112. std::vector<Link> initial_links = FillTestLinks(kTestCase1);
  113. EXPECT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  114. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  115. // Try to initialize again. This should fail and leave the links intact.
  116. EXPECT_FALSE(custom_links_->Initialize(FillTestTiles(kTestCase2)));
  117. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  118. }
  119. TEST_F(CustomLinksManagerImplTest, UninitializeDeletesOldLinks) {
  120. // Initialize.
  121. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  122. ASSERT_EQ(FillTestLinks(kTestCase1), custom_links_->GetLinks());
  123. custom_links_->Uninitialize();
  124. EXPECT_TRUE(custom_links_->GetLinks().empty());
  125. // Initialize with no links.
  126. EXPECT_TRUE(custom_links_->Initialize(NTPTilesVector()));
  127. EXPECT_TRUE(custom_links_->GetLinks().empty());
  128. }
  129. TEST_F(CustomLinksManagerImplTest, ReInitializeWithNewLinks) {
  130. // Initialize.
  131. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  132. ASSERT_EQ(FillTestLinks(kTestCase1), custom_links_->GetLinks());
  133. custom_links_->Uninitialize();
  134. ASSERT_TRUE(custom_links_->GetLinks().empty());
  135. // Initialize with new links.
  136. EXPECT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase2)));
  137. EXPECT_EQ(FillTestLinks(kTestCase2), custom_links_->GetLinks());
  138. }
  139. TEST_F(CustomLinksManagerImplTest, AddLink) {
  140. // Initialize.
  141. std::vector<Link> initial_links = FillTestLinks(kTestCase1);
  142. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  143. ASSERT_EQ(initial_links, custom_links_->GetLinks());
  144. // Add link.
  145. std::vector<Link> expected_links = initial_links;
  146. expected_links.emplace_back(Link{GURL(kTestUrl), kTestTitle16, false});
  147. EXPECT_TRUE(custom_links_->AddLink(GURL(kTestUrl), kTestTitle16));
  148. EXPECT_EQ(expected_links, custom_links_->GetLinks());
  149. }
  150. TEST_F(CustomLinksManagerImplTest, AddLinkWhenAtMaxLinks) {
  151. // Initialize.
  152. std::vector<Link> initial_links = FillTestLinks(kTestCaseMax);
  153. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCaseMax)));
  154. ASSERT_EQ(initial_links, custom_links_->GetLinks());
  155. // Try to add link. This should fail and not modify the list.
  156. EXPECT_FALSE(custom_links_->AddLink(GURL(kTestUrl), kTestTitle16));
  157. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  158. }
  159. TEST_F(CustomLinksManagerImplTest, AddDuplicateLink) {
  160. // Initialize.
  161. std::vector<Link> initial_links = FillTestLinks(kTestCase1);
  162. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  163. ASSERT_EQ(initial_links, custom_links_->GetLinks());
  164. // Try to add duplicate link. This should fail and not modify the list.
  165. EXPECT_FALSE(
  166. custom_links_->AddLink(GURL(kTestCase1[0].url), kTestCase1[0].title));
  167. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  168. }
  169. TEST_F(CustomLinksManagerImplTest, UpdateLink) {
  170. // Initialize.
  171. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  172. ASSERT_EQ(FillTestLinks(kTestCase1), custom_links_->GetLinks());
  173. // Update the link's URL.
  174. EXPECT_TRUE(custom_links_->UpdateLink(GURL(kTestCase1[0].url), GURL(kTestUrl),
  175. std::u16string()));
  176. EXPECT_EQ(
  177. std::vector<Link>({Link{GURL(kTestUrl), kTestCase1[0].title, false}}),
  178. custom_links_->GetLinks());
  179. // Update the link's title.
  180. EXPECT_TRUE(custom_links_->UpdateLink(GURL(kTestUrl), GURL(), kTestTitle16));
  181. EXPECT_EQ(std::vector<Link>({Link{GURL(kTestUrl), kTestTitle16, false}}),
  182. custom_links_->GetLinks());
  183. // Update the link's URL and title.
  184. EXPECT_TRUE(custom_links_->UpdateLink(GURL(kTestUrl), GURL(kTestCase1[0].url),
  185. kTestCase1[0].title));
  186. EXPECT_EQ(std::vector<Link>(
  187. {Link{GURL(kTestCase1[0].url), kTestCase1[0].title, false}}),
  188. custom_links_->GetLinks());
  189. }
  190. TEST_F(CustomLinksManagerImplTest, UpdateLinkWithInvalidParams) {
  191. // Initialize.
  192. std::vector<Link> initial_links = FillTestLinks(kTestCase1);
  193. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  194. ASSERT_EQ(initial_links, custom_links_->GetLinks());
  195. // Try to update a link that does not exist. This should fail and not modify
  196. // the list.
  197. EXPECT_FALSE(custom_links_->UpdateLink(GURL(kTestUrl), GURL(), kTestTitle16));
  198. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  199. // Try to pass empty params. This should fail and not modify the list.
  200. EXPECT_FALSE(custom_links_->UpdateLink(GURL(kTestCase1[0].url), GURL(),
  201. std::u16string()));
  202. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  203. // Try to pass an invalid URL. This should fail and not modify the list.
  204. EXPECT_FALSE(custom_links_->UpdateLink(GURL("test"), GURL(), kTestTitle16));
  205. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  206. EXPECT_FALSE(custom_links_->UpdateLink(GURL(kTestCase1[0].url), GURL("test"),
  207. std::u16string()));
  208. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  209. }
  210. TEST_F(CustomLinksManagerImplTest, UpdateLinkWhenUrlAlreadyExists) {
  211. // Initialize.
  212. std::vector<Link> initial_links = FillTestLinks(kTestCase2);
  213. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase2)));
  214. ASSERT_EQ(initial_links, custom_links_->GetLinks());
  215. // Try to update a link with a URL that exists in the list. This should fail
  216. // and not modify the list.
  217. EXPECT_FALSE(custom_links_->UpdateLink(
  218. GURL(kTestCase2[0].url), GURL(kTestCase2[1].url), std::u16string()));
  219. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  220. }
  221. TEST_F(CustomLinksManagerImplTest, ReorderLink) {
  222. // Initialize.
  223. std::vector<Link> initial_links = FillTestLinks(kTestCase3);
  224. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase3)));
  225. ASSERT_EQ(initial_links, custom_links_->GetLinks());
  226. // Try to call reorder with the current index. This should fail and not modify
  227. // the list.
  228. EXPECT_FALSE(custom_links_->ReorderLink(GURL(kTestCase3[2].url), (size_t)2));
  229. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  230. // Try to call reorder with an invalid index. This should fail and not modify
  231. // the list.
  232. EXPECT_FALSE(custom_links_->ReorderLink(GURL(kTestCase3[2].url), (size_t)-1));
  233. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  234. EXPECT_FALSE(custom_links_->ReorderLink(GURL(kTestCase3[2].url),
  235. initial_links.size()));
  236. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  237. // Try to call reorder with an invalid URL. This should fail and not modify
  238. // the list.
  239. EXPECT_FALSE(custom_links_->ReorderLink(GURL(kTestUrl), 0));
  240. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  241. EXPECT_FALSE(custom_links_->ReorderLink(GURL("test"), 0));
  242. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  243. // Move the last link to the front.
  244. EXPECT_TRUE(custom_links_->ReorderLink(GURL(kTestCase3[2].url), (size_t)0));
  245. EXPECT_EQ(std::vector<Link>(
  246. {Link{GURL(kTestCase3[2].url), kTestCase3[2].title, true},
  247. Link{GURL(kTestCase3[0].url), kTestCase3[0].title, true},
  248. Link{GURL(kTestCase3[1].url), kTestCase3[1].title, true}}),
  249. custom_links_->GetLinks());
  250. // Move the same link to the right.
  251. EXPECT_TRUE(custom_links_->ReorderLink(GURL(kTestCase3[2].url), (size_t)1));
  252. EXPECT_EQ(std::vector<Link>(
  253. {Link{GURL(kTestCase3[0].url), kTestCase3[0].title, true},
  254. Link{GURL(kTestCase3[2].url), kTestCase3[2].title, true},
  255. Link{GURL(kTestCase3[1].url), kTestCase3[1].title, true}}),
  256. custom_links_->GetLinks());
  257. // Move the same link to the end.
  258. EXPECT_TRUE(custom_links_->ReorderLink(GURL(kTestCase3[2].url), (size_t)2));
  259. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  260. }
  261. TEST_F(CustomLinksManagerImplTest, DeleteLink) {
  262. // Initialize.
  263. NTPTilesVector initial_tiles;
  264. AddTile(&initial_tiles, kTestUrl, kTestTitle16);
  265. ASSERT_TRUE(custom_links_->Initialize(initial_tiles));
  266. ASSERT_EQ(std::vector<Link>({Link{GURL(kTestUrl), kTestTitle16, true}}),
  267. custom_links_->GetLinks());
  268. // Delete link.
  269. EXPECT_TRUE(custom_links_->DeleteLink(GURL(kTestUrl)));
  270. EXPECT_TRUE(custom_links_->GetLinks().empty());
  271. }
  272. // The following tests include a default chrome app; these tests are only
  273. // relevant if extensions and apps are enabled.
  274. #if BUILDFLAG(ENABLE_EXTENSIONS)
  275. TEST_F(CustomLinksManagerImplTest, MigratedDefaultAppDeletedSingle) {
  276. NTPTilesVector initial_tiles;
  277. AddTile(&initial_tiles, kTestGmailURL, kTestGmail16);
  278. // Initialize tile with Gmail URL and then remove them.
  279. ASSERT_TRUE(custom_links_->Initialize(initial_tiles));
  280. // Create new instance of CustomLinksManagerImpl to trigger the logic.
  281. std::unique_ptr<CustomLinksManagerImpl> custom_links_test_ =
  282. std::make_unique<CustomLinksManagerImpl>(&prefs_, history_service_.get());
  283. // Should be empty as NTP Default App is Removed.
  284. ASSERT_TRUE(custom_links_test_->GetLinks().empty());
  285. }
  286. TEST_F(CustomLinksManagerImplTest, DeletedMigratedDefaultAppMultiLink) {
  287. // Initialize tiles vector with random links + Gmail.
  288. NTPTilesVector initial_tiles = FillTestTiles(kTestCase2);
  289. AddTile(&initial_tiles, kTestGmailURL, kTestGmail16);
  290. // Initialize tiles and fill up custom links.
  291. ASSERT_TRUE(custom_links_->Initialize(initial_tiles));
  292. // Create new instance of CustomLinksManagerImpl to trigger the logic.
  293. std::unique_ptr<CustomLinksManagerImpl> custom_links_test_ =
  294. std::make_unique<CustomLinksManagerImpl>(&prefs_, history_service_.get());
  295. // Verify that Gmail does not exist in the custom links.
  296. ASSERT_EQ(std::vector<Link>(
  297. {Link{GURL(kTestCase2[0].url), kTestCase2[0].title, true},
  298. Link{GURL(kTestCase2[1].url), kTestCase2[1].title, true}}),
  299. custom_links_test_->GetLinks());
  300. }
  301. #endif // BUILDFLAG(ENABLE_EXTENSIONS)
  302. TEST_F(CustomLinksManagerImplTest, DeleteLinkWhenUrlDoesNotExist) {
  303. // Initialize.
  304. ASSERT_TRUE(custom_links_->Initialize(NTPTilesVector()));
  305. ASSERT_TRUE(custom_links_->GetLinks().empty());
  306. // Try to delete link. This should fail and not modify the list.
  307. EXPECT_FALSE(custom_links_->DeleteLink(GURL(kTestUrl)));
  308. EXPECT_TRUE(custom_links_->GetLinks().empty());
  309. }
  310. TEST_F(CustomLinksManagerImplTest, UndoAddLink) {
  311. // Initialize.
  312. std::vector<Link> initial_links = FillTestLinks(kTestCase1);
  313. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  314. ASSERT_EQ(initial_links, custom_links_->GetLinks());
  315. // Try to undo before add is called. This should fail and not modify the list.
  316. EXPECT_FALSE(custom_links_->UndoAction());
  317. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  318. // Add link.
  319. EXPECT_TRUE(custom_links_->AddLink(GURL(kTestUrl), kTestTitle16));
  320. EXPECT_EQ(std::vector<Link>(
  321. {Link{GURL(kTestCase1[0].url), kTestCase1[0].title, true},
  322. {Link{GURL(kTestUrl), kTestTitle16, false}}}),
  323. custom_links_->GetLinks());
  324. // Undo add link.
  325. EXPECT_TRUE(custom_links_->UndoAction());
  326. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  327. // Try to undo again. This should fail and not modify the list.
  328. EXPECT_FALSE(custom_links_->UndoAction());
  329. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  330. }
  331. TEST_F(CustomLinksManagerImplTest, UndoUpdateLink) {
  332. // Initialize.
  333. std::vector<Link> initial_links = FillTestLinks(kTestCase1);
  334. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  335. ASSERT_EQ(initial_links, custom_links_->GetLinks());
  336. // Update the link's URL.
  337. EXPECT_TRUE(custom_links_->UpdateLink(GURL(kTestCase1[0].url), GURL(kTestUrl),
  338. std::u16string()));
  339. EXPECT_EQ(
  340. std::vector<Link>({Link{GURL(kTestUrl), kTestCase1[0].title, false}}),
  341. custom_links_->GetLinks());
  342. // Undo update link.
  343. EXPECT_TRUE(custom_links_->UndoAction());
  344. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  345. // Update the link's title.
  346. EXPECT_TRUE(
  347. custom_links_->UpdateLink(GURL(kTestCase1[0].url), GURL(), kTestTitle16));
  348. EXPECT_EQ(
  349. std::vector<Link>({Link{GURL(kTestCase1[0].url), kTestTitle16, false}}),
  350. custom_links_->GetLinks());
  351. // Undo update link.
  352. EXPECT_TRUE(custom_links_->UndoAction());
  353. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  354. // Try to undo again. This should fail and not modify the list.
  355. EXPECT_FALSE(custom_links_->UndoAction());
  356. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  357. }
  358. TEST_F(CustomLinksManagerImplTest, UndoDeleteLink) {
  359. // Initialize.
  360. NTPTilesVector initial_tiles;
  361. AddTile(&initial_tiles, kTestUrl, kTestTitle16);
  362. std::vector<Link> expected_links({Link{GURL(kTestUrl), kTestTitle16, true}});
  363. ASSERT_TRUE(custom_links_->Initialize(initial_tiles));
  364. ASSERT_EQ(expected_links, custom_links_->GetLinks());
  365. // Delete link.
  366. ASSERT_TRUE(custom_links_->DeleteLink(GURL(kTestUrl)));
  367. ASSERT_TRUE(custom_links_->GetLinks().empty());
  368. // Undo delete link.
  369. EXPECT_TRUE(custom_links_->UndoAction());
  370. EXPECT_EQ(expected_links, custom_links_->GetLinks());
  371. }
  372. TEST_F(CustomLinksManagerImplTest, UndoDeleteLinkAfterAdd) {
  373. // Initialize.
  374. ASSERT_TRUE(custom_links_->Initialize(NTPTilesVector()));
  375. ASSERT_TRUE(custom_links_->GetLinks().empty());
  376. // Add link.
  377. std::vector<Link> expected_links({Link{GURL(kTestUrl), kTestTitle16, false}});
  378. ASSERT_TRUE(custom_links_->AddLink(GURL(kTestUrl), kTestTitle16));
  379. ASSERT_EQ(expected_links, custom_links_->GetLinks());
  380. // Delete link.
  381. ASSERT_TRUE(custom_links_->DeleteLink(GURL(kTestUrl)));
  382. ASSERT_TRUE(custom_links_->GetLinks().empty());
  383. // Undo delete link.
  384. EXPECT_TRUE(custom_links_->UndoAction());
  385. EXPECT_EQ(expected_links, custom_links_->GetLinks());
  386. }
  387. TEST_F(CustomLinksManagerImplTest, ShouldDeleteMostVisitedOnHistoryDeletion) {
  388. NTPTilesVector initial_tiles = FillTestTiles(kTestCase2);
  389. std::vector<Link> initial_links = FillTestLinks(kTestCase2);
  390. std::vector<Link> expected_links(initial_links);
  391. // Remove the link that will be deleted on history clear.
  392. expected_links.pop_back();
  393. // Set up Most Visited callback.
  394. base::MockCallback<base::RepeatingClosure> callback;
  395. base::CallbackListSubscription subscription =
  396. custom_links_->RegisterCallbackForOnChanged(callback.Get());
  397. // Initialize.
  398. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase2)));
  399. ASSERT_EQ(FillTestLinks(kTestCase2), custom_links_->GetLinks());
  400. // Delete a specific Most Visited link.
  401. EXPECT_CALL(callback, Run());
  402. static_cast<history::HistoryServiceObserver*>(custom_links_.get())
  403. ->OnURLsDeleted(
  404. history_service_.get(),
  405. history::DeletionInfo(history::DeletionTimeRange::Invalid(),
  406. /*expired=*/false,
  407. {history::URLRow(GURL(kTestCase2[1].url))},
  408. /*favicon_urls=*/std::set<GURL>(),
  409. /*restrict_urls=*/absl::nullopt));
  410. EXPECT_EQ(std::vector<Link>(
  411. {Link{GURL(kTestCase2[0].url), kTestCase2[0].title, true}}),
  412. custom_links_->GetLinks());
  413. task_environment_.RunUntilIdle();
  414. }
  415. TEST_F(CustomLinksManagerImplTest,
  416. ShouldDeleteMostVisitedOnAllHistoryDeletion) {
  417. // Set up Most Visited callback.
  418. base::MockCallback<base::RepeatingClosure> callback;
  419. base::CallbackListSubscription subscription =
  420. custom_links_->RegisterCallbackForOnChanged(callback.Get());
  421. // Initialize.
  422. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase2)));
  423. ASSERT_EQ(FillTestLinks(kTestCase2), custom_links_->GetLinks());
  424. // Delete all Most Visited links.
  425. EXPECT_CALL(callback, Run());
  426. static_cast<history::HistoryServiceObserver*>(custom_links_.get())
  427. ->OnURLsDeleted(
  428. history_service_.get(),
  429. history::DeletionInfo(history::DeletionTimeRange::AllTime(),
  430. /*expired=*/false, history::URLRows(),
  431. /*favicon_urls=*/std::set<GURL>(),
  432. /*restrict_urls=*/absl::nullopt));
  433. EXPECT_TRUE(custom_links_->GetLinks().empty());
  434. task_environment_.RunUntilIdle();
  435. }
  436. TEST_F(CustomLinksManagerImplTest, ShouldDeleteOnHistoryDeletionAfterShutdown) {
  437. // Initialize.
  438. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase2)));
  439. ASSERT_EQ(FillTestLinks(kTestCase2), custom_links_->GetLinks());
  440. // Simulate shutdown by recreating CustomLinksManagerImpl.
  441. custom_links_.reset();
  442. custom_links_ =
  443. std::make_unique<CustomLinksManagerImpl>(&prefs_, history_service_.get());
  444. // Set up Most Visited callback.
  445. base::MockCallback<base::RepeatingClosure> callback;
  446. base::CallbackListSubscription subscription =
  447. custom_links_->RegisterCallbackForOnChanged(callback.Get());
  448. // Delete all Most Visited links.
  449. EXPECT_CALL(callback, Run());
  450. static_cast<history::HistoryServiceObserver*>(custom_links_.get())
  451. ->OnURLsDeleted(
  452. history_service_.get(),
  453. history::DeletionInfo(history::DeletionTimeRange::AllTime(),
  454. /*expired=*/false, history::URLRows(),
  455. /*favicon_urls=*/std::set<GURL>(),
  456. /*restrict_urls=*/absl::nullopt));
  457. EXPECT_TRUE(custom_links_->GetLinks().empty());
  458. task_environment_.RunUntilIdle();
  459. }
  460. TEST_F(CustomLinksManagerImplTest, ShouldNotDeleteCustomLinkOnHistoryDeletion) {
  461. // Set up Most Visited callback.
  462. base::MockCallback<base::RepeatingClosure> callback;
  463. base::CallbackListSubscription subscription =
  464. custom_links_->RegisterCallbackForOnChanged(callback.Get());
  465. // Initialize.
  466. std::vector<Link> links_after_add(
  467. {Link{GURL(kTestCase1[0].url), kTestCase1[0].title, true},
  468. Link{GURL(kTestUrl), kTestTitle16, false}});
  469. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  470. ASSERT_EQ(FillTestLinks(kTestCase1), custom_links_->GetLinks());
  471. // Add link.
  472. ASSERT_TRUE(custom_links_->AddLink(GURL(kTestUrl), kTestTitle16));
  473. ASSERT_EQ(links_after_add, custom_links_->GetLinks());
  474. // Try to delete the added link. This should fail and not modify the list.
  475. static_cast<history::HistoryServiceObserver*>(custom_links_.get())
  476. ->OnURLsDeleted(history_service_.get(),
  477. history::DeletionInfo(
  478. history::DeletionTimeRange::Invalid(),
  479. /*expired=*/false, {history::URLRow(GURL(kTestUrl))},
  480. /*favicon_urls=*/std::set<GURL>(),
  481. /*restrict_urls=*/absl::nullopt));
  482. EXPECT_EQ(links_after_add, custom_links_->GetLinks());
  483. // Delete all Most Visited links.
  484. EXPECT_CALL(callback, Run());
  485. static_cast<history::HistoryServiceObserver*>(custom_links_.get())
  486. ->OnURLsDeleted(
  487. history_service_.get(),
  488. history::DeletionInfo(history::DeletionTimeRange::AllTime(),
  489. /*expired=*/false, history::URLRows(),
  490. /*favicon_urls=*/std::set<GURL>(),
  491. /*restrict_urls=*/absl::nullopt));
  492. EXPECT_EQ(std::vector<Link>({Link{GURL(kTestUrl), kTestTitle16, false}}),
  493. custom_links_->GetLinks());
  494. task_environment_.RunUntilIdle();
  495. }
  496. TEST_F(CustomLinksManagerImplTest, ShouldIgnoreHistoryExpiredDeletions) {
  497. // Set up Most Visited callback.
  498. base::MockCallback<base::RepeatingClosure> callback;
  499. base::CallbackListSubscription subscription =
  500. custom_links_->RegisterCallbackForOnChanged(callback.Get());
  501. // Initialize.
  502. std::vector<Link> initial_links = FillTestLinks(kTestCase1);
  503. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  504. ASSERT_EQ(initial_links, custom_links_->GetLinks());
  505. EXPECT_CALL(callback, Run()).Times(0);
  506. static_cast<history::HistoryServiceObserver*>(custom_links_.get())
  507. ->OnURLsDeleted(
  508. history_service_.get(),
  509. history::DeletionInfo(history::DeletionTimeRange::AllTime(),
  510. /*expired=*/true, history::URLRows(),
  511. /*favicon_urls=*/std::set<GURL>(),
  512. /*restrict_urls=*/absl::nullopt));
  513. static_cast<history::HistoryServiceObserver*>(custom_links_.get())
  514. ->OnURLsDeleted(
  515. // /*history_service=*/nullptr,
  516. history_service_.get(),
  517. history::DeletionInfo(history::DeletionTimeRange::Invalid(),
  518. /*expired=*/true,
  519. {history::URLRow(GURL(kTestCase1[0].url))},
  520. /*favicon_urls=*/std::set<GURL>(),
  521. /*restrict_urls=*/absl::nullopt));
  522. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  523. task_environment_.RunUntilIdle();
  524. }
  525. TEST_F(CustomLinksManagerImplTest, ShouldIgnoreEmptyHistoryDeletions) {
  526. // Set up Most Visited callback.
  527. base::MockCallback<base::RepeatingClosure> callback;
  528. base::CallbackListSubscription subscription =
  529. custom_links_->RegisterCallbackForOnChanged(callback.Get());
  530. // Initialize.
  531. std::vector<Link> initial_links = FillTestLinks(kTestCase1);
  532. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  533. ASSERT_EQ(initial_links, custom_links_->GetLinks());
  534. EXPECT_CALL(callback, Run()).Times(0);
  535. static_cast<history::HistoryServiceObserver*>(custom_links_.get())
  536. ->OnURLsDeleted(history_service_.get(),
  537. history::DeletionInfo::ForUrls({}, {}));
  538. EXPECT_EQ(initial_links, custom_links_->GetLinks());
  539. task_environment_.RunUntilIdle();
  540. }
  541. TEST_F(CustomLinksManagerImplTest, ShouldNotUndoAfterHistoryDeletion) {
  542. // Set up Most Visited callback.
  543. base::MockCallback<base::RepeatingClosure> callback;
  544. base::CallbackListSubscription subscription =
  545. custom_links_->RegisterCallbackForOnChanged(callback.Get());
  546. // Initialize.
  547. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  548. ASSERT_EQ(FillTestLinks(kTestCase1), custom_links_->GetLinks());
  549. // Add link.
  550. std::vector<Link> links_after_add(
  551. {Link{GURL(kTestCase1[0].url), kTestCase1[0].title, true},
  552. Link{GURL(kTestUrl), kTestTitle16, false}});
  553. ASSERT_TRUE(custom_links_->AddLink(GURL(kTestUrl), kTestTitle16));
  554. ASSERT_EQ(links_after_add, custom_links_->GetLinks());
  555. // Try an empty history deletion. This should do nothing.
  556. EXPECT_CALL(callback, Run()).Times(0);
  557. static_cast<history::HistoryServiceObserver*>(custom_links_.get())
  558. ->OnURLsDeleted(history_service_.get(),
  559. history::DeletionInfo::ForUrls({}, {}));
  560. EXPECT_EQ(links_after_add, custom_links_->GetLinks());
  561. // Try to undo. This should fail and not modify the list.
  562. EXPECT_FALSE(custom_links_->UndoAction());
  563. EXPECT_EQ(links_after_add, custom_links_->GetLinks());
  564. task_environment_.RunUntilIdle();
  565. }
  566. TEST_F(CustomLinksManagerImplTest, UpdateListAfterRemoteChange) {
  567. // Set up Most Visited callback.
  568. base::MockCallback<base::RepeatingClosure> callback;
  569. base::CallbackListSubscription subscription =
  570. custom_links_->RegisterCallbackForOnChanged(callback.Get());
  571. // Initialize.
  572. ASSERT_TRUE(custom_links_->Initialize(NTPTilesVector()));
  573. ASSERT_EQ(std::vector<Link>(), custom_links_->GetLinks());
  574. // Modifying ourselves should not notify.
  575. EXPECT_CALL(callback, Run()).Times(0);
  576. EXPECT_TRUE(
  577. custom_links_->AddLink(GURL(kTestCase1[0].url), kTestCase1[0].title));
  578. EXPECT_EQ(std::vector<Link>(
  579. {Link{GURL(kTestCase1[0].url), kTestCase1[0].title, false}}),
  580. custom_links_->GetLinks());
  581. // Modify the preference. This should notify and update the current list of
  582. // links.
  583. EXPECT_CALL(callback, Run());
  584. prefs_.SetUserPref(prefs::kCustomLinksList,
  585. base::Value(FillTestList(kTestUrl, kTestTitle, true)));
  586. EXPECT_EQ(std::vector<Link>({Link{GURL(kTestUrl), kTestTitle16, true}}),
  587. custom_links_->GetLinks());
  588. }
  589. TEST_F(CustomLinksManagerImplTest, InitializeListAfterRemoteChange) {
  590. // Set up Most Visited callback.
  591. base::MockCallback<base::RepeatingClosure> callback;
  592. base::CallbackListSubscription subscription =
  593. custom_links_->RegisterCallbackForOnChanged(callback.Get());
  594. ASSERT_FALSE(custom_links_->IsInitialized());
  595. // Modify the preference. This should notify and initialize custom links.
  596. EXPECT_CALL(callback, Run()).Times(2);
  597. prefs_.SetUserPref(prefs::kCustomLinksInitialized, base::Value(true));
  598. prefs_.SetUserPref(prefs::kCustomLinksList,
  599. base::Value(FillTestList(kTestUrl, kTestTitle, false)));
  600. EXPECT_TRUE(custom_links_->IsInitialized());
  601. EXPECT_EQ(std::vector<Link>({Link{GURL(kTestUrl), kTestTitle16, false}}),
  602. custom_links_->GetLinks());
  603. }
  604. TEST_F(CustomLinksManagerImplTest, UninitializeListAfterRemoteChange) {
  605. // Set up Most Visited callback.
  606. base::MockCallback<base::RepeatingClosure> callback;
  607. base::CallbackListSubscription subscription =
  608. custom_links_->RegisterCallbackForOnChanged(callback.Get());
  609. // Initialize.
  610. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  611. ASSERT_EQ(FillTestLinks(kTestCase1), custom_links_->GetLinks());
  612. // Modify the preference. This should notify and uninitialize custom links.
  613. EXPECT_CALL(callback, Run()).Times(2);
  614. prefs_.SetUserPref(prefs::kCustomLinksInitialized, base::Value(false));
  615. prefs_.SetUserPref(prefs::kCustomLinksList, base::Value(base::Value::List()));
  616. EXPECT_FALSE(custom_links_->IsInitialized());
  617. EXPECT_EQ(std::vector<Link>(), custom_links_->GetLinks());
  618. }
  619. TEST_F(CustomLinksManagerImplTest, ClearThenUninitializeListAfterRemoteChange) {
  620. // Set up Most Visited callback.
  621. base::MockCallback<base::RepeatingClosure> callback;
  622. base::CallbackListSubscription subscription =
  623. custom_links_->RegisterCallbackForOnChanged(callback.Get());
  624. // Initialize.
  625. ASSERT_TRUE(custom_links_->Initialize(FillTestTiles(kTestCase1)));
  626. ASSERT_EQ(FillTestLinks(kTestCase1), custom_links_->GetLinks());
  627. // Modify the preference. Simulates when the list preference is synced before
  628. // the initialized preference. This should notify and uninitialize custom
  629. // links.
  630. EXPECT_CALL(callback, Run()).Times(2);
  631. prefs_.SetUserPref(prefs::kCustomLinksList, base::Value(base::Value::List()));
  632. EXPECT_TRUE(custom_links_->IsInitialized());
  633. EXPECT_EQ(std::vector<Link>(), custom_links_->GetLinks());
  634. prefs_.SetUserPref(prefs::kCustomLinksInitialized, base::Value(false));
  635. EXPECT_FALSE(custom_links_->IsInitialized());
  636. EXPECT_EQ(std::vector<Link>(), custom_links_->GetLinks());
  637. }
  638. } // namespace ntp_tiles