1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/places/tests/bookmarks/test_bookmarks.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,738 @@ 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 +let bs = PlacesUtils.bookmarks; 1.11 +let hs = PlacesUtils.history; 1.12 +let anno = PlacesUtils.annotations; 1.13 + 1.14 + 1.15 +let bookmarksObserver = { 1.16 + onBeginUpdateBatch: function() { 1.17 + this._beginUpdateBatch = true; 1.18 + }, 1.19 + onEndUpdateBatch: function() { 1.20 + this._endUpdateBatch = true; 1.21 + }, 1.22 + onItemAdded: function(id, folder, index, itemType, uri, title, dateAdded, 1.23 + guid) { 1.24 + this._itemAddedId = id; 1.25 + this._itemAddedParent = folder; 1.26 + this._itemAddedIndex = index; 1.27 + this._itemAddedURI = uri; 1.28 + this._itemAddedTitle = title; 1.29 + 1.30 + // Ensure that we've created a guid for this item. 1.31 + let stmt = DBConn().createStatement( 1.32 + "SELECT guid " 1.33 + + "FROM moz_bookmarks " 1.34 + + "WHERE id = :item_id " 1.35 + ); 1.36 + stmt.params.item_id = id; 1.37 + do_check_true(stmt.executeStep()); 1.38 + do_check_false(stmt.getIsNull(0)); 1.39 + do_check_valid_places_guid(stmt.row.guid); 1.40 + do_check_eq(stmt.row.guid, guid); 1.41 + stmt.finalize(); 1.42 + }, 1.43 + onItemRemoved: function(id, folder, index, itemType) { 1.44 + this._itemRemovedId = id; 1.45 + this._itemRemovedFolder = folder; 1.46 + this._itemRemovedIndex = index; 1.47 + }, 1.48 + onItemChanged: function(id, property, isAnnotationProperty, value, 1.49 + lastModified, itemType) { 1.50 + this._itemChangedId = id; 1.51 + this._itemChangedProperty = property; 1.52 + this._itemChanged_isAnnotationProperty = isAnnotationProperty; 1.53 + this._itemChangedValue = value; 1.54 + }, 1.55 + onItemVisited: function(id, visitID, time) { 1.56 + this._itemVisitedId = id; 1.57 + this._itemVisitedVistId = visitID; 1.58 + this._itemVisitedTime = time; 1.59 + }, 1.60 + onItemMoved: function(id, oldParent, oldIndex, newParent, newIndex, 1.61 + itemType) { 1.62 + this._itemMovedId = id 1.63 + this._itemMovedOldParent = oldParent; 1.64 + this._itemMovedOldIndex = oldIndex; 1.65 + this._itemMovedNewParent = newParent; 1.66 + this._itemMovedNewIndex = newIndex; 1.67 + }, 1.68 + QueryInterface: XPCOMUtils.generateQI([ 1.69 + Ci.nsINavBookmarkObserver, 1.70 + ]) 1.71 +}; 1.72 + 1.73 + 1.74 +// Get bookmarks menu folder id. 1.75 +let root = bs.bookmarksMenuFolder; 1.76 +// Index at which items should begin. 1.77 +let bmStartIndex = 0; 1.78 + 1.79 + 1.80 +function run_test() { 1.81 + run_next_test(); 1.82 +} 1.83 + 1.84 +add_task(function test_bookmarks() { 1.85 + bs.addObserver(bookmarksObserver, false); 1.86 + 1.87 + // test special folders 1.88 + do_check_true(bs.placesRoot > 0); 1.89 + do_check_true(bs.bookmarksMenuFolder > 0); 1.90 + do_check_true(bs.tagsFolder > 0); 1.91 + do_check_true(bs.toolbarFolder > 0); 1.92 + do_check_true(bs.unfiledBookmarksFolder > 0); 1.93 + 1.94 + // test getFolderIdForItem() with bogus item id will throw 1.95 + try { 1.96 + let id = bs.getFolderIdForItem(0); 1.97 + do_throw("getFolderIdForItem accepted bad input"); 1.98 + } catch(ex) {} 1.99 + 1.100 + // test getFolderIdForItem() with bogus item id will throw 1.101 + try { 1.102 + let id = bs.getFolderIdForItem(-1); 1.103 + do_throw("getFolderIdForItem accepted bad input"); 1.104 + } catch(ex) {} 1.105 + 1.106 + // test root parentage 1.107 + do_check_eq(bs.getFolderIdForItem(bs.bookmarksMenuFolder), bs.placesRoot); 1.108 + do_check_eq(bs.getFolderIdForItem(bs.tagsFolder), bs.placesRoot); 1.109 + do_check_eq(bs.getFolderIdForItem(bs.toolbarFolder), bs.placesRoot); 1.110 + do_check_eq(bs.getFolderIdForItem(bs.unfiledBookmarksFolder), bs.placesRoot); 1.111 + 1.112 + // create a folder to hold all the tests 1.113 + // this makes the tests more tolerant of changes to default_places.html 1.114 + let testRoot = bs.createFolder(root, "places bookmarks xpcshell tests", 1.115 + bs.DEFAULT_INDEX); 1.116 + do_check_eq(bookmarksObserver._itemAddedId, testRoot); 1.117 + do_check_eq(bookmarksObserver._itemAddedParent, root); 1.118 + do_check_eq(bookmarksObserver._itemAddedIndex, bmStartIndex); 1.119 + do_check_eq(bookmarksObserver._itemAddedURI, null); 1.120 + let testStartIndex = 0; 1.121 + 1.122 + // test getItemIndex for folders 1.123 + do_check_eq(bs.getItemIndex(testRoot), bmStartIndex); 1.124 + 1.125 + // test getItemType for folders 1.126 + do_check_eq(bs.getItemType(testRoot), bs.TYPE_FOLDER); 1.127 + 1.128 + // insert a bookmark. 1.129 + // the time before we insert, in microseconds 1.130 + let beforeInsert = Date.now() * 1000; 1.131 + do_check_true(beforeInsert > 0); 1.132 + 1.133 + let newId = bs.insertBookmark(testRoot, uri("http://google.com/"), 1.134 + bs.DEFAULT_INDEX, ""); 1.135 + do_check_eq(bookmarksObserver._itemAddedId, newId); 1.136 + do_check_eq(bookmarksObserver._itemAddedParent, testRoot); 1.137 + do_check_eq(bookmarksObserver._itemAddedIndex, testStartIndex); 1.138 + do_check_true(bookmarksObserver._itemAddedURI.equals(uri("http://google.com/"))); 1.139 + do_check_eq(bs.getBookmarkURI(newId).spec, "http://google.com/"); 1.140 + 1.141 + let dateAdded = bs.getItemDateAdded(newId); 1.142 + // dateAdded can equal beforeInsert 1.143 + do_check_true(is_time_ordered(beforeInsert, dateAdded)); 1.144 + 1.145 + // after just inserting, modified should not be set 1.146 + let lastModified = bs.getItemLastModified(newId); 1.147 + do_check_eq(lastModified, dateAdded); 1.148 + 1.149 + // The time before we set the title, in microseconds. 1.150 + let beforeSetTitle = Date.now() * 1000; 1.151 + do_check_true(beforeSetTitle >= beforeInsert); 1.152 + 1.153 + // Workaround possible VM timers issues moving lastModified and dateAdded 1.154 + // to the past. 1.155 + bs.setItemLastModified(newId, --lastModified); 1.156 + bs.setItemDateAdded(newId, --dateAdded); 1.157 + 1.158 + // set bookmark title 1.159 + bs.setItemTitle(newId, "Google"); 1.160 + do_check_eq(bookmarksObserver._itemChangedId, newId); 1.161 + do_check_eq(bookmarksObserver._itemChangedProperty, "title"); 1.162 + do_check_eq(bookmarksObserver._itemChangedValue, "Google"); 1.163 + 1.164 + // check that dateAdded hasn't changed 1.165 + let dateAdded2 = bs.getItemDateAdded(newId); 1.166 + do_check_eq(dateAdded2, dateAdded); 1.167 + 1.168 + // check lastModified after we set the title 1.169 + let lastModified2 = bs.getItemLastModified(newId); 1.170 + LOG("test setItemTitle"); 1.171 + LOG("dateAdded = " + dateAdded); 1.172 + LOG("beforeSetTitle = " + beforeSetTitle); 1.173 + LOG("lastModified = " + lastModified); 1.174 + LOG("lastModified2 = " + lastModified2); 1.175 + do_check_true(is_time_ordered(lastModified, lastModified2)); 1.176 + do_check_true(is_time_ordered(dateAdded, lastModified2)); 1.177 + 1.178 + // get item title 1.179 + let title = bs.getItemTitle(newId); 1.180 + do_check_eq(title, "Google"); 1.181 + 1.182 + // test getItemType for bookmarks 1.183 + do_check_eq(bs.getItemType(newId), bs.TYPE_BOOKMARK); 1.184 + 1.185 + // get item title bad input 1.186 + try { 1.187 + let title = bs.getItemTitle(-3); 1.188 + do_throw("getItemTitle accepted bad input"); 1.189 + } catch(ex) {} 1.190 + 1.191 + // get the folder that the bookmark is in 1.192 + let folderId = bs.getFolderIdForItem(newId); 1.193 + do_check_eq(folderId, testRoot); 1.194 + 1.195 + // test getItemIndex for bookmarks 1.196 + do_check_eq(bs.getItemIndex(newId), testStartIndex); 1.197 + 1.198 + // create a folder at a specific index 1.199 + let workFolder = bs.createFolder(testRoot, "Work", 0); 1.200 + do_check_eq(bookmarksObserver._itemAddedId, workFolder); 1.201 + do_check_eq(bookmarksObserver._itemAddedParent, testRoot); 1.202 + do_check_eq(bookmarksObserver._itemAddedIndex, 0); 1.203 + do_check_eq(bookmarksObserver._itemAddedURI, null); 1.204 + 1.205 + do_check_eq(bs.getItemTitle(workFolder), "Work"); 1.206 + bs.setItemTitle(workFolder, "Work #"); 1.207 + do_check_eq(bs.getItemTitle(workFolder), "Work #"); 1.208 + 1.209 + // add item into subfolder, specifying index 1.210 + let newId2 = bs.insertBookmark(workFolder, 1.211 + uri("http://developer.mozilla.org/"), 1.212 + 0, ""); 1.213 + do_check_eq(bookmarksObserver._itemAddedId, newId2); 1.214 + do_check_eq(bookmarksObserver._itemAddedParent, workFolder); 1.215 + do_check_eq(bookmarksObserver._itemAddedIndex, 0); 1.216 + 1.217 + // change item 1.218 + bs.setItemTitle(newId2, "DevMo"); 1.219 + do_check_eq(bookmarksObserver._itemChangedProperty, "title"); 1.220 + 1.221 + // insert item into subfolder 1.222 + let newId3 = bs.insertBookmark(workFolder, 1.223 + uri("http://msdn.microsoft.com/"), 1.224 + bs.DEFAULT_INDEX, ""); 1.225 + do_check_eq(bookmarksObserver._itemAddedId, newId3); 1.226 + do_check_eq(bookmarksObserver._itemAddedParent, workFolder); 1.227 + do_check_eq(bookmarksObserver._itemAddedIndex, 1); 1.228 + 1.229 + // change item 1.230 + bs.setItemTitle(newId3, "MSDN"); 1.231 + do_check_eq(bookmarksObserver._itemChangedProperty, "title"); 1.232 + 1.233 + // remove item 1.234 + bs.removeItem(newId2); 1.235 + do_check_eq(bookmarksObserver._itemRemovedId, newId2); 1.236 + do_check_eq(bookmarksObserver._itemRemovedFolder, workFolder); 1.237 + do_check_eq(bookmarksObserver._itemRemovedIndex, 0); 1.238 + 1.239 + // insert item into subfolder 1.240 + let newId4 = bs.insertBookmark(workFolder, 1.241 + uri("http://developer.mozilla.org/"), 1.242 + bs.DEFAULT_INDEX, ""); 1.243 + do_check_eq(bookmarksObserver._itemAddedId, newId4); 1.244 + do_check_eq(bookmarksObserver._itemAddedParent, workFolder); 1.245 + do_check_eq(bookmarksObserver._itemAddedIndex, 1); 1.246 + 1.247 + // create folder 1.248 + let homeFolder = bs.createFolder(testRoot, "Home", bs.DEFAULT_INDEX); 1.249 + do_check_eq(bookmarksObserver._itemAddedId, homeFolder); 1.250 + do_check_eq(bookmarksObserver._itemAddedParent, testRoot); 1.251 + do_check_eq(bookmarksObserver._itemAddedIndex, 2); 1.252 + 1.253 + // insert item 1.254 + let newId5 = bs.insertBookmark(homeFolder, uri("http://espn.com/"), 1.255 + bs.DEFAULT_INDEX, ""); 1.256 + do_check_eq(bookmarksObserver._itemAddedId, newId5); 1.257 + do_check_eq(bookmarksObserver._itemAddedParent, homeFolder); 1.258 + do_check_eq(bookmarksObserver._itemAddedIndex, 0); 1.259 + 1.260 + // change item 1.261 + bs.setItemTitle(newId5, "ESPN"); 1.262 + do_check_eq(bookmarksObserver._itemChangedId, newId5); 1.263 + do_check_eq(bookmarksObserver._itemChangedProperty, "title"); 1.264 + 1.265 + // insert query item 1.266 + let uri6 = uri("place:domain=google.com&type="+ 1.267 + Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY); 1.268 + let newId6 = bs.insertBookmark(testRoot, uri6, bs.DEFAULT_INDEX, ""); 1.269 + do_check_eq(bookmarksObserver._itemAddedParent, testRoot); 1.270 + do_check_eq(bookmarksObserver._itemAddedIndex, 3); 1.271 + 1.272 + // change item 1.273 + bs.setItemTitle(newId6, "Google Sites"); 1.274 + do_check_eq(bookmarksObserver._itemChangedProperty, "title"); 1.275 + 1.276 + // test getIdForItemAt 1.277 + do_check_eq(bs.getIdForItemAt(testRoot, 0), workFolder); 1.278 + // wrong parent, should return -1 1.279 + do_check_eq(bs.getIdForItemAt(1337, 0), -1); 1.280 + // wrong index, should return -1 1.281 + do_check_eq(bs.getIdForItemAt(testRoot, 1337), -1); 1.282 + // wrong parent and index, should return -1 1.283 + do_check_eq(bs.getIdForItemAt(1337, 1337), -1); 1.284 + 1.285 + // move folder, appending, to different folder 1.286 + let oldParentCC = getChildCount(testRoot); 1.287 + bs.moveItem(workFolder, homeFolder, bs.DEFAULT_INDEX); 1.288 + do_check_eq(bookmarksObserver._itemMovedId, workFolder); 1.289 + do_check_eq(bookmarksObserver._itemMovedOldParent, testRoot); 1.290 + do_check_eq(bookmarksObserver._itemMovedOldIndex, 0); 1.291 + do_check_eq(bookmarksObserver._itemMovedNewParent, homeFolder); 1.292 + do_check_eq(bookmarksObserver._itemMovedNewIndex, 1); 1.293 + 1.294 + // test that the new index is properly stored 1.295 + do_check_eq(bs.getItemIndex(workFolder), 1); 1.296 + do_check_eq(bs.getFolderIdForItem(workFolder), homeFolder); 1.297 + 1.298 + // try to get index of the item from within the old parent folder 1.299 + // check that it has been really removed from there 1.300 + do_check_neq(bs.getIdForItemAt(testRoot, 0), workFolder); 1.301 + // check the last item from within the old parent folder 1.302 + do_check_neq(bs.getIdForItemAt(testRoot, -1), workFolder); 1.303 + // check the index of the item within the new parent folder 1.304 + do_check_eq(bs.getIdForItemAt(homeFolder, 1), workFolder); 1.305 + // try to get index of the last item within the new parent folder 1.306 + do_check_eq(bs.getIdForItemAt(homeFolder, -1), workFolder); 1.307 + // XXX expose FolderCount, and check that the old parent has one less child? 1.308 + do_check_eq(getChildCount(testRoot), oldParentCC-1); 1.309 + 1.310 + // move item, appending, to different folder 1.311 + bs.moveItem(newId5, testRoot, bs.DEFAULT_INDEX); 1.312 + do_check_eq(bookmarksObserver._itemMovedId, newId5); 1.313 + do_check_eq(bookmarksObserver._itemMovedOldParent, homeFolder); 1.314 + do_check_eq(bookmarksObserver._itemMovedOldIndex, 0); 1.315 + do_check_eq(bookmarksObserver._itemMovedNewParent, testRoot); 1.316 + do_check_eq(bookmarksObserver._itemMovedNewIndex, 3); 1.317 + 1.318 + // test get folder's index 1.319 + let tmpFolder = bs.createFolder(testRoot, "tmp", 2); 1.320 + do_check_eq(bs.getItemIndex(tmpFolder), 2); 1.321 + 1.322 + // test setKeywordForBookmark 1.323 + let kwTestItemId = bs.insertBookmark(testRoot, uri("http://keywordtest.com"), 1.324 + bs.DEFAULT_INDEX, ""); 1.325 + try { 1.326 + let dateAdded = bs.getItemDateAdded(kwTestItemId); 1.327 + // after just inserting, modified should not be set 1.328 + let lastModified = bs.getItemLastModified(kwTestItemId); 1.329 + do_check_eq(lastModified, dateAdded); 1.330 + 1.331 + // Workaround possible VM timers issues moving lastModified and dateAdded 1.332 + // to the past. 1.333 + bs.setItemLastModified(kwTestItemId, --lastModified); 1.334 + bs.setItemDateAdded(kwTestItemId, --dateAdded); 1.335 + 1.336 + bs.setKeywordForBookmark(kwTestItemId, "bar"); 1.337 + 1.338 + let lastModified2 = bs.getItemLastModified(kwTestItemId); 1.339 + LOG("test setKeywordForBookmark"); 1.340 + LOG("dateAdded = " + dateAdded); 1.341 + LOG("lastModified = " + lastModified); 1.342 + LOG("lastModified2 = " + lastModified2); 1.343 + do_check_true(is_time_ordered(lastModified, lastModified2)); 1.344 + do_check_true(is_time_ordered(dateAdded, lastModified2)); 1.345 + } catch(ex) { 1.346 + do_throw("setKeywordForBookmark: " + ex); 1.347 + } 1.348 + 1.349 + let lastModified3 = bs.getItemLastModified(kwTestItemId); 1.350 + // test getKeywordForBookmark 1.351 + let k = bs.getKeywordForBookmark(kwTestItemId); 1.352 + do_check_eq("bar", k); 1.353 + 1.354 + // test getKeywordForURI 1.355 + let k = bs.getKeywordForURI(uri("http://keywordtest.com/")); 1.356 + do_check_eq("bar", k); 1.357 + 1.358 + // test getURIForKeyword 1.359 + let u = bs.getURIForKeyword("bar"); 1.360 + do_check_eq("http://keywordtest.com/", u.spec); 1.361 + 1.362 + // test removeFolderChildren 1.363 + // 1) add/remove each child type (bookmark, separator, folder) 1.364 + let tmpFolder = bs.createFolder(testRoot, "removeFolderChildren", 1.365 + bs.DEFAULT_INDEX); 1.366 + bs.insertBookmark(tmpFolder, uri("http://foo9.com/"), bs.DEFAULT_INDEX, ""); 1.367 + bs.createFolder(tmpFolder, "subfolder", bs.DEFAULT_INDEX); 1.368 + bs.insertSeparator(tmpFolder, bs.DEFAULT_INDEX); 1.369 + // 2) confirm that folder has 3 children 1.370 + let options = hs.getNewQueryOptions(); 1.371 + let query = hs.getNewQuery(); 1.372 + query.setFolders([tmpFolder], 1); 1.373 + try { 1.374 + let result = hs.executeQuery(query, options); 1.375 + let rootNode = result.root; 1.376 + rootNode.containerOpen = true; 1.377 + do_check_eq(rootNode.childCount, 3); 1.378 + rootNode.containerOpen = false; 1.379 + } catch(ex) { 1.380 + do_throw("test removeFolderChildren() - querying for children failed: " + ex); 1.381 + } 1.382 + // 3) remove all children 1.383 + bs.removeFolderChildren(tmpFolder); 1.384 + // 4) confirm that folder has 0 children 1.385 + try { 1.386 + result = hs.executeQuery(query, options); 1.387 + let rootNode = result.root; 1.388 + rootNode.containerOpen = true; 1.389 + do_check_eq(rootNode.childCount, 0); 1.390 + rootNode.containerOpen = false; 1.391 + } catch(ex) { 1.392 + do_throw("removeFolderChildren(): " + ex); 1.393 + } 1.394 + 1.395 + // XXX - test folderReadOnly 1.396 + 1.397 + // test bookmark id in query output 1.398 + try { 1.399 + let options = hs.getNewQueryOptions(); 1.400 + let query = hs.getNewQuery(); 1.401 + query.setFolders([testRoot], 1); 1.402 + let result = hs.executeQuery(query, options); 1.403 + let rootNode = result.root; 1.404 + rootNode.containerOpen = true; 1.405 + let cc = rootNode.childCount; 1.406 + LOG("bookmark itemId test: CC = " + cc); 1.407 + do_check_true(cc > 0); 1.408 + for (let i=0; i < cc; ++i) { 1.409 + let node = rootNode.getChild(i); 1.410 + if (node.type == node.RESULT_TYPE_FOLDER || 1.411 + node.type == node.RESULT_TYPE_URI || 1.412 + node.type == node.RESULT_TYPE_SEPARATOR || 1.413 + node.type == node.RESULT_TYPE_QUERY) { 1.414 + do_check_true(node.itemId > 0); 1.415 + } 1.416 + else { 1.417 + do_check_eq(node.itemId, -1); 1.418 + } 1.419 + } 1.420 + rootNode.containerOpen = false; 1.421 + } 1.422 + catch(ex) { 1.423 + do_throw("bookmarks query: " + ex); 1.424 + } 1.425 + 1.426 + // test that multiple bookmarks with same URI show up right in bookmark 1.427 + // folder queries, todo: also to do for complex folder queries 1.428 + try { 1.429 + // test uri 1.430 + let mURI = uri("http://multiple.uris.in.query"); 1.431 + 1.432 + let testFolder = bs.createFolder(testRoot, "test Folder", bs.DEFAULT_INDEX); 1.433 + // add 2 bookmarks 1.434 + bs.insertBookmark(testFolder, mURI, bs.DEFAULT_INDEX, "title 1"); 1.435 + bs.insertBookmark(testFolder, mURI, bs.DEFAULT_INDEX, "title 2"); 1.436 + 1.437 + // query 1.438 + let options = hs.getNewQueryOptions(); 1.439 + let query = hs.getNewQuery(); 1.440 + query.setFolders([testFolder], 1); 1.441 + let result = hs.executeQuery(query, options); 1.442 + let rootNode = result.root; 1.443 + rootNode.containerOpen = true; 1.444 + let cc = rootNode.childCount; 1.445 + do_check_eq(cc, 2); 1.446 + do_check_eq(rootNode.getChild(0).title, "title 1"); 1.447 + do_check_eq(rootNode.getChild(1).title, "title 2"); 1.448 + rootNode.containerOpen = false; 1.449 + } 1.450 + catch(ex) { 1.451 + do_throw("bookmarks query: " + ex); 1.452 + } 1.453 + 1.454 + // test change bookmark uri 1.455 + let newId10 = bs.insertBookmark(testRoot, uri("http://foo10.com/"), 1.456 + bs.DEFAULT_INDEX, ""); 1.457 + let dateAdded = bs.getItemDateAdded(newId10); 1.458 + // after just inserting, modified should not be set 1.459 + let lastModified = bs.getItemLastModified(newId10); 1.460 + do_check_eq(lastModified, dateAdded); 1.461 + 1.462 + // Workaround possible VM timers issues moving lastModified and dateAdded 1.463 + // to the past. 1.464 + bs.setItemLastModified(newId10, --lastModified); 1.465 + bs.setItemDateAdded(newId10, --dateAdded); 1.466 + 1.467 + bs.changeBookmarkURI(newId10, uri("http://foo11.com/")); 1.468 + 1.469 + // check that lastModified is set after we change the bookmark uri 1.470 + let lastModified2 = bs.getItemLastModified(newId10); 1.471 + LOG("test changeBookmarkURI"); 1.472 + LOG("dateAdded = " + dateAdded); 1.473 + LOG("lastModified = " + lastModified); 1.474 + LOG("lastModified2 = " + lastModified2); 1.475 + do_check_true(is_time_ordered(lastModified, lastModified2)); 1.476 + do_check_true(is_time_ordered(dateAdded, lastModified2)); 1.477 + 1.478 + do_check_eq(bookmarksObserver._itemChangedId, newId10); 1.479 + do_check_eq(bookmarksObserver._itemChangedProperty, "uri"); 1.480 + do_check_eq(bookmarksObserver._itemChangedValue, "http://foo11.com/"); 1.481 + 1.482 + // test getBookmarkURI 1.483 + let newId11 = bs.insertBookmark(testRoot, uri("http://foo11.com/"), 1.484 + bs.DEFAULT_INDEX, ""); 1.485 + let bmURI = bs.getBookmarkURI(newId11); 1.486 + do_check_eq("http://foo11.com/", bmURI.spec); 1.487 + 1.488 + // test getBookmarkURI with non-bookmark items 1.489 + try { 1.490 + bs.getBookmarkURI(testRoot); 1.491 + do_throw("getBookmarkURI() should throw for non-bookmark items!"); 1.492 + } catch(ex) {} 1.493 + 1.494 + // test getItemIndex 1.495 + let newId12 = bs.insertBookmark(testRoot, uri("http://foo11.com/"), 1, ""); 1.496 + let bmIndex = bs.getItemIndex(newId12); 1.497 + do_check_eq(1, bmIndex); 1.498 + 1.499 + // insert a bookmark with title ZZZXXXYYY and then search for it. 1.500 + // this test confirms that we can find bookmarks that we haven't visited 1.501 + // (which are "hidden") and that we can find by title. 1.502 + // see bug #369887 for more details 1.503 + let newId13 = bs.insertBookmark(testRoot, uri("http://foobarcheese.com/"), 1.504 + bs.DEFAULT_INDEX, ""); 1.505 + do_check_eq(bookmarksObserver._itemAddedId, newId13); 1.506 + do_check_eq(bookmarksObserver._itemAddedParent, testRoot); 1.507 + do_check_eq(bookmarksObserver._itemAddedIndex, 11); 1.508 + 1.509 + // set bookmark title 1.510 + bs.setItemTitle(newId13, "ZZZXXXYYY"); 1.511 + do_check_eq(bookmarksObserver._itemChangedId, newId13); 1.512 + do_check_eq(bookmarksObserver._itemChangedProperty, "title"); 1.513 + do_check_eq(bookmarksObserver._itemChangedValue, "ZZZXXXYYY"); 1.514 + 1.515 + // check if setting an item annotation triggers onItemChanged 1.516 + bookmarksObserver._itemChangedId = -1; 1.517 + anno.setItemAnnotation(newId3, "test-annotation", "foo", 0, 0); 1.518 + do_check_eq(bookmarksObserver._itemChangedId, newId3); 1.519 + do_check_eq(bookmarksObserver._itemChangedProperty, "test-annotation"); 1.520 + do_check_true(bookmarksObserver._itemChanged_isAnnotationProperty); 1.521 + do_check_eq(bookmarksObserver._itemChangedValue, ""); 1.522 + 1.523 + // test search on bookmark title ZZZXXXYYY 1.524 + try { 1.525 + let options = hs.getNewQueryOptions(); 1.526 + options.excludeQueries = 1; 1.527 + options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS; 1.528 + let query = hs.getNewQuery(); 1.529 + query.searchTerms = "ZZZXXXYYY"; 1.530 + let result = hs.executeQuery(query, options); 1.531 + let rootNode = result.root; 1.532 + rootNode.containerOpen = true; 1.533 + let cc = rootNode.childCount; 1.534 + do_check_eq(cc, 1); 1.535 + let node = rootNode.getChild(0); 1.536 + do_check_eq(node.title, "ZZZXXXYYY"); 1.537 + do_check_true(node.itemId > 0); 1.538 + rootNode.containerOpen = false; 1.539 + } 1.540 + catch(ex) { 1.541 + do_throw("bookmarks query: " + ex); 1.542 + } 1.543 + 1.544 + // test dateAdded and lastModified properties 1.545 + // for a search query 1.546 + try { 1.547 + let options = hs.getNewQueryOptions(); 1.548 + options.excludeQueries = 1; 1.549 + options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS; 1.550 + let query = hs.getNewQuery(); 1.551 + query.searchTerms = "ZZZXXXYYY"; 1.552 + let result = hs.executeQuery(query, options); 1.553 + let rootNode = result.root; 1.554 + rootNode.containerOpen = true; 1.555 + let cc = rootNode.childCount; 1.556 + do_check_eq(cc, 1); 1.557 + let node = rootNode.getChild(0); 1.558 + 1.559 + do_check_eq(typeof node.dateAdded, "number"); 1.560 + do_check_true(node.dateAdded > 0); 1.561 + 1.562 + do_check_eq(typeof node.lastModified, "number"); 1.563 + do_check_true(node.lastModified > 0); 1.564 + 1.565 + rootNode.containerOpen = false; 1.566 + } 1.567 + catch(ex) { 1.568 + do_throw("bookmarks query: " + ex); 1.569 + } 1.570 + 1.571 + // test dateAdded and lastModified properties 1.572 + // for a folder query 1.573 + try { 1.574 + let options = hs.getNewQueryOptions(); 1.575 + let query = hs.getNewQuery(); 1.576 + query.setFolders([testRoot], 1); 1.577 + let result = hs.executeQuery(query, options); 1.578 + let rootNode = result.root; 1.579 + rootNode.containerOpen = true; 1.580 + let cc = rootNode.childCount; 1.581 + do_check_true(cc > 0); 1.582 + for (let i = 0; i < cc; i++) { 1.583 + let node = rootNode.getChild(i); 1.584 + 1.585 + if (node.type == node.RESULT_TYPE_URI) { 1.586 + do_check_eq(typeof node.dateAdded, "number"); 1.587 + do_check_true(node.dateAdded > 0); 1.588 + 1.589 + do_check_eq(typeof node.lastModified, "number"); 1.590 + do_check_true(node.lastModified > 0); 1.591 + break; 1.592 + } 1.593 + } 1.594 + rootNode.containerOpen = false; 1.595 + } 1.596 + catch(ex) { 1.597 + do_throw("bookmarks query: " + ex); 1.598 + } 1.599 + 1.600 + // check setItemLastModified() and setItemDateAdded() 1.601 + let newId14 = bs.insertBookmark(testRoot, uri("http://bar.tld/"), 1.602 + bs.DEFAULT_INDEX, ""); 1.603 + let dateAdded = bs.getItemDateAdded(newId14); 1.604 + let lastModified = bs.getItemLastModified(newId14); 1.605 + do_check_eq(lastModified, dateAdded); 1.606 + bs.setItemLastModified(newId14, 1234); 1.607 + let fakeLastModified = bs.getItemLastModified(newId14); 1.608 + do_check_eq(fakeLastModified, 1234); 1.609 + bs.setItemDateAdded(newId14, 4321); 1.610 + let fakeDateAdded = bs.getItemDateAdded(newId14); 1.611 + do_check_eq(fakeDateAdded, 4321); 1.612 + 1.613 + // ensure that removing an item removes its annotations 1.614 + do_check_true(anno.itemHasAnnotation(newId3, "test-annotation")); 1.615 + bs.removeItem(newId3); 1.616 + do_check_false(anno.itemHasAnnotation(newId3, "test-annotation")); 1.617 + 1.618 + // bug 378820 1.619 + let uri1 = uri("http://foo.tld/a"); 1.620 + bs.insertBookmark(testRoot, uri1, bs.DEFAULT_INDEX, ""); 1.621 + yield promiseAddVisits(uri1); 1.622 + 1.623 + // bug 646993 - test bookmark titles longer than the maximum allowed length 1.624 + let title15 = Array(TITLE_LENGTH_MAX + 5).join("X"); 1.625 + let title15expected = title15.substring(0, TITLE_LENGTH_MAX); 1.626 + let newId15 = bs.insertBookmark(testRoot, uri("http://evil.com/"), 1.627 + bs.DEFAULT_INDEX, title15); 1.628 + 1.629 + do_check_eq(bs.getItemTitle(newId15).length, 1.630 + title15expected.length); 1.631 + do_check_eq(bookmarksObserver._itemAddedTitle, title15expected); 1.632 + // test title length after updates 1.633 + bs.setItemTitle(newId15, title15 + " updated"); 1.634 + do_check_eq(bs.getItemTitle(newId15).length, 1.635 + title15expected.length); 1.636 + do_check_eq(bookmarksObserver._itemChangedId, newId15); 1.637 + do_check_eq(bookmarksObserver._itemChangedProperty, "title"); 1.638 + do_check_eq(bookmarksObserver._itemChangedValue, title15expected); 1.639 + 1.640 + testSimpleFolderResult(); 1.641 +}); 1.642 + 1.643 +function testSimpleFolderResult() { 1.644 + // the time before we create a folder, in microseconds 1.645 + // Workaround possible VM timers issues subtracting 1us. 1.646 + let beforeCreate = Date.now() * 1000 - 1; 1.647 + do_check_true(beforeCreate > 0); 1.648 + 1.649 + // create a folder 1.650 + let parent = bs.createFolder(root, "test", bs.DEFAULT_INDEX); 1.651 + 1.652 + let dateCreated = bs.getItemDateAdded(parent); 1.653 + LOG("check that the folder was created with a valid dateAdded"); 1.654 + LOG("beforeCreate = " + beforeCreate); 1.655 + LOG("dateCreated = " + dateCreated); 1.656 + do_check_true(is_time_ordered(beforeCreate, dateCreated)); 1.657 + 1.658 + // the time before we insert, in microseconds 1.659 + // Workaround possible VM timers issues subtracting 1ms. 1.660 + let beforeInsert = Date.now() * 1000 - 1; 1.661 + do_check_true(beforeInsert > 0); 1.662 + 1.663 + // insert a separator 1.664 + let sep = bs.insertSeparator(parent, bs.DEFAULT_INDEX); 1.665 + 1.666 + let dateAdded = bs.getItemDateAdded(sep); 1.667 + LOG("check that the separator was created with a valid dateAdded"); 1.668 + LOG("beforeInsert = " + beforeInsert); 1.669 + LOG("dateAdded = " + dateAdded); 1.670 + do_check_true(is_time_ordered(beforeInsert, dateAdded)); 1.671 + 1.672 + // re-set item title separately so can test nodes' last modified 1.673 + let item = bs.insertBookmark(parent, uri("about:blank"), 1.674 + bs.DEFAULT_INDEX, ""); 1.675 + bs.setItemTitle(item, "test bookmark"); 1.676 + 1.677 + // see above 1.678 + let folder = bs.createFolder(parent, "test folder", bs.DEFAULT_INDEX); 1.679 + bs.setItemTitle(folder, "test folder"); 1.680 + 1.681 + let longName = Array(TITLE_LENGTH_MAX + 5).join("A"); 1.682 + let folderLongName = bs.createFolder(parent, longName, bs.DEFAULT_INDEX); 1.683 + do_check_eq(bookmarksObserver._itemAddedTitle, longName.substring(0, TITLE_LENGTH_MAX)); 1.684 + 1.685 + let options = hs.getNewQueryOptions(); 1.686 + let query = hs.getNewQuery(); 1.687 + query.setFolders([parent], 1); 1.688 + let result = hs.executeQuery(query, options); 1.689 + let rootNode = result.root; 1.690 + rootNode.containerOpen = true; 1.691 + do_check_eq(rootNode.childCount, 4); 1.692 + 1.693 + let node = rootNode.getChild(0); 1.694 + do_check_true(node.dateAdded > 0); 1.695 + do_check_eq(node.lastModified, node.dateAdded); 1.696 + do_check_eq(node.itemId, sep); 1.697 + do_check_eq(node.title, ""); 1.698 + node = rootNode.getChild(1); 1.699 + do_check_eq(node.itemId, item); 1.700 + do_check_true(node.dateAdded > 0); 1.701 + do_check_true(node.lastModified > 0); 1.702 + do_check_eq(node.title, "test bookmark"); 1.703 + node = rootNode.getChild(2); 1.704 + do_check_eq(node.itemId, folder); 1.705 + do_check_eq(node.title, "test folder"); 1.706 + do_check_true(node.dateAdded > 0); 1.707 + do_check_true(node.lastModified > 0); 1.708 + node = rootNode.getChild(3); 1.709 + do_check_eq(node.itemId, folderLongName); 1.710 + do_check_eq(node.title, longName.substring(0, TITLE_LENGTH_MAX)); 1.711 + do_check_true(node.dateAdded > 0); 1.712 + do_check_true(node.lastModified > 0); 1.713 + 1.714 + // update with another long title 1.715 + bs.setItemTitle(folderLongName, longName + " updated"); 1.716 + do_check_eq(bookmarksObserver._itemChangedId, folderLongName); 1.717 + do_check_eq(bookmarksObserver._itemChangedProperty, "title"); 1.718 + do_check_eq(bookmarksObserver._itemChangedValue, longName.substring(0, TITLE_LENGTH_MAX)); 1.719 + 1.720 + node = rootNode.getChild(3); 1.721 + do_check_eq(node.title, longName.substring(0, TITLE_LENGTH_MAX)); 1.722 + 1.723 + rootNode.containerOpen = false; 1.724 +} 1.725 + 1.726 +function getChildCount(aFolderId) { 1.727 + let cc = -1; 1.728 + try { 1.729 + let options = hs.getNewQueryOptions(); 1.730 + let query = hs.getNewQuery(); 1.731 + query.setFolders([aFolderId], 1); 1.732 + let result = hs.executeQuery(query, options); 1.733 + let rootNode = result.root; 1.734 + rootNode.containerOpen = true; 1.735 + cc = rootNode.childCount; 1.736 + rootNode.containerOpen = false; 1.737 + } catch(ex) { 1.738 + do_throw("getChildCount failed: " + ex); 1.739 + } 1.740 + return cc; 1.741 +}