Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 5 #include <iostream> | |
| 6 #include <map> | |
| 7 #include <string> | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/json/json_reader.h" | |
| 11 #include "base/json/json_writer.h" | |
| 12 #include "base/memory/scoped_ptr.h" | |
| 13 #include "base/values.h" | |
| 14 #include "chrome/browser/supervised_user/supervised_user_bookmarks_handler.h" | |
| 15 #include "testing/gtest/include/gtest/gtest.h" | |
| 16 | |
| 17 using Folder = SupervisedUserBookmarksHandler::Folder; | |
| 18 using Link = SupervisedUserBookmarksHandler::Link; | |
| 19 | |
| 20 namespace { | |
| 21 | |
| 22 typedef std::pair<std::string, std::string> Setting; | |
| 23 | |
| 24 // Settings representing the following tree: | |
| 25 // |--Folder1 | |
| 26 // |--SubFolder | |
| 27 // |--Empty SubSubFolder | |
| 28 // |--Google(google.com) | |
| 29 // |--(www.theoatmeal.com) | |
| 30 // |--Test(www.test.de) | |
| 31 // |--Empty Folder | |
| 32 // |--XKCD(m.xkcd.com) | |
| 33 | |
| 34 // Folder setting format: "<ID>", "<ParentID>:<Name>" | |
| 35 const Setting FOLDER_SETTINGS[] = { | |
| 36 Setting("5", "0:Folder1"), | |
| 37 Setting("9", "0:Empty Folder"), | |
| 38 Setting("3", "5:SubFolder"), | |
| 39 Setting("4", "3:Empty SubSubFolder"), | |
| 40 }; | |
| 41 | |
| 42 const Setting FOLDER_SETTINGS_INVALID_PARENT[] = { | |
| 43 Setting("5", "0:Folder1"), | |
| 44 Setting("9", "7:Empty Folder"), // Invalid parent id. | |
| 45 Setting("3", "5:SubFolder"), | |
| 46 Setting("4", "3:Empty SubSubFolder"), | |
| 47 }; | |
| 48 | |
| 49 const Setting FOLDER_SETTINGS_CIRCLE[] = { | |
| 50 Setting("5", "3:Folder1"), | |
| 51 Setting("9", "5:Empty Folder"), | |
| 52 Setting("3", "9:SubFolder"), | |
| 53 }; | |
| 54 | |
| 55 // Link setting format: "<ID>:<URL>", "<ParentID>:<Name>" | |
| 56 const Setting LINK_SETTINGS[] = { | |
| 57 Setting("4:www.theoatmeal.com", "3:"), | |
| 58 Setting("1:m.xkcd.com", "0:XKCD"), | |
| 59 Setting("2:www.test.de", "5:Test"), | |
| 60 Setting("3:google.com", "3:Google"), | |
| 61 }; | |
| 62 | |
| 63 const Setting LINK_SETTINGS_INVALID_PARENT[] = { | |
| 64 Setting("4:www.theoatmeal.com", "3:"), | |
| 65 Setting("1:m.xkcd.com", "7:XKCD"), // Invalid parent id. | |
| 66 Setting("2:www.test.de", "8:Test"), // Invalid parent id. | |
| 67 }; | |
| 68 | |
| 69 // Parsed data is sorted by ID (even though the parsed links don't actually | |
| 70 // contain their IDs!) | |
| 71 | |
| 72 const Folder PARSED_FOLDERS[] = { | |
| 73 Folder(3, "SubFolder", 5), // Note: Forward reference. | |
| 74 Folder(4, "Empty SubSubFolder", 3), | |
| 75 Folder(5, "Folder1", 0), | |
| 76 Folder(9, "Empty Folder", 0), | |
| 77 }; | |
| 78 | |
| 79 const Link PARSED_LINKS[] = { | |
| 80 Link("m.xkcd.com", "XKCD", 0), | |
| 81 Link("www.test.de", "Test", 5), | |
| 82 Link("google.com", "Google", 3), | |
| 83 Link("www.theoatmeal.com", std::string(), 3), | |
| 84 }; | |
| 85 | |
| 86 const char BOOKMARKS_TREE_JSON[] = | |
| 87 "[" | |
| 88 " {" | |
| 89 " \"id\":5," | |
| 90 " \"name\":\"Folder1\"," | |
| 91 " \"children\":[" | |
| 92 " {" | |
| 93 " \"id\":3," | |
| 94 " \"name\":\"SubFolder\"," | |
| 95 " \"children\":[" | |
| 96 " {" | |
| 97 " \"id\":4," | |
| 98 " \"name\":\"Empty SubSubFolder\"," | |
| 99 " \"children\":[]" | |
| 100 " }," | |
| 101 " {" | |
| 102 " \"name\":\"Google\"," | |
| 103 " \"url\":\"http://google.com/\"" | |
| 104 " }," | |
| 105 " {" | |
| 106 " \"name\":\"\"," | |
| 107 " \"url\":\"http://www.theoatmeal.com/\"" | |
| 108 " }" | |
| 109 " ]" | |
| 110 " }," | |
| 111 " {" | |
| 112 " \"name\":\"Test\"," | |
| 113 " \"url\":\"http://www.test.de/\"" | |
| 114 " }" | |
| 115 " ]" | |
| 116 " }," | |
| 117 " {" | |
| 118 " \"id\":9," | |
| 119 " \"name\":\"Empty Folder\"," | |
| 120 " \"children\":[]" | |
| 121 " }," | |
| 122 " {" | |
| 123 " \"name\":\"XKCD\"," | |
| 124 " \"url\":\"http://m.xkcd.com/\"" | |
| 125 " }" | |
| 126 "]"; | |
| 127 | |
| 128 const char BOOKMARKS_TREE_INVALID_PARENTS_JSON[] = | |
| 129 "[" | |
| 130 " {" | |
| 131 " \"id\":5," | |
| 132 " \"name\":\"Folder1\"," | |
| 133 " \"children\":[" | |
| 134 " {" | |
| 135 " \"id\":3," | |
| 136 " \"name\":\"SubFolder\"," | |
| 137 " \"children\":[" | |
| 138 " {" | |
| 139 " \"id\":4," | |
| 140 " \"name\":\"Empty SubSubFolder\"," | |
| 141 " \"children\":[]" | |
| 142 " }," | |
| 143 " {" | |
| 144 " \"name\":\"\"," | |
| 145 " \"url\":\"http://www.theoatmeal.com/\"" | |
| 146 " }" | |
| 147 " ]" | |
| 148 " }" | |
| 149 " ]" | |
| 150 " }" | |
| 151 "]"; | |
| 152 | |
| 153 // Builds the base::Values tree from a json string above. | |
| 154 scoped_ptr<base::ListValue> CreateTree(const char* json) { | |
| 155 base::Value* value = base::JSONReader::Read(json); | |
| 156 EXPECT_NE(value, nullptr); | |
| 157 base::ListValue* list; | |
| 158 EXPECT_TRUE(value->GetAsList(&list)); | |
| 159 return make_scoped_ptr(list); | |
| 160 } | |
| 161 | |
| 162 scoped_ptr<base::ListValue> CreateBookmarksTree() { | |
| 163 return CreateTree(BOOKMARKS_TREE_JSON); | |
| 164 } | |
| 165 | |
| 166 scoped_ptr<base::ListValue> CreateBookmarksTreeWithInvalidParents() { | |
| 167 return CreateTree(BOOKMARKS_TREE_INVALID_PARENTS_JSON); | |
| 168 } | |
| 169 | |
| 170 } // namespace | |
| 171 | |
| 172 static bool operator==(const Folder& f1, const Folder& f2) { | |
| 173 return f1.id == f2.id && f1.name == f2.name && f1.parent_id == f2.parent_id; | |
| 174 } | |
| 175 | |
| 176 static bool operator==(const Link& l1, const Link& l2) { | |
| 177 return l1.url == l2.url && l1.name == l2.name && l1.parent_id == l2.parent_id; | |
| 178 } | |
| 179 | |
| 180 std::ostream& operator<<(std::ostream& str, const Folder& folder) { | |
| 181 str << folder.id << " " << folder.name << " " << folder.parent_id; | |
| 182 return str; | |
| 183 } | |
| 184 | |
| 185 std::ostream& operator<<(std::ostream& str, const Link& link) { | |
| 186 str << link.url << " " << link.name << " " << link.parent_id; | |
| 187 return str; | |
| 188 } | |
| 189 | |
| 190 class SupervisedUserBookmarksHandlerTest : public ::testing::Test { | |
| 191 protected: | |
| 192 static base::DictionaryValue* CreateSettings(base::DictionaryValue* links, | |
| 193 base::DictionaryValue* folders) { | |
| 194 base::DictionaryValue* settings = new base::DictionaryValue; | |
| 195 settings->SetStringWithoutPathExpansion("some_setting", "bleh"); | |
| 196 settings->SetWithoutPathExpansion("SupervisedBookmarkLink", links); | |
| 197 settings->SetStringWithoutPathExpansion("some_other_setting", "foo"); | |
| 198 settings->SetWithoutPathExpansion("SupervisedBookmarkFolder", folders); | |
| 199 settings->SetStringWithoutPathExpansion("another_one", "blurb"); | |
| 200 return settings; | |
| 201 } | |
| 202 | |
| 203 static base::DictionaryValue* CreateDictionary(const Setting* begin, | |
| 204 const Setting* end) { | |
| 205 base::DictionaryValue* dict = new base::DictionaryValue; | |
| 206 for (const Setting* setting = begin; setting != end; ++setting) | |
| 207 dict->SetStringWithoutPathExpansion(setting->first, setting->second); | |
| 208 return dict; | |
| 209 } | |
| 210 | |
| 211 static base::DictionaryValue* CreateLinkDictionary() { | |
| 212 return CreateDictionary(LINK_SETTINGS, | |
| 213 LINK_SETTINGS + arraysize(LINK_SETTINGS)); | |
| 214 } | |
| 215 | |
| 216 static base::DictionaryValue* CreateLinkDictionaryWithInvalidParents() { | |
| 217 return CreateDictionary( | |
| 218 LINK_SETTINGS_INVALID_PARENT, | |
| 219 LINK_SETTINGS_INVALID_PARENT + arraysize(LINK_SETTINGS_INVALID_PARENT)); | |
| 220 } | |
| 221 | |
| 222 static base::DictionaryValue* CreateFolderDictionary() { | |
| 223 return CreateDictionary(FOLDER_SETTINGS, | |
| 224 FOLDER_SETTINGS + arraysize(FOLDER_SETTINGS)); | |
| 225 } | |
| 226 | |
| 227 static base::DictionaryValue* CreateFolderDictionaryWithInvalidParents() { | |
| 228 return CreateDictionary( | |
| 229 FOLDER_SETTINGS_INVALID_PARENT, | |
| 230 FOLDER_SETTINGS_INVALID_PARENT + | |
| 231 arraysize(FOLDER_SETTINGS_INVALID_PARENT)); | |
| 232 } | |
| 233 | |
| 234 static base::DictionaryValue* CreateFolderDictionaryWithCircle() { | |
| 235 return CreateDictionary( | |
| 236 FOLDER_SETTINGS_CIRCLE, | |
| 237 FOLDER_SETTINGS_CIRCLE + arraysize(FOLDER_SETTINGS_CIRCLE)); | |
| 238 } | |
| 239 | |
| 240 void ParseFolders(const base::DictionaryValue& folders) { | |
| 241 deserializer_.ParseFolders(folders); | |
| 242 } | |
| 243 | |
| 244 void ParseLinks(const base::DictionaryValue& links) { | |
| 245 deserializer_.ParseLinks(links); | |
| 246 } | |
| 247 | |
| 248 const std::vector<Folder>& GetFolders() const { | |
| 249 return deserializer_.folders_for_testing(); | |
| 250 } | |
| 251 | |
| 252 const std::vector<Link>& GetLinks() const { | |
| 253 return deserializer_.links_for_testing(); | |
| 254 } | |
| 255 | |
| 256 private: | |
| 257 SupervisedUserBookmarksHandler deserializer_; | |
| 258 }; | |
| 259 | |
| 260 TEST_F(SupervisedUserBookmarksHandlerTest, ParseSettings) { | |
| 261 scoped_ptr<base::DictionaryValue> link_dictionary(CreateLinkDictionary()); | |
| 262 scoped_ptr<base::DictionaryValue> folder_dictionary(CreateFolderDictionary()); | |
| 263 | |
| 264 ParseLinks(*link_dictionary.get()); | |
| 265 ParseFolders(*folder_dictionary.get()); | |
| 266 | |
| 267 const std::vector<Link>& links = GetLinks(); | |
| 268 EXPECT_EQ(arraysize(PARSED_LINKS), links.size()); | |
| 269 for (size_t i = 0; i < links.size(); ++i) | |
| 270 EXPECT_EQ(PARSED_LINKS[i], links[i]); | |
| 271 | |
| 272 const std::vector<Folder>& folders = GetFolders(); | |
| 273 EXPECT_EQ(arraysize(PARSED_FOLDERS), folders.size()); | |
| 274 for (size_t i = 0; i < folders.size(); ++i) | |
| 275 EXPECT_EQ(PARSED_FOLDERS[i], folders[i]); | |
| 276 } | |
| 277 | |
| 278 TEST_F(SupervisedUserBookmarksHandlerTest, BuildBookmarksTree) { | |
| 279 scoped_ptr<base::DictionaryValue> settings( | |
|
Pam (message me for reviews)
2015/01/14 14:03:37
Please add comments explaining what's going on her
Marc Treib
2015/01/14 16:40:50
Done.
| |
| 280 CreateSettings(CreateLinkDictionary(), CreateFolderDictionary())); | |
| 281 scoped_ptr<base::ListValue> bookmarks( | |
| 282 SupervisedUserBookmarksHandler::BuildBookmarksTree(*settings.get())); | |
| 283 | |
| 284 scoped_ptr<base::ListValue> expected_bookmarks(CreateBookmarksTree()); | |
| 285 EXPECT_TRUE(bookmarks->Equals(expected_bookmarks.get())); | |
| 286 } | |
| 287 | |
| 288 TEST_F(SupervisedUserBookmarksHandlerTest, | |
| 289 BuildBookmarksTreeWithInvalidParents) { | |
| 290 scoped_ptr<base::DictionaryValue> settings( | |
| 291 CreateSettings(CreateLinkDictionaryWithInvalidParents(), | |
| 292 CreateFolderDictionaryWithInvalidParents())); | |
| 293 scoped_ptr<base::ListValue> bookmarks( | |
| 294 SupervisedUserBookmarksHandler::BuildBookmarksTree(*settings.get())); | |
| 295 | |
| 296 scoped_ptr<base::ListValue> expected_bookmarks( | |
| 297 CreateBookmarksTreeWithInvalidParents()); | |
| 298 EXPECT_TRUE(bookmarks->Equals(expected_bookmarks.get())); | |
| 299 } | |
| 300 | |
| 301 TEST_F(SupervisedUserBookmarksHandlerTest, Circle) { | |
| 302 scoped_ptr<base::DictionaryValue> settings( | |
| 303 CreateSettings(CreateLinkDictionary(), | |
| 304 CreateFolderDictionaryWithCircle())); | |
| 305 scoped_ptr<base::ListValue> bookmarks( | |
| 306 SupervisedUserBookmarksHandler::BuildBookmarksTree(*settings.get())); | |
| 307 // Don't care what exactly the result looks like, just that we don't run into | |
| 308 // an endless loop. | |
| 309 } | |
| OLD | NEW |