summaryrefslogtreecommitdiffstats
path: root/browser/components/aboutlogins/tests/unit
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /browser/components/aboutlogins/tests/unit
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'browser/components/aboutlogins/tests/unit')
-rw-r--r--browser/components/aboutlogins/tests/unit/head.js22
-rw-r--r--browser/components/aboutlogins/tests/unit/test_getPotentialBreachesByLoginGUID.js327
-rw-r--r--browser/components/aboutlogins/tests/unit/xpcshell.ini7
3 files changed, 356 insertions, 0 deletions
diff --git a/browser/components/aboutlogins/tests/unit/head.js b/browser/components/aboutlogins/tests/unit/head.js
new file mode 100644
index 0000000000..938e06e3c0
--- /dev/null
+++ b/browser/components/aboutlogins/tests/unit/head.js
@@ -0,0 +1,22 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const { LoginTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/LoginTestUtils.sys.mjs"
+);
+const { LoginHelper } = ChromeUtils.importESModule(
+ "resource://gre/modules/LoginHelper.sys.mjs"
+);
+
+const TestData = LoginTestUtils.testData;
+const newPropertyBag = LoginHelper.newPropertyBag;
+
+/**
+ * All the tests are implemented with add_task, this starts them automatically.
+ */
+function run_test() {
+ do_get_profile();
+ run_next_test();
+}
diff --git a/browser/components/aboutlogins/tests/unit/test_getPotentialBreachesByLoginGUID.js b/browser/components/aboutlogins/tests/unit/test_getPotentialBreachesByLoginGUID.js
new file mode 100644
index 0000000000..a868572a6a
--- /dev/null
+++ b/browser/components/aboutlogins/tests/unit/test_getPotentialBreachesByLoginGUID.js
@@ -0,0 +1,327 @@
+/**
+ * Test LoginBreaches.getPotentialBreachesByLoginGUID
+ */
+
+"use strict";
+
+const { RemoteSettings } = ChromeUtils.importESModule(
+ "resource://services-settings/remote-settings.sys.mjs"
+);
+
+// Initializing BrowserGlue requires a profile on Windows.
+do_get_profile();
+
+const gBrowserGlue = Cc["@mozilla.org/browser/browserglue;1"].getService(
+ Ci.nsIObserver
+);
+
+ChromeUtils.defineESModuleGetters(this, {
+ LoginBreaches: "resource:///modules/LoginBreaches.sys.mjs",
+});
+
+const TEST_BREACHES = [
+ {
+ AddedDate: "2018-12-20T23:56:26Z",
+ BreachDate: "2018-12-16",
+ Domain: "breached.com",
+ Name: "Breached",
+ PwnCount: 1643100,
+ DataClasses: ["Email addresses", "Usernames", "Passwords", "IP addresses"],
+ _status: "synced",
+ id: "047940fe-d2fd-4314-b636-b4a952ee0043",
+ last_modified: "1541615610052",
+ schema: "1541615609018",
+ },
+ {
+ AddedDate: "2018-12-20T23:56:26Z",
+ BreachDate: "2018-12-16",
+ Domain: "breached-subdomain.host.com",
+ Name: "Only a Sub-Domain was Breached",
+ PwnCount: 2754200,
+ DataClasses: ["Email addresses", "Usernames", "Passwords", "IP addresses"],
+ _status: "synced",
+ id: "047940fe-d2fd-4314-b636-b4a952ee0044",
+ last_modified: "1541615610052",
+ schema: "1541615609018",
+ },
+ {
+ AddedDate: "2018-12-20T23:56:26Z",
+ BreachDate: "2018-12-16",
+ Domain: "breached-site-without-passwords.com",
+ Name: "Breached Site without passwords",
+ PwnCount: 987654,
+ DataClasses: ["Email addresses", "Usernames", "IP addresses"],
+ _status: "synced",
+ id: "047940fe-d2fd-4314-b636-b4a952ee0045",
+ last_modified: "1541615610052",
+ schema: "1541615609018",
+ },
+];
+
+const CRASHING_URI_LOGIN = LoginTestUtils.testData.formLogin({
+ origin: "chrome://grwatcher",
+ formActionOrigin: "https://www.example.com",
+ username: "username",
+ password: "password",
+ timePasswordChanged: new Date("2018-12-15").getTime(),
+});
+const NOT_BREACHED_LOGIN = LoginTestUtils.testData.formLogin({
+ origin: "https://www.example.com",
+ formActionOrigin: "https://www.example.com",
+ username: "username",
+ password: "password",
+ timePasswordChanged: new Date("2018-12-15").getTime(),
+});
+const BREACHED_LOGIN = LoginTestUtils.testData.formLogin({
+ origin: "https://www.breached.com",
+ formActionOrigin: "https://www.breached.com",
+ username: "username",
+ password: "password",
+ timePasswordChanged: new Date("2018-12-15").getTime(),
+});
+const NOT_BREACHED_SUBDOMAIN_LOGIN = LoginTestUtils.testData.formLogin({
+ origin: "https://not-breached-subdomain.host.com",
+ formActionOrigin: "https://not-breached-subdomain.host.com",
+ username: "username",
+ password: "password",
+});
+const BREACHED_SUBDOMAIN_LOGIN = LoginTestUtils.testData.formLogin({
+ origin: "https://breached-subdomain.host.com",
+ formActionOrigin: "https://breached-subdomain.host.com",
+ username: "username",
+ password: "password",
+ timePasswordChanged: new Date("2018-12-15").getTime(),
+});
+const LOGIN_FOR_BREACHED_SITE_WITHOUT_PASSWORDS =
+ LoginTestUtils.testData.formLogin({
+ origin: "https://breached-site-without-passwords.com",
+ formActionOrigin: "https://breached-site-without-passwords.com",
+ username: "username",
+ password: "password",
+ timePasswordChanged: new Date("2018-12-15").getTime(),
+ });
+const LOGIN_WITH_NON_STANDARD_URI = LoginTestUtils.testData.formLogin({
+ origin: "someApp://random/path/to/login",
+ formActionOrigin: "someApp://random/path/to/login",
+ username: "username",
+ password: "password",
+ timePasswordChanged: new Date("2018-12-15").getTime(),
+});
+
+add_task(async function test_notBreachedLogin() {
+ await Services.logins.addLoginAsync(NOT_BREACHED_LOGIN);
+ const breachesByLoginGUID =
+ await LoginBreaches.getPotentialBreachesByLoginGUID(
+ [NOT_BREACHED_LOGIN],
+ TEST_BREACHES
+ );
+ Assert.strictEqual(
+ breachesByLoginGUID.size,
+ 0,
+ "Should be 0 breached logins."
+ );
+});
+
+add_task(async function test_breachedLogin() {
+ await Services.logins.addLoginAsync(BREACHED_LOGIN);
+ const breachesByLoginGUID =
+ await LoginBreaches.getPotentialBreachesByLoginGUID(
+ [NOT_BREACHED_LOGIN, BREACHED_LOGIN],
+ TEST_BREACHES
+ );
+ Assert.strictEqual(
+ breachesByLoginGUID.size,
+ 1,
+ "Should be 1 breached login: " + BREACHED_LOGIN.origin
+ );
+ Assert.strictEqual(
+ breachesByLoginGUID.get(BREACHED_LOGIN.guid).breachAlertURL,
+ "https://monitor.firefox.com/breach-details/Breached?utm_source=firefox-desktop&utm_medium=referral&utm_campaign=about-logins&utm_content=about-logins",
+ "Breach alert link should be equal to the breachAlertURL"
+ );
+});
+
+add_task(async function test_breachedLoginAfterCrashingUriLogin() {
+ await Services.logins.addLoginAsync(CRASHING_URI_LOGIN);
+
+ const breachesByLoginGUID =
+ await LoginBreaches.getPotentialBreachesByLoginGUID(
+ [CRASHING_URI_LOGIN, BREACHED_LOGIN],
+ TEST_BREACHES
+ );
+ Assert.strictEqual(
+ breachesByLoginGUID.size,
+ 1,
+ "Should be 1 breached login: " + BREACHED_LOGIN.origin
+ );
+ Assert.strictEqual(
+ breachesByLoginGUID.get(BREACHED_LOGIN.guid).breachAlertURL,
+ "https://monitor.firefox.com/breach-details/Breached?utm_source=firefox-desktop&utm_medium=referral&utm_campaign=about-logins&utm_content=about-logins",
+ "Breach alert link should be equal to the breachAlertURL"
+ );
+});
+
+add_task(async function test_notBreachedSubdomain() {
+ await Services.logins.addLoginAsync(NOT_BREACHED_SUBDOMAIN_LOGIN);
+
+ const breachesByLoginGUID =
+ await LoginBreaches.getPotentialBreachesByLoginGUID(
+ [NOT_BREACHED_LOGIN, NOT_BREACHED_SUBDOMAIN_LOGIN],
+ TEST_BREACHES
+ );
+ Assert.strictEqual(
+ breachesByLoginGUID.size,
+ 0,
+ "Should be 0 breached logins."
+ );
+});
+
+add_task(async function test_breachedSubdomain() {
+ await Services.logins.addLoginAsync(BREACHED_SUBDOMAIN_LOGIN);
+
+ const breachesByLoginGUID =
+ await LoginBreaches.getPotentialBreachesByLoginGUID(
+ [NOT_BREACHED_SUBDOMAIN_LOGIN, BREACHED_SUBDOMAIN_LOGIN],
+ TEST_BREACHES
+ );
+ Assert.strictEqual(
+ breachesByLoginGUID.size,
+ 1,
+ "Should be 1 breached login: " + BREACHED_SUBDOMAIN_LOGIN.origin
+ );
+});
+
+add_task(async function test_breachedSiteWithoutPasswords() {
+ await Services.logins.addLoginAsync(
+ LOGIN_FOR_BREACHED_SITE_WITHOUT_PASSWORDS
+ );
+
+ const breachesByLoginGUID =
+ await LoginBreaches.getPotentialBreachesByLoginGUID(
+ [LOGIN_FOR_BREACHED_SITE_WITHOUT_PASSWORDS],
+ TEST_BREACHES
+ );
+ Assert.strictEqual(
+ breachesByLoginGUID.size,
+ 0,
+ "Should be 0 breached login: " +
+ LOGIN_FOR_BREACHED_SITE_WITHOUT_PASSWORDS.origin
+ );
+});
+
+add_task(async function test_breachAlertHiddenAfterDismissal() {
+ BREACHED_LOGIN.guid = "{d2de5ac1-4de6-e544-a7af-1f75abcba92b}";
+
+ await Services.logins.initializationPromise;
+ const storageJSON = Services.logins.wrappedJSObject._storage.wrappedJSObject;
+
+ storageJSON.recordBreachAlertDismissal(BREACHED_LOGIN.guid);
+
+ const breachesByLoginGUID =
+ await LoginBreaches.getPotentialBreachesByLoginGUID(
+ [BREACHED_LOGIN, NOT_BREACHED_LOGIN],
+ TEST_BREACHES
+ );
+ Assert.strictEqual(
+ breachesByLoginGUID.size,
+ 0,
+ "Should be 0 breached logins after dismissal: " + BREACHED_LOGIN.origin
+ );
+
+ info("Clear login storage");
+ Services.logins.removeAllUserFacingLogins();
+
+ const breachesByLoginGUID2 =
+ await LoginBreaches.getPotentialBreachesByLoginGUID(
+ [BREACHED_LOGIN, NOT_BREACHED_LOGIN],
+ TEST_BREACHES
+ );
+ Assert.strictEqual(
+ breachesByLoginGUID2.size,
+ 1,
+ "Breached login should re-appear after clearing storage: " +
+ BREACHED_LOGIN.origin
+ );
+});
+
+add_task(async function test_newBreachAfterDismissal() {
+ TEST_BREACHES[0].AddedDate = new Date().toISOString();
+
+ const breachesByLoginGUID =
+ await LoginBreaches.getPotentialBreachesByLoginGUID(
+ [BREACHED_LOGIN, NOT_BREACHED_LOGIN],
+ TEST_BREACHES
+ );
+
+ Assert.strictEqual(
+ breachesByLoginGUID.size,
+ 1,
+ "Should be 1 breached login after new breach following the dismissal of a previous breach: " +
+ BREACHED_LOGIN.origin
+ );
+});
+
+add_task(async function test_ExceptionsThrownByNonStandardURIsAreCaught() {
+ await Services.logins.addLoginAsync(LOGIN_WITH_NON_STANDARD_URI);
+
+ const breachesByLoginGUID =
+ await LoginBreaches.getPotentialBreachesByLoginGUID(
+ [LOGIN_WITH_NON_STANDARD_URI, BREACHED_LOGIN],
+ TEST_BREACHES
+ );
+
+ Assert.strictEqual(
+ breachesByLoginGUID.size,
+ 1,
+ "Exceptions thrown by logins with non-standard URIs should be caught."
+ );
+});
+
+add_task(async function test_setBreachesFromRemoteSettingsSync() {
+ const login = NOT_BREACHED_SUBDOMAIN_LOGIN;
+ const nowExampleIsInBreachedRecords = [
+ {
+ AddedDate: "2018-12-20T23:56:26Z",
+ BreachDate: "2018-12-16",
+ Domain: "not-breached-subdomain.host.com",
+ Name: "not-breached-subdomain.host.com is now breached!",
+ PwnCount: 1643100,
+ DataClasses: [
+ "Email addresses",
+ "Usernames",
+ "Passwords",
+ "IP addresses",
+ ],
+ _status: "synced",
+ id: "047940fe-d2fd-4314-b636-b4a952ee0044",
+ last_modified: "1541615610052",
+ schema: "1541615609018",
+ },
+ ];
+ async function emitSync() {
+ await RemoteSettings(LoginBreaches.REMOTE_SETTINGS_COLLECTION).emit(
+ "sync",
+ { data: { current: nowExampleIsInBreachedRecords } }
+ );
+ }
+
+ const beforeSyncBreachesByLoginGUID =
+ await LoginBreaches.getPotentialBreachesByLoginGUID([login]);
+ Assert.strictEqual(
+ beforeSyncBreachesByLoginGUID.size,
+ 0,
+ "Should be 0 breached login before not-breached-subdomain.host.com is added to fxmonitor-breaches collection and synced: "
+ );
+ gBrowserGlue.observe(null, "browser-glue-test", "add-breaches-sync-handler");
+ const db = RemoteSettings(LoginBreaches.REMOTE_SETTINGS_COLLECTION).db;
+ await db.importChanges({}, Date.now(), [nowExampleIsInBreachedRecords[0]]);
+ await emitSync();
+
+ const breachesByLoginGUID =
+ await LoginBreaches.getPotentialBreachesByLoginGUID([login]);
+ Assert.strictEqual(
+ breachesByLoginGUID.size,
+ 1,
+ "Should be 1 breached login after not-breached-subdomain.host.com is added to fxmonitor-breaches collection and synced: "
+ );
+});
diff --git a/browser/components/aboutlogins/tests/unit/xpcshell.ini b/browser/components/aboutlogins/tests/unit/xpcshell.ini
new file mode 100644
index 0000000000..e827d6d688
--- /dev/null
+++ b/browser/components/aboutlogins/tests/unit/xpcshell.ini
@@ -0,0 +1,7 @@
+[DEFAULT]
+skip-if = toolkit == 'android' # bug 1730213
+head = head.js
+firefox-appdir = browser
+
+[test_getPotentialBreachesByLoginGUID.js]
+tags = remote-settings