summaryrefslogtreecommitdiffstats
path: root/comm/mail/components/addrbook/test/browser/browser_mailing_lists.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/components/addrbook/test/browser/browser_mailing_lists.js')
-rw-r--r--comm/mail/components/addrbook/test/browser/browser_mailing_lists.js474
1 files changed, 474 insertions, 0 deletions
diff --git a/comm/mail/components/addrbook/test/browser/browser_mailing_lists.js b/comm/mail/components/addrbook/test/browser/browser_mailing_lists.js
new file mode 100644
index 0000000000..64d679ec13
--- /dev/null
+++ b/comm/mail/components/addrbook/test/browser/browser_mailing_lists.js
@@ -0,0 +1,474 @@
+/* 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.import(
+ "resource:///modules/DisplayNameUtils.jsm"
+);
+var { mailTestUtils } = ChromeUtils.import(
+ "resource://testing-common/mailnews/MailTestUtils.jsm"
+);
+
+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 () => {
+ let bookPrefName = MailServices.ab.newAddressBook(
+ inputs.abName,
+ null,
+ Ci.nsIAbManager.JS_DIRECTORY_TYPE
+ );
+ let addressBook = MailServices.ab.getDirectoryFromId(bookPrefName);
+
+ let 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 () => {
+ let mailingListWindowPromise = promiseLoadSubDialog(
+ "chrome://messenger/content/addressbook/abMailListDialog.xhtml"
+ ).then(async function (mlWindow) {
+ let mlDocument = mlWindow.document;
+ let mlDocElement = mlDocument.querySelector("dialog");
+
+ let listName = mlDocument.getElementById("ListName");
+ if (mlDocument.activeElement != listName) {
+ await BrowserTestUtils.waitForEvent(listName, "focus");
+ }
+
+ let abPopup = mlDocument.getElementById("abPopup");
+ let listNickName = mlDocument.getElementById("ListNickName");
+ let listDescription = mlDocument.getElementById("ListDescription");
+ let addressInput1 = mlDocument.getElementById("addressCol1#1");
+ let 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.
+ 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"
+ );
+
+ let 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"
+ );
+
+ let 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"
+ );
+
+ let 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 () => {
+ let mailingListWindowPromise = promiseLoadSubDialog(
+ "chrome://messenger/content/addressbook/abEditListDialog.xhtml"
+ ).then(async function (mlWindow) {
+ let mlDocument = mlWindow.document;
+ let 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"
+ );
+ }
+
+ let listName = mlDocument.getElementById("ListName");
+ let listNickName = mlDocument.getElementById("ListNickName");
+ let listDescription = mlDocument.getElementById("ListDescription");
+ let addressInput1 = mlDocument.getElementById("addressCol1#1");
+ let 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"
+ );
+
+ let 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.
+ let 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"
+ );
+
+ let 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"
+ );
+
+ let 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"
+ );
+
+ let 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"
+ );
+
+ let 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 () => {
+ let mailingListWindowPromise = promiseLoadSubDialog(
+ "chrome://messenger/content/addressbook/abEditListDialog.xhtml"
+ ).then(async function (mailingListWindow) {
+ let mlDocument = mailingListWindow.document;
+ let 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"
+ );
+ }
+
+ let listName = mlDocument.getElementById("ListName");
+ let listNickName = mlDocument.getElementById("ListNickName");
+ let listDescription = mlDocument.getElementById("ListDescription");
+ let addressInput1 = mlDocument.getElementById("addressCol1#1");
+ let addressInput2 = mlDocument.getElementById("addressCol1#2");
+ let 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"
+ );
+
+ let 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 () => {
+ let mailingListWindowPromise = BrowserTestUtils.promiseAlertDialog(
+ "accept",
+ "chrome://global/content/commonDialog.xhtml"
+ );
+ let 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]);
+
+ let addressBook = MailServices.ab.directories.find(
+ directory => directory.dirName == inputs.abName
+ );
+
+ Assert.ok(!addressBook, "address book was deleted");
+
+ closeAddressBookWindow();
+});