diff options
Diffstat (limited to 'toolkit/components/passwordmgr/test/unit/test_LoginManagerParent_searchAndDedupeLogins.js')
-rw-r--r-- | toolkit/components/passwordmgr/test/unit/test_LoginManagerParent_searchAndDedupeLogins.js | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/toolkit/components/passwordmgr/test/unit/test_LoginManagerParent_searchAndDedupeLogins.js b/toolkit/components/passwordmgr/test/unit/test_LoginManagerParent_searchAndDedupeLogins.js new file mode 100644 index 0000000000..33ee5bd04c --- /dev/null +++ b/toolkit/components/passwordmgr/test/unit/test_LoginManagerParent_searchAndDedupeLogins.js @@ -0,0 +1,207 @@ +/** + * Test LoginManagerParent._searchAndDedupeLogins() + */ + +"use strict"; + +const { LoginManagerParent: LMP } = ChromeUtils.importESModule( + "resource://gre/modules/LoginManagerParent.sys.mjs" +); + +const DOMAIN1_HTTP_ORIGIN = "http://www3.example.com"; +const DOMAIN1_HTTPS_ORIGIN = "https://www3.example.com"; + +const DOMAIN1_HTTP_TO_HTTP_U1_P1 = TestData.formLogin({}); +const DOMAIN1_HTTP_TO_HTTP_U2_P1 = TestData.formLogin({ + username: "user2", +}); +const DOMAIN1_HTTP_TO_HTTP_U3_P1 = TestData.formLogin({ + username: "user3", +}); +const DOMAIN1_HTTPS_TO_HTTPS_U1_P1 = TestData.formLogin({ + origin: DOMAIN1_HTTPS_ORIGIN, + formActionOrigin: "https://login.example.com", +}); +const DOMAIN1_HTTPS_TO_HTTPS_U2_P1 = TestData.formLogin({ + origin: DOMAIN1_HTTPS_ORIGIN, + formActionOrigin: "https://login.example.com", + username: "user2", +}); +const DOMAIN1_HTTPS_TO_HTTPS_U1_P2 = TestData.formLogin({ + origin: DOMAIN1_HTTPS_ORIGIN, + formActionOrigin: "https://login.example.com", + password: "password two", +}); +const DOMAIN1_HTTPS_TO_HTTPS_U1_P2_DIFFERENT_PORT = TestData.formLogin({ + origin: "https://www3.example.com:8080", + password: "password two", +}); +const DOMAIN1_HTTP_TO_HTTP_U1_P2 = TestData.formLogin({ + password: "password two", +}); +const DOMAIN1_HTTP_TO_HTTP_U1_P1_DIFFERENT_PORT = TestData.formLogin({ + origin: "http://www3.example.com:8080", +}); +const DOMAIN2_HTTP_TO_HTTP_U1_P1 = TestData.formLogin({ + origin: "http://different.example.com", +}); +const DOMAIN2_HTTPS_TO_HTTPS_U1_P1 = TestData.formLogin({ + origin: "https://different.example.com", + formActionOrigin: "https://login.example.com", +}); + +add_task(function setup() { + // Not enabled by default in all.js: + Services.prefs.setBoolPref("signon.schemeUpgrades", true); +}); + +add_task(async function test_searchAndDedupeLogins_acceptDifferentSubdomains() { + let testcases = [ + { + description: "HTTPS form, same hostPort, same username, different scheme", + formActionOrigin: DOMAIN1_HTTPS_ORIGIN, + logins: [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P1], + expected: [DOMAIN1_HTTPS_TO_HTTPS_U1_P1], + }, + { + description: "HTTP form, same hostPort, same username, different scheme", + formActionOrigin: DOMAIN1_HTTP_ORIGIN, + logins: [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P1], + expected: [DOMAIN1_HTTP_TO_HTTP_U1_P1], + }, + { + description: "HTTPS form, different passwords, different scheme", + formActionOrigin: DOMAIN1_HTTPS_ORIGIN, + logins: [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P2], + expected: [DOMAIN1_HTTPS_TO_HTTPS_U1_P1], + }, + { + description: "HTTP form, different passwords, different scheme", + formActionOrigin: DOMAIN1_HTTP_ORIGIN, + logins: [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P2], + expected: [DOMAIN1_HTTP_TO_HTTP_U1_P2], + }, + { + description: "HTTPS form, same origin, different port, both schemes", + formActionOrigin: DOMAIN1_HTTPS_ORIGIN, + logins: [ + DOMAIN1_HTTPS_TO_HTTPS_U1_P1, + DOMAIN1_HTTP_TO_HTTP_U1_P1_DIFFERENT_PORT, + DOMAIN1_HTTPS_TO_HTTPS_U1_P2_DIFFERENT_PORT, + ], + expected: [ + DOMAIN1_HTTPS_TO_HTTPS_U1_P1, + DOMAIN1_HTTPS_TO_HTTPS_U1_P2_DIFFERENT_PORT, + ], + }, + { + description: "HTTP form, same origin, different port, both schemes", + formActionOrigin: DOMAIN1_HTTP_ORIGIN, + logins: [ + DOMAIN1_HTTPS_TO_HTTPS_U1_P1, + DOMAIN1_HTTP_TO_HTTP_U1_P1_DIFFERENT_PORT, + DOMAIN1_HTTPS_TO_HTTPS_U1_P2_DIFFERENT_PORT, + ], + expected: [DOMAIN1_HTTP_TO_HTTP_U1_P1_DIFFERENT_PORT], + }, + { + description: "HTTPS form, different origin, different scheme", + formActionOrigin: DOMAIN1_HTTPS_ORIGIN, + logins: [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN2_HTTP_TO_HTTP_U1_P1], + expected: [DOMAIN1_HTTPS_TO_HTTPS_U1_P1], + }, + { + description: + "HTTPS form, different origin, different scheme, same password, same hostPort preferred", + formActionOrigin: DOMAIN1_HTTPS_ORIGIN, + logins: [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN2_HTTPS_TO_HTTPS_U1_P1], + expected: [DOMAIN1_HTTP_TO_HTTP_U1_P1], + }, + { + description: "HTTP form, different origin, different scheme", + formActionOrigin: DOMAIN1_HTTP_ORIGIN, + logins: [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN2_HTTP_TO_HTTP_U1_P1], + expected: [DOMAIN2_HTTP_TO_HTTP_U1_P1], + }, + { + description: "HTTPS form, different username, different scheme", + formActionOrigin: DOMAIN1_HTTPS_ORIGIN, + logins: [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U2_P1], + expected: [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U2_P1], + }, + { + description: "HTTP form, different username, different scheme", + formActionOrigin: DOMAIN1_HTTP_ORIGIN, + logins: [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U2_P1], + expected: [DOMAIN1_HTTP_TO_HTTP_U2_P1], + }, + { + description: "HTTPS form, different usernames, different schemes", + formActionOrigin: DOMAIN1_HTTPS_ORIGIN, + logins: [ + DOMAIN1_HTTPS_TO_HTTPS_U1_P2, + DOMAIN1_HTTPS_TO_HTTPS_U2_P1, + DOMAIN1_HTTP_TO_HTTP_U1_P1, + DOMAIN1_HTTP_TO_HTTP_U3_P1, + ], + expected: [ + DOMAIN1_HTTPS_TO_HTTPS_U1_P2, + DOMAIN1_HTTPS_TO_HTTPS_U2_P1, + DOMAIN1_HTTP_TO_HTTP_U3_P1, + ], + }, + ]; + + for (let tc of testcases) { + info(tc.description); + + let guids = await Services.logins.addLogins(tc.logins); + Assert.strictEqual( + guids.length, + tc.logins.length, + "Check length of added logins" + ); + + let actual = await LMP.searchAndDedupeLogins(tc.formActionOrigin, { + formActionOrigin: tc.formActionOrigin, + looseActionOriginMatch: true, + acceptDifferentSubdomains: true, + }); + info(`actual:\n ${JSON.stringify(actual, null, 2)}`); + info(`expected:\n ${JSON.stringify(tc.expected, null, 2)}`); + Assert.strictEqual( + actual.length, + tc.expected.length, + `Check result length` + ); + for (let [i, login] of tc.expected.entries()) { + Assert.ok(actual[i].equals(login), `Check index ${i}`); + } + + Services.logins.removeAllUserFacingLogins(); + } +}); + +add_task(async function test_reject_duplicates() { + const testcases = [ + { + description: "HTTPS form, both https, same username, different password", + formActionOrigin: DOMAIN1_HTTPS_ORIGIN, + logins: [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTPS_TO_HTTPS_U1_P2], + }, + { + description: "HTTP form, both https, same username, different password", + formActionOrigin: DOMAIN1_HTTP_ORIGIN, + logins: [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTPS_TO_HTTPS_U1_P2], + }, + ]; + + for (const tc of testcases) { + info(tc.description); + + const result = await Services.logins.addLogins(tc.logins); + Assert.equal(result.length, 1, "only single login added"); + + Services.logins.removeAllUserFacingLogins(); + } +}); |