Revision control
Copy as Markdown
Other Tools
/* 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
const { ensure_table_view } = ChromeUtils.importESModule(
);
const { MessageGenerator } = ChromeUtils.importESModule(
);
const { PromiseTestUtils } = ChromeUtils.importESModule(
);
const tabmail = document.getElementById("tabmail");
const about3Pane = tabmail.currentAbout3Pane;
let rootFolder, testFolder, testMessages;
add_setup(async function () {
const account = MailServices.accounts.createLocalMailAccount();
account.addIdentity(MailServices.accounts.createIdentity());
rootFolder = account.incomingServer.rootFolder;
testFolder = await rootFolder.createSubfolderAsync("tableView");
testFolder.QueryInterface(Ci.nsIMsgLocalMailFolder);
const generator = new MessageGenerator();
testFolder.addMessageBatch(
generator
.makeMessages({ count: 5 })
.map(message => message.toMessageString())
);
testMessages = [...testFolder.messages];
about3Pane.displayFolder(testFolder.URI);
about3Pane.paneLayout.messagePaneVisible = false;
registerCleanupFunction(() => {
MailServices.junk.resetTrainingData();
MailServices.accounts.removeAccount(account, false);
about3Pane.paneLayout.messagePaneVisible = true;
about3Pane.folderTree.focus();
});
});
add_task(async function testButtons() {
await ensure_table_view(document);
const threadTree = about3Pane.threadTree;
// .rows is a live collection.
const rows = threadTree.table.body.rows;
// Check the initial state.
Assert.ok(!testMessages[1].isRead, "message 1 should be not marked as read");
Assert.ok(!testMessages[2].isFlagged, "message 2 should not be flagged");
Assert.equal(
testMessages[3].getStringProperty("junkscore"),
"",
"message 3 should not be marked as spam"
);
Assert.equal(rows.length, 5, "there should be five rows");
Assert.ok(
rows[1].dataset.properties.split(" ").includes("unread"),
"row 1 properties should include 'unread'"
);
Assert.ok(
!rows[2].dataset.properties.split(" ").includes("flagged"),
"row 2 properties should not include 'flagged'"
);
Assert.ok(
!rows[3].dataset.properties.split(" ").includes("junk"),
"row 3 properties should not include 'junk'"
);
// Click all the buttons.
let classificationPromise = PromiseTestUtils.promiseFolderNotification(
testFolder,
"msgsJunkStatusChanged"
);
EventUtils.synthesizeMouseAtCenter(
rows[1].querySelector("button.tree-button-unread"),
{},
about3Pane
);
EventUtils.synthesizeMouseAtCenter(
rows[2].querySelector("button.tree-button-flag"),
{},
about3Pane
);
EventUtils.synthesizeMouseAtCenter(
rows[3].querySelector("button.tree-button-spam"),
{},
about3Pane
);
Assert.ok(testMessages[1].isRead, "message 1 should be marked as read");
Assert.ok(testMessages[2].isFlagged, "message 2 should be flagged");
Assert.equal(
testMessages[3].getStringProperty("junkscore"),
"100",
"message 3 should be marked as spam"
);
// Wait for the tree to update.
await classificationPromise;
await new Promise(resolve => requestAnimationFrame(resolve));
await new Promise(resolve => setTimeout(resolve));
Assert.equal(rows.length, 5, "there should be five rows");
Assert.ok(
!rows[1].dataset.properties.split(" ").includes("unread"),
"row 1 properties should not include 'unread'"
);
Assert.ok(
rows[2].dataset.properties.split(" ").includes("flagged"),
"row 2 properties should include 'flagged'"
);
Assert.ok(
rows[3].dataset.properties.split(" ").includes("junk"),
"row 3 properties should include 'junk'"
);
// Click all the buttons again.
classificationPromise = PromiseTestUtils.promiseFolderNotification(
testFolder,
"msgsJunkStatusChanged"
);
EventUtils.synthesizeMouseAtCenter(
rows[1].querySelector("button.tree-button-unread"),
{},
about3Pane
);
EventUtils.synthesizeMouseAtCenter(
rows[2].querySelector("button.tree-button-flag"),
{},
about3Pane
);
EventUtils.synthesizeMouseAtCenter(
rows[3].querySelector("button.tree-button-spam"),
{},
about3Pane
);
Assert.ok(!testMessages[1].isRead, "message 1 should be not marked as read");
Assert.ok(!testMessages[2].isFlagged, "message 2 should not be flagged");
Assert.equal(
testMessages[3].getStringProperty("junkscore"),
"0",
"message 3 should not be marked as spam"
);
// Wait for the tree to update.
await classificationPromise;
await new Promise(resolve => requestAnimationFrame(resolve));
await new Promise(resolve => setTimeout(resolve));
Assert.equal(rows.length, 5, "there should be five rows");
Assert.ok(
rows[1].dataset.properties.split(" ").includes("unread"),
"row 1 properties should include 'unread'"
);
Assert.ok(
!rows[2].dataset.properties.split(" ").includes("flagged"),
"row 2 properties should not include 'flagged'"
);
Assert.ok(
!rows[3].dataset.properties.split(" ").includes("junk"),
"row 3 properties should not include 'junk'"
);
// Show the delete button column.
EventUtils.synthesizeMouseAtCenter(
threadTree.querySelector("th.last-column button.button-column-picker"),
{},
about3Pane
);
const pickerPopup = threadTree.querySelector(
"menupopup.menupopup-column-picker"
);
await BrowserTestUtils.waitForPopupEvent(pickerPopup, "shown");
pickerPopup.activateItem(
pickerPopup.querySelector(`menuitem[value="deleteCol"]`)
);
pickerPopup.hidePopup();
await BrowserTestUtils.waitForPopupEvent(pickerPopup, "hidden");
await BrowserTestUtils.waitForMutationCondition(
threadTree,
{ attributes: true, subtree: true },
() =>
BrowserTestUtils.isVisible(
rows[4].querySelector("button.tree-button-delete")
),
{ msg: "waiting for the delete button column to be visible" }
);
// Test the delete button.
const deletionPromise = PromiseTestUtils.promiseFolderEvent(
testFolder,
"DeleteOrMoveMsgCompleted"
);
EventUtils.synthesizeMouseAtCenter(
rows[4].querySelector("button.tree-button-delete"),
{},
about3Pane
);
await deletionPromise;
Assert.equal(rows.length, 4, "there should be four rows");
});