summaryrefslogtreecommitdiffstats
path: root/comm/mail/components/extensions/test/xpcshell/test_ext_accounts.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/components/extensions/test/xpcshell/test_ext_accounts.js')
-rw-r--r--comm/mail/components/extensions/test/xpcshell/test_ext_accounts.js1089
1 files changed, 1089 insertions, 0 deletions
diff --git a/comm/mail/components/extensions/test/xpcshell/test_ext_accounts.js b/comm/mail/components/extensions/test/xpcshell/test_ext_accounts.js
new file mode 100644
index 0000000000..ac6f5482ce
--- /dev/null
+++ b/comm/mail/components/extensions/test/xpcshell/test_ext_accounts.js
@@ -0,0 +1,1089 @@
+/* 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/. */
+
+"use strict";
+
+var { ExtensionTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/ExtensionXPCShellUtils.sys.mjs"
+);
+
+add_task(async function test_accounts() {
+ // Here all the accounts are local but the first account will behave as
+ // an actual local account and will be kept last always.
+ let files = {
+ "background.js": async () => {
+ let [account1Id, account1Name] = await window.waitForMessage();
+
+ let defaultAccount = await browser.accounts.getDefault();
+ browser.test.assertEq(
+ null,
+ defaultAccount,
+ "The default account should be null, as none is defined."
+ );
+
+ let result1 = await browser.accounts.list();
+ browser.test.assertEq(1, result1.length);
+ window.assertDeepEqual(
+ {
+ id: account1Id,
+ name: account1Name,
+ type: "none",
+ folders: [
+ {
+ accountId: account1Id,
+ name: "Trash",
+ path: "/Trash",
+ type: "trash",
+ },
+ {
+ accountId: account1Id,
+ name: "Outbox",
+ path: "/Unsent Messages",
+ type: "outbox",
+ },
+ ],
+ },
+ result1[0]
+ );
+
+ // Test that excluding folders works.
+ let result1WithOutFolders = await browser.accounts.list(false);
+ for (let account of result1WithOutFolders) {
+ browser.test.assertEq(null, account.folders, "Folders not included");
+ }
+
+ let [account2Id, account2Name] = await window.sendMessage(
+ "create account 2"
+ );
+ // The new account is defined as default and should be returned first.
+ let result2 = await browser.accounts.list();
+ browser.test.assertEq(2, result2.length);
+ window.assertDeepEqual(
+ [
+ {
+ id: account2Id,
+ name: account2Name,
+ type: "imap",
+ folders: [
+ {
+ accountId: account2Id,
+ name: "Inbox",
+ path: "/INBOX",
+ type: "inbox",
+ },
+ ],
+ },
+ {
+ id: account1Id,
+ name: account1Name,
+ type: "none",
+ folders: [
+ {
+ accountId: account1Id,
+ name: "Trash",
+ path: "/Trash",
+ type: "trash",
+ },
+ {
+ accountId: account1Id,
+ name: "Outbox",
+ path: "/Unsent Messages",
+ type: "outbox",
+ },
+ ],
+ },
+ ],
+ result2
+ );
+
+ let result3 = await browser.accounts.get(account1Id);
+ window.assertDeepEqual(result1[0], result3);
+ let result4 = await browser.accounts.get(account2Id);
+ window.assertDeepEqual(result2[0], result4);
+
+ let result3WithoutFolders = await browser.accounts.get(account1Id, false);
+ browser.test.assertEq(
+ null,
+ result3WithoutFolders.folders,
+ "Folders not included"
+ );
+ let result4WithoutFolders = await browser.accounts.get(account2Id, false);
+ browser.test.assertEq(
+ null,
+ result4WithoutFolders.folders,
+ "Folders not included"
+ );
+
+ await window.sendMessage("create folders");
+ let result5 = await browser.accounts.get(account1Id);
+ let platformInfo = await browser.runtime.getPlatformInfo();
+ window.assertDeepEqual(
+ [
+ {
+ accountId: account1Id,
+ name: "Trash",
+ path: "/Trash",
+ subFolders: [
+ {
+ accountId: account1Id,
+ name: "%foo %test% 'bar'(!)+",
+ path: "/Trash/%foo %test% 'bar'(!)+",
+ },
+ {
+ accountId: account1Id,
+ name: "Ϟ",
+ // This character is not supported on Windows, so it gets hashed,
+ // by NS_MsgHashIfNecessary.
+ path: platformInfo.os == "win" ? "/Trash/b52bc214" : "/Trash/Ϟ",
+ },
+ ],
+ type: "trash",
+ },
+ {
+ accountId: account1Id,
+ name: "Outbox",
+ path: "/Unsent Messages",
+ type: "outbox",
+ },
+ ],
+ result5.folders
+ );
+
+ // Check we can access the folders through folderPathToURI.
+ for (let folder of result5.folders) {
+ await browser.messages.list(folder);
+ }
+
+ let result6 = await browser.accounts.get(account2Id);
+ window.assertDeepEqual(
+ [
+ {
+ accountId: account2Id,
+ name: "Inbox",
+ path: "/INBOX",
+ subFolders: [
+ {
+ accountId: account2Id,
+ name: "%foo %test% 'bar'(!)+",
+ path: "/INBOX/%foo %test% 'bar'(!)+",
+ },
+ {
+ accountId: account2Id,
+ name: "Ϟ",
+ path: "/INBOX/&A94-",
+ },
+ ],
+ type: "inbox",
+ },
+ {
+ // The trash folder magically appears at this point.
+ // It wasn't here before.
+ accountId: "account2",
+ name: "Trash",
+ path: "/Trash",
+ type: "trash",
+ },
+ ],
+ result6.folders
+ );
+
+ // Check we can access the folders through folderPathToURI.
+ for (let folder of result6.folders) {
+ await browser.messages.list(folder);
+ }
+
+ defaultAccount = await browser.accounts.getDefault();
+ browser.test.assertEq(result2[0].id, defaultAccount.id);
+
+ browser.test.notifyPass("finished");
+ },
+ "utils.js": await getUtilsJS(),
+ };
+ let extension = ExtensionTestUtils.loadExtension({
+ files,
+ manifest: {
+ background: { scripts: ["utils.js", "background.js"] },
+ permissions: ["accountsRead", "accountsIdentities", "messagesRead"],
+ },
+ });
+
+ await extension.startup();
+ let account1 = createAccount();
+ extension.sendMessage(account1.key, account1.incomingServer.prettyName);
+
+ await extension.awaitMessage("create account 2");
+ let account2 = createAccount("imap");
+ IMAPServer.open();
+ account2.incomingServer.port = IMAPServer.port;
+ account2.incomingServer.username = "user";
+ account2.incomingServer.password = "password";
+ MailServices.accounts.defaultAccount = account2;
+ extension.sendMessage(account2.key, account2.incomingServer.prettyName);
+
+ await extension.awaitMessage("create folders");
+ let inbox1 = account1.incomingServer.rootFolder.subFolders[0];
+ // Test our code can handle characters that might be escaped.
+ inbox1.createSubfolder("%foo %test% 'bar'(!)+", null);
+ inbox1.createSubfolder("Ϟ", null); // Test our code can handle unicode.
+
+ let inbox2 = account2.incomingServer.rootFolder.subFolders[0];
+ inbox2.QueryInterface(Ci.nsIMsgImapMailFolder).hierarchyDelimiter = "/";
+ // Test our code can handle characters that might be escaped.
+ inbox2.createSubfolder("%foo %test% 'bar'(!)+", null);
+ await PromiseTestUtils.promiseFolderAdded("%foo %test% 'bar'(!)+");
+ inbox2.createSubfolder("Ϟ", null); // Test our code can handle unicode.
+ await PromiseTestUtils.promiseFolderAdded("Ϟ");
+
+ extension.sendMessage();
+
+ await extension.awaitFinish("finished");
+ await extension.unload();
+
+ cleanUpAccount(account1);
+ cleanUpAccount(account2);
+});
+
+add_task(async function test_identities() {
+ let account1 = createAccount();
+ let account2 = createAccount("imap");
+ let identity0 = addIdentity(account1, "id0@invalid");
+ let identity1 = addIdentity(account1, "id1@invalid");
+ let identity2 = addIdentity(account1, "id2@invalid");
+ let identity3 = addIdentity(account2, "id3@invalid");
+ addIdentity(account2, "id4@invalid");
+ identity2.label = "A label";
+ identity2.fullName = "Identity 2!";
+ identity2.organization = "Dis Organization";
+ identity2.replyTo = "reply@invalid";
+ identity2.composeHtml = true;
+ identity2.htmlSigText = "This is me. And this is my Dog.";
+ identity2.htmlSigFormat = false;
+
+ equal(account1.defaultIdentity.key, identity0.key);
+ equal(account2.defaultIdentity.key, identity3.key);
+ let files = {
+ "background.js": async () => {
+ let accounts = await browser.accounts.list();
+ browser.test.assertEq(2, accounts.length);
+
+ const localAccount = accounts.find(account => account.type == "none");
+ const imapAccount = accounts.find(account => account.type == "imap");
+
+ // Register event listener.
+ let onCreatedLog = [];
+ browser.identities.onCreated.addListener((id, created) => {
+ onCreatedLog.push({ id, created });
+ });
+ let onUpdatedLog = [];
+ browser.identities.onUpdated.addListener((id, changed) => {
+ onUpdatedLog.push({ id, changed });
+ });
+ let onDeletedLog = [];
+ browser.identities.onDeleted.addListener(id => {
+ onDeletedLog.push(id);
+ });
+
+ const { id: accountId, identities } = localAccount;
+ const identityIds = identities.map(i => i.id);
+ browser.test.assertEq(3, identities.length);
+
+ browser.test.assertEq(accountId, identities[0].accountId);
+ browser.test.assertEq("id0@invalid", identities[0].email);
+ browser.test.assertEq(accountId, identities[1].accountId);
+ browser.test.assertEq("id1@invalid", identities[1].email);
+ browser.test.assertEq(accountId, identities[2].accountId);
+ browser.test.assertEq("id2@invalid", identities[2].email);
+ browser.test.assertEq("A label", identities[2].label);
+ browser.test.assertEq("Identity 2!", identities[2].name);
+ browser.test.assertEq("Dis Organization", identities[2].organization);
+ browser.test.assertEq("reply@invalid", identities[2].replyTo);
+ browser.test.assertEq(true, identities[2].composeHtml);
+ browser.test.assertEq(
+ "This is me. And this is my Dog.",
+ identities[2].signature
+ );
+ browser.test.assertEq(true, identities[2].signatureIsPlainText);
+
+ // Testing browser.identities.list().
+
+ let allIdentities = await browser.identities.list();
+ browser.test.assertEq(5, allIdentities.length);
+
+ let localIdentities = await browser.identities.list(localAccount.id);
+ browser.test.assertEq(
+ 3,
+ localIdentities.length,
+ "number of local identities is correct"
+ );
+ for (let i = 0; i < 2; i++) {
+ browser.test.assertEq(
+ localAccount.identities[i].id,
+ localIdentities[i].id,
+ "returned local identity is correct"
+ );
+ }
+
+ let imapIdentities = await browser.identities.list(imapAccount.id);
+ browser.test.assertEq(
+ 2,
+ imapIdentities.length,
+ "number of imap identities is correct"
+ );
+ for (let i = 0; i < 1; i++) {
+ browser.test.assertEq(
+ imapAccount.identities[i].id,
+ imapIdentities[i].id,
+ "returned imap identity is correct"
+ );
+ }
+
+ // Testing browser.identities.get().
+
+ let badIdentity = await browser.identities.get("funny");
+ browser.test.assertEq(null, badIdentity);
+
+ for (let identity of identities) {
+ let testIdentity = await browser.identities.get(identity.id);
+ for (let prop of Object.keys(identity)) {
+ browser.test.assertEq(
+ identity[prop],
+ testIdentity[prop],
+ `Testing identity.${prop}`
+ );
+ }
+ }
+
+ // Testing browser.identities.delete().
+
+ let imapDefaultIdentity = await browser.identities.getDefault(
+ imapAccount.id
+ );
+ let imapNonDefaultIdentity = imapIdentities.find(
+ identity => identity.id != imapDefaultIdentity.id
+ );
+
+ await browser.identities.delete(imapNonDefaultIdentity.id);
+ imapIdentities = await browser.identities.list(imapAccount.id);
+ browser.test.assertEq(
+ 1,
+ imapIdentities.length,
+ "number of imap identities after delete is correct"
+ );
+ browser.test.assertEq(
+ imapDefaultIdentity.id,
+ imapIdentities[0].id,
+ "leftover identity after delete is correct"
+ );
+
+ await browser.test.assertRejects(
+ browser.identities.delete(imapDefaultIdentity.id),
+ `Identity ${imapDefaultIdentity.id} is the default identity of account ${imapAccount.id} and cannot be deleted`,
+ "browser.identities.delete threw exception"
+ );
+
+ await browser.test.assertRejects(
+ browser.identities.delete("somethingInvalid"),
+ "Identity not found: somethingInvalid",
+ "browser.identities.delete threw exception"
+ );
+
+ // Testing browser.identities.create().
+
+ let createTests = [
+ {
+ // Set all.
+ accountId: imapAccount.id,
+ details: {
+ email: "id0+test@invalid",
+ label: "TestLabel",
+ name: "Mr. Test",
+ organization: "MZLA",
+ replyTo: "id0+test@invalid",
+ signature: "This is Bruce. And this is my Cat.",
+ composeHtml: true,
+ signatureIsPlainText: false,
+ },
+ },
+ {
+ // Set some.
+ accountId: imapAccount.id,
+ details: {
+ email: "id0+work@invalid",
+ replyTo: "",
+ signature: "I am Batman.",
+ composeHtml: false,
+ },
+ },
+ {
+ // Set none.
+ accountId: imapAccount.id,
+ details: {},
+ },
+ {
+ // Set some on an invalid account.
+ accountId: "somethingInvalid",
+ details: {
+ email: "id0+work@invalid",
+ replyTo: "",
+ signature: "I am Batman.",
+ composeHtml: false,
+ },
+ expectedThrow: `Account not found: somethingInvalid`,
+ },
+ {
+ // Try to set a protected property.
+ accountId: imapAccount.id,
+ details: {
+ accountId: "accountId5",
+ },
+ expectedThrow: `Setting the accountId property of a MailIdentity is not supported.`,
+ },
+ {
+ // Try to set a protected property together with others.
+ accountId: imapAccount.id,
+ details: {
+ id: "id8",
+ email: "id0+work@invalid",
+ label: "TestLabel",
+ name: "Mr. Test",
+ organization: "MZLA",
+ replyTo: "",
+ signature: "I am Batman.",
+ composeHtml: false,
+ signatureIsPlainText: false,
+ },
+ expectedThrow: `Setting the id property of a MailIdentity is not supported.`,
+ },
+ ];
+ for (let createTest of createTests) {
+ if (createTest.expectedThrow) {
+ await browser.test.assertRejects(
+ browser.identities.create(createTest.accountId, createTest.details),
+ createTest.expectedThrow,
+ `It rejects as expected: ${createTest.expectedThrow}.`
+ );
+ } else {
+ let createPromise = new Promise(resolve => {
+ const callback = (id, identity) => {
+ browser.identities.onCreated.removeListener(callback);
+ resolve(identity);
+ };
+ browser.identities.onCreated.addListener(callback);
+ });
+ let createdIdentity = await browser.identities.create(
+ createTest.accountId,
+ createTest.details
+ );
+ let createdIdentity2 = await createPromise;
+
+ let expected = createTest.details;
+ for (let prop of Object.keys(expected)) {
+ browser.test.assertEq(
+ expected[prop],
+ createdIdentity[prop],
+ `Testing created identity.${prop}`
+ );
+ browser.test.assertEq(
+ expected[prop],
+ createdIdentity2[prop],
+ `Testing created identity.${prop}`
+ );
+ }
+ await browser.identities.delete(createdIdentity.id);
+ }
+
+ let foundIdentities = await browser.identities.list(imapAccount.id);
+ browser.test.assertEq(
+ 1,
+ foundIdentities.length,
+ "number of imap identities after create/delete is correct"
+ );
+ }
+
+ // Testing browser.identities.update().
+
+ let updateTests = [
+ {
+ // Set all.
+ identityId: identities[2].id,
+ details: {
+ email: "id0+test@invalid",
+ label: "TestLabel",
+ name: "Mr. Test",
+ organization: "MZLA",
+ replyTo: "id0+test@invalid",
+ signature: "This is Bruce. And this is my Cat.",
+ composeHtml: true,
+ signatureIsPlainText: false,
+ },
+ },
+ {
+ // Set some.
+ identityId: identities[2].id,
+ details: {
+ email: "id0+work@invalid",
+ replyTo: "",
+ signature: "I am Batman.",
+ composeHtml: false,
+ },
+ expected: {
+ email: "id0+work@invalid",
+ label: "TestLabel",
+ name: "Mr. Test",
+ organization: "MZLA",
+ replyTo: "",
+ signature: "I am Batman.",
+ composeHtml: false,
+ signatureIsPlainText: false,
+ },
+ },
+ {
+ // Clear.
+ identityId: identities[2].id,
+ details: {
+ email: "",
+ label: "",
+ name: "",
+ organization: "",
+ replyTo: "",
+ signature: "",
+ composeHtml: false,
+ signatureIsPlainText: true,
+ },
+ },
+ {
+ // Try to update an invalid identity.
+ identityId: "somethingInvalid",
+ details: {
+ email: "id0+work@invalid",
+ replyTo: "",
+ signature: "I am Batman.",
+ composeHtml: false,
+ },
+ expectedThrow: "Identity not found: somethingInvalid",
+ },
+ {
+ // Try to update a protected property.
+ identityId: identities[2].id,
+ details: {
+ accountId: "accountId5",
+ },
+ expectedThrow:
+ "Setting the accountId property of a MailIdentity is not supported.",
+ },
+ {
+ // Try to update another protected property together with others.
+ identityId: identities[2].id,
+ details: {
+ id: "id8",
+ email: "id0+work@invalid",
+ label: "TestLabel",
+ name: "Mr. Test",
+ organization: "MZLA",
+ replyTo: "",
+ signature: "I am Batman.",
+ composeHtml: false,
+ signatureIsPlainText: false,
+ },
+ expectedThrow:
+ "Setting the id property of a MailIdentity is not supported.",
+ },
+ ];
+ for (let updateTest of updateTests) {
+ if (updateTest.expectedThrow) {
+ await browser.test.assertRejects(
+ browser.identities.update(
+ updateTest.identityId,
+ updateTest.details
+ ),
+ updateTest.expectedThrow,
+ `It rejects as expected: ${updateTest.expectedThrow}.`
+ );
+ continue;
+ }
+
+ let updatePromise = new Promise(resolve => {
+ const callback = (id, changed) => {
+ browser.identities.onUpdated.removeListener(callback);
+ resolve(changed);
+ };
+ browser.identities.onUpdated.addListener(callback);
+ });
+ let updatedIdentity = await browser.identities.update(
+ updateTest.identityId,
+ updateTest.details
+ );
+ await updatePromise;
+
+ let returnedIdentity = await browser.identities.get(
+ updateTest.identityId
+ );
+
+ let expected = updateTest.expected || updateTest.details;
+ for (let prop of Object.keys(expected)) {
+ browser.test.assertEq(
+ expected[prop],
+ updatedIdentity[prop],
+ `Testing updated identity.${prop}`
+ );
+ browser.test.assertEq(
+ expected[prop],
+ returnedIdentity[prop],
+ `Testing returned identity.${prop}`
+ );
+ }
+ }
+
+ // Testing getDefault().
+
+ let defaultIdentity = await browser.identities.getDefault(accountId);
+ browser.test.assertEq(identities[0].id, defaultIdentity.id);
+
+ await browser.identities.setDefault(accountId, identityIds[2]);
+ defaultIdentity = await browser.identities.getDefault(accountId);
+ browser.test.assertEq(identities[2].id, defaultIdentity.id);
+
+ let { identities: newIdentities } = await browser.accounts.get(accountId);
+ browser.test.assertEq(3, newIdentities.length);
+ browser.test.assertEq(identityIds[2], newIdentities[0].id);
+ browser.test.assertEq(identityIds[0], newIdentities[1].id);
+ browser.test.assertEq(identityIds[1], newIdentities[2].id);
+
+ await browser.identities.setDefault(accountId, identityIds[1]);
+ defaultIdentity = await browser.identities.getDefault(accountId);
+ browser.test.assertEq(identities[1].id, defaultIdentity.id);
+
+ ({ identities: newIdentities } = await browser.accounts.get(accountId));
+ browser.test.assertEq(3, newIdentities.length);
+ browser.test.assertEq(identityIds[1], newIdentities[0].id);
+ browser.test.assertEq(identityIds[2], newIdentities[1].id);
+ browser.test.assertEq(identityIds[0], newIdentities[2].id);
+
+ // Check event listeners.
+ window.assertDeepEqual(
+ onCreatedLog,
+ [
+ {
+ id: "id6",
+ created: {
+ accountId: "account4",
+ id: "id6",
+ label: "TestLabel",
+ name: "Mr. Test",
+ email: "id0+test@invalid",
+ replyTo: "id0+test@invalid",
+ organization: "MZLA",
+ composeHtml: true,
+ signature: "This is Bruce. And this is my Cat.",
+ signatureIsPlainText: false,
+ },
+ },
+ {
+ id: "id7",
+ created: {
+ accountId: "account4",
+ id: "id7",
+ label: "",
+ name: "",
+ email: "id0+work@invalid",
+ replyTo: "",
+ organization: "",
+ composeHtml: false,
+ signature: "I am Batman.",
+ signatureIsPlainText: true,
+ },
+ },
+ {
+ id: "id8",
+ created: {
+ accountId: "account4",
+ id: "id8",
+ label: "",
+ name: "",
+ email: "",
+ replyTo: "",
+ organization: "",
+ composeHtml: true,
+ signature: "",
+ signatureIsPlainText: true,
+ },
+ },
+ ],
+ "captured onCreated events are correct"
+ );
+ window.assertDeepEqual(
+ onUpdatedLog,
+ [
+ {
+ id: "id3",
+ changed: {
+ label: "TestLabel",
+ name: "Mr. Test",
+ email: "id0+test@invalid",
+ replyTo: "id0+test@invalid",
+ organization: "MZLA",
+ signature: "This is Bruce. And this is my Cat.",
+ signatureIsPlainText: false,
+ accountId: "account3",
+ id: "id3",
+ },
+ },
+ {
+ id: "id3",
+ changed: {
+ email: "id0+work@invalid",
+ replyTo: "",
+ composeHtml: false,
+ signature: "I am Batman.",
+ accountId: "account3",
+ id: "id3",
+ },
+ },
+ {
+ id: "id3",
+ changed: {
+ label: "",
+ name: "",
+ email: "",
+ organization: "",
+ signature: "",
+ signatureIsPlainText: true,
+ accountId: "account3",
+ id: "id3",
+ },
+ },
+ ],
+ "captured onUpdated events are correct"
+ );
+ window.assertDeepEqual(
+ onDeletedLog,
+ ["id5", "id6", "id7", "id8"],
+ "captured onDeleted events are correct"
+ );
+
+ browser.test.notifyPass("finished");
+ },
+ "utils.js": await getUtilsJS(),
+ };
+ let extension = ExtensionTestUtils.loadExtension({
+ files,
+ manifest: {
+ background: { scripts: ["utils.js", "background.js"] },
+ permissions: ["accountsRead", "accountsIdentities"],
+ },
+ });
+
+ await extension.startup();
+ await extension.awaitFinish("finished");
+ await extension.unload();
+
+ equal(account1.defaultIdentity.key, identity1.key);
+
+ cleanUpAccount(account1);
+ cleanUpAccount(account2);
+});
+
+add_task(async function test_identities_without_write_permissions() {
+ let account = createAccount();
+ let identity0 = addIdentity(account, "id0@invalid");
+
+ equal(account.defaultIdentity.key, identity0.key);
+
+ let extension = ExtensionTestUtils.loadExtension({
+ async background() {
+ let accounts = await browser.accounts.list();
+ browser.test.assertEq(1, accounts.length);
+
+ const [{ identities }] = accounts;
+ browser.test.assertEq(1, identities.length);
+
+ // Testing browser.identities.update().
+
+ await browser.test.assertThrows(
+ () => browser.identities.update(identities[0].id, {}),
+ "browser.identities.update is not a function",
+ "It rejects for a missing permission."
+ );
+
+ // Testing browser.identities.delete().
+
+ await browser.test.assertThrows(
+ () => browser.identities.delete(identities[0].id),
+ "browser.identities.delete is not a function",
+ "It rejects for a missing permission."
+ );
+
+ browser.test.notifyPass("finished");
+ },
+ manifest: {
+ permissions: ["accountsRead"],
+ },
+ });
+
+ await extension.startup();
+ await extension.awaitFinish("finished");
+ await extension.unload();
+
+ cleanUpAccount(account);
+});
+
+add_task(async function test_accounts_events() {
+ let account1 = createAccount();
+ addIdentity(account1, "id1@invalid");
+
+ let files = {
+ "background.js": async () => {
+ // Register event listener.
+ let onCreatedLog = [];
+ let onUpdatedLog = [];
+ let onDeletedLog = [];
+
+ let createListener = (id, created) => {
+ onCreatedLog.push({ id, created });
+ };
+ let updateListener = (id, changed) => {
+ onUpdatedLog.push({ id, changed });
+ };
+ let deleteListener = id => {
+ onDeletedLog.push(id);
+ };
+
+ await browser.accounts.onCreated.addListener(createListener);
+ await browser.accounts.onUpdated.addListener(updateListener);
+ await browser.accounts.onDeleted.addListener(deleteListener);
+
+ // Create accounts.
+ let imapAccountKey = await window.sendMessage("createAccount", {
+ type: "imap",
+ identity: "user@invalidImap",
+ });
+ let localAccountKey = await window.sendMessage("createAccount", {
+ type: "none",
+ identity: "user@invalidLocal",
+ });
+ let popAccountKey = await window.sendMessage("createAccount", {
+ type: "pop3",
+ identity: "user@invalidPop",
+ });
+
+ // Update account identities.
+ let accounts = await browser.accounts.list();
+ let imapAccount = accounts.find(a => a.id == imapAccountKey);
+ let localAccount = accounts.find(a => a.id == localAccountKey);
+ let popAccount = accounts.find(a => a.id == popAccountKey);
+
+ let id1 = await browser.identities.create(imapAccount.id, {
+ composeHtml: true,
+ email: "user1@inter.net",
+ name: "user1",
+ });
+ let id2 = await browser.identities.create(localAccount.id, {
+ composeHtml: false,
+ email: "user2@inter.net",
+ name: "user2",
+ });
+ let id3 = await browser.identities.create(popAccount.id, {
+ composeHtml: false,
+ email: "user3@inter.net",
+ name: "user3",
+ });
+
+ await browser.identities.setDefault(imapAccount.id, id1.id);
+ browser.test.assertEq(
+ id1.id,
+ (await browser.identities.getDefault(imapAccount.id)).id
+ );
+ await browser.identities.setDefault(localAccount.id, id2.id);
+ browser.test.assertEq(
+ id2.id,
+ (await browser.identities.getDefault(localAccount.id)).id
+ );
+ await browser.identities.setDefault(popAccount.id, id3.id);
+ browser.test.assertEq(
+ id3.id,
+ (await browser.identities.getDefault(popAccount.id)).id
+ );
+
+ // Update account names.
+ await window.sendMessage("updateAccountName", {
+ accountKey: imapAccountKey,
+ name: "Test1",
+ });
+ await window.sendMessage("updateAccountName", {
+ accountKey: localAccountKey,
+ name: "Test2",
+ });
+ await window.sendMessage("updateAccountName", {
+ accountKey: popAccountKey,
+ name: "Test3",
+ });
+
+ // Delete accounts.
+ await window.sendMessage("removeAccount", {
+ accountKey: imapAccountKey,
+ });
+ await window.sendMessage("removeAccount", {
+ accountKey: localAccountKey,
+ });
+ await window.sendMessage("removeAccount", {
+ accountKey: popAccountKey,
+ });
+
+ await browser.accounts.onCreated.removeListener(createListener);
+ await browser.accounts.onUpdated.removeListener(updateListener);
+ await browser.accounts.onDeleted.removeListener(deleteListener);
+
+ // Check event listeners.
+ browser.test.assertEq(3, onCreatedLog.length);
+ window.assertDeepEqual(
+ [
+ {
+ id: "account7",
+ created: {
+ id: "account7",
+ type: "imap",
+ identities: [],
+ name: "Mail for account7user@localhost",
+ folders: null,
+ },
+ },
+ {
+ id: "account8",
+ created: {
+ id: "account8",
+ type: "none",
+ identities: [],
+ name: "account8user on localhost",
+ folders: null,
+ },
+ },
+ {
+ id: "account9",
+ created: {
+ id: "account9",
+ type: "pop3",
+ identities: [],
+ name: "account9user on localhost",
+ folders: null,
+ },
+ },
+ ],
+ onCreatedLog,
+ "captured onCreated events are correct"
+ );
+ window.assertDeepEqual(
+ [
+ {
+ id: "account7",
+ changed: { id: "account7", name: "Mail for user@localhost" },
+ },
+ {
+ id: "account7",
+ changed: {
+ id: "account7",
+ defaultIdentity: { id: "id11" },
+ },
+ },
+ {
+ id: "account8",
+ changed: {
+ id: "account8",
+ defaultIdentity: { id: "id12" },
+ },
+ },
+ {
+ id: "account9",
+ changed: {
+ id: "account9",
+ defaultIdentity: { id: "id13" },
+ },
+ },
+ {
+ id: "account7",
+ changed: {
+ id: "account7",
+ defaultIdentity: { id: "id14" },
+ },
+ },
+ {
+ id: "account8",
+ changed: {
+ id: "account8",
+ defaultIdentity: { id: "id15" },
+ },
+ },
+ {
+ id: "account9",
+ changed: {
+ id: "account9",
+ defaultIdentity: { id: "id16" },
+ },
+ },
+ {
+ id: "account7",
+ changed: {
+ id: "account7",
+ name: "Test1",
+ },
+ },
+ {
+ id: "account8",
+ changed: {
+ id: "account8",
+ name: "Test2",
+ },
+ },
+ {
+ id: "account9",
+ changed: {
+ id: "account9",
+ name: "Test3",
+ },
+ },
+ ],
+ onUpdatedLog,
+ "captured onUpdated events are correct"
+ );
+ window.assertDeepEqual(
+ ["account7", "account8", "account9"],
+ onDeletedLog,
+ "captured onDeleted events are correct"
+ );
+
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ await new Promise(r => window.setTimeout(r, 250));
+ browser.test.notifyPass("finished");
+ },
+ "utils.js": await getUtilsJS(),
+ };
+ let extension = ExtensionTestUtils.loadExtension({
+ files,
+ manifest: {
+ background: { scripts: ["utils.js", "background.js"] },
+ permissions: ["accountsRead", "accountsIdentities"],
+ },
+ });
+
+ extension.onMessage("createAccount", details => {
+ let account = createAccount(details.type);
+ addIdentity(account, details.identity);
+ extension.sendMessage(account.key);
+ });
+ extension.onMessage("updateAccountName", details => {
+ let account = MailServices.accounts.getAccount(details.accountKey);
+ account.incomingServer.prettyName = details.name;
+ extension.sendMessage();
+ });
+ extension.onMessage("removeAccount", details => {
+ let account = MailServices.accounts.getAccount(details.accountKey);
+ cleanUpAccount(account);
+ extension.sendMessage();
+ });
+
+ await extension.startup();
+ await extension.awaitFinish("finished");
+ await extension.unload();
+
+ cleanUpAccount(account1);
+});