summaryrefslogtreecommitdiffstats
path: root/toolkit/components/places/tests/bookmarks/test_keywords.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/places/tests/bookmarks/test_keywords.js')
-rw-r--r--toolkit/components/places/tests/bookmarks/test_keywords.js767
1 files changed, 767 insertions, 0 deletions
diff --git a/toolkit/components/places/tests/bookmarks/test_keywords.js b/toolkit/components/places/tests/bookmarks/test_keywords.js
new file mode 100644
index 0000000000..9b5be8f595
--- /dev/null
+++ b/toolkit/components/places/tests/bookmarks/test_keywords.js
@@ -0,0 +1,767 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+ChromeUtils.defineESModuleGetters(this, {
+ Preferences: "resource://gre/modules/Preferences.sys.mjs",
+});
+
+const URI1 = "http://test1.mozilla.org/";
+const URI2 = "http://test2.mozilla.org/";
+const URI3 = "http://test3.mozilla.org/";
+
+async function check_keyword(aURI, aKeyword) {
+ if (aKeyword) {
+ aKeyword = aKeyword.toLowerCase();
+ }
+
+ if (aKeyword) {
+ let uri = await PlacesUtils.keywords.fetch(aKeyword);
+ Assert.equal(uri.url, aURI);
+ // Check case insensitivity.
+ uri = await PlacesUtils.keywords.fetch(aKeyword.toUpperCase());
+ Assert.equal(uri.url, aURI);
+ } else {
+ let entry = await PlacesUtils.keywords.fetch({ url: aURI });
+ if (entry) {
+ throw new Error(`${aURI.spec} should not have a keyword`);
+ }
+ }
+}
+
+async function check_orphans() {
+ let db = await PlacesUtils.promiseDBConnection();
+ let rows = await db.executeCached(
+ `SELECT id FROM moz_keywords k
+ WHERE NOT EXISTS (SELECT 1 FROM moz_places WHERE id = k.place_id)
+ `
+ );
+ Assert.equal(rows.length, 0);
+}
+
+function expectNotifications() {
+ let notifications = [];
+ let observer = new Proxy(NavBookmarkObserver, {
+ get(target, name) {
+ if (name == "check") {
+ PlacesUtils.bookmarks.removeObserver(observer);
+ return expectedNotifications =>
+ Assert.deepEqual(notifications, expectedNotifications);
+ }
+
+ if (name.startsWith("onItemChanged")) {
+ return function(
+ id,
+ prop,
+ isAnno,
+ val,
+ lastMod,
+ itemType,
+ parentId,
+ guid,
+ parentGuid,
+ oldVal
+ ) {
+ if (prop != "keyword") {
+ return;
+ }
+ let args = Array.from(arguments, arg => {
+ if (arg && arg instanceof Ci.nsIURI) {
+ return new URL(arg.spec);
+ }
+ if (arg && typeof arg == "number" && arg >= Date.now() * 1000) {
+ return new Date(parseInt(arg / 1000));
+ }
+ return arg;
+ });
+ notifications.push({ name, arguments: args });
+ };
+ }
+
+ return target[name];
+ },
+ });
+ PlacesUtils.bookmarks.addObserver(observer);
+ return observer;
+}
+
+add_task(function test_invalid_input() {});
+
+add_task(async function test_addBookmarkAndKeyword() {
+ let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+ Preferences.set("privacy.reduceTimerPrecision", false);
+
+ registerCleanupFunction(function() {
+ Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+ });
+
+ await check_keyword(URI1, null);
+ let fc = await foreign_count(URI1);
+ let observer = expectNotifications();
+
+ let bookmark = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+ url: URI1,
+ title: "test",
+ });
+ await PlacesUtils.keywords.insert({ url: URI1, keyword: "keyword" });
+ let itemId = await PlacesUtils.promiseItemId(bookmark.guid);
+ observer.check([
+ {
+ name: "onItemChanged",
+ arguments: [
+ itemId,
+ "keyword",
+ false,
+ "keyword",
+ bookmark.lastModified * 1000,
+ bookmark.type,
+ await PlacesUtils.promiseItemId(bookmark.parentGuid),
+ bookmark.guid,
+ bookmark.parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ ]);
+ await check_keyword(URI1, "keyword");
+ Assert.equal(await foreign_count(URI1), fc + 2); // + 1 bookmark + 1 keyword
+ await check_orphans();
+});
+
+add_task(async function test_addBookmarkToURIHavingKeyword() {
+ // The uri has already a keyword.
+ await check_keyword(URI1, "keyword");
+ let fc = await foreign_count(URI1);
+
+ let bookmark = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+ url: URI1,
+ title: "test",
+ });
+ await check_keyword(URI1, "keyword");
+ Assert.equal(await foreign_count(URI1), fc + 1); // + 1 bookmark
+ await PlacesUtils.bookmarks.remove(bookmark);
+ await check_orphans();
+});
+
+add_task(async function test_sameKeywordDifferentURI() {
+ let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+ Preferences.set("privacy.reduceTimerPrecision", false);
+
+ registerCleanupFunction(function() {
+ Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+ });
+
+ let fc1 = await foreign_count(URI1);
+ let fc2 = await foreign_count(URI2);
+ let observer = expectNotifications();
+
+ let bookmark2 = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+ url: URI2,
+ title: "test2",
+ });
+ await check_keyword(URI1, "keyword");
+ await check_keyword(URI2, null);
+
+ await PlacesUtils.keywords.insert({ url: URI2, keyword: "kEyWoRd" });
+
+ let bookmark1 = await PlacesUtils.bookmarks.fetch({ url: URI1 });
+ observer.check([
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(bookmark1.guid),
+ "keyword",
+ false,
+ "",
+ bookmark1.lastModified * 1000,
+ bookmark1.type,
+ await PlacesUtils.promiseItemId(bookmark1.parentGuid),
+ bookmark1.guid,
+ bookmark1.parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(bookmark2.guid),
+ "keyword",
+ false,
+ "keyword",
+ bookmark2.lastModified * 1000,
+ bookmark2.type,
+ await PlacesUtils.promiseItemId(bookmark2.parentGuid),
+ bookmark2.guid,
+ bookmark2.parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ ]);
+
+ // The keyword should have been "moved" to the new URI.
+ await check_keyword(URI1, null);
+ Assert.equal(await foreign_count(URI1), fc1 - 1); // - 1 keyword
+ await check_keyword(URI2, "keyword");
+ Assert.equal(await foreign_count(URI2), fc2 + 2); // + 1 bookmark + 1 keyword
+ await check_orphans();
+});
+
+add_task(async function test_sameURIDifferentKeyword() {
+ let fc = await foreign_count(URI2);
+ let observer = expectNotifications();
+
+ await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+ url: URI2,
+ title: "test2",
+ });
+ await check_keyword(URI2, "keyword");
+
+ await PlacesUtils.keywords.insert({ url: URI2, keyword: "keyword2" });
+ let bookmarks = [];
+ await PlacesUtils.bookmarks.fetch({ url: URI2 }, bm => bookmarks.push(bm));
+ observer.check([
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(bookmarks[0].guid),
+ "keyword",
+ false,
+ "keyword2",
+ bookmarks[0].lastModified * 1000,
+ bookmarks[0].type,
+ await PlacesUtils.promiseItemId(bookmarks[0].parentGuid),
+ bookmarks[0].guid,
+ bookmarks[0].parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(bookmarks[1].guid),
+ "keyword",
+ false,
+ "keyword2",
+ bookmarks[1].lastModified * 1000,
+ bookmarks[1].type,
+ await PlacesUtils.promiseItemId(bookmarks[1].parentGuid),
+ bookmarks[1].guid,
+ bookmarks[1].parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ ]);
+ await check_keyword(URI2, "keyword2");
+ Assert.equal(await foreign_count(URI2), fc + 1); // + 1 bookmark - 1 keyword + 1 keyword
+ await check_orphans();
+});
+
+add_task(async function test_removeBookmarkWithKeyword() {
+ let fc = await foreign_count(URI2);
+ let bookmark = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+ url: URI2,
+ title: "test",
+ });
+
+ // The keyword should not be removed, since there are other bookmarks yet.
+ await PlacesUtils.bookmarks.remove(bookmark);
+
+ await check_keyword(URI2, "keyword2");
+ Assert.equal(await foreign_count(URI2), fc); // + 1 bookmark - 1 bookmark
+ await check_orphans();
+});
+
+add_task(async function test_unsetKeyword() {
+ let fc = await foreign_count(URI2);
+ let observer = expectNotifications();
+
+ await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+ url: URI2,
+ title: "test",
+ });
+
+ // The keyword should be removed from any bookmark.
+ await PlacesUtils.keywords.remove("keyword2");
+
+ let bookmarks = [];
+ await PlacesUtils.bookmarks.fetch({ url: URI2 }, bookmark =>
+ bookmarks.push(bookmark)
+ );
+ Assert.equal(bookmarks.length, 3, "Check number of bookmarks");
+ observer.check([
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(bookmarks[0].guid),
+ "keyword",
+ false,
+ "",
+ bookmarks[0].lastModified * 1000,
+ bookmarks[0].type,
+ await PlacesUtils.promiseItemId(bookmarks[0].parentGuid),
+ bookmarks[0].guid,
+ bookmarks[0].parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(bookmarks[1].guid),
+ "keyword",
+ false,
+ "",
+ bookmarks[1].lastModified * 1000,
+ bookmarks[1].type,
+ await PlacesUtils.promiseItemId(bookmarks[1].parentGuid),
+ bookmarks[1].guid,
+ bookmarks[1].parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(bookmarks[2].guid),
+ "keyword",
+ false,
+ "",
+ bookmarks[2].lastModified * 1000,
+ bookmarks[2].type,
+ await PlacesUtils.promiseItemId(bookmarks[2].parentGuid),
+ bookmarks[2].guid,
+ bookmarks[2].parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ ]);
+
+ await check_keyword(URI1, null);
+ await check_keyword(URI2, null);
+ Assert.equal(await foreign_count(URI2), fc); // + 1 bookmark - 1 keyword
+ await check_orphans();
+});
+
+add_task(async function test_addRemoveBookmark() {
+ let fc = await foreign_count(URI3);
+ let observer = expectNotifications();
+
+ let bookmark = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+ url: URI3,
+ title: "test3",
+ });
+ let itemId = await PlacesUtils.promiseItemId(bookmark.guid);
+ await PlacesUtils.keywords.insert({ url: URI3, keyword: "keyword" });
+ await PlacesUtils.bookmarks.remove(bookmark);
+
+ observer.check([
+ {
+ name: "onItemChanged",
+ arguments: [
+ itemId,
+ "keyword",
+ false,
+ "keyword",
+ bookmark.lastModified * 1000,
+ bookmark.type,
+ await PlacesUtils.promiseItemId(bookmark.parentGuid),
+ bookmark.guid,
+ bookmark.parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ ]);
+
+ await check_keyword(URI3, null);
+ Assert.equal(await foreign_count(URI3), fc); // +- 1 bookmark +- 1 keyword
+ await check_orphans();
+});
+
+add_task(async function test_reassign() {
+ // Should move keywords from old URL to new URL.
+ info("Old URL with keywords; new URL without keywords");
+ {
+ let oldURL = "http://example.com/1/kw";
+ let oldBmk = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.menuGuid,
+ url: oldURL,
+ });
+ await PlacesUtils.keywords.insert({
+ url: oldURL,
+ keyword: "kw1-1",
+ postData: "a=b",
+ });
+ await PlacesUtils.keywords.insert({
+ url: oldURL,
+ keyword: "kw1-2",
+ postData: "c=d",
+ });
+ let oldFC = await foreign_count(oldURL);
+ equal(oldFC, 3);
+
+ let newURL = "http://example.com/2/no-kw";
+ let newBmk = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.menuGuid,
+ url: newURL,
+ });
+ let newFC = await foreign_count(newURL);
+ equal(newFC, 1);
+
+ let observer = expectNotifications();
+ await PlacesUtils.keywords.reassign(oldURL, newURL);
+ observer.check([
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(oldBmk.guid),
+ "keyword",
+ false,
+ "",
+ oldBmk.lastModified * 1000,
+ oldBmk.type,
+ await PlacesUtils.promiseItemId(oldBmk.parentGuid),
+ oldBmk.guid,
+ oldBmk.parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(newBmk.guid),
+ "keyword",
+ false,
+ "",
+ newBmk.lastModified * 1000,
+ newBmk.type,
+ await PlacesUtils.promiseItemId(newBmk.parentGuid),
+ newBmk.guid,
+ newBmk.parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(newBmk.guid),
+ "keyword",
+ false,
+ "kw1-1",
+ newBmk.lastModified * 1000,
+ newBmk.type,
+ await PlacesUtils.promiseItemId(newBmk.parentGuid),
+ newBmk.guid,
+ newBmk.parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(newBmk.guid),
+ "keyword",
+ false,
+ "kw1-2",
+ newBmk.lastModified * 1000,
+ newBmk.type,
+ await PlacesUtils.promiseItemId(newBmk.parentGuid),
+ newBmk.guid,
+ newBmk.parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ ]);
+
+ await check_keyword(oldURL, null);
+ await check_keyword(newURL, "kw1-1");
+ await check_keyword(newURL, "kw1-2");
+
+ equal(await foreign_count(oldURL), oldFC - 2); // Removed both keywords.
+ equal(await foreign_count(newURL), newFC + 2); // Added two keywords.
+ }
+
+ // Should not remove any keywords from new URL.
+ info("Old URL without keywords; new URL with keywords");
+ {
+ let oldURL = "http://example.com/3/no-kw";
+ await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.menuGuid,
+ url: oldURL,
+ });
+ let oldFC = await foreign_count(oldURL);
+ equal(oldFC, 1);
+
+ let newURL = "http://example.com/4/kw";
+ await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.menuGuid,
+ url: newURL,
+ });
+ await PlacesUtils.keywords.insert({
+ url: newURL,
+ keyword: "kw4-1",
+ });
+ let newFC = await foreign_count(newURL);
+ equal(newFC, 2);
+
+ let observer = expectNotifications();
+ await PlacesUtils.keywords.reassign(oldURL, newURL);
+ observer.check([]);
+
+ await check_keyword(newURL, "kw4-1");
+
+ equal(await foreign_count(oldURL), oldFC);
+ equal(await foreign_count(newURL), newFC);
+ }
+
+ // Should remove all keywords from new URL, then move keywords from old URL.
+ info("Old URL with keywords; new URL with keywords");
+ {
+ let oldURL = "http://example.com/8/kw";
+ let oldBmk = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.menuGuid,
+ url: oldURL,
+ });
+ await PlacesUtils.keywords.insert({
+ url: oldURL,
+ keyword: "kw8-1",
+ postData: "a=b",
+ });
+ await PlacesUtils.keywords.insert({
+ url: oldURL,
+ keyword: "kw8-2",
+ postData: "c=d",
+ });
+ let oldFC = await foreign_count(oldURL);
+ equal(oldFC, 3);
+
+ let newURL = "http://example.com/9/kw";
+ let newBmk = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.menuGuid,
+ url: newURL,
+ });
+ await PlacesUtils.keywords.insert({
+ url: newURL,
+ keyword: "kw9-1",
+ });
+ let newFC = await foreign_count(newURL);
+ equal(newFC, 2);
+
+ let observer = expectNotifications();
+ await PlacesUtils.keywords.reassign(oldURL, newURL);
+ observer.check([
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(oldBmk.guid),
+ "keyword",
+ false,
+ "",
+ oldBmk.lastModified * 1000,
+ oldBmk.type,
+ await PlacesUtils.promiseItemId(oldBmk.parentGuid),
+ oldBmk.guid,
+ oldBmk.parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(newBmk.guid),
+ "keyword",
+ false,
+ "",
+ newBmk.lastModified * 1000,
+ newBmk.type,
+ await PlacesUtils.promiseItemId(newBmk.parentGuid),
+ newBmk.guid,
+ newBmk.parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(newBmk.guid),
+ "keyword",
+ false,
+ "kw8-1",
+ newBmk.lastModified * 1000,
+ newBmk.type,
+ await PlacesUtils.promiseItemId(newBmk.parentGuid),
+ newBmk.guid,
+ newBmk.parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ {
+ name: "onItemChanged",
+ arguments: [
+ await PlacesUtils.promiseItemId(newBmk.guid),
+ "keyword",
+ false,
+ "kw8-2",
+ newBmk.lastModified * 1000,
+ newBmk.type,
+ await PlacesUtils.promiseItemId(newBmk.parentGuid),
+ newBmk.guid,
+ newBmk.parentGuid,
+ "",
+ Ci.nsINavBookmarksService.SOURCE_DEFAULT,
+ ],
+ },
+ ]);
+
+ await check_keyword(oldURL, null);
+ await check_keyword(newURL, "kw8-1");
+ await check_keyword(newURL, "kw8-2");
+
+ equal(await foreign_count(oldURL), oldFC - 2); // Removed both keywords.
+ equal(await foreign_count(newURL), newFC + 1); // Removed old keyword; added two keywords.
+ }
+
+ // Should do nothing.
+ info("Old URL without keywords; new URL without keywords");
+ {
+ let oldURL = "http://example.com/10/no-kw";
+ let oldFC = await foreign_count(oldURL);
+
+ let newURL = "http://example.com/11/no-kw";
+ let newFC = await foreign_count(newURL);
+
+ let observer = expectNotifications();
+ await PlacesUtils.keywords.reassign(oldURL, newURL);
+ observer.check([]);
+
+ equal(await foreign_count(oldURL), oldFC);
+ equal(await foreign_count(newURL), newFC);
+ }
+
+ await check_orphans();
+});
+
+add_task(async function test_invalidation() {
+ info("Insert bookmarks");
+ let fx = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.menuGuid,
+ title: "Get Firefox!",
+ url: "http://getfirefox.com",
+ });
+ let tb = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+ title: "Get Thunderbird!",
+ url: "http://getthunderbird.com",
+ });
+
+ info("Set keywords for bookmarks");
+ await PlacesUtils.keywords.insert({ url: fx.url, keyword: "fx" });
+ await PlacesUtils.keywords.insert({ url: tb.url, keyword: "tb" });
+
+ info("Invalidate cached keywords");
+ await PlacesUtils.keywords.invalidateCachedKeywords();
+
+ info("Change URL of bookmark with keyword");
+ let promiseNotification = PlacesTestUtils.waitForNotification(
+ "onItemChanged",
+ (id, prop, isAnnoProp, newValue, lastModified, type, parentId, guid) =>
+ guid == fx.guid && prop == "keyword" && newValue == "fx"
+ );
+ await PlacesUtils.bookmarks.update({
+ guid: fx.guid,
+ url: "https://www.mozilla.org/firefox",
+ });
+ await promiseNotification;
+
+ let entriesByKeyword = [];
+ await PlacesUtils.keywords.fetch({ keyword: "fx" }, e =>
+ entriesByKeyword.push(e.url.href)
+ );
+ deepEqual(
+ entriesByKeyword,
+ ["https://www.mozilla.org/firefox"],
+ "Should return new URL for keyword"
+ );
+
+ ok(
+ !(await PlacesUtils.keywords.fetch({ url: "http://getfirefox.com" })),
+ "Should not return keywords for old URL"
+ );
+
+ let entiresByURL = [];
+ await PlacesUtils.keywords.fetch(
+ { url: "https://www.mozilla.org/firefox" },
+ e => entiresByURL.push(e.keyword)
+ );
+ deepEqual(entiresByURL, ["fx"], "Should return keyword for new URL");
+
+ info("Invalidate cached keywords");
+ await PlacesUtils.keywords.invalidateCachedKeywords();
+
+ info("Remove bookmark with keyword");
+ await PlacesUtils.bookmarks.remove(tb.guid);
+
+ ok(
+ !(await PlacesUtils.keywords.fetch({ url: "http://getthunderbird.com" })),
+ "Should not return keywords for removed bookmark URL"
+ );
+
+ ok(
+ !(await PlacesUtils.keywords.fetch({ keyword: "tb" })),
+ "Should not return URL for removed bookmark keyword"
+ );
+ await check_orphans();
+
+ await PlacesUtils.bookmarks.eraseEverything();
+});
+
+add_task(async function test_eraseAllBookmarks() {
+ info("Insert bookmarks");
+ let fx = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.menuGuid,
+ title: "Get Firefox!",
+ url: "http://getfirefox.com",
+ });
+ let tb = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+ title: "Get Thunderbird!",
+ url: "http://getthunderbird.com",
+ });
+
+ info("Set keywords for bookmarks");
+ await PlacesUtils.keywords.insert({ url: fx.url, keyword: "fx" });
+ await PlacesUtils.keywords.insert({ url: tb.url, keyword: "tb" });
+
+ info("Erase everything");
+ await PlacesUtils.bookmarks.eraseEverything();
+
+ ok(
+ !(await PlacesUtils.keywords.fetch({ keyword: "fx" })),
+ "Should remove Firefox keyword"
+ );
+
+ ok(
+ !(await PlacesUtils.keywords.fetch({ keyword: "tb" })),
+ "Should remove Thunderbird keyword"
+ );
+});