summaryrefslogtreecommitdiffstats
path: root/security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js
diff options
context:
space:
mode:
Diffstat (limited to 'security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js')
-rw-r--r--security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js164
1 files changed, 164 insertions, 0 deletions
diff --git a/security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js b/security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js
new file mode 100644
index 0000000000..8e6af27cbb
--- /dev/null
+++ b/security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js
@@ -0,0 +1,164 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/publicdomain/zero/1.0/
+"use strict";
+
+// Tests that the UI for setting the password on a to be exported PKCS #12 file:
+// 1. Correctly requires the password to be typed in twice as confirmation.
+// 2. Calculates and displays the strength of said password.
+
+/**
+ * @typedef TestCase
+ * @type {object}
+ * @property {string} name
+ * The name of the test case for display purposes.
+ * @property {string} password1
+ * The password to enter into the first password textbox.
+ * @property {string} password2
+ * The password to enter into the second password textbox.
+ * @property {string} strength
+ * The expected strength of the password in the range [0, 100].
+ */
+
+/**
+ * A list of test cases representing various inputs to the password textboxes.
+ *
+ * @type {TestCase[]}
+ */
+const TEST_CASES = [
+ { name: "empty", password1: "", password2: "", strength: "0" },
+ { name: "match-weak", password1: "foo", password2: "foo", strength: "10" },
+ {
+ name: "match-medium",
+ password1: "foo123",
+ password2: "foo123",
+ strength: "60",
+ },
+ {
+ name: "match-strong",
+ password1: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三",
+ password2: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三",
+ strength: "100",
+ },
+ { name: "mismatch-weak", password1: "foo", password2: "bar", strength: "10" },
+ {
+ name: "mismatch-medium",
+ password1: "foo123",
+ password2: "bar",
+ strength: "60",
+ },
+ {
+ name: "mismatch-strong",
+ password1: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三",
+ password2: "bar",
+ strength: "100",
+ },
+];
+
+/**
+ * Opens the dialog shown to set the password on a PKCS #12 file being exported.
+ *
+ * @returns {Promise}
+ * A promise that resolves when the dialog has finished loading, with
+ * an array consisting of:
+ * 1. The window of the opened dialog.
+ * 2. The return value nsIWritablePropertyBag2 passed to the dialog.
+ */
+function openSetP12PasswordDialog() {
+ let returnVals = Cc["@mozilla.org/hash-property-bag;1"].createInstance(
+ Ci.nsIWritablePropertyBag2
+ );
+ let win = window.openDialog(
+ "chrome://pippki/content/setp12password.xhtml",
+ "",
+ "",
+ returnVals
+ );
+ return new Promise((resolve, reject) => {
+ win.addEventListener(
+ "load",
+ function () {
+ executeSoon(() => resolve([win, returnVals]));
+ },
+ { once: true }
+ );
+ });
+}
+
+// Tests that the first password textbox is the element that is initially
+// focused.
+add_task(async function testFocus() {
+ let [win] = await openSetP12PasswordDialog();
+ Assert.equal(
+ win.document.activeElement,
+ win.document.getElementById("pw1"),
+ "First password textbox should have focus"
+ );
+ await BrowserTestUtils.closeWindow(win);
+});
+
+// Tests that the password strength algorithm used is reasonable, and that the
+// Accept button is only enabled if the two passwords match.
+add_task(async function testPasswordStrengthAndEquality() {
+ let [win] = await openSetP12PasswordDialog();
+ let password1Textbox = win.document.getElementById("pw1");
+ let password2Textbox = win.document.getElementById("pw2");
+ let strengthProgressBar = win.document.getElementById("pwmeter");
+
+ for (let testCase of TEST_CASES) {
+ password1Textbox.value = testCase.password1;
+ password2Textbox.value = testCase.password2;
+ // Setting the value of the password textboxes via |.value| apparently
+ // doesn't cause the oninput handlers to be called, so we do it here.
+ password1Textbox.oninput();
+ password2Textbox.oninput();
+
+ Assert.equal(
+ win.document.getElementById("setp12password").getButton("accept")
+ .disabled,
+ password1Textbox.value != password2Textbox.value,
+ "Actual and expected accept button disable state should " +
+ `match for ${testCase.name}`
+ );
+ Assert.equal(
+ strengthProgressBar.value,
+ testCase.strength,
+ `Actual and expected strength value should match for ${testCase.name}`
+ );
+ }
+
+ await BrowserTestUtils.closeWindow(win);
+});
+
+// Test that the right values are returned when the dialog is accepted.
+add_task(async function testAcceptDialogReturnValues() {
+ let [win, retVals] = await openSetP12PasswordDialog();
+ const password = "fooBAR 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三";
+ win.document.getElementById("pw1").value = password;
+ win.document.getElementById("pw2").value = password;
+ info("Accepting dialog");
+ win.document.getElementById("setp12password").acceptDialog();
+ await BrowserTestUtils.windowClosed(win);
+
+ Assert.ok(
+ retVals.get("confirmedPassword"),
+ "Return value should signal user confirmed a password"
+ );
+ Assert.equal(
+ retVals.get("password"),
+ password,
+ "Actual and expected password should match"
+ );
+});
+
+// Test that the right values are returned when the dialog is canceled.
+add_task(async function testCancelDialogReturnValues() {
+ let [win, retVals] = await openSetP12PasswordDialog();
+ info("Canceling dialog");
+ win.document.getElementById("setp12password").cancelDialog();
+ await BrowserTestUtils.windowClosed(win);
+
+ Assert.ok(
+ !retVals.get("confirmedPassword"),
+ "Return value should signal user didn't confirm a password"
+ );
+});