diff options
Diffstat (limited to 'toolkit/components/places/tests/unit/test_keywords.js')
-rw-r--r-- | toolkit/components/places/tests/unit/test_keywords.js | 548 |
1 files changed, 548 insertions, 0 deletions
diff --git a/toolkit/components/places/tests/unit/test_keywords.js b/toolkit/components/places/tests/unit/test_keywords.js new file mode 100644 index 000000000..57b734c5d --- /dev/null +++ b/toolkit/components/places/tests/unit/test_keywords.js @@ -0,0 +1,548 @@ +"use strict" + +function* check_keyword(aExpectExists, aHref, aKeyword, aPostData = null) { + // Check case-insensitivity. + aKeyword = aKeyword.toUpperCase(); + + let entry = yield PlacesUtils.keywords.fetch(aKeyword); + + Assert.deepEqual(entry, yield PlacesUtils.keywords.fetch({ keyword: aKeyword })); + + if (aExpectExists) { + Assert.ok(!!entry, "A keyword should exist"); + Assert.equal(entry.url.href, aHref); + Assert.equal(entry.postData, aPostData); + Assert.deepEqual(entry, yield PlacesUtils.keywords.fetch({ keyword: aKeyword, url: aHref })); + let entries = []; + yield PlacesUtils.keywords.fetch({ url: aHref }, e => entries.push(e)); + Assert.ok(entries.some(e => e.url.href == aHref && e.keyword == aKeyword.toLowerCase())); + } else { + Assert.ok(!entry || entry.url.href != aHref, + "The given keyword entry should not exist"); + Assert.equal(null, yield PlacesUtils.keywords.fetch({ keyword: aKeyword, url: aHref })); + } +} + +/** + * Polls the keywords cache waiting for the given keyword entry. + */ +function* promiseKeyword(keyword, expectedHref) { + let href = null; + do { + yield new Promise(resolve => do_timeout(100, resolve)); + let entry = yield PlacesUtils.keywords.fetch(keyword); + if (entry) + href = entry.url.href; + } while (href != expectedHref); +} + +function* check_no_orphans() { + let db = yield PlacesUtils.promiseDBConnection(); + let rows = yield 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 expectBookmarkNotifications() { + 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(itemId, property) { + if (property != "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: name, arguments: args }); + } + } + + if (name in target) + return target[name]; + return undefined; + } + }); + PlacesUtils.bookmarks.addObserver(observer, false); + return observer; +} + +add_task(function* test_invalid_input() { + Assert.throws(() => PlacesUtils.keywords.fetch(null), + /Invalid keyword/); + Assert.throws(() => PlacesUtils.keywords.fetch(5), + /Invalid keyword/); + Assert.throws(() => PlacesUtils.keywords.fetch(undefined), + /Invalid keyword/); + Assert.throws(() => PlacesUtils.keywords.fetch({ keyword: null }), + /Invalid keyword/); + Assert.throws(() => PlacesUtils.keywords.fetch({ keyword: {} }), + /Invalid keyword/); + Assert.throws(() => PlacesUtils.keywords.fetch({ keyword: 5 }), + /Invalid keyword/); + Assert.throws(() => PlacesUtils.keywords.fetch({}), + /At least keyword or url must be provided/); + Assert.throws(() => PlacesUtils.keywords.fetch({ keyword: "test" }, "test"), + /onResult callback must be a valid function/); + Assert.throws(() => PlacesUtils.keywords.fetch({ url: "test" }), + /is not a valid URL/); + Assert.throws(() => PlacesUtils.keywords.fetch({ url: {} }), + /is not a valid URL/); + Assert.throws(() => PlacesUtils.keywords.fetch({ url: null }), + /is not a valid URL/); + Assert.throws(() => PlacesUtils.keywords.fetch({ url: "" }), + /is not a valid URL/); + + Assert.throws(() => PlacesUtils.keywords.insert(null), + /Input should be a valid object/); + Assert.throws(() => PlacesUtils.keywords.insert("test"), + /Input should be a valid object/); + Assert.throws(() => PlacesUtils.keywords.insert(undefined), + /Input should be a valid object/); + Assert.throws(() => PlacesUtils.keywords.insert({ }), + /Invalid keyword/); + Assert.throws(() => PlacesUtils.keywords.insert({ keyword: null }), + /Invalid keyword/); + Assert.throws(() => PlacesUtils.keywords.insert({ keyword: 5 }), + /Invalid keyword/); + Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "" }), + /Invalid keyword/); + Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "test", postData: 5 }), + /Invalid POST data/); + Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "test", postData: {} }), + /Invalid POST data/); + Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "test" }), + /is not a valid URL/); + Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "test", url: 5 }), + /is not a valid URL/); + Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "test", url: "" }), + /is not a valid URL/); + Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "test", url: null }), + /is not a valid URL/); + Assert.throws(() => PlacesUtils.keywords.insert({ keyword: "test", url: "mozilla" }), + /is not a valid URL/); + + Assert.throws(() => PlacesUtils.keywords.remove(null), + /Invalid keyword/); + Assert.throws(() => PlacesUtils.keywords.remove(""), + /Invalid keyword/); + Assert.throws(() => PlacesUtils.keywords.remove(5), + /Invalid keyword/); +}); + +add_task(function* test_addKeyword() { + yield check_keyword(false, "http://example.com/", "keyword"); + let fc = yield foreign_count("http://example.com/"); + let observer = expectBookmarkNotifications(); + + yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" }); + observer.check([]); + + yield check_keyword(true, "http://example.com/", "keyword"); + Assert.equal((yield foreign_count("http://example.com/")), fc + 1); // +1 keyword + + // Now remove the keyword. + observer = expectBookmarkNotifications(); + yield PlacesUtils.keywords.remove("keyword"); + observer.check([]); + + yield check_keyword(false, "http://example.com/", "keyword"); + Assert.equal((yield foreign_count("http://example.com/")), fc); // -1 keyword + + // Check using URL. + yield PlacesUtils.keywords.insert({ keyword: "keyword", url: new URL("http://example.com/") }); + yield check_keyword(true, "http://example.com/", "keyword"); + yield PlacesUtils.keywords.remove("keyword"); + yield check_keyword(false, "http://example.com/", "keyword"); + + yield check_no_orphans(); +}); + +add_task(function* test_addBookmarkAndKeyword() { + yield check_keyword(false, "http://example.com/", "keyword"); + let fc = yield foreign_count("http://example.com/"); + let bookmark = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/", + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + parentGuid: PlacesUtils.bookmarks.unfiledGuid }); + + let observer = expectBookmarkNotifications(); + yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" }); + + observer.check([{ name: "onItemChanged", + arguments: [ (yield PlacesUtils.promiseItemId(bookmark.guid)), + "keyword", false, "keyword", + bookmark.lastModified, bookmark.type, + (yield PlacesUtils.promiseItemId(bookmark.parentGuid)), + bookmark.guid, bookmark.parentGuid, "", + Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]); + + yield check_keyword(true, "http://example.com/", "keyword"); + Assert.equal((yield foreign_count("http://example.com/")), fc + 2); // +1 bookmark +1 keyword + + // Now remove the keyword. + observer = expectBookmarkNotifications(); + yield PlacesUtils.keywords.remove("keyword"); + + observer.check([{ name: "onItemChanged", + arguments: [ (yield PlacesUtils.promiseItemId(bookmark.guid)), + "keyword", false, "", + bookmark.lastModified, bookmark.type, + (yield PlacesUtils.promiseItemId(bookmark.parentGuid)), + bookmark.guid, bookmark.parentGuid, "", + Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]); + + yield check_keyword(false, "http://example.com/", "keyword"); + Assert.equal((yield foreign_count("http://example.com/")), fc + 1); // -1 keyword + + // Add again the keyword, then remove the bookmark. + yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" }); + + observer = expectBookmarkNotifications(); + yield PlacesUtils.bookmarks.remove(bookmark.guid); + // the notification is synchronous but the removal process is async. + // Unfortunately there's nothing explicit we can wait for. + while ((yield foreign_count("http://example.com/"))); + // We don't get any itemChanged notification since the bookmark has been + // removed already. + observer.check([]); + + yield check_keyword(false, "http://example.com/", "keyword"); + + yield check_no_orphans(); +}); + +add_task(function* test_addKeywordToURIHavingKeyword() { + yield check_keyword(false, "http://example.com/", "keyword"); + let fc = yield foreign_count("http://example.com/"); + + let observer = expectBookmarkNotifications(); + yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" }); + observer.check([]); + + yield check_keyword(true, "http://example.com/", "keyword"); + Assert.equal((yield foreign_count("http://example.com/")), fc + 1); // +1 keyword + + yield PlacesUtils.keywords.insert({ keyword: "keyword2", url: "http://example.com/" }); + + yield check_keyword(true, "http://example.com/", "keyword"); + yield check_keyword(true, "http://example.com/", "keyword2"); + Assert.equal((yield foreign_count("http://example.com/")), fc + 2); // +1 keyword + let entries = []; + let entry = yield PlacesUtils.keywords.fetch({ url: "http://example.com/" }, e => entries.push(e)); + Assert.equal(entries.length, 2); + Assert.deepEqual(entries[0], entry); + + // Now remove the keywords. + observer = expectBookmarkNotifications(); + yield PlacesUtils.keywords.remove("keyword"); + yield PlacesUtils.keywords.remove("keyword2"); + observer.check([]); + + yield check_keyword(false, "http://example.com/", "keyword"); + yield check_keyword(false, "http://example.com/", "keyword2"); + Assert.equal((yield foreign_count("http://example.com/")), fc); // -1 keyword + + yield check_no_orphans(); +}); + +add_task(function* test_addBookmarkToURIHavingKeyword() { + yield check_keyword(false, "http://example.com/", "keyword"); + let fc = yield foreign_count("http://example.com/"); + let observer = expectBookmarkNotifications(); + + yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" }); + observer.check([]); + + yield check_keyword(true, "http://example.com/", "keyword"); + Assert.equal((yield foreign_count("http://example.com/")), fc + 1); // +1 keyword + + observer = expectBookmarkNotifications(); + let bookmark = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/", + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + parentGuid: PlacesUtils.bookmarks.unfiledGuid }); + Assert.equal((yield foreign_count("http://example.com/")), fc + 2); // +1 bookmark + observer.check([]); + + observer = expectBookmarkNotifications(); + yield PlacesUtils.bookmarks.remove(bookmark.guid); + // the notification is synchronous but the removal process is async. + // Unfortunately there's nothing explicit we can wait for. + while ((yield foreign_count("http://example.com/"))); + // We don't get any itemChanged notification since the bookmark has been + // removed already. + observer.check([]); + + yield check_keyword(false, "http://example.com/", "keyword"); + + yield check_no_orphans(); +}); + +add_task(function* test_sameKeywordDifferentURL() { + let fc1 = yield foreign_count("http://example1.com/"); + let bookmark1 = yield PlacesUtils.bookmarks.insert({ url: "http://example1.com/", + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + parentGuid: PlacesUtils.bookmarks.unfiledGuid }); + let fc2 = yield foreign_count("http://example2.com/"); + let bookmark2 = yield PlacesUtils.bookmarks.insert({ url: "http://example2.com/", + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + parentGuid: PlacesUtils.bookmarks.unfiledGuid }); + yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example1.com/" }); + + yield check_keyword(true, "http://example1.com/", "keyword"); + Assert.equal((yield foreign_count("http://example1.com/")), fc1 + 2); // +1 bookmark +1 keyword + yield check_keyword(false, "http://example2.com/", "keyword"); + Assert.equal((yield foreign_count("http://example2.com/")), fc2 + 1); // +1 bookmark + + // Assign the same keyword to another url. + let observer = expectBookmarkNotifications(); + yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example2.com/" }); + + observer.check([{ name: "onItemChanged", + arguments: [ (yield PlacesUtils.promiseItemId(bookmark1.guid)), + "keyword", false, "", + bookmark1.lastModified, bookmark1.type, + (yield PlacesUtils.promiseItemId(bookmark1.parentGuid)), + bookmark1.guid, bookmark1.parentGuid, "", + Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }, + { name: "onItemChanged", + arguments: [ (yield PlacesUtils.promiseItemId(bookmark2.guid)), + "keyword", false, "keyword", + bookmark2.lastModified, bookmark2.type, + (yield PlacesUtils.promiseItemId(bookmark2.parentGuid)), + bookmark2.guid, bookmark2.parentGuid, "", + Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]); + + yield check_keyword(false, "http://example1.com/", "keyword"); + Assert.equal((yield foreign_count("http://example1.com/")), fc1 + 1); // -1 keyword + yield check_keyword(true, "http://example2.com/", "keyword"); + Assert.equal((yield foreign_count("http://example2.com/")), fc2 + 2); // +1 keyword + + // Now remove the keyword. + observer = expectBookmarkNotifications(); + yield PlacesUtils.keywords.remove("keyword"); + observer.check([{ name: "onItemChanged", + arguments: [ (yield PlacesUtils.promiseItemId(bookmark2.guid)), + "keyword", false, "", + bookmark2.lastModified, bookmark2.type, + (yield PlacesUtils.promiseItemId(bookmark2.parentGuid)), + bookmark2.guid, bookmark2.parentGuid, "", + Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]); + + yield check_keyword(false, "http://example1.com/", "keyword"); + yield check_keyword(false, "http://example2.com/", "keyword"); + Assert.equal((yield foreign_count("http://example1.com/")), fc1 + 1); + Assert.equal((yield foreign_count("http://example2.com/")), fc2 + 1); // -1 keyword + + yield PlacesUtils.bookmarks.remove(bookmark1); + yield PlacesUtils.bookmarks.remove(bookmark2); + Assert.equal((yield foreign_count("http://example1.com/")), fc1); // -1 bookmark + while ((yield foreign_count("http://example2.com/"))); // -1 keyword + + yield check_no_orphans(); +}); + +add_task(function* test_sameURIDifferentKeyword() { + let fc = yield foreign_count("http://example.com/"); + + let observer = expectBookmarkNotifications(); + let bookmark = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/", + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + parentGuid: PlacesUtils.bookmarks.unfiledGuid }); + yield PlacesUtils.keywords.insert({keyword: "keyword", url: "http://example.com/" }); + + yield check_keyword(true, "http://example.com/", "keyword"); + Assert.equal((yield foreign_count("http://example.com/")), fc + 2); // +1 bookmark +1 keyword + + observer.check([{ name: "onItemChanged", + arguments: [ (yield PlacesUtils.promiseItemId(bookmark.guid)), + "keyword", false, "keyword", + bookmark.lastModified, bookmark.type, + (yield PlacesUtils.promiseItemId(bookmark.parentGuid)), + bookmark.guid, bookmark.parentGuid, "", + Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]); + + observer = expectBookmarkNotifications(); + yield PlacesUtils.keywords.insert({ keyword: "keyword2", url: "http://example.com/" }); + yield check_keyword(true, "http://example.com/", "keyword"); + yield check_keyword(true, "http://example.com/", "keyword2"); + Assert.equal((yield foreign_count("http://example.com/")), fc + 3); // +1 keyword + observer.check([{ name: "onItemChanged", + arguments: [ (yield PlacesUtils.promiseItemId(bookmark.guid)), + "keyword", false, "keyword2", + bookmark.lastModified, bookmark.type, + (yield PlacesUtils.promiseItemId(bookmark.parentGuid)), + bookmark.guid, bookmark.parentGuid, "", + Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]); + + // Add a third keyword. + yield PlacesUtils.keywords.insert({ keyword: "keyword3", url: "http://example.com/" }); + yield check_keyword(true, "http://example.com/", "keyword"); + yield check_keyword(true, "http://example.com/", "keyword2"); + yield check_keyword(true, "http://example.com/", "keyword3"); + Assert.equal((yield foreign_count("http://example.com/")), fc + 4); // +1 keyword + + // Remove one of the keywords. + observer = expectBookmarkNotifications(); + yield PlacesUtils.keywords.remove("keyword"); + yield check_keyword(false, "http://example.com/", "keyword"); + yield check_keyword(true, "http://example.com/", "keyword2"); + yield check_keyword(true, "http://example.com/", "keyword3"); + observer.check([{ name: "onItemChanged", + arguments: [ (yield PlacesUtils.promiseItemId(bookmark.guid)), + "keyword", false, "", + bookmark.lastModified, bookmark.type, + (yield PlacesUtils.promiseItemId(bookmark.parentGuid)), + bookmark.guid, bookmark.parentGuid, "", + Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]); + Assert.equal((yield foreign_count("http://example.com/")), fc + 3); // -1 keyword + + // Now remove the bookmark. + yield PlacesUtils.bookmarks.remove(bookmark); + while ((yield foreign_count("http://example.com/"))); + yield check_keyword(false, "http://example.com/", "keyword"); + yield check_keyword(false, "http://example.com/", "keyword2"); + yield check_keyword(false, "http://example.com/", "keyword3"); + + check_no_orphans(); +}); + +add_task(function* test_deleteKeywordMultipleBookmarks() { + let fc = yield foreign_count("http://example.com/"); + + let observer = expectBookmarkNotifications(); + let bookmark1 = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/", + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + parentGuid: PlacesUtils.bookmarks.unfiledGuid }); + let bookmark2 = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/", + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + parentGuid: PlacesUtils.bookmarks.unfiledGuid }); + yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" }); + + yield check_keyword(true, "http://example.com/", "keyword"); + Assert.equal((yield foreign_count("http://example.com/")), fc + 3); // +2 bookmark +1 keyword + observer.check([{ name: "onItemChanged", + arguments: [ (yield PlacesUtils.promiseItemId(bookmark2.guid)), + "keyword", false, "keyword", + bookmark2.lastModified, bookmark2.type, + (yield PlacesUtils.promiseItemId(bookmark2.parentGuid)), + bookmark2.guid, bookmark2.parentGuid, "", + Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }, + { name: "onItemChanged", + arguments: [ (yield PlacesUtils.promiseItemId(bookmark1.guid)), + "keyword", false, "keyword", + bookmark1.lastModified, bookmark1.type, + (yield PlacesUtils.promiseItemId(bookmark1.parentGuid)), + bookmark1.guid, bookmark1.parentGuid, "", + Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]); + + observer = expectBookmarkNotifications(); + yield PlacesUtils.keywords.remove("keyword"); + yield check_keyword(false, "http://example.com/", "keyword"); + Assert.equal((yield foreign_count("http://example.com/")), fc + 2); // -1 keyword + observer.check([{ name: "onItemChanged", + arguments: [ (yield PlacesUtils.promiseItemId(bookmark2.guid)), + "keyword", false, "", + bookmark2.lastModified, bookmark2.type, + (yield PlacesUtils.promiseItemId(bookmark2.parentGuid)), + bookmark2.guid, bookmark2.parentGuid, "", + Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }, + { name: "onItemChanged", + arguments: [ (yield PlacesUtils.promiseItemId(bookmark1.guid)), + "keyword", false, "", + bookmark1.lastModified, bookmark1.type, + (yield PlacesUtils.promiseItemId(bookmark1.parentGuid)), + bookmark1.guid, bookmark1.parentGuid, "", + Ci.nsINavBookmarksService.SOURCE_DEFAULT ] } ]); + + // Now remove the bookmarks. + yield PlacesUtils.bookmarks.remove(bookmark1); + yield PlacesUtils.bookmarks.remove(bookmark2); + Assert.equal((yield foreign_count("http://example.com/")), fc); // -2 bookmarks + + check_no_orphans(); +}); + +add_task(function* test_multipleKeywordsSamePostData() { + yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/", postData: "postData1" }); + yield check_keyword(true, "http://example.com/", "keyword", "postData1"); + // Add another keyword with same postData, should fail. + yield Assert.rejects(PlacesUtils.keywords.insert({ keyword: "keyword2", url: "http://example.com/", postData: "postData1" }), + /constraint failed/); + yield check_keyword(false, "http://example.com/", "keyword2", "postData1"); + + yield PlacesUtils.keywords.remove("keyword"); + + check_no_orphans(); +}); + +add_task(function* test_oldPostDataAPI() { + let bookmark = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/", + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + parentGuid: PlacesUtils.bookmarks.unfiledGuid }); + yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" }); + let itemId = yield PlacesUtils.promiseItemId(bookmark.guid); + yield PlacesUtils.setPostDataForBookmark(itemId, "postData"); + yield check_keyword(true, "http://example.com/", "keyword", "postData"); + Assert.equal(PlacesUtils.getPostDataForBookmark(itemId), "postData"); + + yield PlacesUtils.keywords.remove("keyword"); + yield PlacesUtils.bookmarks.remove(bookmark); + + check_no_orphans(); +}); + +add_task(function* test_oldKeywordsAPI() { + let bookmark = yield PlacesUtils.bookmarks.insert({ url: "http://example.com/", + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + parentGuid: PlacesUtils.bookmarks.unfiledGuid }); + yield check_keyword(false, "http://example.com/", "keyword"); + let itemId = yield PlacesUtils.promiseItemId(bookmark.guid); + + PlacesUtils.bookmarks.setKeywordForBookmark(itemId, "keyword"); + yield promiseKeyword("keyword", "http://example.com/"); + + // Remove the keyword. + PlacesUtils.bookmarks.setKeywordForBookmark(itemId, ""); + yield promiseKeyword("keyword", null); + + yield PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com" }); + Assert.equal(PlacesUtils.bookmarks.getKeywordForBookmark(itemId), "keyword"); + Assert.equal(PlacesUtils.bookmarks.getURIForKeyword("keyword").spec, "http://example.com/"); + yield PlacesUtils.bookmarks.remove(bookmark); + + check_no_orphans(); +}); + +add_task(function* test_bookmarkURLChange() { + let fc1 = yield foreign_count("http://example1.com/"); + let fc2 = yield foreign_count("http://example2.com/"); + let bookmark = yield PlacesUtils.bookmarks.insert({ url: "http://example1.com/", + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + parentGuid: PlacesUtils.bookmarks.unfiledGuid }); + yield PlacesUtils.keywords.insert({ keyword: "keyword", + url: "http://example1.com/" }); + + yield check_keyword(true, "http://example1.com/", "keyword"); + Assert.equal((yield foreign_count("http://example1.com/")), fc1 + 2); // +1 bookmark +1 keyword + + yield PlacesUtils.bookmarks.update({ guid: bookmark.guid, + url: "http://example2.com/"}); + yield promiseKeyword("keyword", "http://example2.com/"); + + yield check_keyword(false, "http://example1.com/", "keyword"); + yield check_keyword(true, "http://example2.com/", "keyword"); + Assert.equal((yield foreign_count("http://example1.com/")), fc1); // -1 bookmark -1 keyword + Assert.equal((yield foreign_count("http://example2.com/")), fc2 + 2); // +1 bookmark +1 keyword +}); |