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
* file, you can obtain one at http://mozilla.org/MPL/2.0/. */
/* globals MailServices, MailUtils */
var { DisplayNameUtils } = ChromeUtils.importESModule(
);
var { mailTestUtils } = ChromeUtils.importESModule(
);
const inputs = {
abName: "Mochitest Address Book",
mlName: "Mochitest Mailing List",
nickName: "Nicky",
description: "Just a test mailing list.",
addresses: [
"alan@example.com",
"betty@example.com",
"clyde@example.com",
"deb@example.com",
],
modification: " (modified)",
};
const getDisplayedAddress = address => `${address} <${address}>`;
let global = {};
/**
* Set up: create a new address book to hold the mailing list.
*/
add_task(async () => {
const bookPrefName = MailServices.ab.newAddressBook(
inputs.abName,
null,
Ci.nsIAbManager.JS_DIRECTORY_TYPE
);
const addressBook = MailServices.ab.getDirectoryFromId(bookPrefName);
const abWindow = await openAddressBookWindow();
global = {
abWindow,
addressBook,
booksList: abWindow.booksList,
mailListUID: undefined,
};
});
/**
* Create a new mailing list with some addresses, in the new address book.
*/
add_task(async () => {
const mailingListWindowPromise = promiseLoadSubDialog(
).then(async function (mlWindow) {
const mlDocument = mlWindow.document;
const mlDocElement = mlDocument.querySelector("dialog");
const listName = mlDocument.getElementById("ListName");
if (mlDocument.activeElement != listName) {
await BrowserTestUtils.waitForEvent(listName, "focus");
}
const abPopup = mlDocument.getElementById("abPopup");
const listNickName = mlDocument.getElementById("ListNickName");
const listDescription = mlDocument.getElementById("ListDescription");
const addressInput1 = mlDocument.getElementById("addressCol1#1");
const addressInputsCount = mlDocument
.getElementById("addressingWidget")
.querySelectorAll("input").length;
Assert.equal(
abPopup.label,
global.addressBook.dirName,
"the correct address book is selected in the menu"
);
Assert.equal(
abPopup.value,
global.addressBook.URI,
"the address book selected in the menu has the correct address book URI"
);
Assert.equal(listName.value, "", "no text in the list name field");
Assert.equal(listNickName.value, "", "no text in the list nickname field");
Assert.equal(listDescription.value, "", "no text in the description field");
Assert.equal(addressInput1.value, "", "no text in the addresses list");
Assert.equal(addressInputsCount, 1, "only one address list input exists");
EventUtils.sendString(inputs.mlName, mlWindow);
// Tab to nickname input.
EventUtils.sendKey("TAB", mlWindow);
EventUtils.sendString(inputs.nickName, mlWindow);
// Tab to description input.
EventUtils.sendKey("TAB", mlWindow);
EventUtils.sendString(inputs.description, mlWindow);
// Tab to address input and add addresses zero and one by entering
// both of them there.
EventUtils.sendKey("TAB", mlWindow);
EventUtils.sendString(inputs.addresses.slice(0, 2).join(", "), mlWindow);
mlDocElement.getButton("accept").click();
});
// Select the address book.
await openDirectory(global.addressBook);
// Open the new mailing list dialog, the callback above interacts with it.
EventUtils.synthesizeMouseAtCenter(
global.abWindow.document.getElementById("toolbarCreateList"),
{ clickCount: 1 },
global.abWindow
);
await mailingListWindowPromise;
// Confirm that the mailing list and addresses were saved in the backend.
Assert.ok(
MailServices.ab.cardForEmailAddress(inputs.addresses[0]),
"address zero was saved"
);
Assert.ok(
MailServices.ab.cardForEmailAddress(inputs.addresses[1]),
"address one was saved"
);
const childCards = global.addressBook.childCards;
Assert.ok(
childCards.find(card => card.primaryEmail == inputs.addresses[0]),
"address zero was saved in the correct address book"
);
Assert.ok(
childCards.find(card => card.primaryEmail == inputs.addresses[1]),
"address one was saved in the correct address book"
);
const mailList = MailUtils.findListInAddressBooks(inputs.mlName);
// Save the mailing list UID so we can confirm it is the same later.
global.mailListUID = mailList.UID;
Assert.ok(mailList, "mailing list was created");
Assert.ok(
global.addressBook.hasMailListWithName(inputs.mlName),
"mailing list was created in the correct address book"
);
Assert.equal(mailList.dirName, inputs.mlName, "mailing list name was saved");
Assert.equal(
mailList.listNickName,
inputs.nickName,
"mailing list nick name was saved"
);
Assert.equal(
mailList.description,
inputs.description,
"mailing list description was saved"
);
const listCards = mailList.childCards;
Assert.equal(listCards.length, 2, "two cards exist in the mailing list");
Assert.ok(
listCards[0].hasEmailAddress(inputs.addresses[0]),
"address zero was saved in the mailing list"
);
Assert.ok(
listCards[1].hasEmailAddress(inputs.addresses[1]),
"address one was saved in the mailing list"
);
});
/**
* Open the mailing list dialog and modify the mailing list.
*/
add_task(async () => {
const mailingListWindowPromise = promiseLoadSubDialog(
).then(async function (mlWindow) {
const mlDocument = mlWindow.document;
const mlDocElement = mlDocument.querySelector("dialog");
if (!mlDocument.getElementById("addressCol1#3")) {
// The address input nodes are not there yet when the dialog window is
// loaded, so wait until they exist.
await mailTestUtils.awaitElementExistence(
MutationObserver,
mlDocument,
"addressingWidget",
"addressCol1#3"
);
}
if (mlDocument.activeElement.id != "addressCol1#3") {
await BrowserTestUtils.waitForEvent(
mlDocument.getElementById("addressCol1#3"),
"focus"
);
}
const listName = mlDocument.getElementById("ListName");
const listNickName = mlDocument.getElementById("ListNickName");
const listDescription = mlDocument.getElementById("ListDescription");
const addressInput1 = mlDocument.getElementById("addressCol1#1");
const addressInput2 = mlDocument.getElementById("addressCol1#2");
Assert.equal(
listName.value,
inputs.mlName,
"list name is displayed correctly"
);
Assert.equal(
listNickName.value,
inputs.nickName,
"list nickname is displayed correctly"
);
Assert.equal(
listDescription.value,
inputs.description,
"list description is displayed correctly"
);
Assert.equal(
addressInput1 && addressInput1.value,
getDisplayedAddress(inputs.addresses[0]),
"address zero is displayed correctly"
);
Assert.equal(
addressInput2 && addressInput2.value,
getDisplayedAddress(inputs.addresses[1]),
"address one is displayed correctly"
);
const textInputs = mlDocument.querySelectorAll(".textbox-addressingWidget");
Assert.equal(textInputs.length, 3, "no extraneous addresses are displayed");
// Add addresses two and three.
EventUtils.sendString(inputs.addresses.slice(2, 4).join(", "), mlWindow);
EventUtils.sendKey("RETURN", mlWindow);
await new Promise(resolve => mlWindow.setTimeout(resolve));
// Delete the address in the second row (address one).
EventUtils.synthesizeMouseAtCenter(
addressInput2,
{ clickCount: 1 },
mlWindow
);
EventUtils.synthesizeKey("a", { accelKey: true }, mlWindow);
EventUtils.sendKey("BACK_SPACE", mlWindow);
// Modify the list's name, nick name, and description fields.
const modifyField = id => {
id.focus();
EventUtils.sendKey("DOWN", mlWindow);
EventUtils.sendString(inputs.modification, mlWindow);
};
modifyField(listName);
modifyField(listNickName);
modifyField(listDescription);
mlDocElement.getButton("accept").click();
});
// Open the mailing list dialog, the callback above interacts with it.
global.booksList.selectedIndex = 3;
global.booksList.showPropertiesOfSelected();
await mailingListWindowPromise;
// Confirm that the mailing list and addresses were saved in the backend.
Assert.equal(
global.booksList.getRowAtIndex(3).querySelector("span").textContent,
inputs.mlName + inputs.modification,
`mailing list ("${
inputs.mlName + inputs.modification
}") is displayed in the address book list`
);
Assert.ok(
MailServices.ab.cardForEmailAddress(inputs.addresses[2]),
"address two was saved"
);
Assert.ok(
MailServices.ab.cardForEmailAddress(inputs.addresses[3]),
"address three was saved"
);
const childCards = global.addressBook.childCards;
Assert.ok(
childCards.find(card => card.primaryEmail == inputs.addresses[2]),
"address two was saved in the correct address book"
);
Assert.ok(
childCards.find(card => card.primaryEmail == inputs.addresses[3]),
"address three was saved in the correct address book"
);
const mailList = MailUtils.findListInAddressBooks(
inputs.mlName + inputs.modification
);
Assert.equal(
mailList && mailList.UID,
global.mailListUID,
"mailing list still exists"
);
Assert.ok(
global.addressBook.hasMailListWithName(inputs.mlName + inputs.modification),
"mailing list is still in the correct address book"
);
Assert.equal(
mailList.dirName,
inputs.mlName + inputs.modification,
"modified mailing list name was saved"
);
Assert.equal(
mailList.listNickName,
inputs.nickName + inputs.modification,
"modified mailing list nick name was saved"
);
Assert.equal(
mailList.description,
inputs.description + inputs.modification,
"modified mailing list description was saved"
);
const listCards = mailList.childCards;
Assert.equal(listCards.length, 3, "three cards exist in the mailing list");
Assert.ok(
listCards[0].hasEmailAddress(inputs.addresses[0]),
"address zero was saved in the mailing list (is still there)"
);
Assert.ok(
listCards[1].hasEmailAddress(inputs.addresses[2]),
"address two was saved in the mailing list"
);
Assert.ok(
listCards[2].hasEmailAddress(inputs.addresses[3]),
"address three was saved in the mailing list"
);
const hasAddressOne = listCards.find(card =>
card.hasEmailAddress(inputs.addresses[1])
);
Assert.ok(!hasAddressOne, "address one was deleted from the mailing list");
});
/**
* Open the mailing list dialog and confirm the changes are displayed.
*/
add_task(async () => {
const mailingListWindowPromise = promiseLoadSubDialog(
).then(async function (mailingListWindow) {
const mlDocument = mailingListWindow.document;
const mlDocElement = mlDocument.querySelector("dialog");
if (!mlDocument.getElementById("addressCol1#4")) {
// The address input nodes are not there yet when the dialog window is
// loaded, so wait until they exist.
await mailTestUtils.awaitElementExistence(
MutationObserver,
mlDocument,
"addressingWidget",
"addressCol1#4"
);
}
if (mlDocument.activeElement.id != "addressCol1#4") {
await BrowserTestUtils.waitForEvent(
mlDocument.getElementById("addressCol1#4"),
"focus"
);
}
const listName = mlDocument.getElementById("ListName");
const listNickName = mlDocument.getElementById("ListNickName");
const listDescription = mlDocument.getElementById("ListDescription");
const addressInput1 = mlDocument.getElementById("addressCol1#1");
const addressInput2 = mlDocument.getElementById("addressCol1#2");
const addressInput3 = mlDocument.getElementById("addressCol1#3");
Assert.equal(
listName.value,
inputs.mlName + inputs.modification,
"modified list name is displayed correctly"
);
Assert.equal(
listNickName.value,
inputs.nickName + inputs.modification,
"modified list nickname is displayed correctly"
);
Assert.equal(
listDescription.value,
inputs.description + inputs.modification,
"modified list description is displayed correctly"
);
Assert.equal(
addressInput1 && addressInput1.value,
getDisplayedAddress(inputs.addresses[0]),
"address zero is displayed correctly (is still there)"
);
Assert.equal(
addressInput2 && addressInput2.value,
getDisplayedAddress(inputs.addresses[2]),
"address two is displayed correctly"
);
Assert.equal(
addressInput3 && addressInput3.value,
getDisplayedAddress(inputs.addresses[3]),
"address three is displayed correctly"
);
const textInputs = mlDocument.querySelectorAll(".textbox-addressingWidget");
Assert.equal(textInputs.length, 4, "no extraneous addresses are displayed");
mlDocElement.getButton("cancel").click();
});
Assert.equal(
global.booksList.getRowAtIndex(3).querySelector("span").textContent,
inputs.mlName + inputs.modification,
`mailing list ("${
inputs.mlName + inputs.modification
}") is still displayed in the address book list`
);
// Open the mailing list dialog, the callback above interacts with it.
global.booksList.selectedIndex = 3;
global.booksList.showPropertiesOfSelected();
await mailingListWindowPromise;
});
/**
* Tear down: delete the address book and close the address book window.
*/
add_task(async () => {
const mailingListWindowPromise = BrowserTestUtils.promiseAlertDialog(
"accept",
);
const deletePromise = TestUtils.topicObserved("addrbook-directory-deleted");
Assert.equal(
global.booksList.getRowAtIndex(2).querySelector("span").textContent,
inputs.abName,
`address book ("${inputs.abName}") is displayed in the address book list`
);
global.booksList.focus();
global.booksList.selectedIndex = 2;
EventUtils.sendKey("DELETE", global.abWindow);
await Promise.all([mailingListWindowPromise, deletePromise]);
const addressBook = MailServices.ab.directories.find(
directory => directory.dirName == inputs.abName
);
Assert.ok(!addressBook, "address book was deleted");
closeAddressBookWindow();
});