Bug 1612480 - Stop expanding mailing lists when passed to the compose.begin* API functions. r=mkmelin
authorGeoff Lankow <geoff@darktrojan.net>
Wed, 29 Jan 2020 20:24:09 +1300
changeset 38059 f66abf60532e01c159c5c35e257b93e24e54e89f
parent 38058 16c59c865c4511b5946dc4e9ea0a006ee7bdc818
child 38060 f1815f2e593f40fedabbf45da7dbab12c9373254
push id398
push userclokep@gmail.com
push dateMon, 09 Mar 2020 19:10:28 +0000
reviewersmkmelin
bugs1612480
Bug 1612480 - Stop expanding mailing lists when passed to the compose.begin* API functions. r=mkmelin
mail/components/extensions/parent/ext-compose.js
mail/components/extensions/test/browser/browser.ini
mail/components/extensions/test/browser/browser_ext_compose_begin.js
--- a/mail/components/extensions/parent/ext-compose.js
+++ b/mail/components/extensions/parent/ext-compose.js
@@ -4,23 +4,16 @@
 
 ChromeUtils.defineModuleGetter(
   this,
   "MailServices",
   "resource:///modules/MailServices.jsm"
 );
 
 async function openComposeWindow(relatedMessageId, type, composeParams) {
-  function generateAddressFromCard(card) {
-    return MailServices.headerParser.makeMimeAddress(
-      card.displayName,
-      card.primaryEmail
-    );
-  }
-
   // ForwardInline is totally broken, see bug 1513824.
   if (type == Ci.nsIMsgCompType.ForwardInline) {
     let msgHdr = null;
     let msgURI = null;
     let hdrIdentity = null;
     if (relatedMessageId) {
       msgHdr = messageTracker.getMessage(relatedMessageId);
       msgURI = msgHdr.folder.getUriForMsg(msgHdr);
@@ -60,24 +53,32 @@ async function openComposeWindow(related
           }
           if (!("addressBookCache" in this)) {
             await extensions.asyncLoadModule("addressBook");
           }
           if (recipient.type == "contact") {
             let contactNode = this.addressBookCache.findContactById(
               recipient.id
             );
-            recipients.push(generateAddressFromCard(contactNode.item));
+            recipients.push(
+              MailServices.headerParser.makeMimeAddress(
+                contactNode.item.displayName,
+                contactNode.item.primaryEmail
+              )
+            );
           } else {
             let mailingListNode = this.addressBookCache.findMailingListById(
               recipient.id
             );
-            for (let contactNode of mailingListNode.contacts) {
-              recipients.push(generateAddressFromCard(contactNode.item));
-            }
+            recipients.push(
+              MailServices.headerParser.makeMimeAddress(
+                mailingListNode.item.dirName,
+                mailingListNode.item.description || mailingListNode.item.dirName
+              )
+            );
           }
         }
         composeFields[field] = recipients.join(",");
       }
     }
     for (let field of ["replyTo", "subject", "body"]) {
       if (composeParams[field]) {
         composeFields[field] = composeParams[field];
--- a/mail/components/extensions/test/browser/browser.ini
+++ b/mail/components/extensions/test/browser/browser.ini
@@ -3,27 +3,29 @@ head = head.js
 prefs =
   browser.tabs.remote.autostart=false # e10s
   ldap_2.servers.osx.description=
   ldap_2.servers.osx.dirType=-1
   ldap_2.servers.osx.uri=
   mail.provider.suppress_dialog_on_startup=true
   mail.spotlight.firstRunDone=true
   mail.winsearch.firstRunDone=true
+  mailnews.database.global.indexer.enabled=false
   mailnews.start_page.override_url=about:blank
   mailnews.start_page.url=about:blank
 subsuite = thunderbird
 tags = webextensions
 
 [browser_ext_addressBooksUI.js]
 [browser_ext_browserAction.js]
 [browser_ext_commands_execute_browser_action.js]
 [browser_ext_commands_getAll.js]
 [browser_ext_commands_onCommand.js]
 [browser_ext_commands_update.js]
+[browser_ext_compose_begin.js]
 [browser_ext_composeAction.js]
 [browser_ext_mailTabs.js]
 [browser_ext_menus.js]
 support-files = data/content.html
 [browser_ext_messageDisplay.js]
 [browser_ext_messageDisplayAction.js]
 [browser_ext_quickFilter.js]
 [browser_ext_windows.js]
new file mode 100644
--- /dev/null
+++ b/mail/components/extensions/test/browser/browser_ext_compose_begin.js
@@ -0,0 +1,177 @@
+/* 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/. */
+
+add_task(async () => {
+  let account = createAccount();
+  addIdentity(account);
+  let rootFolder = account.incomingServer.rootFolder;
+  rootFolder.createSubfolder("test", null);
+  let folder = rootFolder.getChildNamed("test");
+  createMessages(folder, 3);
+
+  window.gFolderTreeView.selectFolder(folder);
+  await new Promise(resolve => executeSoon(resolve));
+
+  let extension = ExtensionTestUtils.loadExtension({
+    background: async () => {
+      function waitForEvent(eventName) {
+        return new Promise(resolve => {
+          let listener = window => {
+            browser.windows[eventName].removeListener(listener);
+            resolve(window);
+          };
+          browser.windows[eventName].addListener(listener);
+        });
+      }
+
+      async function checkWindow(expected) {
+        let createdWindow = await createdWindowPromise;
+        browser.test.assertEq("messageCompose", createdWindow.type);
+        browser.test.sendMessage("checkWindow", expected);
+        await new Promise(resolve => {
+          browser.test.onMessage.addListener(function listener() {
+            browser.test.onMessage.removeListener(listener);
+            resolve();
+          });
+        });
+        let removedWindowPromise = waitForEvent("onRemoved");
+        browser.windows.remove(createdWindow.id);
+        await removedWindowPromise;
+      }
+
+      let accounts = await browser.accounts.list();
+      browser.test.assertEq(1, accounts.length);
+      let folder = accounts[0].folders.find(f => f.name == "test");
+      let { messages } = await browser.messages.list(folder);
+      browser.test.assertEq(3, messages.length);
+
+      let addressBook = await browser.addressBooks.create({
+        name: "Baker Street",
+      });
+      let contacts = {
+        sherlock: await browser.contacts.create(addressBook, {
+          DisplayName: "Sherlock Holmes",
+          PrimaryEmail: "sherlock@bakerstreet.invalid",
+        }),
+        john: await browser.contacts.create(addressBook, {
+          DisplayName: "John Watson",
+          PrimaryEmail: "john@bakerstreet.invalid",
+        }),
+      };
+      let list = await browser.mailingLists.create(addressBook, {
+        name: "Holmes and Watson",
+        description: "Tenants at 221B",
+      });
+      await browser.mailingLists.addMember(list, contacts.sherlock);
+      await browser.mailingLists.addMember(list, contacts.john);
+
+      let createdWindowPromise;
+
+      // Start a new message.
+
+      createdWindowPromise = waitForEvent("onCreated");
+      await browser.compose.beginNew();
+      await checkWindow({});
+
+      // Start a new message, with a subject and recipients.
+
+      createdWindowPromise = waitForEvent("onCreated");
+      await browser.compose.beginNew({
+        to: ["Sherlock Holmes <sherlock@bakerstreet.invalid>"],
+        cc: ["John Watson <john@bakerstreet.invalid>"],
+        subject: "Did you miss me?",
+      });
+      await checkWindow({
+        to: "Sherlock Holmes <sherlock@bakerstreet.invalid>",
+        cc: "John Watson <john@bakerstreet.invalid>",
+        subject: "Did you miss me?",
+      });
+
+      // Start a new message, with a subject and recipients as contacts.
+
+      createdWindowPromise = waitForEvent("onCreated");
+      await browser.compose.beginNew({
+        to: [{ id: contacts.sherlock, type: "contact" }],
+        cc: [{ id: contacts.john, type: "contact" }],
+        subject: "Did you miss me?",
+      });
+      await checkWindow({
+        to: "Sherlock Holmes <sherlock@bakerstreet.invalid>",
+        cc: "John Watson <john@bakerstreet.invalid>",
+        subject: "Did you miss me?",
+      });
+
+      // Start a new message, with a subject and recipients as a mailing list.
+
+      createdWindowPromise = waitForEvent("onCreated");
+      await browser.compose.beginNew({
+        to: [{ id: list, type: "mailingList" }],
+        subject: "Did you miss me?",
+      });
+      await checkWindow({
+        to: 'Holmes and Watson <"Tenants at 221B">',
+        subject: "Did you miss me?",
+      });
+
+      // Reply to a message.
+
+      createdWindowPromise = waitForEvent("onCreated");
+      await browser.compose.beginReply(messages[0].id);
+      await checkWindow({
+        to: messages[0].author.replace(/"/g, ""),
+        subject: `Re: ${messages[0].subject}`,
+      });
+
+      // Forward a message.
+
+      createdWindowPromise = waitForEvent("onCreated");
+      await browser.compose.beginForward(
+        messages[1].id,
+        "forwardAsAttachment",
+        {
+          to: ["Mycroft Holmes <mycroft@bakerstreet.invalid>"],
+        }
+      );
+      await checkWindow({
+        to: "Mycroft Holmes <mycroft@bakerstreet.invalid>",
+        subject: `Fwd: ${messages[1].subject}`,
+      });
+
+      await browser.addressBooks.delete(addressBook);
+      browser.test.notifyPass("finished");
+    },
+    manifest: { permissions: ["accountsRead", "addressBooks", "messagesRead"] },
+  });
+
+  extension.onMessage("checkWindow", async expected => {
+    let composeWindows = [...Services.wm.getEnumerator("msgcompose")];
+    is(composeWindows.length, 1);
+    await new Promise(resolve => composeWindows[0].setTimeout(resolve));
+
+    let fields = Cc[
+      "@mozilla.org/messengercompose/composefields;1"
+    ].createInstance(Ci.nsIMsgCompFields);
+    composeWindows[0].Recipients2CompFields(fields);
+    for (let field of ["to", "cc", "bcc", "replyTo"]) {
+      if (field in expected) {
+        is(fields[field], expected[field], `${field} is correct`);
+      } else {
+        is(fields[field], "", `${field} is empty`);
+      }
+    }
+
+    let subject = composeWindows[0].document.getElementById("msgSubject").value;
+    if ("subject" in expected) {
+      is(subject, expected.subject, "subject is correct");
+    } else {
+      is(subject, "", "subject is empty");
+    }
+
+    extension.sendMessage();
+  });
+
+  await extension.startup();
+  await extension.awaitFinish("finished");
+  await extension.unload();
+});