michael@0: /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:set ts=2 sw=2 sts=2 et: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // Get services. michael@0: try { michael@0: var histSvc = Cc["@mozilla.org/browser/nav-history-service;1"]. michael@0: getService(Ci.nsINavHistoryService); michael@0: var bmSvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. michael@0: getService(Ci.nsINavBookmarksService); michael@0: var annoSvc = Cc["@mozilla.org/browser/annotation-service;1"] michael@0: .getService(Ci.nsIAnnotationService); michael@0: } catch(ex) { michael@0: do_throw("Could not get services\n"); michael@0: } michael@0: michael@0: var validAnnoName = "validAnno"; michael@0: var validItemName = "validItem"; michael@0: var deletedAnnoName = "deletedAnno"; michael@0: var deletedItemName = "deletedItem"; michael@0: var bookmarkedURI = uri("http://www.mozilla.org/"); michael@0: // set lastModified to the past to prevent VM timing bugs michael@0: var pastDate = Date.now() * 1000 - 1; michael@0: var deletedBookmarkIds = []; michael@0: michael@0: // bookmarks observer michael@0: var observer = { michael@0: // cached ordered array of notified items michael@0: _onItemRemovedItemIds: [], michael@0: onItemRemoved: function(aItemId, aParentId, aIndex) { michael@0: // We should first get notifications for children, then for their parent michael@0: do_check_eq(this._onItemRemovedItemIds.indexOf(aParentId), -1); michael@0: // Ensure we are not wrongly removing 1 level up michael@0: do_check_neq(aParentId, bmSvc.toolbarFolder); michael@0: // Removed item must be one of those we have manually deleted michael@0: do_check_neq(deletedBookmarkIds.indexOf(aItemId), -1); michael@0: this._onItemRemovedItemIds.push(aItemId); michael@0: }, michael@0: michael@0: QueryInterface: function(aIID) { michael@0: if (aIID.equals(Ci.nsINavBookmarkObserver) || michael@0: aIID.equals(Ci.nsISupports)) { michael@0: return this; michael@0: } michael@0: throw Cr.NS_ERROR_NO_INTERFACE; michael@0: } michael@0: }; michael@0: michael@0: bmSvc.addObserver(observer, false); michael@0: michael@0: function add_bookmarks() { michael@0: // This is the folder we will cleanup michael@0: var validFolderId = bmSvc.createFolder(bmSvc.toolbarFolder, michael@0: validItemName, michael@0: bmSvc.DEFAULT_INDEX); michael@0: annoSvc.setItemAnnotation(validFolderId, validAnnoName, michael@0: "annotation", 0, michael@0: annoSvc.EXPIRE_NEVER); michael@0: bmSvc.setItemLastModified(validFolderId, pastDate); michael@0: michael@0: // This bookmark should not be deleted michael@0: var validItemId = bmSvc.insertBookmark(bmSvc.toolbarFolder, michael@0: bookmarkedURI, michael@0: bmSvc.DEFAULT_INDEX, michael@0: validItemName); michael@0: annoSvc.setItemAnnotation(validItemId, validAnnoName, michael@0: "annotation", 0, annoSvc.EXPIRE_NEVER); michael@0: michael@0: // The following contents should be deleted michael@0: var deletedItemId = bmSvc.insertBookmark(validFolderId, michael@0: bookmarkedURI, michael@0: bmSvc.DEFAULT_INDEX, michael@0: deletedItemName); michael@0: annoSvc.setItemAnnotation(deletedItemId, deletedAnnoName, michael@0: "annotation", 0, annoSvc.EXPIRE_NEVER); michael@0: deletedBookmarkIds.push(deletedItemId); michael@0: michael@0: var internalFolderId = bmSvc.createFolder(validFolderId, michael@0: deletedItemName, michael@0: bmSvc.DEFAULT_INDEX); michael@0: annoSvc.setItemAnnotation(internalFolderId, deletedAnnoName, michael@0: "annotation", 0, annoSvc.EXPIRE_NEVER); michael@0: deletedBookmarkIds.push(internalFolderId); michael@0: michael@0: deletedItemId = bmSvc.insertBookmark(internalFolderId, michael@0: bookmarkedURI, michael@0: bmSvc.DEFAULT_INDEX, michael@0: deletedItemName); michael@0: annoSvc.setItemAnnotation(deletedItemId, deletedAnnoName, michael@0: "annotation", 0, annoSvc.EXPIRE_NEVER); michael@0: deletedBookmarkIds.push(deletedItemId); michael@0: michael@0: return validFolderId; michael@0: } michael@0: michael@0: function check_bookmarks(aFolderId) { michael@0: // check that we still have valid bookmarks michael@0: var bookmarks = bmSvc.getBookmarkIdsForURI(bookmarkedURI); michael@0: for(var i = 0; i < bookmarks.length; i++) { michael@0: do_check_eq(bmSvc.getItemTitle(bookmarks[i]), validItemName); michael@0: do_check_true(annoSvc.itemHasAnnotation(bookmarks[i],validAnnoName)); michael@0: } michael@0: michael@0: // check that folder exists and has still its annotation michael@0: do_check_eq(bmSvc.getItemTitle(aFolderId), validItemName); michael@0: do_check_true(annoSvc.itemHasAnnotation(aFolderId, validAnnoName)); michael@0: michael@0: // check that folder is empty michael@0: var options = histSvc.getNewQueryOptions(); michael@0: var query = histSvc.getNewQuery(); michael@0: query.setFolders([aFolderId], 1); michael@0: var result = histSvc.executeQuery(query, options); michael@0: var root = result.root; michael@0: root.containerOpen = true; michael@0: do_check_eq(root.childCount, 0); michael@0: root.containerOpen = false; michael@0: michael@0: // test that lastModified got updated michael@0: do_check_true(pastDate < bmSvc.getItemLastModified(aFolderId)); michael@0: michael@0: // test that all children have been deleted, we use annos for that michael@0: var deletedItems = annoSvc.getItemsWithAnnotation(deletedAnnoName); michael@0: do_check_eq(deletedItems.length, 0); michael@0: michael@0: // test that observer has been called for (and only for) deleted items michael@0: do_check_eq(observer._onItemRemovedItemIds.length, deletedBookmarkIds.length); michael@0: michael@0: // Sanity check: all roots should be intact michael@0: do_check_eq(bmSvc.getFolderIdForItem(bmSvc.placesRoot), 0); michael@0: do_check_eq(bmSvc.getFolderIdForItem(bmSvc.bookmarksMenuFolder), bmSvc.placesRoot); michael@0: do_check_eq(bmSvc.getFolderIdForItem(bmSvc.tagsFolder), bmSvc.placesRoot); michael@0: do_check_eq(bmSvc.getFolderIdForItem(bmSvc.unfiledBookmarksFolder), bmSvc.placesRoot); michael@0: do_check_eq(bmSvc.getFolderIdForItem(bmSvc.toolbarFolder), bmSvc.placesRoot); michael@0: } michael@0: michael@0: // main michael@0: function run_test() { michael@0: var folderId = add_bookmarks(); michael@0: bmSvc.removeFolderChildren(folderId); michael@0: check_bookmarks(folderId); michael@0: }