Dactyloidae/toolkit/components/passwordmgr/test/unit/test_logins_search.js

220 lines
8 KiB
JavaScript

/*
* Tests methods that find specific logins in the store (findLogins,
* searchLogins, and countLogins).
*
* The getAllLogins method is not tested explicitly here, because it is used by
* all tests to verify additions, removals and modifications to the login store.
*/
"use strict";
// Globals
/**
* Returns a list of new nsILoginInfo objects that are a subset of the test
* data, built to match the specified query.
*
* @param aQuery
* Each property and value of this object restricts the search to those
* entries from the test data that match the property exactly.
*/
function buildExpectedLogins(aQuery)
{
return TestData.loginList().filter(
entry => Object.keys(aQuery).every(name => entry[name] === aQuery[name]));
}
/**
* Tests the searchLogins function.
*
* @param aQuery
* Each property and value of this object is translated to an entry in
* the nsIPropertyBag parameter of searchLogins.
* @param aExpectedCount
* Number of logins from the test data that should be found. The actual
* list of logins is obtained using the buildExpectedLogins helper, and
* this value is just used to verify that modifications to the test data
* don't make the current test meaningless.
*/
function checkSearchLogins(aQuery, aExpectedCount)
{
do_print("Testing searchLogins for " + JSON.stringify(aQuery));
let expectedLogins = buildExpectedLogins(aQuery);
do_check_eq(expectedLogins.length, aExpectedCount);
let outCount = {};
let logins = Services.logins.searchLogins(outCount, newPropertyBag(aQuery));
do_check_eq(outCount.value, expectedLogins.length);
LoginTestUtils.assertLoginListsEqual(logins, expectedLogins);
}
/**
* Tests findLogins, searchLogins, and countLogins with the same query.
*
* @param aQuery
* The "hostname", "formSubmitURL", and "httpRealm" properties of this
* object are passed as parameters to findLogins and countLogins. The
* same object is then passed to the checkSearchLogins function.
* @param aExpectedCount
* Number of logins from the test data that should be found. The actual
* list of logins is obtained using the buildExpectedLogins helper, and
* this value is just used to verify that modifications to the test data
* don't make the current test meaningless.
*/
function checkAllSearches(aQuery, aExpectedCount)
{
do_print("Testing all search functions for " + JSON.stringify(aQuery));
let expectedLogins = buildExpectedLogins(aQuery);
do_check_eq(expectedLogins.length, aExpectedCount);
// The findLogins and countLogins functions support wildcard matches by
// specifying empty strings as parameters, while searchLogins requires
// omitting the property entirely.
let hostname = ("hostname" in aQuery) ? aQuery.hostname : "";
let formSubmitURL = ("formSubmitURL" in aQuery) ? aQuery.formSubmitURL : "";
let httpRealm = ("httpRealm" in aQuery) ? aQuery.httpRealm : "";
// Test findLogins.
let outCount = {};
let logins = Services.logins.findLogins(outCount, hostname, formSubmitURL,
httpRealm);
do_check_eq(outCount.value, expectedLogins.length);
LoginTestUtils.assertLoginListsEqual(logins, expectedLogins);
// Test countLogins.
let count = Services.logins.countLogins(hostname, formSubmitURL, httpRealm);
do_check_eq(count, expectedLogins.length);
// Test searchLogins.
checkSearchLogins(aQuery, aExpectedCount);
}
// Tests
/**
* Prepare data for the following tests.
*/
add_task(function test_initialize()
{
for (let login of TestData.loginList()) {
Services.logins.addLogin(login);
}
});
/**
* Tests findLogins, searchLogins, and countLogins with basic queries.
*/
add_task(function test_search_all_basic()
{
// Find all logins, using no filters in the search functions.
checkAllSearches({}, 23);
// Find all form logins, then all authentication logins.
checkAllSearches({ httpRealm: null }, 14);
checkAllSearches({ formSubmitURL: null }, 9);
// Find all form logins on one host, then all authentication logins.
checkAllSearches({ hostname: "http://www4.example.com",
httpRealm: null }, 3);
checkAllSearches({ hostname: "http://www2.example.org",
formSubmitURL: null }, 2);
// Verify that scheme and subdomain are distinct in the hostname.
checkAllSearches({ hostname: "http://www.example.com" }, 1);
checkAllSearches({ hostname: "https://www.example.com" }, 1);
checkAllSearches({ hostname: "https://example.com" }, 1);
checkAllSearches({ hostname: "http://www3.example.com" }, 3);
// Verify that scheme and subdomain are distinct in formSubmitURL.
checkAllSearches({ formSubmitURL: "http://www.example.com" }, 2);
checkAllSearches({ formSubmitURL: "https://www.example.com" }, 2);
checkAllSearches({ formSubmitURL: "http://example.com" }, 1);
// Find by formSubmitURL on a single host.
checkAllSearches({ hostname: "http://www3.example.com",
formSubmitURL: "http://www.example.com" }, 1);
checkAllSearches({ hostname: "http://www3.example.com",
formSubmitURL: "https://www.example.com" }, 1);
checkAllSearches({ hostname: "http://www3.example.com",
formSubmitURL: "http://example.com" }, 1);
// Find by httpRealm on all hosts.
checkAllSearches({ httpRealm: "The HTTP Realm" }, 3);
checkAllSearches({ httpRealm: "ftp://ftp.example.org" }, 1);
checkAllSearches({ httpRealm: "The HTTP Realm Other" }, 2);
// Find by httpRealm on a single host.
checkAllSearches({ hostname: "http://example.net",
httpRealm: "The HTTP Realm" }, 1);
checkAllSearches({ hostname: "http://example.net",
httpRealm: "The HTTP Realm Other" }, 1);
checkAllSearches({ hostname: "ftp://example.net",
httpRealm: "ftp://example.net" }, 1);
});
/**
* Tests searchLogins with advanced queries.
*/
add_task(function test_searchLogins()
{
checkSearchLogins({ usernameField: "form_field_username" }, 12);
checkSearchLogins({ passwordField: "form_field_password" }, 13);
// Find all logins with an empty usernameField, including for authentication.
checkSearchLogins({ usernameField: "" }, 11);
// Find form logins with an empty usernameField.
checkSearchLogins({ httpRealm: null,
usernameField: "" }, 2);
// Find logins with an empty usernameField on one host.
checkSearchLogins({ hostname: "http://www6.example.com",
usernameField: "" }, 1);
});
/**
* Tests searchLogins with invalid arguments.
*/
add_task(function test_searchLogins_invalid()
{
Assert.throws(() => Services.logins.searchLogins({},
newPropertyBag({ username: "value" })),
/Unexpected field/);
});
/**
* Tests that matches are case-sensitive, compare the full field value, and are
* strict when interpreting the prePath of URIs.
*/
add_task(function test_search_all_full_case_sensitive()
{
checkAllSearches({ hostname: "http://www.example.com" }, 1);
checkAllSearches({ hostname: "http://www.example.com/" }, 0);
checkAllSearches({ hostname: "example.com" }, 0);
checkAllSearches({ formSubmitURL: "http://www.example.com" }, 2);
checkAllSearches({ formSubmitURL: "http://www.example.com/" }, 0);
checkAllSearches({ formSubmitURL: "http://" }, 0);
checkAllSearches({ formSubmitURL: "example.com" }, 0);
checkAllSearches({ httpRealm: "The HTTP Realm" }, 3);
checkAllSearches({ httpRealm: "The http Realm" }, 0);
checkAllSearches({ httpRealm: "The HTTP" }, 0);
checkAllSearches({ httpRealm: "Realm" }, 0);
});
/**
* Tests findLogins, searchLogins, and countLogins with queries that should
* return no values.
*/
add_task(function test_search_all_empty()
{
checkAllSearches({ hostname: "http://nonexistent.example.com" }, 0);
checkAllSearches({ formSubmitURL: "http://www.example.com",
httpRealm: "The HTTP Realm" }, 0);
checkSearchLogins({ hostname: "" }, 0);
checkSearchLogins({ id: "1000" }, 0);
});