summaryrefslogtreecommitdiffstats
path: root/toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js')
-rw-r--r--toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js284
1 files changed, 284 insertions, 0 deletions
diff --git a/toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js b/toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js
new file mode 100644
index 000000000..38344aa7d
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js
@@ -0,0 +1,284 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Tests the handling of nsILoginMetaInfo by methods that add, remove, modify,
+ * and find logins.
+ */
+
+"use strict";
+
+// Globals
+
+XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator",
+ "@mozilla.org/uuid-generator;1",
+ "nsIUUIDGenerator");
+
+var gLooksLikeUUIDRegex = /^\{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}\}$/;
+
+/**
+ * Retrieves the only login among the current data that matches the hostname of
+ * the given nsILoginInfo. In case there is more than one login for the
+ * hostname, the test fails.
+ */
+function retrieveLoginMatching(aLoginInfo)
+{
+ let logins = Services.logins.findLogins({}, aLoginInfo.hostname, "", "");
+ do_check_eq(logins.length, 1);
+ return logins[0].QueryInterface(Ci.nsILoginMetaInfo);
+}
+
+/**
+ * Checks that the nsILoginInfo and nsILoginMetaInfo properties of two different
+ * login instances are equal.
+ */
+function assertMetaInfoEqual(aActual, aExpected)
+{
+ do_check_neq(aActual, aExpected);
+
+ // Check the nsILoginInfo properties.
+ do_check_true(aActual.equals(aExpected));
+
+ // Check the nsILoginMetaInfo properties.
+ do_check_eq(aActual.guid, aExpected.guid);
+ do_check_eq(aActual.timeCreated, aExpected.timeCreated);
+ do_check_eq(aActual.timeLastUsed, aExpected.timeLastUsed);
+ do_check_eq(aActual.timePasswordChanged, aExpected.timePasswordChanged);
+ do_check_eq(aActual.timesUsed, aExpected.timesUsed);
+}
+
+/**
+ * nsILoginInfo instances with or without nsILoginMetaInfo properties.
+ */
+var gLoginInfo1;
+var gLoginInfo2;
+var gLoginInfo3;
+
+/**
+ * nsILoginInfo instances reloaded with all the nsILoginMetaInfo properties.
+ * These are often used to provide the reference values to test against.
+ */
+var gLoginMetaInfo1;
+var gLoginMetaInfo2;
+var gLoginMetaInfo3;
+
+// Tests
+
+/**
+ * Prepare the test objects that will be used by the following tests.
+ */
+add_task(function test_initialize()
+{
+ // Use a reference time from ten minutes ago to initialize one instance of
+ // nsILoginMetaInfo, to test that reference times are updated when needed.
+ let baseTimeMs = Date.now() - 600000;
+
+ gLoginInfo1 = TestData.formLogin();
+ gLoginInfo2 = TestData.formLogin({
+ hostname: "http://other.example.com",
+ guid: gUUIDGenerator.generateUUID().toString(),
+ timeCreated: baseTimeMs,
+ timeLastUsed: baseTimeMs + 2,
+ timePasswordChanged: baseTimeMs + 1,
+ timesUsed: 2,
+ });
+ gLoginInfo3 = TestData.authLogin();
+});
+
+/**
+ * Tests the behavior of addLogin with regard to metadata. The logins added
+ * here are also used by the following tests.
+ */
+add_task(function test_addLogin_metainfo()
+{
+ // Add a login without metadata to the database.
+ Services.logins.addLogin(gLoginInfo1);
+
+ // The object provided to addLogin should not have been modified.
+ do_check_eq(gLoginInfo1.guid, null);
+ do_check_eq(gLoginInfo1.timeCreated, 0);
+ do_check_eq(gLoginInfo1.timeLastUsed, 0);
+ do_check_eq(gLoginInfo1.timePasswordChanged, 0);
+ do_check_eq(gLoginInfo1.timesUsed, 0);
+
+ // A login with valid metadata should have been stored.
+ gLoginMetaInfo1 = retrieveLoginMatching(gLoginInfo1);
+ do_check_true(gLooksLikeUUIDRegex.test(gLoginMetaInfo1.guid));
+ let creationTime = gLoginMetaInfo1.timeCreated;
+ LoginTestUtils.assertTimeIsAboutNow(creationTime);
+ do_check_eq(gLoginMetaInfo1.timeLastUsed, creationTime);
+ do_check_eq(gLoginMetaInfo1.timePasswordChanged, creationTime);
+ do_check_eq(gLoginMetaInfo1.timesUsed, 1);
+
+ // Add a login without metadata to the database.
+ let originalLogin = gLoginInfo2.clone().QueryInterface(Ci.nsILoginMetaInfo);
+ Services.logins.addLogin(gLoginInfo2);
+
+ // The object provided to addLogin should not have been modified.
+ assertMetaInfoEqual(gLoginInfo2, originalLogin);
+
+ // A login with the provided metadata should have been stored.
+ gLoginMetaInfo2 = retrieveLoginMatching(gLoginInfo2);
+ assertMetaInfoEqual(gLoginMetaInfo2, gLoginInfo2);
+
+ // Add an authentication login to the database before continuing.
+ Services.logins.addLogin(gLoginInfo3);
+ gLoginMetaInfo3 = retrieveLoginMatching(gLoginInfo3);
+ LoginTestUtils.checkLogins([gLoginInfo1, gLoginInfo2, gLoginInfo3]);
+});
+
+/**
+ * Tests that adding a login with a duplicate GUID throws an exception.
+ */
+add_task(function test_addLogin_metainfo_duplicate()
+{
+ let loginInfo = TestData.formLogin({
+ hostname: "http://duplicate.example.com",
+ guid: gLoginMetaInfo2.guid,
+ });
+ Assert.throws(() => Services.logins.addLogin(loginInfo),
+ /specified GUID already exists/);
+
+ // Verify that no data was stored by the previous call.
+ LoginTestUtils.checkLogins([gLoginInfo1, gLoginInfo2, gLoginInfo3]);
+});
+
+/**
+ * Tests that the existing metadata is not changed when modifyLogin is called
+ * with an nsILoginInfo argument.
+ */
+add_task(function test_modifyLogin_nsILoginInfo_metainfo_ignored()
+{
+ let newLoginInfo = gLoginInfo1.clone().QueryInterface(Ci.nsILoginMetaInfo);
+ newLoginInfo.guid = gUUIDGenerator.generateUUID().toString();
+ newLoginInfo.timeCreated = Date.now();
+ newLoginInfo.timeLastUsed = Date.now();
+ newLoginInfo.timePasswordChanged = Date.now();
+ newLoginInfo.timesUsed = 12;
+ Services.logins.modifyLogin(gLoginInfo1, newLoginInfo);
+
+ newLoginInfo = retrieveLoginMatching(gLoginInfo1);
+ assertMetaInfoEqual(newLoginInfo, gLoginMetaInfo1);
+});
+
+/**
+ * Tests the modifyLogin function with an nsIProperyBag argument.
+ */
+add_task(function test_modifyLogin_nsIProperyBag_metainfo()
+{
+ // Use a new reference time that is two minutes from now.
+ let newTimeMs = Date.now() + 120000;
+ let newUUIDValue = gUUIDGenerator.generateUUID().toString();
+
+ // Check that properties are changed as requested.
+ Services.logins.modifyLogin(gLoginInfo1, newPropertyBag({
+ guid: newUUIDValue,
+ timeCreated: newTimeMs,
+ timeLastUsed: newTimeMs + 2,
+ timePasswordChanged: newTimeMs + 1,
+ timesUsed: 2,
+ }));
+
+ gLoginMetaInfo1 = retrieveLoginMatching(gLoginInfo1);
+ do_check_eq(gLoginMetaInfo1.guid, newUUIDValue);
+ do_check_eq(gLoginMetaInfo1.timeCreated, newTimeMs);
+ do_check_eq(gLoginMetaInfo1.timeLastUsed, newTimeMs + 2);
+ do_check_eq(gLoginMetaInfo1.timePasswordChanged, newTimeMs + 1);
+ do_check_eq(gLoginMetaInfo1.timesUsed, 2);
+
+ // Check that timePasswordChanged is updated when changing the password.
+ let originalLogin = gLoginInfo2.clone().QueryInterface(Ci.nsILoginMetaInfo);
+ Services.logins.modifyLogin(gLoginInfo2, newPropertyBag({
+ password: "new password",
+ }));
+ gLoginInfo2.password = "new password";
+
+ gLoginMetaInfo2 = retrieveLoginMatching(gLoginInfo2);
+ do_check_eq(gLoginMetaInfo2.password, gLoginInfo2.password);
+ do_check_eq(gLoginMetaInfo2.timeCreated, originalLogin.timeCreated);
+ do_check_eq(gLoginMetaInfo2.timeLastUsed, originalLogin.timeLastUsed);
+ LoginTestUtils.assertTimeIsAboutNow(gLoginMetaInfo2.timePasswordChanged);
+
+ // Check that timePasswordChanged is not set to the current time when changing
+ // the password and specifying a new value for the property at the same time.
+ Services.logins.modifyLogin(gLoginInfo2, newPropertyBag({
+ password: "other password",
+ timePasswordChanged: newTimeMs,
+ }));
+ gLoginInfo2.password = "other password";
+
+ gLoginMetaInfo2 = retrieveLoginMatching(gLoginInfo2);
+ do_check_eq(gLoginMetaInfo2.password, gLoginInfo2.password);
+ do_check_eq(gLoginMetaInfo2.timeCreated, originalLogin.timeCreated);
+ do_check_eq(gLoginMetaInfo2.timeLastUsed, originalLogin.timeLastUsed);
+ do_check_eq(gLoginMetaInfo2.timePasswordChanged, newTimeMs);
+
+ // Check the special timesUsedIncrement property.
+ Services.logins.modifyLogin(gLoginInfo2, newPropertyBag({
+ timesUsedIncrement: 2,
+ }));
+
+ gLoginMetaInfo2 = retrieveLoginMatching(gLoginInfo2);
+ do_check_eq(gLoginMetaInfo2.timeCreated, originalLogin.timeCreated);
+ do_check_eq(gLoginMetaInfo2.timeLastUsed, originalLogin.timeLastUsed);
+ do_check_eq(gLoginMetaInfo2.timePasswordChanged, newTimeMs);
+ do_check_eq(gLoginMetaInfo2.timesUsed, 4);
+});
+
+/**
+ * Tests that modifying a login to a duplicate GUID throws an exception.
+ */
+add_task(function test_modifyLogin_nsIProperyBag_metainfo_duplicate()
+{
+ Assert.throws(() => Services.logins.modifyLogin(gLoginInfo1, newPropertyBag({
+ guid: gLoginInfo2.guid,
+ })), /specified GUID already exists/);
+ LoginTestUtils.checkLogins([gLoginInfo1, gLoginInfo2, gLoginInfo3]);
+});
+
+/**
+ * Tests searching logins using nsILoginMetaInfo properties.
+ */
+add_task(function test_searchLogins_metainfo()
+{
+ // Find by GUID.
+ let logins = Services.logins.searchLogins({}, newPropertyBag({
+ guid: gLoginMetaInfo1.guid,
+ }));
+ do_check_eq(logins.length, 1);
+ let foundLogin = logins[0].QueryInterface(Ci.nsILoginMetaInfo);
+ assertMetaInfoEqual(foundLogin, gLoginMetaInfo1);
+
+ // Find by timestamp.
+ logins = Services.logins.searchLogins({}, newPropertyBag({
+ timePasswordChanged: gLoginMetaInfo2.timePasswordChanged,
+ }));
+ do_check_eq(logins.length, 1);
+ foundLogin = logins[0].QueryInterface(Ci.nsILoginMetaInfo);
+ assertMetaInfoEqual(foundLogin, gLoginMetaInfo2);
+
+ // Find using two properties at the same time.
+ logins = Services.logins.searchLogins({}, newPropertyBag({
+ guid: gLoginMetaInfo3.guid,
+ timePasswordChanged: gLoginMetaInfo3.timePasswordChanged,
+ }));
+ do_check_eq(logins.length, 1);
+ foundLogin = logins[0].QueryInterface(Ci.nsILoginMetaInfo);
+ assertMetaInfoEqual(foundLogin, gLoginMetaInfo3);
+});
+
+/**
+ * Tests that the default nsILoginManagerStorage module attached to the Login
+ * Manager service is able to save and reload nsILoginMetaInfo properties.
+ */
+add_task(function* test_storage_metainfo()
+{
+ yield* LoginTestUtils.reloadData();
+ LoginTestUtils.checkLogins([gLoginInfo1, gLoginInfo2, gLoginInfo3]);
+
+ assertMetaInfoEqual(retrieveLoginMatching(gLoginInfo1), gLoginMetaInfo1);
+ assertMetaInfoEqual(retrieveLoginMatching(gLoginInfo2), gLoginMetaInfo2);
+ assertMetaInfoEqual(retrieveLoginMatching(gLoginInfo3), gLoginMetaInfo3);
+});