Bug 1617448 - Allow the compose APIs to work with identities. r=mkmelin
authorGeoff Lankow <geoff@darktrojan.net>
Sat, 28 Mar 2020 15:19:49 +1300
changeset 38650 83b898e3dfb2017a173b8fcc91a89e2aa3a625fe
parent 38649 b2b96ec63aff658f33e49832cd828aaf19d80a94
child 38651 f91579666b7a560981d4d2305bf286896581375e
push id400
push userclokep@gmail.com
push dateMon, 04 May 2020 18:56:09 +0000
reviewersmkmelin
bugs1617448
Bug 1617448 - Allow the compose APIs to work with identities. r=mkmelin
mail/components/compose/content/MsgComposeCommands.js
mail/components/extensions/parent/ext-compose.js
mail/components/extensions/schemas/compose.json
mail/components/extensions/test/browser/browser_ext_compose_begin.js
mail/components/extensions/test/browser/browser_ext_compose_details.js
mail/components/extensions/test/browser/browser_ext_compose_onBeforeSend.js
mail/components/extensions/test/browser/head.js
--- a/mail/components/compose/content/MsgComposeCommands.js
+++ b/mail/components/compose/content/MsgComposeCommands.js
@@ -3965,16 +3965,26 @@ function GetComposeDetails() {
  * @param {string} [newValues.replyTo]
  * @param {string} [newValues.newsgroups]
  * @param {string} [newValues.followupTo]
  * @param {string} [newValues.subject]
  * @param {string} [newValues.body]
  * @param {string} [newValues.plainTextBody]
  */
 function SetComposeDetails(newValues) {
+  if (newValues.identityKey !== null) {
+    let identityList = document.getElementById("msgIdentity");
+    for (let menuItem of identityList.menupopup.children) {
+      if (menuItem.getAttribute("identitykey") == newValues.identityKey) {
+        identityList.selectedItem = menuItem;
+        LoadIdentity(false);
+        break;
+      }
+    }
+  }
   CompFields2Recipients(newValues);
   if (typeof newValues.subject == "string") {
     gMsgCompose.compFields.subject = document.getElementById(
       "msgSubject"
     ).value = newValues.subject;
     SetComposeWindowTitle();
   }
   if (
--- a/mail/components/extensions/parent/ext-compose.js
+++ b/mail/components/extensions/parent/ext-compose.js
@@ -39,17 +39,17 @@ async function parseComposeRecipientList
         );
       }
     }
     return recipients.join(",");
   }
   return list;
 }
 
-async function openComposeWindow(relatedMessageId, type, details) {
+async function openComposeWindow(relatedMessageId, type, details, extension) {
   function waitForWindow() {
     return new Promise(resolve => {
       function observer(subject, topic, data) {
         if (
           subject.location.href ==
           "chrome://messenger/content/messengercompose/messengercompose.xhtml"
         ) {
           Services.obs.removeObserver(observer, "chrome-document-loaded");
@@ -103,16 +103,31 @@ async function openComposeWindow(related
       }
       if (details.isPlainText) {
         throw new ExtensionError(
           "Cannot specify body when isPlainText is true. Use plainTextBody instead."
         );
       }
     }
 
+    if (details.identityId !== null) {
+      if (!extension.hasPermission("accountsRead")) {
+        throw new ExtensionError(
+          'Using identities requires the "accountsRead" permission'
+        );
+      }
+
+      let identity = MailServices.accounts.allIdentities.find(
+        i => i.key == details.identityId
+      );
+      if (!identity) {
+        throw new ExtensionError(`Identity not found: ${details.identityId}`);
+      }
+      params.identity = identity;
+    }
     for (let field of ["to", "cc", "bcc", "replyTo", "followupTo"]) {
       composeFields[field] = await parseComposeRecipientList(details[field]);
     }
     if (details.newsgroups) {
       if (Array.isArray(details.newsgroups)) {
         composeFields.newsgroups = details.newsgroups.join(",");
       } else {
         composeFields.newsgroups = details.newsgroups;
@@ -134,17 +149,17 @@ async function openComposeWindow(related
 
   params.composeFields = composeFields;
 
   let newWindowPromise = waitForWindow();
   MailServices.compose.OpenComposeWindowWithParams(null, params);
   return newWindowPromise;
 }
 
-function getComposeDetails(composeWindow) {
+function getComposeDetails(composeWindow, extension) {
   let composeFields = composeWindow.GetComposeDetails();
   let editor = composeWindow.GetCurrentEditor();
 
   let details = {
     to: composeFields.splitRecipients(composeFields.to, false),
     cc: composeFields.splitRecipients(composeFields.cc, false),
     bcc: composeFields.splitRecipients(composeFields.bcc, false),
     replyTo: composeFields.splitRecipients(composeFields.replyTo, false),
@@ -152,40 +167,59 @@ function getComposeDetails(composeWindow
     newsgroups: composeFields.newsgroups
       ? composeFields.newsgroups.split(",")
       : [],
     subject: composeFields.subject,
     isPlainText: !composeWindow.IsHTMLEditor(),
     body: editor.outputToString("text/html", 0),
     plainTextBody: editor.outputToString("text/plain", 0),
   };
+  if (extension.hasPermission("accountsRead")) {
+    details.identityId = composeWindow.getCurrentIdentityKey();
+  }
   return details;
 }
 
-async function setComposeDetails(composeWindow, details) {
+async function setComposeDetails(composeWindow, details, extension) {
   if (details.body && details.plainTextBody) {
     throw new ExtensionError(
       "Only one of body and plainTextBody can be specified."
     );
   }
 
+  if (details.identityId) {
+    if (!extension.hasPermission("accountsRead")) {
+      throw new ExtensionError(
+        'Using identities requires the "accountsRead" permission'
+      );
+    }
+
+    let identity = MailServices.accounts.allIdentities.find(
+      i => i.key == details.identityId
+    );
+    if (!identity) {
+      throw new ExtensionError(`Identity not found: ${details.identityId}`);
+    }
+    details.identityKey = details.identityId;
+  }
   for (let field of ["to", "cc", "bcc", "replyTo", "followupTo"]) {
     if (field in details) {
       details[field] = await parseComposeRecipientList(details[field]);
     }
   }
   if (Array.isArray(details.newsgroups)) {
     details.newsgroups = details.newsgroups.join(",");
   }
   composeWindow.SetComposeDetails(details);
 }
 
-var composeEventTracker = new (class extends EventEmitter {
-  constructor() {
+class ComposeEventTracker extends EventEmitter {
+  constructor(extension) {
     super();
+    this.extension = extension;
     this.listenerCount = 0;
   }
   on(event, listener) {
     super.on(event, listener);
 
     this.listenerCount++;
     if (this.listenerCount == 1) {
       windowTracker.addListener("beforesend", this);
@@ -205,39 +239,43 @@ var composeEventTracker = new (class ext
     let msgType = event.detail;
     let composeWindow = event.target;
 
     composeWindow.ToggleWindowLock(true);
 
     let results = await this.emit(
       "compose-before-send",
       composeWindow,
-      getComposeDetails(composeWindow)
+      getComposeDetails(composeWindow, this.extension)
     );
     if (results) {
       for (let result of results) {
         if (!result) {
           continue;
         }
         if (result.cancel) {
           composeWindow.ToggleWindowLock(false);
           return;
         }
         if (result.details) {
-          await setComposeDetails(composeWindow, result.details);
+          await setComposeDetails(
+            composeWindow,
+            result.details,
+            this.extension
+          );
           composeWindow.GetComposeDetails();
           composeWindow.expandRecipients();
         }
       }
     }
 
     composeWindow.ToggleWindowLock(false);
     composeWindow.CompleteGenericSendMessage(msgType);
   }
-})();
+}
 
 this.compose = class extends ExtensionAPI {
   getAPI(context) {
     function getComposeTab(tabId) {
       let tab = tabManager.get(tabId);
       if (tab instanceof TabmailTab) {
         throw new ExtensionError("Not a valid compose window");
       }
@@ -248,65 +286,72 @@ this.compose = class extends ExtensionAP
       ) {
         throw new ExtensionError(`Not a valid compose window: ${location}`);
       }
       return tab;
     }
 
     let { extension } = context;
     let { tabManager, windowManager } = extension;
+    this.eventTracker = new ComposeEventTracker(extension);
+
     return {
       compose: {
         onBeforeSend: new EventManager({
           context,
           name: "compose.onBeforeSend",
           inputHandling: true,
           register: fire => {
             let listener = (event, window, details) => {
               let win = windowManager.wrapWindow(window);
               return fire.async(
                 tabManager.convert(win.activeTab.nativeTab),
                 details
               );
             };
 
-            composeEventTracker.on("compose-before-send", listener);
+            this.eventTracker.on("compose-before-send", listener);
             return () => {
-              composeEventTracker.off("compose-before-send", listener);
+              this.eventTracker.off("compose-before-send", listener);
             };
           },
         }).api(),
         beginNew(details) {
-          return openComposeWindow(null, Ci.nsIMsgCompType.New, details);
+          return openComposeWindow(
+            null,
+            Ci.nsIMsgCompType.New,
+            details,
+            extension
+          );
         },
-        beginReply(messageId, replyType) {
+        beginReply(messageId, replyType, details) {
           let type = Ci.nsIMsgCompType.Reply;
           if (replyType == "replyToList") {
             type = Ci.nsIMsgCompType.ReplyToList;
           } else if (replyType == "replyToAll") {
             type = Ci.nsIMsgCompType.ReplyAll;
           }
-          return openComposeWindow(messageId, type);
+          return openComposeWindow(messageId, type, details, extension);
         },
         beginForward(messageId, forwardType, details) {
           let type = Ci.nsIMsgCompType.ForwardInline;
           if (forwardType == "forwardAsAttachment") {
             type = Ci.nsIMsgCompType.ForwardAsAttachment;
           } else if (
             forwardType === null &&
             Services.prefs.getIntPref("mail.forward_message_mode") == 0
           ) {
             type = Ci.nsIMsgCompType.ForwardAsAttachment;
           }
-          return openComposeWindow(messageId, type, details);
+          return openComposeWindow(messageId, type, details, extension);
         },
         getComposeDetails(tabId) {
           let tab = getComposeTab(tabId);
-          return getComposeDetails(tab.nativeTab);
+          return getComposeDetails(tab.nativeTab, extension);
         },
         setComposeDetails(tabId, details) {
           let tab = getComposeTab(tabId);
-          return setComposeDetails(tab.nativeTab, details);
+          return setComposeDetails(tab.nativeTab, details, extension);
         },
       },
     };
   }
 };
--- a/mail/components/extensions/schemas/compose.json
+++ b/mail/components/extensions/schemas/compose.json
@@ -59,16 +59,21 @@
           }
         ]
       },
       {
         "id": "ComposeDetails",
         "type": "object",
         "description": "Used by various functions to represent the state of a message being composed. Note that functions using this type may have a partial implementation.",
         "properties": {
+          "identityId": {
+            "type": "string",
+            "description": "The ID of an identity from the :doc:`accounts` API. The settings from the identity will be used in the composed message. If ``from`` is also specified, the ``name`` and ``email`` properties of the identity are overridden. If ``replyTo`` is also specified, the ``replyTo`` property of the identity is overridden.",
+            "optional": true
+          },
           "to": {
             "$ref": "ComposeRecipientList",
             "optional": true
           },
           "cc": {
             "$ref": "ComposeRecipientList",
             "optional": true
           },
@@ -183,16 +188,21 @@
             "name": "replyType",
             "type": "string",
             "enum": [
               "replyToSender",
               "replyToList",
               "replyToAll"
             ],
             "optional": true
+          },
+          {
+            "name": "details",
+            "$ref": "ComposeDetails",
+            "optional": true
           }
         ]
       },
       {
         "name": "beginForward",
         "type": "function",
         "async": true,
         "parameters": [
--- a/mail/components/extensions/test/browser/browser_ext_compose_begin.js
+++ b/mail/components/extensions/test/browser/browser_ext_compose_begin.js
@@ -1,24 +1,92 @@
 /* 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/. */
 
 let account = createAccount();
-addIdentity(account);
+let defaultIdentity = addIdentity(account);
+let nonDefaultIdentity = addIdentity(account);
+let rootFolder = account.incomingServer.rootFolder;
+rootFolder.createSubfolder("test", null);
+let folder = rootFolder.getChildNamed("test");
+createMessages(folder, 3);
+
+add_task(async () => {
+  window.gFolderTreeView.selectFolder(folder);
+  await new Promise(resolve => executeSoon(resolve));
+});
+
+add_task(async function testIdentity() {
+  let extension = ExtensionTestUtils.loadExtension({
+    background: async () => {
+      let [account] = await browser.accounts.list();
+      let [defaultIdentity, nonDefaultIdentity] = account.identities;
+      let folder = account.folders.find(f => f.name == "test");
+      let { messages } = await browser.messages.list(folder);
+      browser.test.assertEq(3, messages.length);
+
+      browser.test.log(defaultIdentity.id);
+      browser.test.log(nonDefaultIdentity.id);
+
+      let funcs = [
+        { name: "beginNew", args: [] },
+        { name: "beginReply", args: [messages[0].id] },
+        { name: "beginForward", args: [messages[1].id, "forwardAsAttachment"] },
+      ];
+      let tests = [
+        { args: [], isDefault: true },
+        {
+          args: [{ identityId: defaultIdentity.id }],
+          isDefault: true,
+        },
+        {
+          args: [{ identityId: nonDefaultIdentity.id }],
+          isDefault: false,
+        },
+      ];
+      for (let func of funcs) {
+        browser.test.log(func.name);
+        for (let test of tests) {
+          browser.test.log(JSON.stringify(test.args));
+          await browser.compose[func.name](...func.args.concat(test.args));
+          browser.test.sendMessage("checkIdentity", test.isDefault);
+          await new Promise(resolve => {
+            browser.test.onMessage.addListener(function listener() {
+              browser.test.onMessage.removeListener(listener);
+              resolve();
+            });
+          });
+        }
+      }
+
+      browser.test.notifyPass("finished");
+    },
+    manifest: { permissions: ["accountsRead", "messagesRead"] },
+  });
+
+  extension.onMessage("checkIdentity", async isDefault => {
+    let composeWindows = [...Services.wm.getEnumerator("msgcompose")];
+    is(composeWindows.length, 1);
+    await new Promise(resolve => composeWindows[0].setTimeout(resolve));
+
+    is(
+      composeWindows[0].getCurrentIdentityKey(),
+      isDefault ? defaultIdentity.key : nonDefaultIdentity.key
+    );
+    composeWindows[0].close();
+    extension.sendMessage();
+  });
+
+  await extension.startup();
+  await extension.awaitFinish("finished");
+  await extension.unload();
+});
 
 add_task(async function testHeaders() {
-  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);
           };
--- a/mail/components/extensions/test/browser/browser_ext_compose_details.js
+++ b/mail/components/extensions/test/browser/browser_ext_compose_details.js
@@ -1,13 +1,15 @@
 /* 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/. */
 
-addIdentity(createAccount());
+let account = createAccount();
+let defaultIdentity = addIdentity(account);
+let nonDefaultIdentity = addIdentity(account);
 
 add_task(async function testHeaders() {
   let extension = ExtensionTestUtils.loadExtension({
     background: async () => {
       function waitForEvent(eventName) {
         return new Promise(resolve => {
           let listener = window => {
             browser.windows[eventName].removeListener(listener);
@@ -54,16 +56,19 @@ add_task(async function testHeaders() {
           browser.test.onMessage.addListener(function listener() {
             browser.test.onMessage.removeListener(listener);
             resolve();
           });
           browser.test.sendMessage("checkWindow", expected);
         });
       }
 
+      let [account] = await browser.accounts.list();
+      let [defaultIdentity, nonDefaultIdentity] = account.identities;
+
       let addressBook = await browser.addressBooks.create({
         name: "Baker Street",
       });
       let contacts = {
         sherlock: await browser.contacts.create(addressBook, {
           DisplayName: "Sherlock Holmes",
           PrimaryEmail: "sherlock@bakerstreet.invalid",
         }),
@@ -83,20 +88,35 @@ add_task(async function testHeaders() {
 
       let createdWindowPromise = waitForEvent("onCreated");
       await browser.compose.beginNew();
       let createdWindow = await createdWindowPromise;
       let [createdTab] = await browser.tabs.query({
         windowId: createdWindow.id,
       });
 
-      await checkWindow({});
+      await checkWindow({ identityId: defaultIdentity.id });
 
       let tests = [
         {
+          // Change the identity.
+          input: { identityId: nonDefaultIdentity.id },
+          expected: { identityId: nonDefaultIdentity.id },
+        },
+        {
+          // Don't change the identity.
+          input: {},
+          expected: { identityId: nonDefaultIdentity.id },
+        },
+        {
+          // Change the identity back again.
+          input: { identityId: defaultIdentity.id },
+          expected: { identityId: defaultIdentity.id },
+        },
+        {
           // Single input, string.
           input: { to: "Greg Lestrade <greg@bakerstreet.invalid>" },
           expected: { to: ["Greg Lestrade <greg@bakerstreet.invalid>"] },
         },
         {
           // Empty string. Done here so we have something to clear.
           input: { to: "" },
           expected: {},
--- a/mail/components/extensions/test/browser/browser_ext_compose_onBeforeSend.js
+++ b/mail/components/extensions/test/browser/browser_ext_compose_onBeforeSend.js
@@ -2,17 +2,18 @@
  * 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/. */
 
 var { ExtensionSupport } = ChromeUtils.import(
   "resource:///modules/ExtensionSupport.jsm"
 );
 
 let account = createAccount();
-addIdentity(account);
+let defaultIdentity = addIdentity(account);
+let nonDefaultIdentity = addIdentity(account, "nondefault@invalid");
 
 add_task(async function testCancel() {
   let extension = ExtensionTestUtils.loadExtension({
     background: async () => {
       function waitForEvent(eventName) {
         return new Promise(resolve => {
           let listener = window => {
             browser.windows[eventName].removeListener(listener);
@@ -223,16 +224,19 @@ add_task(async function testChangeDetail
           browser.test.onMessage.addListener(function listener() {
             browser.test.onMessage.removeListener(listener);
             resolve();
           });
           browser.test.sendMessage("checkWindow", expected);
         });
       }
 
+      let [account] = await browser.accounts.list();
+      let [defaultIdentity, nonDefaultIdentity] = account.identities;
+
       // Add a listener that changes the headers and body. Sending should
       // continue and the headers should change. This is largely the same code
       // as tested in browser_ext_compose_details.js, so just test that the
       // changes happen.
 
       let createdWindowPromise = waitForEvent("onCreated");
       await browser.compose.beginNew({
         to: ["test@test.invalid"],
@@ -250,26 +254,28 @@ add_task(async function testChangeDetail
 
       let [tab] = await browser.tabs.query({ windowId: createdWindow.id });
 
       let listener5 = (tab, details) => {
         listener5.tab = tab;
         listener5.details = details;
         return {
           details: {
+            identityId: nonDefaultIdentity.id,
             to: ["to@test5.invalid"],
             cc: ["cc@test5.invalid"],
             subject: "Changed by listener5",
             body: "New body from listener5.",
           },
         };
       };
       browser.compose.onBeforeSend.addListener(listener5);
       await beginSend();
       browser.test.assertEq(tab.id, listener5.tab.id, "listener5 was fired");
+      browser.test.assertEq(defaultIdentity.id, listener5.details.identityId);
       browser.test.assertEq(1, listener5.details.to.length);
       browser.test.assertEq(
         "test@test.invalid",
         listener5.details.to[0],
         "listener5 recipient correct"
       );
       browser.test.assertEq(
         "Test",
@@ -302,40 +308,42 @@ add_task(async function testChangeDetail
         listener6.details = details;
         return new Promise(resolve => {
           listener6.resolve = resolve;
         });
       };
       browser.compose.onBeforeSend.addListener(listener6);
       await beginSend();
       browser.test.assertEq(tab.id, listener6.tab.id, "listener6 was fired");
+      browser.test.assertEq(defaultIdentity.id, listener6.details.identityId);
       browser.test.assertEq(1, listener6.details.to.length);
       browser.test.assertEq(
         "test@test.invalid",
         listener6.details.to[0],
         "listener6 recipient correct"
       );
       browser.test.assertEq(
         "Test",
         listener6.details.subject,
         "listener6 subject correct"
       );
       listener6.resolve({
         details: {
+          identityId: nonDefaultIdentity.id,
           to: ["to@test6.invalid"],
           cc: ["cc@test6.invalid"],
           subject: "Changed by listener6",
           body: "New body from listener6.",
         },
       });
       browser.compose.onBeforeSend.removeListener(listener6);
 
       browser.test.notifyPass("finished");
     },
-    manifest: { permissions: ["compose"] },
+    manifest: { permissions: ["accountsRead", "compose"] },
   });
 
   extension.onMessage("beginSend", async () => {
     let composeWindows = [...Services.wm.getEnumerator("msgcompose")];
     is(composeWindows.length, 1);
 
     composeWindows[0].GenericSendMessage(Ci.nsIMsgCompDeliverMode.Later);
     extension.sendMessage();
@@ -354,16 +362,17 @@ add_task(async function testChangeDetail
   await extension.startup();
   await extension.awaitFinish("finished");
   await extension.unload();
 
   let outbox = account.incomingServer.rootFolder.getChildNamed("outbox");
   let outboxMessages = outbox.messages;
   ok(outboxMessages.hasMoreElements());
   let sentMessage5 = outboxMessages.getNext();
+  is(sentMessage5.author, "nondefault@invalid", "author was changed");
   is(sentMessage5.subject, "Changed by listener5", "subject was changed");
   is(sentMessage5.recipients, "to@test5.invalid", "to was changed");
   is(sentMessage5.ccList, "cc@test5.invalid", "cc was changed");
 
   await new Promise(resolve => {
     window.MsgHdrToMimeMessage(sentMessage5, null, (msgHdr, mimeMessage) => {
       is(
         // Fold Windows line-endings \r\n to \n.
@@ -371,16 +380,17 @@ add_task(async function testChangeDetail
         "New body from listener5.\n"
       );
       resolve();
     });
   });
 
   ok(outboxMessages.hasMoreElements());
   let sentMessage6 = outboxMessages.getNext();
+  is(sentMessage6.author, "nondefault@invalid", "author was changed");
   is(sentMessage6.subject, "Changed by listener6", "subject was changed");
   is(sentMessage6.recipients, "to@test6.invalid", "to was changed");
   is(sentMessage6.ccList, "cc@test6.invalid", "cc was changed");
 
   await new Promise(resolve => {
     window.MsgHdrToMimeMessage(sentMessage6, null, (msgHdr, mimeMessage) => {
       is(
         // Fold Windows line-endings \r\n to \n.
--- a/mail/components/extensions/test/browser/head.js
+++ b/mail/components/extensions/test/browser/head.js
@@ -43,22 +43,25 @@ function createAccount() {
   return account;
 }
 
 function cleanUpAccount(account) {
   info(`Cleaning up account ${account.toString()}`);
   MailServices.accounts.removeAccount(account, true);
 }
 
-function addIdentity(account) {
+function addIdentity(account, email = "mochitest@localhost") {
   let identity = MailServices.accounts.createIdentity();
-  identity.email = "mochitest@localhost";
+  identity.email = email;
   account.addIdentity(identity);
-  account.defaultIdentity = identity;
+  if (!account.defaultIdentity) {
+    account.defaultIdentity = identity;
+  }
   info(`Created identity ${identity.toString()}`);
+  return identity;
 }
 
 function createMessages(folder, count) {
   const { MessageGenerator } = ChromeUtils.import(
     "resource://testing-common/mailnews/MessageGenerator.jsm"
   );
   let messages = new MessageGenerator().makeMessages({ count });
   let messageStrings = messages.map(message => message.toMboxString());
@@ -197,16 +200,20 @@ async function openNewMailWindow(options
  * @param {string} [fields.subject]
  */
 async function checkComposeHeaders(expected) {
   let composeWindows = [...Services.wm.getEnumerator("msgcompose")];
   is(composeWindows.length, 1);
   let composeDocument = composeWindows[0].document;
   await new Promise(resolve => composeWindows[0].setTimeout(resolve));
 
+  if ("identityId" in expected) {
+    is(composeWindows[0].getCurrentIdentityKey(), expected.identityId);
+  }
+
   let checkField = (fieldName, elementId) => {
     let pills = composeDocument
       .getElementById(elementId)
       .getElementsByTagName("mail-address-pill");
 
     if (fieldName in expected) {
       is(
         pills.length,