BookmarkManager: Fix 'new folder text field size changes on clicking it' issue.
[chromium-blink-merge.git] / chrome / browser / supervised_user / supervised_user_bookmarks_handler_unittest.cc
blob8de4d52ac70d70016d9d87e620a63091d8ec2a7f
1 // Copyright 2015 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.
5 #include <iostream>
6 #include <map>
7 #include <string>
8 #include <vector>
10 #include "base/json/json_reader.h"
11 #include "base/json/json_writer.h"
12 #include "base/macros.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/values.h"
15 #include "chrome/browser/supervised_user/supervised_user_bookmarks_handler.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 using Folder = SupervisedUserBookmarksHandler::Folder;
19 using Link = SupervisedUserBookmarksHandler::Link;
21 namespace {
23 typedef std::pair<std::string, std::string> Setting;
25 // Settings representing the following tree:
26 // |--Folder1
27 // |--SubFolder
28 // |--Empty SubSubFolder
29 // |--Google(google.com)
30 // |--(www.theoatmeal.com)
31 // |--Test(www.test.de)
32 // |--Empty Folder
33 // |--XKCD(m.xkcd.com)
35 // Folder setting format: "<ID>", "<ParentID>:<Name>"
36 const Setting FOLDER_SETTINGS[] = {
37 Setting("5", "0:Folder1"),
38 Setting("9", "0:Empty Folder"),
39 Setting("3", "5:SubFolder"),
40 Setting("4", "3:Empty SubSubFolder"),
43 const Setting FOLDER_SETTINGS_INVALID_PARENT[] = {
44 Setting("5", "0:Folder1"),
45 Setting("9", "7:Empty Folder"), // Invalid parent id.
46 Setting("3", "5:SubFolder"),
47 Setting("4", "3:Empty SubSubFolder"),
50 const Setting FOLDER_SETTINGS_CIRCLE[] = {
51 Setting("5", "3:Folder1"),
52 Setting("9", "5:Empty Folder"),
53 Setting("3", "9:SubFolder"),
56 // Link setting format: "<ID>:<URL>", "<ParentID>:<Name>"
57 const Setting LINK_SETTINGS[] = {
58 Setting("4:www.theoatmeal.com", "3:"),
59 Setting("1:m.xkcd.com", "0:XKCD"),
60 Setting("2:www.test.de", "5:Test"),
61 Setting("3:google.com", "3:Google"),
64 const Setting LINK_SETTINGS_INVALID_PARENT[] = {
65 Setting("4:www.theoatmeal.com", "3:"),
66 Setting("1:m.xkcd.com", "7:XKCD"), // Invalid parent id.
67 Setting("2:www.test.de", "8:Test"), // Invalid parent id.
70 // Parsed data is sorted by ID (even though the parsed links don't actually
71 // contain their IDs!)
73 const Folder PARSED_FOLDERS[] = {
74 Folder(3, "SubFolder", 5), // Note: Forward reference.
75 Folder(4, "Empty SubSubFolder", 3),
76 Folder(5, "Folder1", 0),
77 Folder(9, "Empty Folder", 0),
80 const Link PARSED_LINKS[] = {
81 Link("m.xkcd.com", "XKCD", 0),
82 Link("www.test.de", "Test", 5),
83 Link("google.com", "Google", 3),
84 Link("www.theoatmeal.com", std::string(), 3),
87 const char BOOKMARKS_TREE_JSON[] =
88 "["
89 " {"
90 " \"id\":5,"
91 " \"name\":\"Folder1\","
92 " \"children\":["
93 " {"
94 " \"id\":3,"
95 " \"name\":\"SubFolder\","
96 " \"children\":["
97 " {"
98 " \"id\":4,"
99 " \"name\":\"Empty SubSubFolder\","
100 " \"children\":[]"
101 " },"
102 " {"
103 " \"name\":\"Google\","
104 " \"url\":\"http://google.com/\""
105 " },"
106 " {"
107 " \"name\":\"\","
108 " \"url\":\"http://www.theoatmeal.com/\""
109 " }"
110 " ]"
111 " },"
112 " {"
113 " \"name\":\"Test\","
114 " \"url\":\"http://www.test.de/\""
115 " }"
116 " ]"
117 " },"
118 " {"
119 " \"id\":9,"
120 " \"name\":\"Empty Folder\","
121 " \"children\":[]"
122 " },"
123 " {"
124 " \"name\":\"XKCD\","
125 " \"url\":\"http://m.xkcd.com/\""
126 " }"
127 "]";
129 const char BOOKMARKS_TREE_INVALID_PARENTS_JSON[] =
131 " {"
132 " \"id\":5,"
133 " \"name\":\"Folder1\","
134 " \"children\":["
135 " {"
136 " \"id\":3,"
137 " \"name\":\"SubFolder\","
138 " \"children\":["
139 " {"
140 " \"id\":4,"
141 " \"name\":\"Empty SubSubFolder\","
142 " \"children\":[]"
143 " },"
144 " {"
145 " \"name\":\"\","
146 " \"url\":\"http://www.theoatmeal.com/\""
147 " }"
148 " ]"
149 " }"
150 " ]"
151 " }"
152 "]";
154 // Builds the base::Values tree from a json string above.
155 scoped_ptr<base::ListValue> CreateTree(const char* json) {
156 scoped_ptr<base::Value> value = base::JSONReader::Read(json);
157 EXPECT_NE(value.get(), nullptr);
158 base::ListValue* list;
159 EXPECT_TRUE(value->GetAsList(&list));
160 ignore_result(value.release());
161 return make_scoped_ptr(list);
164 scoped_ptr<base::ListValue> CreateBookmarksTree() {
165 return CreateTree(BOOKMARKS_TREE_JSON);
168 scoped_ptr<base::ListValue> CreateBookmarksTreeWithInvalidParents() {
169 return CreateTree(BOOKMARKS_TREE_INVALID_PARENTS_JSON);
172 } // namespace
174 static bool operator==(const Folder& f1, const Folder& f2) {
175 return f1.id == f2.id && f1.name == f2.name && f1.parent_id == f2.parent_id;
178 static bool operator==(const Link& l1, const Link& l2) {
179 return l1.url == l2.url && l1.name == l2.name && l1.parent_id == l2.parent_id;
182 std::ostream& operator<<(std::ostream& str, const Folder& folder) {
183 str << folder.id << " " << folder.name << " " << folder.parent_id;
184 return str;
187 std::ostream& operator<<(std::ostream& str, const Link& link) {
188 str << link.url << " " << link.name << " " << link.parent_id;
189 return str;
192 class SupervisedUserBookmarksHandlerTest : public ::testing::Test {
193 protected:
194 static base::DictionaryValue* CreateSettings(base::DictionaryValue* links,
195 base::DictionaryValue* folders) {
196 base::DictionaryValue* settings = new base::DictionaryValue;
197 settings->SetStringWithoutPathExpansion("some_setting", "bleh");
198 settings->SetWithoutPathExpansion("SupervisedBookmarkLink", links);
199 settings->SetStringWithoutPathExpansion("some_other_setting", "foo");
200 settings->SetWithoutPathExpansion("SupervisedBookmarkFolder", folders);
201 settings->SetStringWithoutPathExpansion("another_one", "blurb");
202 return settings;
205 static base::DictionaryValue* CreateDictionary(const Setting* begin,
206 const Setting* end) {
207 base::DictionaryValue* dict = new base::DictionaryValue;
208 for (const Setting* setting = begin; setting != end; ++setting)
209 dict->SetStringWithoutPathExpansion(setting->first, setting->second);
210 return dict;
213 static base::DictionaryValue* CreateLinkDictionary() {
214 return CreateDictionary(LINK_SETTINGS,
215 LINK_SETTINGS + arraysize(LINK_SETTINGS));
218 static base::DictionaryValue* CreateLinkDictionaryWithInvalidParents() {
219 return CreateDictionary(
220 LINK_SETTINGS_INVALID_PARENT,
221 LINK_SETTINGS_INVALID_PARENT + arraysize(LINK_SETTINGS_INVALID_PARENT));
224 static base::DictionaryValue* CreateFolderDictionary() {
225 return CreateDictionary(FOLDER_SETTINGS,
226 FOLDER_SETTINGS + arraysize(FOLDER_SETTINGS));
229 static base::DictionaryValue* CreateFolderDictionaryWithInvalidParents() {
230 return CreateDictionary(
231 FOLDER_SETTINGS_INVALID_PARENT,
232 FOLDER_SETTINGS_INVALID_PARENT +
233 arraysize(FOLDER_SETTINGS_INVALID_PARENT));
236 static base::DictionaryValue* CreateFolderDictionaryWithCircle() {
237 return CreateDictionary(
238 FOLDER_SETTINGS_CIRCLE,
239 FOLDER_SETTINGS_CIRCLE + arraysize(FOLDER_SETTINGS_CIRCLE));
242 void ParseFolders(const base::DictionaryValue& folders) {
243 deserializer_.ParseFolders(folders);
246 void ParseLinks(const base::DictionaryValue& links) {
247 deserializer_.ParseLinks(links);
250 const std::vector<Folder>& GetFolders() const {
251 return deserializer_.folders_for_testing();
254 const std::vector<Link>& GetLinks() const {
255 return deserializer_.links_for_testing();
258 private:
259 SupervisedUserBookmarksHandler deserializer_;
262 TEST_F(SupervisedUserBookmarksHandlerTest, ParseSettings) {
263 scoped_ptr<base::DictionaryValue> link_dictionary(CreateLinkDictionary());
264 scoped_ptr<base::DictionaryValue> folder_dictionary(CreateFolderDictionary());
266 ParseLinks(*link_dictionary.get());
267 ParseFolders(*folder_dictionary.get());
269 const std::vector<Link>& links = GetLinks();
270 EXPECT_EQ(arraysize(PARSED_LINKS), links.size());
271 for (size_t i = 0; i < links.size(); ++i)
272 EXPECT_EQ(PARSED_LINKS[i], links[i]);
274 const std::vector<Folder>& folders = GetFolders();
275 EXPECT_EQ(arraysize(PARSED_FOLDERS), folders.size());
276 for (size_t i = 0; i < folders.size(); ++i)
277 EXPECT_EQ(PARSED_FOLDERS[i], folders[i]);
280 TEST_F(SupervisedUserBookmarksHandlerTest, BuildBookmarksTree) {
281 // Make some fake settings.
282 scoped_ptr<base::DictionaryValue> settings(
283 CreateSettings(CreateLinkDictionary(), CreateFolderDictionary()));
284 // Parse the settings into a bookmarks tree.
285 scoped_ptr<base::ListValue> bookmarks(
286 SupervisedUserBookmarksHandler::BuildBookmarksTree(*settings.get()));
288 // Check that the parsed tree matches the expected tree constructed directly
289 // from the hardcoded json above.
290 scoped_ptr<base::ListValue> expected_bookmarks(CreateBookmarksTree());
291 EXPECT_TRUE(bookmarks->Equals(expected_bookmarks.get()));
294 TEST_F(SupervisedUserBookmarksHandlerTest,
295 BuildBookmarksTreeWithInvalidParents) {
296 // Make some fake settings, including some entries with invalid parent
297 // references.
298 scoped_ptr<base::DictionaryValue> settings(
299 CreateSettings(CreateLinkDictionaryWithInvalidParents(),
300 CreateFolderDictionaryWithInvalidParents()));
301 // Parse the settings into a bookmarks tree.
302 scoped_ptr<base::ListValue> bookmarks(
303 SupervisedUserBookmarksHandler::BuildBookmarksTree(*settings.get()));
305 // Check that the parsed tree matches the expected tree constructed directly
306 // from the hardcoded json above (which does not contain the entries with
307 // invalid parents!).
308 scoped_ptr<base::ListValue> expected_bookmarks(
309 CreateBookmarksTreeWithInvalidParents());
310 EXPECT_TRUE(bookmarks->Equals(expected_bookmarks.get()));
313 TEST_F(SupervisedUserBookmarksHandlerTest, Circle) {
314 // Make some fake settings which include a circular reference in the folders.
315 scoped_ptr<base::DictionaryValue> settings(
316 CreateSettings(CreateLinkDictionary(),
317 CreateFolderDictionaryWithCircle()));
318 scoped_ptr<base::ListValue> bookmarks(
319 SupervisedUserBookmarksHandler::BuildBookmarksTree(*settings.get()));
320 // Don't care what exactly the result looks like, just that we don't run into
321 // an endless loop.