diff options
Diffstat (limited to 'toolkit/components/places/tests/bookmarks/test_nsINavBookmarkObserver.js')
-rw-r--r-- | toolkit/components/places/tests/bookmarks/test_nsINavBookmarkObserver.js | 640 |
1 files changed, 640 insertions, 0 deletions
diff --git a/toolkit/components/places/tests/bookmarks/test_nsINavBookmarkObserver.js b/toolkit/components/places/tests/bookmarks/test_nsINavBookmarkObserver.js new file mode 100644 index 000000000..06f45b18e --- /dev/null +++ b/toolkit/components/places/tests/bookmarks/test_nsINavBookmarkObserver.js @@ -0,0 +1,640 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Tests that each nsINavBookmarksObserver method gets the correct input. +Cu.import("resource://gre/modules/PromiseUtils.jsm"); + +const GUID_RE = /^[a-zA-Z0-9\-_]{12}$/; + +var gBookmarksObserver = { + expected: [], + setup(expected) { + this.expected = expected; + this.deferred = PromiseUtils.defer(); + return this.deferred.promise; + }, + validate: function (aMethodName, aArguments) { + do_check_eq(this.expected[0].name, aMethodName); + + let args = this.expected.shift().args; + do_check_eq(aArguments.length, args.length); + for (let i = 0; i < aArguments.length; i++) { + do_check_true(args[i].check(aArguments[i]), aMethodName + "(args[" + i + "]: " + args[i].name + ")"); + } + + if (this.expected.length === 0) { + this.deferred.resolve(); + } + }, + + // nsINavBookmarkObserver + onBeginUpdateBatch() { + return this.validate("onBeginUpdateBatch", arguments); + }, + onEndUpdateBatch() { + return this.validate("onEndUpdateBatch", arguments); + }, + onItemAdded() { + return this.validate("onItemAdded", arguments); + }, + onItemRemoved() { + return this.validate("onItemRemoved", arguments); + }, + onItemChanged() { + return this.validate("onItemChanged", arguments); + }, + onItemVisited() { + return this.validate("onItemVisited", arguments); + }, + onItemMoved() { + return this.validate("onItemMoved", arguments); + }, + + // nsISupports + QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver]), +}; + +var gBookmarkSkipObserver = { + skipTags: true, + skipDescendantsOnItemRemoval: true, + + expected: null, + setup(expected) { + this.expected = expected; + this.deferred = PromiseUtils.defer(); + return this.deferred.promise; + }, + validate: function (aMethodName) { + do_check_eq(this.expected.shift(), aMethodName); + if (this.expected.length === 0) { + this.deferred.resolve(); + } + }, + + // nsINavBookmarkObserver + onBeginUpdateBatch() { + return this.validate("onBeginUpdateBatch", arguments); + }, + onEndUpdateBatch() { + return this.validate("onEndUpdateBatch", arguments); + }, + onItemAdded() { + return this.validate("onItemAdded", arguments); + }, + onItemRemoved() { + return this.validate("onItemRemoved", arguments); + }, + onItemChanged() { + return this.validate("onItemChanged", arguments); + }, + onItemVisited() { + return this.validate("onItemVisited", arguments); + }, + onItemMoved() { + return this.validate("onItemMoved", arguments); + }, + + // nsISupports + QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver]), +}; + + +add_task(function setup() { + PlacesUtils.bookmarks.addObserver(gBookmarksObserver, false); + PlacesUtils.bookmarks.addObserver(gBookmarkSkipObserver, false); +}); + +add_task(function* batch() { + let promise = Promise.all([ + gBookmarksObserver.setup([ + { name: "onBeginUpdateBatch", + args: [] }, + { name: "onEndUpdateBatch", + args: [] }, + ]), + gBookmarkSkipObserver.setup([ + "onBeginUpdateBatch", "onEndUpdateBatch" + ])]); + PlacesUtils.bookmarks.runInBatchMode({ + runBatched: function () { + // Nothing. + } + }, null); + yield promise; +}); + +add_task(function* onItemAdded_bookmark() { + const TITLE = "Bookmark 1"; + let uri = NetUtil.newURI("http://1.mozilla.org/"); + let promise = Promise.all([ + gBookmarkSkipObserver.setup([ + "onItemAdded" + ]), + gBookmarksObserver.setup([ + { name: "onItemAdded", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId }, + { name: "index", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK }, + { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) }, + { name: "title", check: v => v === TITLE }, + { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + ])]); + PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId, + uri, PlacesUtils.bookmarks.DEFAULT_INDEX, + TITLE); + yield promise; +}); + +add_task(function* onItemAdded_separator() { + let promise = Promise.all([ + gBookmarkSkipObserver.setup([ + "onItemAdded" + ]), + gBookmarksObserver.setup([ + { name: "onItemAdded", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId }, + { name: "index", check: v => v === 1 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_SEPARATOR }, + { name: "uri", check: v => v === null }, + { name: "title", check: v => v === null }, + { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + ])]); + PlacesUtils.bookmarks.insertSeparator(PlacesUtils.unfiledBookmarksFolderId, + PlacesUtils.bookmarks.DEFAULT_INDEX); + yield promise; +}); + +add_task(function* onItemAdded_folder() { + const TITLE = "Folder 1"; + let promise = Promise.all([ + gBookmarkSkipObserver.setup([ + "onItemAdded" + ]), + gBookmarksObserver.setup([ + { name: "onItemAdded", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId }, + { name: "index", check: v => v === 2 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER }, + { name: "uri", check: v => v === null }, + { name: "title", check: v => v === TITLE }, + { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + ])]); + PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId, + TITLE, + PlacesUtils.bookmarks.DEFAULT_INDEX); + yield promise; +}); + +add_task(function* onItemChanged_title_bookmark() { + let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0); + const TITLE = "New title"; + let promise = Promise.all([ + gBookmarkSkipObserver.setup([ + "onItemChanged" + ]), + gBookmarksObserver.setup([ + { name: "onItemChanged", // This is an unfortunate effect of bug 653910. + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "property", check: v => v === "title" }, + { name: "isAnno", check: v => v === false }, + { name: "newValue", check: v => v === TITLE }, + { name: "lastModified", check: v => typeof(v) == "number" && v > 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK }, + { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "oldValue", check: v => typeof(v) == "string" }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + ])]); + PlacesUtils.bookmarks.setItemTitle(id, TITLE); + yield promise; +}); + +add_task(function* onItemChanged_tags_bookmark() { + let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0); + let uri = PlacesUtils.bookmarks.getBookmarkURI(id); + const TAG = "tag"; + let promise = Promise.all([ + gBookmarkSkipObserver.setup([ + "onItemChanged", "onItemChanged" + ]), + gBookmarksObserver.setup([ + { name: "onItemAdded", // This is the tag folder. + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => v === PlacesUtils.tagsFolderId }, + { name: "index", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER }, + { name: "uri", check: v => v === null }, + { name: "title", check: v => v === TAG }, + { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemAdded", // This is the tag. + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => typeof(v) == "number" && v > 0 }, + { name: "index", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK }, + { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) }, + { name: "title", check: v => v === null }, + { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemChanged", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "property", check: v => v === "tags" }, + { name: "isAnno", check: v => v === false }, + { name: "newValue", check: v => v === "" }, + { name: "lastModified", check: v => typeof(v) == "number" && v > 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK }, + { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "oldValue", check: v => typeof(v) == "string" }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemRemoved", // This is the tag. + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => typeof(v) == "number" && v > 0 }, + { name: "index", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK }, + { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemRemoved", // This is the tag folder. + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => v === PlacesUtils.tagsFolderId }, + { name: "index", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER }, + { name: "uri", check: v => v === null }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemChanged", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "property", check: v => v === "tags" }, + { name: "isAnno", check: v => v === false }, + { name: "newValue", check: v => v === "" }, + { name: "lastModified", check: v => typeof(v) == "number" && v > 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK }, + { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "oldValue", check: v => typeof(v) == "string" }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + ])]); + PlacesUtils.tagging.tagURI(uri, [TAG]); + PlacesUtils.tagging.untagURI(uri, [TAG]); + yield promise; +}); + +add_task(function* onItemMoved_bookmark() { + let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0); + let promise = Promise.all([ + gBookmarkSkipObserver.setup([ + "onItemMoved", "onItemMoved" + ]), + gBookmarksObserver.setup([ + { name: "onItemMoved", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "oldParentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId }, + { name: "oldIndex", check: v => v === 0 }, + { name: "newParentId", check: v => v === PlacesUtils.toolbarFolderId }, + { name: "newIndex", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "oldParentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "newParentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemMoved", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "oldParentId", check: v => v === PlacesUtils.toolbarFolderId }, + { name: "oldIndex", check: v => v === 0 }, + { name: "newParentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId }, + { name: "newIndex", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "oldParentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "newParentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + ])]); + PlacesUtils.bookmarks.moveItem(id, PlacesUtils.toolbarFolderId, 0); + PlacesUtils.bookmarks.moveItem(id, PlacesUtils.unfiledBookmarksFolderId, 0); + yield promise; +}); + +add_task(function* onItemMoved_bookmark() { + let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0); + let uri = PlacesUtils.bookmarks.getBookmarkURI(id); + let promise = Promise.all([ + gBookmarkSkipObserver.setup([ + "onItemVisited" + ]), + gBookmarksObserver.setup([ + { name: "onItemVisited", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "visitId", check: v => typeof(v) == "number" && v > 0 }, + { name: "time", check: v => typeof(v) == "number" && v > 0 }, + { name: "transitionType", check: v => v === PlacesUtils.history.TRANSITION_TYPED }, + { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) }, + { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + ] }, + ])]); + PlacesTestUtils.addVisits({ uri: uri, transition: TRANSITION_TYPED }); + yield promise; +}); + +add_task(function* onItemRemoved_bookmark() { + let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0); + let uri = PlacesUtils.bookmarks.getBookmarkURI(id); + let promise = Promise.all([ + gBookmarkSkipObserver.setup([ + "onItemChanged", "onItemRemoved" + ]), + gBookmarksObserver.setup([ + { name: "onItemChanged", // This is an unfortunate effect of bug 653910. + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "property", check: v => v === "" }, + { name: "isAnno", check: v => v === true }, + { name: "newValue", check: v => v === "" }, + { name: "lastModified", check: v => typeof(v) == "number" && v > 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK }, + { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "oldValue", check: v => typeof(v) == "string" }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemRemoved", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId }, + { name: "index", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK }, + { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + ])]); + PlacesUtils.bookmarks.removeItem(id); + yield promise; +}); + +add_task(function* onItemRemoved_separator() { + let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0); + let promise = Promise.all([ + gBookmarkSkipObserver.setup([ + "onItemChanged", "onItemRemoved" + ]), + gBookmarksObserver.setup([ + { name: "onItemChanged", // This is an unfortunate effect of bug 653910. + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "property", check: v => v === "" }, + { name: "isAnno", check: v => v === true }, + { name: "newValue", check: v => v === "" }, + { name: "lastModified", check: v => typeof(v) == "number" && v > 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_SEPARATOR }, + { name: "parentId", check: v => typeof(v) == "number" && v > 0 }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "oldValue", check: v => typeof(v) == "string" }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemRemoved", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => typeof(v) == "number" && v > 0 }, + { name: "index", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_SEPARATOR }, + { name: "uri", check: v => v === null }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + ])]); + PlacesUtils.bookmarks.removeItem(id); + yield promise; +}); + +add_task(function* onItemRemoved_folder() { + let id = PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0); + let promise = Promise.all([ + gBookmarkSkipObserver.setup([ + "onItemChanged", "onItemRemoved" + ]), + gBookmarksObserver.setup([ + { name: "onItemChanged", // This is an unfortunate effect of bug 653910. + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "property", check: v => v === "" }, + { name: "isAnno", check: v => v === true }, + { name: "newValue", check: v => v === "" }, + { name: "lastModified", check: v => typeof(v) == "number" && v > 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER }, + { name: "parentId", check: v => typeof(v) == "number" && v > 0 }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "oldValue", check: v => typeof(v) == "string" }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemRemoved", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => typeof(v) == "number" && v > 0 }, + { name: "index", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER }, + { name: "uri", check: v => v === null }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + ])]); + PlacesUtils.bookmarks.removeItem(id); + yield promise; +}); + +add_task(function* onItemRemoved_folder_recursive() { + const TITLE = "Folder 3"; + const BMTITLE = "Bookmark 1"; + let uri = NetUtil.newURI("http://1.mozilla.org/"); + let promise = Promise.all([ + gBookmarkSkipObserver.setup([ + "onItemAdded", "onItemAdded", "onItemAdded", "onItemAdded", + "onItemChanged", "onItemRemoved" + ]), + gBookmarksObserver.setup([ + { name: "onItemAdded", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => v === PlacesUtils.unfiledBookmarksFolderId }, + { name: "index", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER }, + { name: "uri", check: v => v === null }, + { name: "title", check: v => v === TITLE }, + { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemAdded", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => v === PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0) }, + { name: "index", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK }, + { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) }, + { name: "title", check: v => v === BMTITLE }, + { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemAdded", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => v === PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0) }, + { name: "index", check: v => v === 1 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER }, + { name: "uri", check: v => v === null }, + { name: "title", check: v => v === TITLE }, + { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemAdded", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => v === PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.bookmarks.getIdForItemAt(PlacesUtils.unfiledBookmarksFolderId, 0), 1) }, + { name: "index", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK }, + { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) }, + { name: "title", check: v => v === BMTITLE }, + { name: "dateAdded", check: v => typeof(v) == "number" && v > 0 }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemChanged", // This is an unfortunate effect of bug 653910. + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "property", check: v => v === "" }, + { name: "isAnno", check: v => v === true }, + { name: "newValue", check: v => v === "" }, + { name: "lastModified", check: v => typeof(v) == "number" && v > 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER }, + { name: "parentId", check: v => typeof(v) == "number" && v > 0 }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "oldValue", check: v => typeof(v) == "string" }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemRemoved", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => typeof(v) == "number" && v > 0 }, + { name: "index", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK }, + { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemRemoved", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => typeof(v) == "number" && v > 0 }, + { name: "index", check: v => v === 1 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER }, + { name: "uri", check: v => v === null }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemRemoved", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => typeof(v) == "number" && v > 0 }, + { name: "index", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_BOOKMARK }, + { name: "uri", check: v => v instanceof Ci.nsIURI && v.equals(uri) }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + { name: "onItemRemoved", + args: [ + { name: "itemId", check: v => typeof(v) == "number" && v > 0 }, + { name: "parentId", check: v => typeof(v) == "number" && v > 0 }, + { name: "index", check: v => v === 0 }, + { name: "itemType", check: v => v === PlacesUtils.bookmarks.TYPE_FOLDER }, + { name: "uri", check: v => v === null }, + { name: "guid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "parentGuid", check: v => typeof(v) == "string" && GUID_RE.test(v) }, + { name: "source", check: v => Object.values(PlacesUtils.bookmarks.SOURCES).includes(v) }, + ] }, + ])]); + let folder = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId, + TITLE, + PlacesUtils.bookmarks.DEFAULT_INDEX); + PlacesUtils.bookmarks.insertBookmark(folder, + uri, PlacesUtils.bookmarks.DEFAULT_INDEX, + BMTITLE); + let folder2 = PlacesUtils.bookmarks.createFolder(folder, TITLE, + PlacesUtils.bookmarks.DEFAULT_INDEX); + PlacesUtils.bookmarks.insertBookmark(folder2, + uri, PlacesUtils.bookmarks.DEFAULT_INDEX, + BMTITLE); + + PlacesUtils.bookmarks.removeItem(folder); + yield promise; +}); + +add_task(function cleanup() +{ + PlacesUtils.bookmarks.removeObserver(gBookmarksObserver); + PlacesUtils.bookmarks.removeObserver(gBookmarkSkipObserver); +}); |