From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../browser/browser_library_views_liveupdate.js | 255 +++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 browser/components/places/tests/browser/browser_library_views_liveupdate.js (limited to 'browser/components/places/tests/browser/browser_library_views_liveupdate.js') diff --git a/browser/components/places/tests/browser/browser_library_views_liveupdate.js b/browser/components/places/tests/browser/browser_library_views_liveupdate.js new file mode 100644 index 0000000000..593b0bd243 --- /dev/null +++ b/browser/components/places/tests/browser/browser_library_views_liveupdate.js @@ -0,0 +1,255 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Tests Library Left pane view for liveupdate. + */ + +let gLibrary = null; + +add_setup(async function () { + gLibrary = await promiseLibrary(); + + await PlacesUtils.bookmarks.eraseEverything(); + + registerCleanupFunction(async () => { + await PlacesUtils.bookmarks.eraseEverything(); + await promiseLibraryClosed(gLibrary); + }); +}); + +async function testInFolder(folderGuid, prefix) { + let addedBookmarks = []; + + let item = await insertAndCheckItem({ + parentGuid: folderGuid, + title: `${prefix}1`, + url: `http://${prefix}1.mozilla.org/`, + }); + item.title = `${prefix}1_edited`; + await updateAndCheckItem(item); + addedBookmarks.push(item); + + item = await insertAndCheckItem( + { + parentGuid: folderGuid, + title: `${prefix}2`, + url: "place:", + }, + 0 + ); + + item.title = `${prefix}2_edited`; + await updateAndCheckItem(item, 0); + addedBookmarks.push(item); + + item = await insertAndCheckItem({ + parentGuid: folderGuid, + type: PlacesUtils.bookmarks.TYPE_SEPARATOR, + }); + addedBookmarks.push(item); + + item = await insertAndCheckItem( + { + parentGuid: folderGuid, + title: `${prefix}f`, + type: PlacesUtils.bookmarks.TYPE_FOLDER, + }, + 1 + ); + + item.title = `${prefix}f_edited`; + await updateAndCheckItem(item, 1); + + item.index = 0; + await updateAndCheckItem(item, 0); + addedBookmarks.push(item); + + let folderGuid1 = item.guid; + + item = await insertAndCheckItem({ + parentGuid: folderGuid1, + title: `${prefix}f1`, + url: `http://${prefix}f1.mozilla.org/`, + }); + addedBookmarks.push(item); + + item = await insertAndCheckItem({ + parentGuid: folderGuid1, + title: `${prefix}f12`, + url: `http://${prefix}f12.mozilla.org/`, + }); + addedBookmarks.push(item); + + item.index = 0; + await updateAndCheckItem(item); + + return addedBookmarks; +} + +add_task(async function test() { + let addedBookmarks = []; + + info("*** Acting on menu bookmarks"); + addedBookmarks = addedBookmarks.concat( + await testInFolder(PlacesUtils.bookmarks.menuGuid, "bm") + ); + + info("*** Acting on toolbar bookmarks"); + addedBookmarks = addedBookmarks.concat( + await testInFolder(PlacesUtils.bookmarks.toolbarGuid, "tb") + ); + + info("*** Acting on unsorted bookmarks"); + addedBookmarks = addedBookmarks.concat( + await testInFolder(PlacesUtils.bookmarks.unfiledGuid, "ub") + ); + + // Remove bookmarks in reverse order, so that the effects are correct. + for (let i = addedBookmarks.length - 1; i >= 0; i--) { + await removeAndCheckItem(addedBookmarks[i]); + } +}); + +async function insertAndCheckItem(itemData, expectedIndex) { + let item = await PlacesUtils.bookmarks.insert(itemData); + + let [node, index, title] = getNodeForTreeItem( + item.guid, + gLibrary.PlacesOrganizer._places + ); + // Left pane should not be updated for normal bookmarks or separators. + switch (itemData.type || PlacesUtils.bookmarks.TYPE_BOOKMARK) { + case PlacesUtils.bookmarks.TYPE_BOOKMARK: + let uriString = itemData.url; + let isQuery = uriString.substr(0, 6) == "place:"; + if (isQuery) { + Assert.ok(node, "Should have a new query in the left pane."); + break; + } + // Fallthrough if this isn't a query + case PlacesUtils.bookmarks.TYPE_SEPARATOR: + Assert.ok( + !node, + "Should not have added a bookmark or separator to the left pane." + ); + break; + default: + Assert.ok( + node, + "Should have added a new node in the left pane for a folder." + ); + } + + if (node) { + Assert.equal(title, itemData.title, "Should have the correct title"); + Assert.equal(index, expectedIndex, "Should have the expected index"); + } + + return item; +} + +async function updateAndCheckItem(newItemData, expectedIndex) { + await PlacesUtils.bookmarks.update(newItemData); + + let [node, index, title] = getNodeForTreeItem( + newItemData.guid, + gLibrary.PlacesOrganizer._places + ); + + // Left pane should not be updated for normal bookmarks or separators. + switch (newItemData.type || PlacesUtils.bookmarks.TYPE_BOOKMARK) { + case PlacesUtils.bookmarks.TYPE_BOOKMARK: + let isQuery = newItemData.url.protocol == "place:"; + if (isQuery) { + Assert.ok(node, "Should be able to find the updated node"); + break; + } + // Fallthrough if this isn't a query + case PlacesUtils.bookmarks.TYPE_SEPARATOR: + Assert.ok(!node, "Should not be able to find the updated node"); + break; + default: + Assert.ok(node, "Should be able to find the updated node"); + } + + if (node) { + Assert.equal(title, newItemData.title, "Should have the correct title"); + Assert.equal(index, expectedIndex, "Should have the expected index"); + } +} + +async function removeAndCheckItem(itemData) { + await PlacesUtils.bookmarks.remove(itemData); + let [node] = getNodeForTreeItem( + itemData.guid, + gLibrary.PlacesOrganizer._places + ); + Assert.ok(!node, "Should not be able to find the removed node"); +} + +/** + * Get places node, index and cell text for a guid in a tree view. + * + * @param {string} aItemGuid + * item guid of the item to search. + * @param {object} aTree + * Tree to search in. + * @returns {Array} + * [node, index, cellText] or [null, null, ""] if not found. + */ +function getNodeForTreeItem(aItemGuid, aTree) { + function findNode(aContainerIndex) { + if (aTree.view.isContainerEmpty(aContainerIndex)) { + return [null, null, ""]; + } + + // The rowCount limit is just for sanity, but we will end looping when + // we have checked the last child of this container or we have found node. + for (let i = aContainerIndex + 1; i < aTree.view.rowCount; i++) { + let node = aTree.view.nodeForTreeIndex(i); + + if (node.bookmarkGuid == aItemGuid) { + // Minus one because we want relative index inside the container. + let tree = gLibrary.PlacesOrganizer._places; + let cellText = tree.view.getCellText(i, tree.columns.getColumnAt(0)); + return [node, i - aContainerIndex - 1, cellText]; + } + + if (PlacesUtils.nodeIsFolder(node)) { + // Open container. + aTree.view.toggleOpenState(i); + // Search inside it. + let foundNode = findNode(i); + // Close container. + aTree.view.toggleOpenState(i); + // Return node if found. + if (foundNode[0] != null) { + return foundNode; + } + } + + // We have finished walking this container. + if (!aTree.view.hasNextSibling(aContainerIndex + 1, i)) { + break; + } + } + return [null, null, ""]; + } + + // Root node is hidden, so we need to manually walk the first level. + for (let i = 0; i < aTree.view.rowCount; i++) { + // Open container. + aTree.view.toggleOpenState(i); + // Search inside it. + let foundNode = findNode(i); + // Close container. + aTree.view.toggleOpenState(i); + // Return node if found. + if (foundNode[0] != null) { + return foundNode; + } + } + return [null, null, ""]; +} -- cgit v1.2.3