summaryrefslogtreecommitdiffstats
path: root/comm/mail/test/browser/openpgp/browser_keyWizard.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/test/browser/openpgp/browser_keyWizard.js')
-rw-r--r--comm/mail/test/browser/openpgp/browser_keyWizard.js363
1 files changed, 363 insertions, 0 deletions
diff --git a/comm/mail/test/browser/openpgp/browser_keyWizard.js b/comm/mail/test/browser/openpgp/browser_keyWizard.js
new file mode 100644
index 0000000000..5b63bb1da9
--- /dev/null
+++ b/comm/mail/test/browser/openpgp/browser_keyWizard.js
@@ -0,0 +1,363 @@
+/* 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/. */
+
+/**
+ * Tests for the creation or import of an OpenPGP key.
+ */
+
+"use strict";
+
+const { mc } = ChromeUtils.import(
+ "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
+);
+const {
+ click_account_tree_row,
+ get_account_tree_row,
+ wait_for_account_tree_load,
+} = ChromeUtils.import(
+ "resource://testing-common/mozmill/AccountManagerHelpers.jsm"
+);
+var { open_content_tab_with_url } = ChromeUtils.import(
+ "resource://testing-common/mozmill/ContentTabHelpers.jsm"
+);
+const { wait_for_frame_load } = ChromeUtils.import(
+ "resource://testing-common/mozmill/WindowHelpers.jsm"
+);
+const { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+const { MockFilePicker } = ChromeUtils.importESModule(
+ "resource://testing-common/MockFilePicker.sys.mjs"
+);
+const { OpenPGPTestUtils } = ChromeUtils.import(
+ "resource://testing-common/mozmill/OpenPGPTestUtils.jsm"
+);
+
+var gAccount;
+var gIdentity;
+var gTab;
+var tabDocument;
+var tabWindow;
+
+const EXTERNAL_GNUP_KEY = "123456789ASD";
+
+var gCreatedKeyId;
+var gImportedKeyId;
+
+/**
+ * Set up the base account and identity.
+ */
+add_setup(function () {
+ gAccount = MailServices.accounts.createAccount();
+ gAccount.incomingServer = MailServices.accounts.createIncomingServer(
+ "alice",
+ "openpgp.example",
+ "pop3"
+ );
+ gIdentity = MailServices.accounts.createIdentity();
+ gIdentity.email = "alice@openpgp.example";
+ gAccount.addIdentity(gIdentity);
+
+ Services.prefs.setBoolPref("mail.openpgp.allow_external_gnupg", true);
+
+ gTab = open_content_tab_with_url("about:accountsettings");
+ wait_for_account_tree_load(gTab);
+
+ // Open the End-to-End Encryption page.
+ let accountRow = get_account_tree_row(gAccount.key, "am-e2e.xhtml", gTab);
+ click_account_tree_row(gTab, accountRow);
+
+ let iframe =
+ gTab.browser.contentWindow.document.getElementById("contentFrame");
+
+ tabDocument = iframe.contentDocument;
+ tabWindow = iframe.contentDocument.ownerGlobal;
+});
+
+/**
+ * Test that we don't have any initial OpenPGP key configured in the
+ * End-to-End Encryption page.
+ */
+add_task(async function check_clean_keylist() {
+ // The OpenPGP Key List container should not be visible.
+ Assert.equal(
+ tabDocument.getElementById("openPgpKeyList").hidden,
+ true,
+ "The openPgpKeyList container shouldn't be visible"
+ );
+
+ // The OpenPGP Key List radiogroup should only have 1 item (the None).
+ Assert.equal(
+ tabDocument.getElementById("openPgpKeyListRadio").itemCount,
+ 1,
+ "The OpenPGP Key List radiogroup should only have 1 item"
+ );
+
+ // The "None" radio item should be currently selected.
+ Assert.equal(
+ tabDocument.getElementById("openPgpNone").selected,
+ true,
+ "The openPgpNone radio option is currently selected"
+ );
+});
+
+/**
+ * Generate a new OpenPGP Key.
+ */
+add_task(async function generate_new_key() {
+ // Open the key wizard from the "Add Key" button.
+ let button = tabDocument.getElementById("addOpenPgpButton");
+ EventUtils.synthesizeMouseAtCenter(button, {}, tabWindow);
+
+ let wizard = wait_for_frame_load(
+ gTab.browser.contentWindow.gSubDialog._topDialog._frame,
+ "chrome://openpgp/content/ui/keyWizard.xhtml"
+ );
+ let doc = wizard.window.document;
+ let dialog = doc.documentElement.querySelector("dialog");
+
+ let keyGenView = doc.getElementById("wizardCreateKey");
+
+ // Accept the dialog since the first option should be automatically selected.
+ dialog.acceptDialog();
+ await BrowserTestUtils.waitForCondition(
+ () => wizard.window.getComputedStyle(keyGenView).opacity == 1,
+ "Timeout waiting for the #wizardCreateKey to appear"
+ );
+
+ // Change the expiration.
+ EventUtils.synthesizeMouseAtCenter(
+ doc.getElementById("keygenDoesNotExpire"),
+ {},
+ dialog.ownerGlobal
+ );
+
+ let wizardOverlay = doc.getElementById("wizardOverlay");
+
+ // Move to the next screen.
+ dialog.acceptDialog();
+ await BrowserTestUtils.waitForCondition(
+ () => wizard.window.getComputedStyle(wizardOverlay).opacity == 1,
+ "Timeout waiting for the #wizardOverlay to appear"
+ );
+
+ // Store the wait event here before the SubDialog is destroyed and we can't
+ // access it anymore.
+ let frameWinUnload = BrowserTestUtils.waitForEvent(
+ gTab.browser.contentWindow.gSubDialog._topDialog._frame.contentWindow,
+ "unload",
+ true
+ );
+
+ // Confirm the generation of the new key.
+ let confirmButton = doc.getElementById("openPgpKeygenConfirmButton");
+ EventUtils.synthesizeMouseAtCenter(confirmButton, {}, dialog.ownerGlobal);
+
+ // Wait for the subdialog to close.
+ info("Waiting for subdialog unload");
+ await frameWinUnload;
+
+ // The key wizard should automatically assign the newly generated key to the
+ // selected identity and close the dialog. Let's wait for that change.
+ await TestUtils.waitForCondition(
+ () => gIdentity.getUnicharAttribute("openpgp_key_id"),
+ "Timeout waiting for the newly generated key to be set"
+ );
+ gCreatedKeyId = gIdentity.getUnicharAttribute("openpgp_key_id");
+
+ // The OpenPGP Key List radiogroup should only have 2 items now (None, and a key).
+ Assert.equal(
+ tabDocument.getElementById("openPgpKeyListRadio").itemCount,
+ 2,
+ "The OpenPGP Key List radiogroup should have 2 items"
+ );
+
+ // The "None" radio item should NOT be selected.
+ Assert.equal(
+ tabDocument.getElementById("openPgpNone").selected,
+ false,
+ "The openPgpNone radio option should not be selected"
+ );
+});
+
+/**
+ * Import a previously exported secret OpenPGP Key.
+ */
+add_task(async function import_secret_key() {
+ // Open the key wizard from the "Add Key" button.
+ let button = tabDocument.getElementById("addOpenPgpButton");
+ EventUtils.synthesizeMouseAtCenter(button, {}, tabWindow);
+
+ let wizard = wait_for_frame_load(
+ gTab.browser.contentWindow.gSubDialog._topDialog._frame,
+ "chrome://openpgp/content/ui/keyWizard.xhtml"
+ );
+ let doc = wizard.window.document;
+ let dialog = doc.documentElement.querySelector("dialog");
+
+ // Change the selection to import a key.
+ EventUtils.synthesizeMouseAtCenter(
+ doc.getElementById("importOpenPgp"),
+ {},
+ dialog.ownerGlobal
+ );
+
+ let importView = doc.getElementById("wizardImportKey");
+
+ // Accept the dialog to move to the next screen.
+ dialog.acceptDialog();
+ await BrowserTestUtils.waitForCondition(
+ () => wizard.window.getComputedStyle(importView).opacity == 1,
+ "Timeout waiting for the #wizardImportKey to appear"
+ );
+
+ let ChromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(
+ Ci.nsIChromeRegistry
+ );
+ let chromeUrl = Services.io.newURI(
+ getRootDirectory(gTestPath) +
+ "data/keys/alice@openpgp.example-0xf231550c4f47e38e-secret.asc"
+ );
+ gImportedKeyId = "0xf231550c4f47e38e";
+ let fileUrl = ChromeRegistry.convertChromeURL(chromeUrl);
+ let file = fileUrl.QueryInterface(Ci.nsIFileURL).file;
+
+ MockFilePicker.init(window);
+ MockFilePicker.setFiles([file]);
+ MockFilePicker.returnValue = MockFilePicker.returnOK;
+
+ let importButton = doc
+ .getElementById("importKeyIntro")
+ .querySelector("button");
+ EventUtils.synthesizeMouseAtCenter(importButton, {}, dialog.ownerGlobal);
+
+ // The container with the listed keys to import should be visible.
+ await BrowserTestUtils.waitForCondition(
+ () => !doc.getElementById("importKeyListContainer").collapsed,
+ "Timeout waiting for the #importKeyListContainer to appear"
+ );
+
+ let keyList = doc.getElementById("importKeyList");
+
+ // The dialog should display 1 key ready to be imported.
+ Assert.equal(
+ keyList.childNodes.length,
+ 1,
+ "Only 1 fetched key is listed in the #importKeyList container"
+ );
+
+ // Be sure the listed private key is checked to be used as personal key.
+ Assert.equal(
+ keyList.querySelector("checkbox").checked,
+ true,
+ "The imported key is marked to be used as personal key"
+ );
+
+ // Accept the dialog to move to the next screen.
+ dialog.acceptDialog();
+ await BrowserTestUtils.waitForCondition(
+ () => !doc.getElementById("importKeyListSuccess").collapsed,
+ "Timeout waiting for the #importKeyListSuccess to appear"
+ );
+
+ let keyListRecap = doc.getElementById("importKeyListRecap");
+
+ // The dialog should display 1 key ready to be imported.
+ Assert.equal(
+ keyListRecap.childNodes.length,
+ 1,
+ "Only 1 imported key is listed in the #importKeyListRecap container"
+ );
+
+ let keyListRadio = tabDocument.getElementById("openPgpKeyListRadio");
+
+ // Accept the dialog to close it.
+ dialog.acceptDialog();
+ await BrowserTestUtils.waitForCondition(
+ () => keyListRadio.itemCount == 3,
+ "Timeout waiting for the #importKeyListSuccess to appear"
+ );
+
+ Assert.equal(keyListRadio.itemCount, 3, "The 3 keys are listed");
+
+ // The previously configured OpenPGP key should still be selected.
+ Assert.equal(
+ keyListRadio.selectedIndex,
+ 1,
+ "The previously generated secret key is still selected"
+ );
+});
+
+/**
+ * Manually set and external GnuPG key.
+ */
+add_task(async function add_external_key() {
+ // Open the key wizard from the "Add Key" button.
+ let button = tabDocument.getElementById("addOpenPgpButton");
+ EventUtils.synthesizeMouseAtCenter(button, {}, tabWindow);
+
+ let wizard = wait_for_frame_load(
+ gTab.browser.contentWindow.gSubDialog._topDialog._frame,
+ "chrome://openpgp/content/ui/keyWizard.xhtml"
+ );
+ let doc = wizard.window.document;
+ let dialog = doc.documentElement.querySelector("dialog");
+
+ // Change the selection to import a key.
+ EventUtils.synthesizeMouseAtCenter(
+ doc.getElementById("externalOpenPgp"),
+ {},
+ dialog.ownerGlobal
+ );
+
+ let externalView = doc.getElementById("wizardExternalKey");
+
+ // Accept the dialog to move to the next screen.
+ dialog.acceptDialog();
+ await BrowserTestUtils.waitForCondition(
+ () => wizard.window.getComputedStyle(externalView).opacity == 1,
+ "Timeout waiting for the #wizardExternalKey to appear"
+ );
+
+ doc.getElementById("externalKey").focus();
+ EventUtils.sendString(EXTERNAL_GNUP_KEY, wizard.window);
+
+ let keyListRadio = tabDocument.getElementById("openPgpKeyListRadio");
+
+ // Accept the dialog to close it.
+ dialog.acceptDialog();
+ await BrowserTestUtils.waitForCondition(
+ () => keyListRadio.itemCount == 4,
+ "Waiting for the newly imported key to be listed"
+ );
+
+ Assert.equal(keyListRadio.itemCount, 4, "The 4 keys are listed");
+
+ // The first key should currently be selected.
+ Assert.equal(
+ keyListRadio.selectedIndex,
+ 1,
+ "The external key is selected and listed at first position"
+ );
+
+ // Confirm that the currently listed key is correct.
+ Assert.equal(
+ gIdentity.getUnicharAttribute("openpgp_key_id"),
+ EXTERNAL_GNUP_KEY,
+ "The external key was properly set for the current identity"
+ );
+});
+
+registerCleanupFunction(async function () {
+ mc.window.document.getElementById("tabmail").closeTab(gTab);
+ gTab = null;
+ tabDocument = null;
+ tabWindow = null;
+
+ Services.prefs.clearUserPref("mail.openpgp.allow_external_gnupg");
+ MailServices.accounts.removeAccount(gAccount, true);
+ gAccount = null;
+ await OpenPGPTestUtils.removeKeyById(gCreatedKeyId, true);
+ await OpenPGPTestUtils.removeKeyById(gImportedKeyId, true);
+});