diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /toolkit/components/places/tests/bookmarks/test_keywords.js | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/places/tests/bookmarks/test_keywords.js')
-rw-r--r-- | toolkit/components/places/tests/bookmarks/test_keywords.js | 691 |
1 files changed, 691 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..fca9ebf32a --- /dev/null +++ b/toolkit/components/places/tests/bookmarks/test_keywords.js @@ -0,0 +1,691 @@ +/* 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() { + const observer = { + notifications: [], + _start() { + this._handle = this._handle.bind(this); + PlacesUtils.observers.addListener( + ["bookmark-keyword-changed"], + this._handle + ); + }, + _handle(events) { + for (const event of events) { + this.notifications.push({ + type: event.type, + id: event.id, + itemType: event.itemType, + url: event.url, + guid: event.guid, + parentGuid: event.parentGuid, + keyword: event.keyword, + lastModified: new Date(event.lastModified), + source: event.source, + isTagging: event.isTagging, + }); + } + }, + check(expected) { + PlacesUtils.observers.removeListener( + ["bookmark-keyword-changed"], + this._handle + ); + Assert.deepEqual(this.notifications, expected); + }, + }; + observer._start(); + 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([ + { + type: "bookmark-keyword-changed", + id: itemId, + itemType: bookmark.type, + url: bookmark.url, + guid: bookmark.guid, + parentGuid: bookmark.parentGuid, + keyword: "keyword", + lastModified: new Date(bookmark.lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + ]); + 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([ + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(bookmark1.guid), + itemType: bookmark1.type, + url: bookmark1.url, + guid: bookmark1.guid, + parentGuid: bookmark1.parentGuid, + keyword: "", + lastModified: new Date(bookmark1.lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(bookmark2.guid), + itemType: bookmark2.type, + url: bookmark2.url, + guid: bookmark2.guid, + parentGuid: bookmark2.parentGuid, + keyword: "keyword", + lastModified: new Date(bookmark2.lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + ]); + + // 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([ + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(bookmarks[0].guid), + itemType: bookmarks[0].type, + url: bookmarks[0].url, + guid: bookmarks[0].guid, + parentGuid: bookmarks[0].parentGuid, + keyword: "keyword2", + lastModified: new Date(bookmarks[0].lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(bookmarks[1].guid), + itemType: bookmarks[1].type, + url: bookmarks[1].url, + guid: bookmarks[1].guid, + parentGuid: bookmarks[1].parentGuid, + keyword: "keyword2", + lastModified: new Date(bookmarks[1].lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + ]); + 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([ + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(bookmarks[0].guid), + itemType: bookmarks[0].type, + url: bookmarks[0].url, + guid: bookmarks[0].guid, + parentGuid: bookmarks[0].parentGuid, + keyword: "", + lastModified: new Date(bookmarks[0].lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(bookmarks[1].guid), + itemType: bookmarks[1].type, + url: bookmarks[1].url, + guid: bookmarks[1].guid, + parentGuid: bookmarks[1].parentGuid, + keyword: "", + lastModified: new Date(bookmarks[1].lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(bookmarks[2].guid), + itemType: bookmarks[2].type, + url: bookmarks[2].url, + guid: bookmarks[2].guid, + parentGuid: bookmarks[2].parentGuid, + keyword: "", + lastModified: new Date(bookmarks[2].lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + ]); + + 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([ + { + type: "bookmark-keyword-changed", + id: itemId, + itemType: bookmark.type, + url: bookmark.url, + guid: bookmark.guid, + parentGuid: bookmark.parentGuid, + keyword: "keyword", + lastModified: new Date(bookmark.lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + ]); + + 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([ + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(oldBmk.guid), + itemType: oldBmk.type, + url: oldBmk.url, + guid: oldBmk.guid, + parentGuid: oldBmk.parentGuid, + keyword: "", + lastModified: new Date(oldBmk.lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(newBmk.guid), + itemType: newBmk.type, + url: newBmk.url, + guid: newBmk.guid, + parentGuid: newBmk.parentGuid, + keyword: "", + lastModified: new Date(newBmk.lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(newBmk.guid), + itemType: newBmk.type, + url: newBmk.url, + guid: newBmk.guid, + parentGuid: newBmk.parentGuid, + keyword: "kw1-1", + lastModified: new Date(newBmk.lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(newBmk.guid), + itemType: newBmk.type, + url: newBmk.url, + guid: newBmk.guid, + parentGuid: newBmk.parentGuid, + keyword: "kw1-2", + lastModified: new Date(newBmk.lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + ]); + + 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([ + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(oldBmk.guid), + itemType: oldBmk.type, + url: oldBmk.url, + guid: oldBmk.guid, + parentGuid: oldBmk.parentGuid, + keyword: "", + lastModified: new Date(oldBmk.lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(newBmk.guid), + itemType: newBmk.type, + url: newBmk.url, + guid: newBmk.guid, + parentGuid: newBmk.parentGuid, + keyword: "", + lastModified: new Date(newBmk.lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(newBmk.guid), + itemType: newBmk.type, + url: newBmk.url, + guid: newBmk.guid, + parentGuid: newBmk.parentGuid, + keyword: "kw8-1", + lastModified: new Date(newBmk.lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + { + type: "bookmark-keyword-changed", + id: await PlacesUtils.promiseItemId(newBmk.guid), + itemType: newBmk.type, + url: newBmk.url, + guid: newBmk.guid, + parentGuid: newBmk.parentGuid, + keyword: "kw8-2", + lastModified: new Date(newBmk.lastModified), + source: Ci.nsINavBookmarksService.SOURCE_DEFAULT, + isTagging: false, + }, + ]); + + 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( + "bookmark-keyword-changed", + events => + events.some(event => event.guid === fx.guid && event.keyword === "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" + ); +}); |