1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/places/tests/unit/test_bookmarks_html.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,385 @@ 1.4 +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim:set ts=2 sw=2 sts=2 et: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar"; 1.11 +const DESCRIPTION_ANNO = "bookmarkProperties/description"; 1.12 + 1.13 +// An object representing the contents of bookmarks.preplaces.html. 1.14 +let test_bookmarks = { 1.15 + menu: [ 1.16 + { title: "Mozilla Firefox", 1.17 + children: [ 1.18 + { title: "Help and Tutorials", 1.19 + url: "http://en-us.www.mozilla.com/en-US/firefox/help/", 1.20 + icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" 1.21 + }, 1.22 + { title: "Customize Firefox", 1.23 + url: "http://en-us.www.mozilla.com/en-US/firefox/customize/", 1.24 + icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" 1.25 + }, 1.26 + { title: "Get Involved", 1.27 + url: "http://en-us.www.mozilla.com/en-US/firefox/community/", 1.28 + icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" 1.29 + }, 1.30 + { title: "About Us", 1.31 + url: "http://en-us.www.mozilla.com/en-US/about/", 1.32 + icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" 1.33 + } 1.34 + ] 1.35 + }, 1.36 + { 1.37 + type: Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR 1.38 + }, 1.39 + { title: "test", 1.40 + description: "folder test comment", 1.41 + dateAdded: 1177541020000000, 1.42 + lastModified: 1177541050000000, 1.43 + children: [ 1.44 + { title: "test post keyword", 1.45 + description: "item description", 1.46 + dateAdded: 1177375336000000, 1.47 + lastModified: 1177375423000000, 1.48 + keyword: "test", 1.49 + sidebar: true, 1.50 + postData: "hidden1%3Dbar&text1%3D%25s", 1.51 + charset: "ISO-8859-1" 1.52 + } 1.53 + ] 1.54 + } 1.55 + ], 1.56 + toolbar: [ 1.57 + { title: "Getting Started", 1.58 + url: "http://en-us.www.mozilla.com/en-US/firefox/central/", 1.59 + icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" 1.60 + }, 1.61 + { title: "Latest Headlines", 1.62 + url: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/", 1.63 + feedUrl: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml" 1.64 + } 1.65 + ], 1.66 + unfiled: [ 1.67 + { title: "Example.tld", 1.68 + url: "http://example.tld/" 1.69 + } 1.70 + ] 1.71 +}; 1.72 + 1.73 +// Pre-Places bookmarks.html file pointer. 1.74 +let gBookmarksFileOld; 1.75 +// Places bookmarks.html file pointer. 1.76 +let gBookmarksFileNew; 1.77 + 1.78 +Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm"); 1.79 + 1.80 +function run_test() 1.81 +{ 1.82 + run_next_test(); 1.83 +} 1.84 + 1.85 +add_task(function setup() { 1.86 + // Avoid creating smart bookmarks during the test. 1.87 + Services.prefs.setIntPref("browser.places.smartBookmarksVersion", -1); 1.88 + 1.89 + // File pointer to legacy bookmarks file. 1.90 + gBookmarksFileOld = do_get_file("bookmarks.preplaces.html"); 1.91 + 1.92 + // File pointer to a new Places-exported bookmarks file. 1.93 + gBookmarksFileNew = Services.dirsvc.get("ProfD", Ci.nsILocalFile); 1.94 + gBookmarksFileNew.append("bookmarks.exported.html"); 1.95 + if (gBookmarksFileNew.exists()) { 1.96 + gBookmarksFileNew.remove(false); 1.97 + } 1.98 + 1.99 + // This test must be the first one, since it setups the new bookmarks.html. 1.100 + // Test importing a pre-Places canonical bookmarks file. 1.101 + // 1. import bookmarks.preplaces.html 1.102 + // 2. run the test-suite 1.103 + // Note: we do not empty the db before this import to catch bugs like 380999 1.104 + yield BookmarkHTMLUtils.importFromFile(gBookmarksFileOld, true); 1.105 + yield promiseAsyncUpdates(); 1.106 + yield testImportedBookmarks(); 1.107 + 1.108 + yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew); 1.109 + yield promiseAsyncUpdates(); 1.110 + remove_all_bookmarks(); 1.111 +}); 1.112 + 1.113 +add_task(function test_import_new() 1.114 +{ 1.115 + // Test importing a Places bookmarks.html file. 1.116 + // 1. import bookmarks.exported.html 1.117 + // 2. run the test-suite 1.118 + yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true); 1.119 + yield promiseAsyncUpdates(); 1.120 + 1.121 + yield testImportedBookmarks(); 1.122 + yield promiseAsyncUpdates(); 1.123 + 1.124 + remove_all_bookmarks(); 1.125 +}); 1.126 + 1.127 +add_task(function test_emptytitle_export() 1.128 +{ 1.129 + // Test exporting and importing with an empty-titled bookmark. 1.130 + // 1. import bookmarks 1.131 + // 2. create an empty-titled bookmark. 1.132 + // 3. export to bookmarks.exported.html 1.133 + // 4. empty bookmarks db 1.134 + // 5. import bookmarks.exported.html 1.135 + // 6. run the test-suite 1.136 + // 7. remove the empty-titled bookmark 1.137 + // 8. export to bookmarks.exported.html 1.138 + // 9. empty bookmarks db and continue 1.139 + 1.140 + yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true); 1.141 + 1.142 + const NOTITLE_URL = "http://notitle.mozilla.org/"; 1.143 + let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId, 1.144 + NetUtil.newURI(NOTITLE_URL), 1.145 + PlacesUtils.bookmarks.DEFAULT_INDEX, 1.146 + ""); 1.147 + test_bookmarks.unfiled.push({ title: "", url: NOTITLE_URL }); 1.148 + 1.149 + yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew); 1.150 + remove_all_bookmarks(); 1.151 + 1.152 + yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true); 1.153 + yield promiseAsyncUpdates(); 1.154 + yield testImportedBookmarks(); 1.155 + 1.156 + // Cleanup. 1.157 + test_bookmarks.unfiled.pop(); 1.158 + PlacesUtils.bookmarks.removeItem(id); 1.159 + 1.160 + yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew); 1.161 + yield promiseAsyncUpdates(); 1.162 + remove_all_bookmarks(); 1.163 +}); 1.164 + 1.165 +add_task(function test_import_chromefavicon() 1.166 +{ 1.167 + // Test exporting and importing with a bookmark pointing to a chrome favicon. 1.168 + // 1. import bookmarks 1.169 + // 2. create a bookmark pointing to a chrome favicon. 1.170 + // 3. export to bookmarks.exported.html 1.171 + // 4. empty bookmarks db 1.172 + // 5. import bookmarks.exported.html 1.173 + // 6. run the test-suite 1.174 + // 7. remove the bookmark pointing to a chrome favicon. 1.175 + // 8. export to bookmarks.exported.html 1.176 + // 9. empty bookmarks db and continue 1.177 + 1.178 + const PAGE_URI = NetUtil.newURI("http://example.com/chromefavicon_page"); 1.179 + const CHROME_FAVICON_URI = NetUtil.newURI("chrome://global/skin/icons/information-16.png"); 1.180 + const CHROME_FAVICON_URI_2 = NetUtil.newURI("chrome://global/skin/icons/error-16.png"); 1.181 + 1.182 + yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true); 1.183 + let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId, 1.184 + PAGE_URI, 1.185 + PlacesUtils.bookmarks.DEFAULT_INDEX, 1.186 + "Test"); 1.187 + 1.188 + let deferred = Promise.defer(); 1.189 + PlacesUtils.favicons.setAndFetchFaviconForPage( 1.190 + PAGE_URI, CHROME_FAVICON_URI, true, 1.191 + PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, 1.192 + deferred.resolve); 1.193 + yield deferred.promise; 1.194 + 1.195 + deferred = Promise.defer(); 1.196 + PlacesUtils.favicons.getFaviconDataForPage(PAGE_URI, 1.197 + function (aURI, aDataLen, aData, aMimeType) deferred.resolve(aData)); 1.198 + let data = yield deferred.promise; 1.199 + 1.200 + let base64Icon = "data:image/png;base64," + 1.201 + base64EncodeString(String.fromCharCode.apply(String, data)); 1.202 + 1.203 + test_bookmarks.unfiled.push( 1.204 + { title: "Test", url: PAGE_URI.spec, icon: base64Icon }); 1.205 + 1.206 + yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew); 1.207 + 1.208 + // Change the favicon to check it's really imported again later. 1.209 + deferred = Promise.defer(); 1.210 + PlacesUtils.favicons.setAndFetchFaviconForPage( 1.211 + PAGE_URI, CHROME_FAVICON_URI_2, true, 1.212 + PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, 1.213 + deferred.resolve); 1.214 + yield deferred.promise; 1.215 + 1.216 + remove_all_bookmarks(); 1.217 + 1.218 + yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true); 1.219 + yield promiseAsyncUpdates(); 1.220 + yield testImportedBookmarks(); 1.221 + 1.222 + // Cleanup. 1.223 + test_bookmarks.unfiled.pop(); 1.224 + PlacesUtils.bookmarks.removeItem(id); 1.225 + 1.226 + yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew); 1.227 + yield promiseAsyncUpdates(); 1.228 + remove_all_bookmarks(); 1.229 +}); 1.230 + 1.231 +add_task(function test_import_ontop() 1.232 +{ 1.233 + // Test importing the exported bookmarks.html file *on top of* the existing 1.234 + // bookmarks. 1.235 + // 1. empty bookmarks db 1.236 + // 2. import the exported bookmarks file 1.237 + // 3. export to file 1.238 + // 3. import the exported bookmarks file 1.239 + // 4. run the test-suite 1.240 + 1.241 + yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true); 1.242 + yield BookmarkHTMLUtils.exportToFile(gBookmarksFileNew); 1.243 + yield BookmarkHTMLUtils.importFromFile(gBookmarksFileNew, true); 1.244 + yield promiseAsyncUpdates(); 1.245 + yield testImportedBookmarks(); 1.246 + yield promiseAsyncUpdates(); 1.247 + remove_all_bookmarks(); 1.248 +}); 1.249 + 1.250 +function testImportedBookmarks() 1.251 +{ 1.252 + for (let group in test_bookmarks) { 1.253 + do_print("[testImportedBookmarks()] Checking group '" + group + "'"); 1.254 + 1.255 + let root; 1.256 + switch (group) { 1.257 + case "menu": 1.258 + root = PlacesUtils.getFolderContents(PlacesUtils.bookmarksMenuFolderId).root; 1.259 + break; 1.260 + case "toolbar": 1.261 + root = PlacesUtils.getFolderContents(PlacesUtils.toolbarFolderId).root; 1.262 + break; 1.263 + case "unfiled": 1.264 + root = PlacesUtils.getFolderContents(PlacesUtils.unfiledBookmarksFolderId).root; 1.265 + break; 1.266 + } 1.267 + 1.268 + let items = test_bookmarks[group]; 1.269 + do_check_eq(root.childCount, items.length); 1.270 + 1.271 + for (let key in items) { 1.272 + yield checkItem(items[key], root.getChild(key)); 1.273 + } 1.274 + 1.275 + root.containerOpen = false; 1.276 + } 1.277 +} 1.278 + 1.279 +function testImportedBookmarksToFolder(aFolder) 1.280 +{ 1.281 + root = PlacesUtils.getFolderContents(aFolder).root; 1.282 + 1.283 + // Menu bookmarks are put directly into the folder, while other roots are 1.284 + // imported into subfolders. 1.285 + let rootFolderCount = test_bookmarks.menu.length; 1.286 + 1.287 + for (let i = 0; i < root.childCount; i++) { 1.288 + let child = root.getChild(i); 1.289 + // This check depends on all "menu" bookmarks being listed first in the imported file :-| 1.290 + if (i < rootFolderCount) { 1.291 + checkItem(test_bookmarks.menu[i], child); 1.292 + } 1.293 + else { 1.294 + let container = child.QueryInterface(Ci.nsINavHistoryContainerResultNode); 1.295 + let group = /Toolbar/.test(container.title) ? test_bookmarks.toolbar 1.296 + : test_bookmarks.unfiled; 1.297 + container.containerOpen = true; 1.298 + do_print("[testImportedBookmarksToFolder()] Checking container '" + container.title + "'"); 1.299 + for (let t = 0; t < container.childCount; t++) { 1.300 + checkItem(group[t], container.getChild(t)); 1.301 + } 1.302 + container.containerOpen = false; 1.303 + } 1.304 + } 1.305 + 1.306 + root.containerOpen = false; 1.307 +} 1.308 + 1.309 +function checkItem(aExpected, aNode) 1.310 +{ 1.311 + let id = aNode.itemId; 1.312 + 1.313 + return Task.spawn(function() { 1.314 + for (prop in aExpected) { 1.315 + switch (prop) { 1.316 + case "type": 1.317 + do_check_eq(aNode.type, aExpected.type); 1.318 + break; 1.319 + case "title": 1.320 + do_check_eq(aNode.title, aExpected.title); 1.321 + break; 1.322 + case "description": 1.323 + do_check_eq(PlacesUtils.annotations 1.324 + .getItemAnnotation(id, DESCRIPTION_ANNO), 1.325 + aExpected.description); 1.326 + break; 1.327 + case "dateAdded": 1.328 + do_check_eq(PlacesUtils.bookmarks.getItemDateAdded(id), 1.329 + aExpected.dateAdded); 1.330 + break; 1.331 + case "lastModified": 1.332 + do_check_eq(PlacesUtils.bookmarks.getItemLastModified(id), 1.333 + aExpected.lastModified); 1.334 + break; 1.335 + case "url": 1.336 + if (!("feedUrl" in aExpected)) 1.337 + do_check_eq(aNode.uri, aExpected.url) 1.338 + break; 1.339 + case "icon": 1.340 + let (deferred = Promise.defer(), data) { 1.341 + PlacesUtils.favicons.getFaviconDataForPage( 1.342 + NetUtil.newURI(aExpected.url), 1.343 + function (aURI, aDataLen, aData, aMimeType) { 1.344 + deferred.resolve(aData); 1.345 + }); 1.346 + data = yield deferred.promise; 1.347 + let base64Icon = "data:image/png;base64," + 1.348 + base64EncodeString(String.fromCharCode.apply(String, data)); 1.349 + do_check_true(base64Icon == aExpected.icon); 1.350 + } 1.351 + break; 1.352 + case "keyword": 1.353 + break; 1.354 + case "sidebar": 1.355 + do_check_eq(PlacesUtils.annotations 1.356 + .itemHasAnnotation(id, LOAD_IN_SIDEBAR_ANNO), 1.357 + aExpected.sidebar); 1.358 + break; 1.359 + case "postData": 1.360 + do_check_eq(PlacesUtils.annotations 1.361 + .getItemAnnotation(id, PlacesUtils.POST_DATA_ANNO), 1.362 + aExpected.postData); 1.363 + break; 1.364 + case "charset": 1.365 + let testURI = NetUtil.newURI(aNode.uri); 1.366 + do_check_eq((yield PlacesUtils.getCharsetForURI(testURI)), aExpected.charset); 1.367 + break; 1.368 + case "feedUrl": 1.369 + let livemark = yield PlacesUtils.livemarks.getLivemark({ id: id }); 1.370 + do_check_eq(livemark.siteURI.spec, aExpected.url); 1.371 + do_check_eq(livemark.feedURI.spec, aExpected.feedUrl); 1.372 + break; 1.373 + case "children": 1.374 + let folder = aNode.QueryInterface(Ci.nsINavHistoryContainerResultNode); 1.375 + do_check_eq(folder.hasChildren, aExpected.children.length > 0); 1.376 + folder.containerOpen = true; 1.377 + do_check_eq(folder.childCount, aExpected.children.length); 1.378 + 1.379 + aExpected.children.forEach(function (item, index) checkItem(item, folder.getChild(index))); 1.380 + 1.381 + folder.containerOpen = false; 1.382 + break; 1.383 + default: 1.384 + throw new Error("Unknown property"); 1.385 + } 1.386 + } 1.387 + }); 1.388 +}