diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/mail/test/browser/folder-tree-modes | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/mail/test/browser/folder-tree-modes')
6 files changed, 1012 insertions, 0 deletions
diff --git a/comm/mail/test/browser/folder-tree-modes/browser.ini b/comm/mail/test/browser/folder-tree-modes/browser.ini new file mode 100644 index 0000000000..9ca3fc18e1 --- /dev/null +++ b/comm/mail/test/browser/folder-tree-modes/browser.ini @@ -0,0 +1,51 @@ +[DEFAULT] +prefs = + mail.account.account1.server=server1 + mail.account.account2.identities=id1,id2 + mail.account.account2.server=server2 + mail.accountmanager.accounts=account1,account2 + mail.accountmanager.defaultaccount=account2 + mail.accountmanager.localfoldersserver=server1 + mail.identity.id1.fullName=Tinderbox + mail.identity.id1.htmlSigFormat=false + mail.identity.id1.smtpServer=smtp1 + mail.identity.id1.useremail=tinderbox@foo.invalid + mail.identity.id1.valid=true + mail.identity.id2.fullName=Tinderboxpushlog + mail.identity.id2.htmlSigFormat=true + mail.identity.id2.smtpServer=smtp1 + mail.identity.id2.useremail=tinderboxpushlog@foo.invalid + mail.identity.id2.valid=true + mail.provider.suppress_dialog_on_startup=true + mail.server.server1.type=none + mail.server.server1.userName=nobody + mail.server.server2.check_new_mail=false + mail.server.server2.directory-rel=[ProfD]Mail/tinderbox + mail.server.server2.download_on_biff=true + mail.server.server2.hostname=tinderbox123 + mail.server.server2.login_at_startup=false + mail.server.server2.name=tinderbox@foo.invalid + mail.server.server2.type=pop3 + mail.server.server2.userName=tinderbox + mail.server.server2.whiteListAbURI= + mail.shell.checkDefaultClient=false + mail.smtp.defaultserver=smtp1 + mail.smtpserver.smtp1.hostname=tinderbox123 + mail.smtpserver.smtp1.username=tinderbox + mail.smtpservers=smtp1 + mail.spotlight.firstRunDone=true + mail.startup.enabledMailCheckOnce=true + mail.winsearch.firstRunDone=true + mailnews.start_page.override_url=about:blank + mailnews.start_page.url=about:blank + ui.prefersReducedMotion=1 +subsuite = thunderbird +support-files = test-extension/** + +[browser_customFolderTreeMode.js] +skip-if = true # No longer supported. +[browser_customSmartFolder.js] +skip-if = true # No longer supported. +[browser_modeSwitching.js] +[browser_smartFolders.js] +[browser_unreadFolders.js] diff --git a/comm/mail/test/browser/folder-tree-modes/browser_customFolderTreeMode.js b/comm/mail/test/browser/folder-tree-modes/browser_customFolderTreeMode.js new file mode 100644 index 0000000000..49189c9254 --- /dev/null +++ b/comm/mail/test/browser/folder-tree-modes/browser_customFolderTreeMode.js @@ -0,0 +1,142 @@ +/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 for custom folder tree modes. The test mode is provided by the test + * extension in the test-extension subdirectory. + */ + +"use strict"; + +var { + assert_folder_mode, + assert_folder_visible, + FAKE_SERVER_HOSTNAME, + get_special_folder, + mc, +} = ChromeUtils.import( + "resource://testing-common/mozmill/FolderDisplayHelpers.jsm" +); +var { close_window, plan_for_new_window, wait_for_new_window } = + ChromeUtils.import("resource://testing-common/mozmill/WindowHelpers.jsm"); + +var { ExtensionSupport } = ChromeUtils.import( + "resource:///modules/ExtensionSupport.jsm" +); +var { MailServices } = ChromeUtils.import( + "resource:///modules/MailServices.jsm" +); +var { MailUtils } = ChromeUtils.import("resource:///modules/MailUtils.jsm"); + +var gInbox; + +add_setup(async function () { + let server = MailServices.accounts.findServer( + "tinderbox", + FAKE_SERVER_HOSTNAME, + "pop3" + ); + gInbox = await get_special_folder(Ci.nsMsgFolderFlags.Inbox, false, server); + + ExtensionSupport.registerWindowListener("mochitest", { + chromeURLs: ["chrome://messenger/content/messenger.xhtml"], + onLoadWindow(aWindow) { + let testFolderTreeMode = { + __proto__: aWindow.IFolderTreeMode, + generateMap(aFTV) { + var { MailServices } = ChromeUtils.import( + "resource:///modules/MailServices.jsm" + ); + // Pick the tinderbox@foo.invalid inbox and use it as the only folder + let server = MailServices.accounts.findServer( + "tinderbox", + "tinderbox123", + "pop3" + ); + let item = []; + let inbox = new aWindow.FtvItem( + server.rootFolder.getChildNamed("Inbox") + ); + inbox.__defineGetter__("children", () => []); + item.push(inbox); + + if (aWindow.gFolderTreeView.activeModes.length > 1) { + item.unshift(new aWindow.FtvItemHeader("Test%20Mode", "testmode")); + } + + return item; + }, + }; + + aWindow.gFolderTreeView.registerFolderTreeMode( + "testmode", + testFolderTreeMode, + "Test Mode" + ); + }, + }); +}); + +// Provided by the extension in test-extension. +var kTestModeID = "testmode"; + +/** + * Switch to the mode and verify that it displays correctly. + */ +add_task(function test_switch_to_test_mode() { + mc.folderTreeView.activeModes = kTestModeID; + // Hide the all folder view mode. + mc.folderTreeView.activeModes = "all"; + + assert_folder_mode(kTestModeID); + assert_folder_visible(gInbox); +}); + +/** + * Open a new 3-pane window while the custom mode is selected, and make sure + * that the mode displayed in the new window is the custom mode. + */ +add_task(async function test_open_new_window_with_custom_mode() { + // Our selection may get lost while changing modes, and be_in_folder is + // not sufficient to ensure actual selection. + mc.folderTreeView.selectFolder(gInbox); + + plan_for_new_window("mail:3pane"); + mc.window.MsgOpenNewWindowForFolder(null, -1); + let mc2 = wait_for_new_window("mail:3pane"); + + await TestUtils.waitForCondition(() => mc2.folderTreeView.isInited); + assert_folder_mode(kTestModeID, mc2); + assert_folder_visible(gInbox, mc2); + + close_window(mc2); +}); + +/** + * Switch back to all folders. + */ +add_task(function test_switch_to_all_folders() { + // Hide the test mode view enabled in the previous test. The activeModes + // setter should take care of restoring the "all" view and prevent and empty + // Folder pane. + mc.folderTreeView.activeModes = kTestModeID; + assert_folder_mode("all"); +}); + +registerCleanupFunction(() => { + mc.window.gFolderTreeView.unregisterFolderTreeMode(kTestModeID); + ExtensionSupport.unregisterWindowListener("mochitest"); + Assert.report( + false, + undefined, + undefined, + "Test ran to completion successfully" + ); + + // Some tests that open new windows don't return focus to the main window + // in a way that satisfies mochitest, and the test times out. + Services.focus.focusedWindow = window; + window.gFolderDisplay.tree.focus(); +}); diff --git a/comm/mail/test/browser/folder-tree-modes/browser_customSmartFolder.js b/comm/mail/test/browser/folder-tree-modes/browser_customSmartFolder.js new file mode 100644 index 0000000000..0f0e663445 --- /dev/null +++ b/comm/mail/test/browser/folder-tree-modes/browser_customSmartFolder.js @@ -0,0 +1,211 @@ +/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 for custom folder tree modes. The test mode is provided by the test + * extension in the test-extension subdirectory. + */ + +"use strict"; + +var { + assert_folder_collapsed, + assert_folder_displayed, + assert_folder_expanded, + assert_folder_mode, + assert_folder_not_visible, + assert_folder_selected_and_displayed, + assert_folder_visible, + collapse_folder, + expand_folder, + get_smart_folder_named, + inboxFolder, + make_message_sets_in_folders, + mc, +} = ChromeUtils.import( + "resource://testing-common/mozmill/FolderDisplayHelpers.jsm" +); + +// spaces in the name are intentional +var smartParentNameA = "My Smart Folder A"; +var smartParentNameB = "My Smart Folder B"; + +var rootFolder; +var inboxSubfolder, subfolderA, subfolderB; +var smartFolderInbox; +var smartFolderA; + +var nsMsgFolderFlags = Ci.nsMsgFolderFlags; + +/** + * create two smart folder types and two real folders, one for each + * smart folder type + */ +add_setup(async function () { + rootFolder = inboxFolder.server.rootFolder; + + // register a new smart folder type + mc.folderTreeView + .getFolderTreeMode("smart") + .addSmartFolderType(smartParentNameA, false, false); + mc.folderTreeView + .getFolderTreeMode("smart") + .addSmartFolderType(smartParentNameB, false, false); + + // Create a folder as a subfolder of the inbox + inboxFolder.createSubfolder("smartFolderA", null); + subfolderA = inboxFolder.getChildNamed("smartFolderA"); + inboxFolder.createSubfolder("smartFolderB", null); + subfolderB = inboxFolder.getChildNamed("smartFolderB"); + + // This is how folders are marked to match a custom smart folder + // The name is added to a cache, as msgDatabase access in nsITreeView is + // bad perf. + mc.window.setSmartFolderName(subfolderA, smartParentNameA); + mc.window.setSmartFolderName(subfolderB, smartParentNameB); + + // The message itself doesn't really matter, as long as there's at least one + // in the folder. + await make_message_sets_in_folders([subfolderA], [{ count: 1 }]); + await make_message_sets_in_folders([subfolderB], [{ count: 1 }]); +}); + +/** + * Switch to the smart folder mode, get the smart inbox. + */ +add_task(function test_switch_to_smart_folder_mode() { + mc.folderTreeView.activeModes = "smart"; + // Hide the all folders view. + mc.folderTreeView.activeModes = "all"; + assert_folder_mode("smart"); + + smartFolderA = get_smart_folder_named(smartParentNameA); + SimpleTest.expectUncaughtException(); + mc.folderTreeView.selectFolder(smartFolderA); +}); + +add_task(function test_cache_property() { + if (mc.window.getSmartFolderName(subfolderA) != smartParentNameA) { + throw new Error("smartFolderName A cache property not set"); + } + if (mc.window.getSmartFolderName(subfolderB) != smartParentNameB) { + throw new Error("smartFolderName B cache property not set"); + } +}); + +function _test_smart_folder_type(folder, parentName) { + let smartMode = mc.folderTreeView.getFolderTreeMode("smart"); + let [flag, name] = smartMode._getSmartFolderType(folder); + if (flag != 0) { + throw new Error( + "custom smart folder definition [" + parentName + "] has a flag" + ); + } + if (name != parentName) { + throw new Error( + "custom smart folder [" + + folder.name + + "] is incorrect [" + + name + + "] should be [" + + parentName + + "]" + ); + } +} + +add_task(function test_smart_folder_type() { + _test_smart_folder_type(subfolderA, smartParentNameA); + _test_smart_folder_type(subfolderB, smartParentNameB); +}); + +/** + * Test that our custom smart folders exist + */ + +add_task(function test_custom_folder_exists() { + assert_folder_mode("smart"); + assert_folder_displayed(smartFolderA); + // this is our custom smart folder parent created in folderPane.js + mc.folderTreeView.selectFolder(subfolderA); + assert_folder_selected_and_displayed(subfolderA); +}); + +function FTVItemHasChild(parentFTVItem, childFolder, recurse) { + for (let child of parentFTVItem.children) { + if ( + child._folder.URI == childFolder.URI || + (recurse && FTVItemHasChild(child, childFolder, recurse)) + ) { + return true; + } + } + return false; +} + +/** + * test that our real smart folder is in fact a child if the correct + * smart folder parent + */ +add_task(function test_smart_child_parent_relationship() { + let folderIndex = assert_folder_visible(smartFolderA); + let folderFTVItem = mc.folderTreeView.getFTVItemForIndex(folderIndex); + if (!FTVItemHasChild(folderFTVItem, subfolderA, false)) { + throw new Error( + "Folder: " + + subfolderA.name + + " is not a child of our smart parent folder" + ); + } + assert_folder_mode("smart"); +}); + +/** + * test that our real smart folder is NOT a child of the smart inbox in the + * tree view. + */ +add_task(function test_real_child_parent_relationship() { + smartFolderInbox = get_smart_folder_named("Inbox"); + expand_folder(smartFolderInbox); + // the real parent should be an Inbox + let folderIndex = assert_folder_visible(subfolderA.parent); + let folderFTVItem = mc.folderTreeView.getFTVItemForIndex(folderIndex); + // in the tree, subfolder is a child of our magic smart folder, and should not + // be a child of inbox + if (FTVItemHasChild(folderFTVItem, subfolderA, true)) { + throw new Error( + "Folder: " + subfolderA.name + " should not be a child of an inbox" + ); + } + assert_folder_mode("smart"); +}); + +/** + * test collapse/expand states of one of our smart folders + */ +add_task(function test_smart_subfolder() { + assert_folder_mode("smart"); + collapse_folder(smartFolderA); + assert_folder_collapsed(smartFolderA); + assert_folder_not_visible(subfolderA); + + expand_folder(smartFolderA); + assert_folder_expanded(smartFolderA); + assert_folder_visible(subfolderA); +}); + +/** + * Switch back to all folders. + */ +add_task(function test_return_to_all_folders() { + assert_folder_mode("smart"); + mc.folderTreeView.activeModes = "smart"; + assert_folder_mode("all"); +}); + +registerCleanupFunction(function () { + inboxFolder.propagateDelete(subfolderA, true); + inboxFolder.propagateDelete(subfolderB, true); +}); diff --git a/comm/mail/test/browser/folder-tree-modes/browser_modeSwitching.js b/comm/mail/test/browser/folder-tree-modes/browser_modeSwitching.js new file mode 100644 index 0000000000..dee646c754 --- /dev/null +++ b/comm/mail/test/browser/folder-tree-modes/browser_modeSwitching.js @@ -0,0 +1,338 @@ +/* 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/. */ + +/* + * Test the ability to switch between multiple folder modes. + */ + +"use strict"; + +var { + assert_folder_visible, + inboxFolder, + make_message_sets_in_folders, + mc, + toggle_main_menu, +} = ChromeUtils.import( + "resource://testing-common/mozmill/FolderDisplayHelpers.jsm" +); +var { MailTelemetryForTests } = ChromeUtils.import( + "resource:///modules/MailGlue.jsm" +); +var { TelemetryTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/TelemetryTestUtils.sys.mjs" +); +var { click_menus_in_sequence, click_through_appmenu, close_popup_sequence } = + ChromeUtils.import("resource://testing-common/mozmill/WindowHelpers.jsm"); + +var rootFolder; +var unreadFolder; +var favoriteFolder; +var modeList_menu; +var modeList_appmenu; +var view_menu; +var view_menupopup; +var appmenu_button; +var appmenu_mainView; +var appmenu_popup; +var menu_state; +var about3Pane; + +add_setup(async function () { + rootFolder = inboxFolder.server.rootFolder; + + // Create one folder with unread messages and one favorite folder. + inboxFolder.createSubfolder("UnreadFolder", null); + unreadFolder = inboxFolder.getChildNamed("UnreadFolder"); + + inboxFolder.createSubfolder("FavoriteFolder", null); + favoriteFolder = inboxFolder.getChildNamed("FavoriteFolder"); + + await make_message_sets_in_folders([unreadFolder], [{ count: 1 }]); + favoriteFolder.setFlag(Ci.nsMsgFolderFlags.Favorite); + + modeList_menu = mc.window.document.getElementById("menu_FolderViewsPopup"); + modeList_appmenu = mc.window.document.getElementById("appMenu-foldersView"); + + view_menu = mc.window.document.getElementById("menu_View"); + view_menupopup = mc.window.document.getElementById("menu_View_Popup"); + appmenu_button = mc.window.document.getElementById("button-appmenu"); + appmenu_mainView = mc.window.document.getElementById("appMenu-mainView"); + appmenu_popup = mc.window.document.getElementById("appMenu-popup"); + + // Main menu is needed for this whole test file. + menu_state = toggle_main_menu(true); + + about3Pane = document.getElementById("tabmail").currentAbout3Pane; + + Services.xulStore.removeDocument( + "chrome://messenger/content/messenger.xhtml" + ); + Services.telemetry.clearScalars(); +}); + +/** + * Check whether the expected folder mode is selected in menus and internally. + * + * @param {string} aMode - The name of the expected mode. + */ +async function assert_mode_selected(aMode) { + if (aMode != "compact") { + // "compact" isn't really a mode, we're just using this function because + // it tests everything we want to test. + Assert.ok(about3Pane.folderPane.activeModes.includes(aMode)); + } + + // We need to open the menu because only then the right mode is set in them. + if (["linux", "win"].includes(AppConstants.platform)) { + // On OS X the main menu seems not accessible for clicking from tests. + EventUtils.synthesizeMouseAtCenter(view_menu, { clickCount: 1 }, mc.window); + let popuplist = await click_menus_in_sequence( + view_menupopup, + [{ id: modeList_menu.parentNode.id }], + true + ); + for (let mode of about3Pane.folderPane.activeModes) { + Assert.ok( + modeList_menu.querySelector(`[value="${mode}"]`).hasAttribute("checked") + ); + } + close_popup_sequence(popuplist); + } + + EventUtils.synthesizeMouseAtCenter(appmenu_button, {}, mc.window); + click_through_appmenu( + [{ id: "appmenu_View" }, { id: "appmenu_FolderViews" }], + null, + mc.window + ); + for (let mode of about3Pane.folderPane.activeModes) { + Assert.ok( + modeList_appmenu + .querySelector(`[value="${mode}"]`) + .hasAttribute("checked") + ); + } + appmenu_popup.hidePopup(); +} + +/** + * Check whether the expected folder mode is unselected in menus and internally. + * + * @param {string} mode - The name of the missing mode. + */ +async function assert_mode_not_selected(mode) { + Assert.ok(!about3Pane.folderPane.activeModes.includes(mode)); + + // We need to open the menu because only then the right mode is set in them. + if (["linux", "win"].includes(AppConstants.platform)) { + // On OS X the main menu seems not accessible for clicking from tests. + EventUtils.synthesizeMouseAtCenter(view_menu, { clickCount: 1 }, mc.window); + let popuplist = await click_menus_in_sequence( + view_menupopup, + [{ id: modeList_menu.parentNode.id }], + true + ); + Assert.ok( + !modeList_menu.querySelector(`[value="${mode}"]`).hasAttribute("checked") + ); + close_popup_sequence(popuplist); + } + + EventUtils.synthesizeMouseAtCenter(appmenu_button, {}, mc.window); + click_through_appmenu( + [{ id: "appmenu_View" }, { id: "appmenu_FolderViews" }], + null, + mc.window + ); + Assert.ok( + !modeList_appmenu.querySelector(`[value="${mode}"]`).hasAttribute("checked") + ); + appmenu_popup.hidePopup(); +} + +/** + * Toggle the folder mode by clicking in the menu. + * + * @param mode The base name of the mode to select. + */ +function select_mode_in_menu(mode) { + EventUtils.synthesizeMouseAtCenter(appmenu_button, {}, mc.window); + click_through_appmenu( + [{ id: "appmenu_View" }, { id: "appmenu_FolderViews" }], + { value: mode }, + mc.window + ); + appmenu_popup.hidePopup(); +} + +/** + * Check the all folders mode. + */ +async function subtest_toggle_all_folders(show) { + let mode = "all"; + select_mode_in_menu(mode); + + if (show) { + await assert_mode_selected(mode); + } else { + await assert_mode_not_selected(mode); + } +} + +/** + * Check the unread folders mode. + */ +async function subtest_toggle_unread_folders(show) { + let mode = "unread"; + select_mode_in_menu(mode); + + if (show) { + await assert_mode_selected(mode); + + // Mode is hierarchical, parent folders are shown. + assert_folder_visible(inboxFolder.server.rootFolder); + assert_folder_visible(inboxFolder); + assert_folder_visible(unreadFolder); + } else { + await assert_mode_not_selected(mode); + } +} + +/** + * Check the favorite folders mode. + */ +async function subtest_toggle_favorite_folders(show) { + let mode = "favorite"; + select_mode_in_menu(mode); + + if (show) { + await assert_mode_selected(mode); + + // Mode is hierarchical, parent folders are shown. + assert_folder_visible(inboxFolder.server.rootFolder); + assert_folder_visible(inboxFolder); + assert_folder_visible(favoriteFolder); + } else { + await assert_mode_not_selected(mode); + } +} + +/** + * Check the recent folders mode. + */ +async function subtest_toggle_recent_folders(show) { + let mode = "recent"; + select_mode_in_menu(mode); + + if (show) { + await assert_mode_selected(mode); + } else { + await assert_mode_not_selected(mode); + } +} + +/** + * Check the smart folders mode. + */ +async function subtest_toggle_smart_folders(show) { + let mode = "smart"; + select_mode_in_menu(mode); + + if (show) { + await assert_mode_selected(mode); + } else { + await assert_mode_not_selected(mode); + } +} + +/** + * Toggle the compact mode. + */ +async function subtest_toggle_compact(compact) { + let mode = "compact"; + select_mode_in_menu(mode); + + if (compact) { + await assert_mode_selected(mode); + } else { + await assert_mode_not_selected(mode); + } +} + +/** + * Toggle the compact mode. + */ +async function subtest_toggle_tags(show) { + let mode = "tags"; + select_mode_in_menu(mode); + + if (show) { + await assert_mode_selected(mode); + } else { + await assert_mode_not_selected(mode); + } +} + +/** + * Check that the current mode(s) are accurately recorded in telemetry. + * Note that `reportUIConfiguration` usually only runs at start-up. + */ +function check_scalars(expected) { + MailTelemetryForTests.reportUIConfiguration(); + let scalarName = "tb.ui.configuration.folder_tree_modes"; + let scalars = TelemetryTestUtils.getProcessScalars("parent"); + if (expected) { + TelemetryTestUtils.assertScalar(scalars, scalarName, expected); + } else { + TelemetryTestUtils.assertScalarUnset(scalars, scalarName); + } +} + +/** + * Toggle folder modes through different means and sequences. + */ +add_task(async function test_toggling_modes() { + check_scalars(); + + await subtest_toggle_all_folders(true); + await subtest_toggle_smart_folders(true); + check_scalars("all,smart"); + + await subtest_toggle_tags(true); + check_scalars("all,smart,tags"); + + await subtest_toggle_unread_folders(true); + await subtest_toggle_favorite_folders(true); + await subtest_toggle_recent_folders(true); + check_scalars("all,smart,tags,unread,favorite,recent"); + + await subtest_toggle_compact(true); + check_scalars("all,smart,tags,unread,favorite,recent (compact)"); + + await subtest_toggle_unread_folders(false); + check_scalars("all,smart,tags,favorite,recent (compact)"); + + await subtest_toggle_compact(false); + check_scalars("all,smart,tags,favorite,recent"); + + await subtest_toggle_favorite_folders(false); + check_scalars("all,smart,tags,recent"); + + await subtest_toggle_all_folders(false); + await subtest_toggle_recent_folders(false); + await subtest_toggle_smart_folders(false); + await subtest_toggle_tags(false); + + // Confirm that the all folders mode is visible even after all the modes have + // been deselected in order to ensure that the Folder Pane is never empty. + await assert_mode_selected("all"); + check_scalars("all"); +}); + +registerCleanupFunction(function () { + inboxFolder.propagateDelete(unreadFolder, true); + inboxFolder.propagateDelete(favoriteFolder, true); + toggle_main_menu(menu_state); +}); diff --git a/comm/mail/test/browser/folder-tree-modes/browser_smartFolders.js b/comm/mail/test/browser/folder-tree-modes/browser_smartFolders.js new file mode 100644 index 0000000000..47fdca0058 --- /dev/null +++ b/comm/mail/test/browser/folder-tree-modes/browser_smartFolders.js @@ -0,0 +1,179 @@ +/* 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/. */ + +/* + * Test that the smart folder mode works properly. + */ + +"use strict"; + +var { + archive_selected_messages, + expand_folder, + FAKE_SERVER_HOSTNAME, + get_about_3pane, + get_smart_folder_named, + get_special_folder, + inboxFolder, + make_message_sets_in_folders, + select_click_row, +} = ChromeUtils.import( + "resource://testing-common/mozmill/FolderDisplayHelpers.jsm" +); +var { MailServices } = ChromeUtils.import( + "resource:///modules/MailServices.jsm" +); + +var about3Pane; +var rootFolder; +var inboxSubfolder; +var trashFolder; +var trashSubfolder; + +var smartInboxFolder; + +var inboxSet; + +add_setup(async function () { + about3Pane = get_about_3pane(); + rootFolder = inboxFolder.server.rootFolder; + // Create a folder as a subfolder of the inbox + inboxFolder.createSubfolder("SmartFoldersA", null); + inboxSubfolder = inboxFolder.getChildNamed("SmartFoldersA"); + + trashFolder = inboxFolder.server.rootFolder.getFolderWithFlags( + Ci.nsMsgFolderFlags.Trash + ); + trashFolder.createSubfolder("SmartFoldersB", null); + trashSubfolder = trashFolder.getChildNamed("SmartFoldersB"); + + // The message itself doesn't really matter, as long as there's at least one + // in the folder. + [inboxSet] = await make_message_sets_in_folders( + [inboxFolder], + [{ count: 1 }] + ); + await make_message_sets_in_folders([inboxSubfolder], [{ count: 1 }]); + + // Switch to the smart folder mode. + about3Pane.folderPane.activeModes = ["smart"]; + + // The smart inbox may not have been created at setup time, so get it now. + smartInboxFolder = get_smart_folder_named("Inbox"); +}); + +/** + * Test that smart folders are updated when the folders they should be + * searching over are added/removed or have the relevant flag set/cleared. + */ +add_task(async function test_folder_flag_changes() { + expand_folder(smartInboxFolder); + // Now attempt to select the folder. + about3Pane.displayFolder(inboxSubfolder); + // Need to archive two messages in two different accounts in order to + // create a smart Archives folder. + select_click_row(0); + archive_selected_messages(); + let pop3Server = MailServices.accounts.findServer( + "tinderbox", + FAKE_SERVER_HOSTNAME, + "pop3" + ); + let pop3Inbox = await get_special_folder( + Ci.nsMsgFolderFlags.Inbox, + false, + pop3Server + ); + await make_message_sets_in_folders([pop3Inbox], [{ count: 1 }]); + about3Pane.displayFolder(pop3Inbox); + select_click_row(0); + archive_selected_messages(); + + let smartArchiveFolder = get_smart_folder_named("Archives"); + let archiveScope = + "|" + + smartArchiveFolder.msgDatabase.dBFolderInfo.getCharProperty( + "searchFolderUri" + ) + + "|"; + // We should have both this account, and a folder corresponding + // to this year in the scope. + rootFolder = inboxFolder.server.rootFolder; + let archiveFolder = rootFolder.getChildNamed("Archives"); + assert_folder_and_children_in_scope(archiveFolder, archiveScope); + archiveFolder = pop3Server.rootFolder.getChildNamed("Archives"); + assert_folder_and_children_in_scope(archiveFolder, archiveScope); + + // Remove the archive flag, and make sure the archive folder and + // its children are no longer in the search scope. + archiveFolder.clearFlag(Ci.nsMsgFolderFlags.Archive); + + // Refresh the archive scope because clearing the flag should have + // changed it. + archiveScope = + "|" + + smartArchiveFolder.msgDatabase.dBFolderInfo.getCharProperty( + "searchFolderUri" + ) + + "|"; + + // figure out what we expect the archiveScope to now be. + rootFolder = inboxFolder.server.rootFolder; + let localArchiveFolder = rootFolder.getChildNamed("Archives"); + let desiredScope = "|" + localArchiveFolder.URI + "|"; + for (let folder of localArchiveFolder.descendants) { + desiredScope += folder.URI + "|"; + } + + Assert.equal( + archiveScope, + desiredScope, + "archive scope after removing folder" + ); + assert_folder_and_children_not_in_scope(archiveFolder, archiveScope); +}); + +function assert_folder_and_children_in_scope(folder, searchScope) { + let folderURI = "|" + folder.URI + "|"; + assert_uri_found(folderURI, searchScope); + for (let f of folder.descendants) { + assert_uri_found(f.URI, searchScope); + } +} + +function assert_folder_and_children_not_in_scope(folder, searchScope) { + let folderURI = "|" + folder.URI + "|"; + assert_uri_not_found(folderURI, searchScope); + for (let f of folder.descendants) { + assert_uri_not_found(f.URI, searchScope); + } +} + +function assert_uri_found(folderURI, scopeList) { + if (!scopeList.includes(folderURI)) { + throw new Error("scope " + scopeList + "doesn't contain " + folderURI); + } +} + +function assert_uri_not_found(folderURI, scopeList) { + if (scopeList.includes(folderURI)) { + throw new Error( + "scope " + scopeList + "contains " + folderURI + " but shouldn't" + ); + } +} + +registerCleanupFunction(async function () { + about3Pane.folderPane.activeModes = ["all"]; + inboxFolder.propagateDelete(inboxSubfolder, true); + inboxFolder.deleteMessages( + [...inboxFolder.messages], + top.msgWindow, + false, + false, + null, + false + ); + trashFolder.propagateDelete(trashSubfolder, true); +}); diff --git a/comm/mail/test/browser/folder-tree-modes/browser_unreadFolders.js b/comm/mail/test/browser/folder-tree-modes/browser_unreadFolders.js new file mode 100644 index 0000000000..ffc6dc96ac --- /dev/null +++ b/comm/mail/test/browser/folder-tree-modes/browser_unreadFolders.js @@ -0,0 +1,91 @@ +/* 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/. */ + +/* + * Test that the unread folder mode works properly. This includes making + * sure that the selected folder is maintained correctly when the view + * is rebuilt because a folder has become newly unread. + */ + +"use strict"; + +var { + assert_folder_visible, + be_in_folder, + delete_messages, + get_about_3pane, + inboxFolder, + make_message_sets_in_folders, + mc, +} = ChromeUtils.import( + "resource://testing-common/mozmill/FolderDisplayHelpers.jsm" +); + +var about3Pane; +var rootFolder; +var inboxSubfolder; +var trashFolder; +var trashSubfolder; +var inboxSet; + +add_setup(async function () { + about3Pane = get_about_3pane(); + rootFolder = inboxFolder.server.rootFolder; + + // Create a folder as a subfolder of the inbox + inboxFolder.createSubfolder("UnreadFoldersA", null); + inboxSubfolder = inboxFolder.getChildNamed("UnreadFoldersA"); + + trashFolder = inboxFolder.server.rootFolder.getFolderWithFlags( + Ci.nsMsgFolderFlags.Trash + ); + trashFolder.createSubfolder("UnreadFoldersB", null); + trashSubfolder = trashFolder.getChildNamed("UnreadFoldersB"); + + // The message itself doesn't really matter, as long as there's at least one + // in the folder. + [inboxSet] = await make_message_sets_in_folders( + [inboxFolder], + [{ count: 1 }] + ); + await make_message_sets_in_folders([inboxSubfolder], [{ count: 1 }]); + + // Switch to the unread folder mode. + await be_in_folder(inboxFolder); + about3Pane.folderPane.activeModes = ["unread"]; +}); + +/** + * Test that inbox and inboxSubfolder are in view + */ +add_task(async function test_folder_population() { + about3Pane.folderTree.expandRowAtIndex(0); + await new Promise(resolve => setTimeout(resolve)); + assert_folder_visible(inboxFolder); + + about3Pane.folderTree.expandRowAtIndex(1); + await new Promise(resolve => setTimeout(resolve)); + assert_folder_visible(inboxSubfolder); +}); + +/** + * Test that a folder newly getting unread messages doesn't + * change the selected folder in unread folders mode. + */ +add_task(async function test_newly_added_folder() { + let [newSet] = await make_message_sets_in_folders( + [trashFolder], + [{ count: 1 }] + ); + assert_folder_visible(trashFolder); + Assert.equal(about3Pane.folderTree.selectedIndex, 0); + await delete_messages(newSet); +}); + +registerCleanupFunction(async function () { + inboxFolder.propagateDelete(inboxSubfolder, true); + await delete_messages(inboxSet); + trashFolder.propagateDelete(trashSubfolder, true); + about3Pane.folderPane.activeModes = ["all"]; +}); |