managed_bookmarks_tracker_unittest.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. // Copyright 2014 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/bookmarks/managed/managed_bookmarks_tracker.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "base/bind.h"
  8. #include "base/files/file_path.h"
  9. #include "base/files/scoped_temp_dir.h"
  10. #include "base/memory/ptr_util.h"
  11. #include "base/memory/raw_ptr.h"
  12. #include "base/run_loop.h"
  13. #include "base/strings/utf_string_conversions.h"
  14. #include "base/test/task_environment.h"
  15. #include "components/bookmarks/browser/bookmark_model.h"
  16. #include "components/bookmarks/browser/bookmark_model_observer.h"
  17. #include "components/bookmarks/browser/bookmark_node.h"
  18. #include "components/bookmarks/browser/bookmark_utils.h"
  19. #include "components/bookmarks/common/bookmark_pref_names.h"
  20. #include "components/bookmarks/test/bookmark_test_helpers.h"
  21. #include "components/bookmarks/test/mock_bookmark_model_observer.h"
  22. #include "components/bookmarks/test/test_bookmark_client.h"
  23. #include "components/prefs/pref_registry_simple.h"
  24. #include "components/prefs/testing_pref_service.h"
  25. #include "components/strings/grit/components_strings.h"
  26. #include "testing/gmock/include/gmock/gmock.h"
  27. #include "testing/gtest/include/gtest/gtest.h"
  28. #include "ui/base/l10n/l10n_util.h"
  29. #include "url/gurl.h"
  30. using testing::Mock;
  31. using testing::_;
  32. namespace bookmarks {
  33. class ManagedBookmarksTrackerTest : public testing::Test {
  34. public:
  35. ManagedBookmarksTrackerTest() : managed_node_(nullptr) {}
  36. ~ManagedBookmarksTrackerTest() override {}
  37. void SetUp() override {
  38. RegisterManagedBookmarksPrefs(prefs_.registry());
  39. ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
  40. }
  41. void TearDown() override {
  42. if (model_)
  43. model_->RemoveObserver(&observer_);
  44. base::RunLoop().RunUntilIdle();
  45. }
  46. void CreateModel() {
  47. // Simulate the creation of the managed node by the BookmarkClient.
  48. auto client = std::make_unique<TestBookmarkClient>();
  49. managed_node_ = client->EnableManagedNode();
  50. ManagedBookmarksTracker::LoadInitial(
  51. managed_node_, prefs_.GetValueList(prefs::kManagedBookmarks), 101);
  52. managed_node_->SetTitle(l10n_util::GetStringUTF16(
  53. IDS_BOOKMARK_BAR_MANAGED_FOLDER_DEFAULT_NAME));
  54. model_ = std::make_unique<BookmarkModel>(std::move(client));
  55. model_->AddObserver(&observer_);
  56. EXPECT_CALL(observer_, BookmarkModelLoaded(model_.get(), _));
  57. model_->Load(&prefs_, scoped_temp_dir_.GetPath());
  58. test::WaitForBookmarkModelToLoad(model_.get());
  59. Mock::VerifyAndClearExpectations(&observer_);
  60. managed_bookmarks_tracker_ = std::make_unique<ManagedBookmarksTracker>(
  61. model_.get(), &prefs_,
  62. base::BindRepeating(&ManagedBookmarksTrackerTest::GetManagementDomain));
  63. managed_bookmarks_tracker_->Init(managed_node_);
  64. }
  65. const BookmarkNode* managed_node() {
  66. return managed_node_;
  67. }
  68. bool IsManaged(const BookmarkNode* node) {
  69. return node && node->HasAncestor(managed_node_.get());
  70. }
  71. void SetManagedPref(const std::string& path, const base::Value::List& list) {
  72. prefs_.SetManagedPref(path, base::Value(list.Clone()));
  73. }
  74. static base::Value::Dict CreateBookmark(const std::string& title,
  75. const std::string& url) {
  76. EXPECT_TRUE(GURL(url).is_valid());
  77. base::Value::Dict dict;
  78. dict.Set("name", title);
  79. dict.Set("url", GURL(url).spec());
  80. return dict;
  81. }
  82. static base::Value::Dict CreateFolder(const std::string& title,
  83. base::Value::List children) {
  84. base::Value::Dict dict;
  85. dict.Set("name", title);
  86. dict.Set("children", std::move(children));
  87. return dict;
  88. }
  89. static base::Value::List CreateTestTree() {
  90. base::Value::List folder;
  91. folder.Append(CreateFolder("Empty", base::Value::List()));
  92. folder.Append(CreateBookmark("Youtube", "http://youtube.com/"));
  93. base::Value::List list;
  94. list.Append(CreateBookmark("Google", "http://google.com/"));
  95. list.Append(CreateFolder("Folder", std::move(folder)));
  96. return list;
  97. }
  98. static std::string GetManagementDomain() {
  99. return std::string();
  100. }
  101. static std::string GetManagedFolderTitle() {
  102. return l10n_util::GetStringUTF8(
  103. IDS_BOOKMARK_BAR_MANAGED_FOLDER_DEFAULT_NAME);
  104. }
  105. static base::Value::Dict CreateExpectedTree() {
  106. return CreateFolder(GetManagedFolderTitle(), CreateTestTree());
  107. }
  108. static bool NodeMatchesValue(const BookmarkNode* node,
  109. const base::Value::Dict& dict) {
  110. const std::string* title = dict.FindString("name");
  111. if (!title || node->GetTitle() != base::UTF8ToUTF16(*title))
  112. return false;
  113. if (node->is_folder()) {
  114. const base::Value::List* children = dict.FindList("children");
  115. if (!children || node->children().size() != children->size())
  116. return false;
  117. size_t i = 0;
  118. return std::all_of(node->children().cbegin(), node->children().cend(),
  119. [children, &i](const auto& child_node) {
  120. const base::Value& child = (*children)[i++];
  121. return child.is_dict() &&
  122. NodeMatchesValue(child_node.get(),
  123. child.GetDict());
  124. });
  125. }
  126. if (!node->is_url())
  127. return false;
  128. const std::string* url = dict.FindString("url");
  129. return url && node->url() == *url;
  130. }
  131. base::ScopedTempDir scoped_temp_dir_;
  132. base::test::TaskEnvironment task_environment_;
  133. TestingPrefServiceSimple prefs_;
  134. std::unique_ptr<BookmarkModel> model_;
  135. MockBookmarkModelObserver observer_;
  136. raw_ptr<BookmarkPermanentNode> managed_node_;
  137. std::unique_ptr<ManagedBookmarksTracker> managed_bookmarks_tracker_;
  138. };
  139. TEST_F(ManagedBookmarksTrackerTest, Empty) {
  140. CreateModel();
  141. EXPECT_TRUE(model_->bookmark_bar_node()->children().empty());
  142. EXPECT_TRUE(model_->other_node()->children().empty());
  143. EXPECT_TRUE(managed_node()->children().empty());
  144. EXPECT_FALSE(managed_node()->IsVisible());
  145. }
  146. TEST_F(ManagedBookmarksTrackerTest, LoadInitial) {
  147. // Set a policy before loading the model.
  148. SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
  149. CreateModel();
  150. EXPECT_TRUE(model_->bookmark_bar_node()->children().empty());
  151. EXPECT_TRUE(model_->other_node()->children().empty());
  152. EXPECT_FALSE(managed_node()->children().empty());
  153. EXPECT_TRUE(managed_node()->IsVisible());
  154. base::Value::Dict expected(CreateExpectedTree());
  155. EXPECT_TRUE(NodeMatchesValue(managed_node(), expected));
  156. }
  157. TEST_F(ManagedBookmarksTrackerTest, LoadInitialWithTitle) {
  158. // Set the managed folder title.
  159. const char kExpectedFolderName[] = "foo";
  160. prefs_.SetString(prefs::kManagedBookmarksFolderName, kExpectedFolderName);
  161. // Set a policy before loading the model.
  162. SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
  163. CreateModel();
  164. EXPECT_TRUE(model_->bookmark_bar_node()->children().empty());
  165. EXPECT_TRUE(model_->other_node()->children().empty());
  166. EXPECT_FALSE(managed_node()->children().empty());
  167. EXPECT_TRUE(managed_node()->IsVisible());
  168. base::Value::Dict expected(
  169. CreateFolder(kExpectedFolderName, CreateTestTree()));
  170. EXPECT_TRUE(NodeMatchesValue(managed_node(), expected));
  171. }
  172. TEST_F(ManagedBookmarksTrackerTest, SwapNodes) {
  173. SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
  174. CreateModel();
  175. // Swap the Google bookmark with the Folder.
  176. base::Value::List updated(CreateTestTree());
  177. ASSERT_FALSE(updated.empty());
  178. base::Value removed = std::move(updated[0]);
  179. updated.erase(updated.begin());
  180. updated.Append(std::move(removed));
  181. // These two nodes should just be swapped.
  182. const BookmarkNode* parent = managed_node();
  183. EXPECT_CALL(observer_, BookmarkNodeMoved(model_.get(), parent, 1, parent, 0));
  184. SetManagedPref(prefs::kManagedBookmarks, updated);
  185. Mock::VerifyAndClearExpectations(&observer_);
  186. // Verify the final tree.
  187. base::Value::Dict expected(
  188. CreateFolder(GetManagedFolderTitle(), std::move(updated)));
  189. EXPECT_TRUE(NodeMatchesValue(managed_node(), expected));
  190. }
  191. TEST_F(ManagedBookmarksTrackerTest, RemoveNode) {
  192. SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
  193. CreateModel();
  194. // Remove the Folder.
  195. base::Value::List updated(CreateTestTree());
  196. updated.erase(updated.begin() + 1);
  197. const BookmarkNode* parent = managed_node();
  198. EXPECT_CALL(observer_, BookmarkNodeRemoved(model_.get(), parent, 1, _, _));
  199. SetManagedPref(prefs::kManagedBookmarks, updated);
  200. Mock::VerifyAndClearExpectations(&observer_);
  201. // Verify the final tree.
  202. base::Value::Dict expected(
  203. CreateFolder(GetManagedFolderTitle(), std::move(updated)));
  204. EXPECT_TRUE(NodeMatchesValue(managed_node(), expected));
  205. }
  206. TEST_F(ManagedBookmarksTrackerTest, CreateNewNodes) {
  207. SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
  208. CreateModel();
  209. // Put all the nodes inside another folder.
  210. base::Value::List updated;
  211. updated.Append(CreateFolder("Container", CreateTestTree()));
  212. EXPECT_CALL(observer_, BookmarkNodeAdded(model_.get(), _, _)).Times(5);
  213. // The remaining nodes have been pushed to positions 1 and 2; they'll both be
  214. // removed when at position 1.
  215. const BookmarkNode* parent = managed_node();
  216. EXPECT_CALL(observer_, BookmarkNodeRemoved(model_.get(), parent, 1, _, _))
  217. .Times(2);
  218. SetManagedPref(prefs::kManagedBookmarks, updated);
  219. Mock::VerifyAndClearExpectations(&observer_);
  220. // Verify the final tree.
  221. base::Value::Dict expected(
  222. CreateFolder(GetManagedFolderTitle(), std::move(updated)));
  223. EXPECT_TRUE(NodeMatchesValue(managed_node(), expected));
  224. }
  225. TEST_F(ManagedBookmarksTrackerTest, RemoveAll) {
  226. SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
  227. CreateModel();
  228. EXPECT_TRUE(managed_node()->IsVisible());
  229. // Remove the policy.
  230. const BookmarkNode* parent = managed_node();
  231. EXPECT_CALL(observer_, BookmarkNodeRemoved(model_.get(), parent, 0, _, _))
  232. .Times(2);
  233. prefs_.RemoveManagedPref(prefs::kManagedBookmarks);
  234. Mock::VerifyAndClearExpectations(&observer_);
  235. EXPECT_TRUE(managed_node()->children().empty());
  236. EXPECT_FALSE(managed_node()->IsVisible());
  237. }
  238. TEST_F(ManagedBookmarksTrackerTest, IsManaged) {
  239. SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
  240. CreateModel();
  241. EXPECT_FALSE(IsManaged(model_->root_node()));
  242. EXPECT_FALSE(IsManaged(model_->bookmark_bar_node()));
  243. EXPECT_FALSE(IsManaged(model_->other_node()));
  244. EXPECT_FALSE(IsManaged(model_->mobile_node()));
  245. EXPECT_TRUE(IsManaged(managed_node()));
  246. const BookmarkNode* parent = managed_node();
  247. ASSERT_EQ(2u, parent->children().size());
  248. EXPECT_TRUE(IsManaged(parent->children()[0].get()));
  249. EXPECT_TRUE(IsManaged(parent->children()[1].get()));
  250. parent = parent->children()[1].get();
  251. ASSERT_EQ(2u, parent->children().size());
  252. EXPECT_TRUE(IsManaged(parent->children()[0].get()));
  253. EXPECT_TRUE(IsManaged(parent->children()[1].get()));
  254. }
  255. TEST_F(ManagedBookmarksTrackerTest, RemoveAllUserBookmarksDoesntRemoveManaged) {
  256. SetManagedPref(prefs::kManagedBookmarks, CreateTestTree());
  257. CreateModel();
  258. EXPECT_EQ(2u, managed_node()->children().size());
  259. EXPECT_CALL(observer_,
  260. BookmarkNodeAdded(model_.get(), model_->bookmark_bar_node(), 0));
  261. EXPECT_CALL(observer_,
  262. BookmarkNodeAdded(model_.get(), model_->bookmark_bar_node(), 1));
  263. model_->AddURL(model_->bookmark_bar_node(), 0, u"Test",
  264. GURL("http://google.com/"));
  265. model_->AddFolder(model_->bookmark_bar_node(), 1, u"Test Folder");
  266. EXPECT_EQ(2u, model_->bookmark_bar_node()->children().size());
  267. Mock::VerifyAndClearExpectations(&observer_);
  268. EXPECT_CALL(observer_, BookmarkAllUserNodesRemoved(model_.get(), _));
  269. model_->RemoveAllUserBookmarks();
  270. EXPECT_EQ(2u, managed_node()->children().size());
  271. EXPECT_EQ(0u, model_->bookmark_bar_node()->children().size());
  272. Mock::VerifyAndClearExpectations(&observer_);
  273. }
  274. } // namespace bookmarks