summaryrefslogtreecommitdiffstats
path: root/browser/components/urlbar/tests/unit/test_autofill_origins.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/urlbar/tests/unit/test_autofill_origins.js')
-rw-r--r--browser/components/urlbar/tests/unit/test_autofill_origins.js1041
1 files changed, 1041 insertions, 0 deletions
diff --git a/browser/components/urlbar/tests/unit/test_autofill_origins.js b/browser/components/urlbar/tests/unit/test_autofill_origins.js
new file mode 100644
index 0000000000..6913b1a3b9
--- /dev/null
+++ b/browser/components/urlbar/tests/unit/test_autofill_origins.js
@@ -0,0 +1,1041 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const HEURISTIC_FALLBACK_PROVIDERNAME = "HeuristicFallback";
+
+const origin = "example.com";
+
+async function cleanup() {
+ let suggestPrefs = ["history", "bookmark", "openpage"];
+ for (let type of suggestPrefs) {
+ Services.prefs.clearUserPref("browser.urlbar.suggest." + type);
+ }
+ await cleanupPlaces();
+}
+
+testEngine_setup();
+
+registerCleanupFunction(async () => {
+ Services.prefs.clearUserPref("browser.urlbar.suggest.quickactions");
+});
+Services.prefs.setBoolPref("browser.urlbar.suggest.quickactions", false);
+
+// "example.com/" should match http://example.com/. i.e., the search string
+// should be treated as if it didn't have the trailing slash.
+add_task(async function trailingSlash() {
+ await PlacesTestUtils.addVisits([
+ {
+ uri: "http://example.com/",
+ },
+ ]);
+
+ let context = createContext(`${origin}/`, { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: `${origin}/`,
+ completed: `http://${origin}/`,
+ matches: [
+ makeVisitResult(context, {
+ uri: `http://${origin}/`,
+ title: `test visit for http://${origin}/`,
+ heuristic: true,
+ }),
+ ],
+ });
+ await cleanup();
+});
+
+// "example.com/" should match http://www.example.com/. i.e., the search string
+// should be treated as if it didn't have the trailing slash.
+add_task(async function trailingSlashWWW() {
+ await PlacesTestUtils.addVisits([
+ {
+ uri: "http://www.example.com/",
+ },
+ ]);
+ let context = createContext(`${origin}/`, { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: "example.com/",
+ completed: "http://www.example.com/",
+ matches: [
+ makeVisitResult(context, {
+ uri: `http://www.${origin}/`,
+ title: `test visit for http://www.${origin}/`,
+ heuristic: true,
+ }),
+ ],
+ });
+ await cleanup();
+});
+
+// "ex" should match http://example.com:8888/, and the port should be completed.
+add_task(async function port() {
+ await PlacesTestUtils.addVisits([
+ {
+ uri: "http://example.com:8888/",
+ },
+ ]);
+ let context = createContext("ex", { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: "example.com:8888/",
+ completed: "http://example.com:8888/",
+ matches: [
+ makeVisitResult(context, {
+ uri: `http://${origin}:8888/`,
+ title: `test visit for http://${origin}:8888/`,
+ heuristic: true,
+ }),
+ ],
+ });
+ await cleanup();
+});
+
+// "example.com:8" should match http://example.com:8888/, and the port should
+// be completed.
+add_task(async function portPartial() {
+ await PlacesTestUtils.addVisits([
+ {
+ uri: "http://example.com:8888/",
+ },
+ ]);
+ let context = createContext(`${origin}:8`, { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: "example.com:8888/",
+ completed: "http://example.com:8888/",
+ matches: [
+ makeVisitResult(context, {
+ uri: `http://${origin}:8888/`,
+ title: `test visit for http://${origin}:8888/`,
+ heuristic: true,
+ }),
+ ],
+ });
+ await cleanup();
+});
+
+// "EXaM" should match http://example.com/ and the case of the search string
+// should be preserved in the autofilled value.
+add_task(async function preserveCase() {
+ await PlacesTestUtils.addVisits([
+ {
+ uri: "http://example.com/",
+ },
+ ]);
+ let context = createContext("EXaM", { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: "EXaMple.com/",
+ completed: "http://example.com/",
+ matches: [
+ makeVisitResult(context, {
+ uri: `http://${origin}/`,
+ title: `test visit for http://${origin}/`,
+ heuristic: true,
+ }),
+ ],
+ });
+ await cleanup();
+});
+
+// "EXaM" should match http://example.com:8888/, the port should be completed,
+// and the case of the search string should be preserved in the autofilled
+// value.
+add_task(async function preserveCasePort() {
+ await PlacesTestUtils.addVisits([
+ {
+ uri: "http://example.com:8888/",
+ },
+ ]);
+ let context = createContext("EXaM", { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: "EXaMple.com:8888/",
+ completed: "http://example.com:8888/",
+ matches: [
+ makeVisitResult(context, {
+ uri: `http://${origin}:8888/`,
+ title: `test visit for http://${origin}:8888/`,
+ heuristic: true,
+ }),
+ ],
+ });
+ await cleanup();
+});
+
+// "example.com:89" should *not* match http://example.com:8888/.
+add_task(async function portNoMatch1() {
+ await PlacesTestUtils.addVisits([
+ {
+ uri: "http://example.com:8888/",
+ },
+ ]);
+ let context = createContext(`${origin}:89`, { isPrivate: false });
+ await check_results({
+ context,
+ matches: [
+ makeVisitResult(context, {
+ source: UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
+ uri: `http://${origin}:89/`,
+ fallbackTitle: `http://${origin}:89/`,
+ iconUri: "",
+ heuristic: true,
+ providerName: HEURISTIC_FALLBACK_PROVIDERNAME,
+ }),
+ ],
+ });
+ await cleanup();
+});
+
+// "example.com:9" should *not* match http://example.com:8888/.
+add_task(async function portNoMatch2() {
+ await PlacesTestUtils.addVisits([
+ {
+ uri: "http://example.com:8888/",
+ },
+ ]);
+ let context = createContext(`${origin}:9`, { isPrivate: false });
+ await check_results({
+ context,
+ matches: [
+ makeVisitResult(context, {
+ source: UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
+ uri: `http://${origin}:9/`,
+ fallbackTitle: `http://${origin}:9/`,
+ iconUri: "",
+ heuristic: true,
+ providerName: HEURISTIC_FALLBACK_PROVIDERNAME,
+ }),
+ ],
+ });
+ await cleanup();
+});
+
+// "example/" should *not* match http://example.com/.
+add_task(async function trailingSlash_2() {
+ await PlacesTestUtils.addVisits([
+ {
+ uri: "http://example.com/",
+ },
+ ]);
+ let context = createContext("example/", { isPrivate: false });
+ await check_results({
+ context,
+ matches: [
+ makeVisitResult(context, {
+ source: UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
+ uri: "http://example/",
+ fallbackTitle: "http://example/",
+ iconUri: "page-icon:http://example/",
+ heuristic: true,
+ providerName: HEURISTIC_FALLBACK_PROVIDERNAME,
+ }),
+ ],
+ });
+ await cleanup();
+});
+
+// multi.dotted.domain, search up to dot.
+add_task(async function multidotted() {
+ await PlacesTestUtils.addVisits([
+ {
+ uri: "http://www.example.co.jp:8888/",
+ },
+ ]);
+ let context = createContext("www.example.co.", { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: "www.example.co.jp:8888/",
+ completed: "http://www.example.co.jp:8888/",
+ matches: [
+ makeVisitResult(context, {
+ uri: "http://www.example.co.jp:8888/",
+ title: "test visit for http://www.example.co.jp:8888/",
+ heuristic: true,
+ }),
+ ],
+ });
+ await cleanup();
+});
+
+add_task(async function test_ip() {
+ // IP addresses have complicated rules around whether they show
+ // HeuristicFallback's backup search result. Flip this pref to disable that
+ // backup search and simplify ths subtest.
+ Services.prefs.setBoolPref("keyword.enabled", false);
+ for (let str of [
+ "192.168.1.1/",
+ "255.255.255.255:8080/",
+ "[2001:db8::1428:57ab]/",
+ "[::c0a8:5909]/",
+ "[::1]/",
+ ]) {
+ info("testing " + str);
+ await PlacesTestUtils.addVisits("http://" + str);
+ for (let i = 1; i < str.length; ++i) {
+ let context = createContext(str.substring(0, i), { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: str,
+ completed: "http://" + str,
+ matches: [
+ makeVisitResult(context, {
+ uri: "http://" + str,
+ title: `test visit for http://${str}`,
+ heuristic: true,
+ }),
+ ],
+ });
+ }
+ await cleanup();
+ }
+ Services.prefs.clearUserPref("keyword.enabled");
+});
+
+// host starting with large number.
+add_task(async function large_number_host() {
+ await PlacesTestUtils.addVisits([
+ {
+ uri: "http://12345example.it:8888/",
+ },
+ ]);
+ let context = createContext("1234", { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: "12345example.it:8888/",
+ completed: "http://12345example.it:8888/",
+ matches: [
+ makeVisitResult(context, {
+ uri: "http://12345example.it:8888/",
+ title: "test visit for http://12345example.it:8888/",
+ heuristic: true,
+ }),
+ ],
+ });
+ await cleanup();
+});
+
+// When determining which origins should be autofilled, all the origins sharing
+// a host should be added together to get their combined frecency -- i.e.,
+// prefixes should be collapsed. And then from that list, the origin with the
+// highest frecency should be chosen.
+add_task(async function groupByHost() {
+ // Add some visits to the same host, example.com. Add one http and two https
+ // so that https has a higher frecency and is therefore the origin that should
+ // be autofilled. Also add another origin that has a higher frecency than
+ // both so that alone, neither http nor https would be autofilled, but added
+ // together they should be.
+ await PlacesTestUtils.addVisits([
+ { uri: "http://example.com/" },
+
+ { uri: "https://example.com/" },
+ { uri: "https://example.com/" },
+
+ { uri: "https://mozilla.org/" },
+ { uri: "https://mozilla.org/" },
+ { uri: "https://mozilla.org/" },
+ { uri: "https://mozilla.org/" },
+ ]);
+
+ let httpFrec = await PlacesTestUtils.getDatabaseValue(
+ "moz_places",
+ "frecency",
+ { url: "http://example.com/" }
+ );
+ let httpsFrec = await PlacesTestUtils.getDatabaseValue(
+ "moz_places",
+ "frecency",
+ { url: "https://example.com/" }
+ );
+ let otherFrec = await PlacesTestUtils.getDatabaseValue(
+ "moz_places",
+ "frecency",
+ { url: "https://mozilla.org/" }
+ );
+ Assert.less(httpFrec, httpsFrec, "Sanity check");
+ Assert.less(httpsFrec, otherFrec, "Sanity check");
+
+ // Make sure the frecencies of the three origins are as expected in relation
+ // to the threshold.
+ let threshold = await getOriginAutofillThreshold();
+ Assert.less(httpFrec, threshold, "http origin should be < threshold");
+ Assert.less(httpsFrec, threshold, "https origin should be < threshold");
+ Assert.ok(threshold <= otherFrec, "Other origin should cross threshold");
+
+ Assert.ok(
+ threshold <= httpFrec + httpsFrec,
+ "http and https origin added together should cross threshold"
+ );
+
+ // The https origin should be autofilled.
+ let context = createContext("ex", { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: "example.com/",
+ completed: "https://example.com/",
+ matches: [
+ makeVisitResult(context, {
+ uri: "https://example.com/",
+ title: "test visit for https://example.com/",
+ heuristic: true,
+ }),
+ ],
+ });
+
+ await cleanup();
+});
+
+// This is the same as the previous (groupByHost), but it changes the standard
+// deviation multiplier by setting the corresponding pref. This makes sure that
+// the pref is respected.
+add_task(async function groupByHostNonDefaultStddevMultiplier() {
+ let stddevMultiplier = 1.5;
+ Services.prefs.setCharPref(
+ "browser.urlbar.autoFill.stddevMultiplier",
+ Number(stddevMultiplier).toFixed(1)
+ );
+
+ await PlacesTestUtils.addVisits([
+ { uri: "http://example.com/" },
+ { uri: "http://example.com/" },
+
+ { uri: "https://example.com/" },
+ { uri: "https://example.com/" },
+ { uri: "https://example.com/" },
+
+ { uri: "https://foo.com/" },
+ { uri: "https://foo.com/" },
+ { uri: "https://foo.com/" },
+
+ { uri: "https://mozilla.org/" },
+ { uri: "https://mozilla.org/" },
+ { uri: "https://mozilla.org/" },
+ { uri: "https://mozilla.org/" },
+ { uri: "https://mozilla.org/" },
+ ]);
+
+ let httpFrec = await PlacesTestUtils.getDatabaseValue(
+ "moz_places",
+ "frecency",
+ {
+ url: "http://example.com/",
+ }
+ );
+ let httpsFrec = await PlacesTestUtils.getDatabaseValue(
+ "moz_places",
+ "frecency",
+ {
+ url: "https://example.com/",
+ }
+ );
+ let otherFrec = await PlacesTestUtils.getDatabaseValue(
+ "moz_places",
+ "frecency",
+ {
+ url: "https://mozilla.org/",
+ }
+ );
+ Assert.less(httpFrec, httpsFrec, "Sanity check");
+ Assert.less(httpsFrec, otherFrec, "Sanity check");
+
+ // Make sure the frecencies of the three origins are as expected in relation
+ // to the threshold.
+ let threshold = await getOriginAutofillThreshold();
+ Assert.less(httpFrec, threshold, "http origin should be < threshold");
+ Assert.less(httpsFrec, threshold, "https origin should be < threshold");
+ Assert.ok(threshold <= otherFrec, "Other origin should cross threshold");
+
+ Assert.ok(
+ threshold <= httpFrec + httpsFrec,
+ "http and https origin added together should cross threshold"
+ );
+
+ // The https origin should be autofilled.
+ let context = createContext("ex", { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: "example.com/",
+ completed: "https://example.com/",
+ matches: [
+ makeVisitResult(context, {
+ uri: "https://example.com/",
+ title: "test visit for https://example.com/",
+ heuristic: true,
+ }),
+ ],
+ });
+
+ Services.prefs.clearUserPref("browser.urlbar.autoFill.stddevMultiplier");
+
+ await cleanup();
+});
+
+// This is similar to suggestHistoryFalse_bookmark_0 in test_autofill_tasks.js,
+// but it adds unbookmarked visits for multiple URLs with the same origin.
+add_task(async function suggestHistoryFalse_bookmark_multiple() {
+ // Force only bookmarked pages to be suggested and therefore only bookmarked
+ // pages to be completed.
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history", false);
+
+ let search = "ex";
+ let baseURL = "http://example.com/";
+ let bookmarkedURL = baseURL + "bookmarked";
+
+ // Add visits for three different URLs all sharing the same origin, and then
+ // bookmark the second one. After that, the origin should be autofilled. The
+ // reason for adding unbookmarked visits before and after adding the
+ // bookmarked visit is to make sure our aggregate SQL query for determining
+ // whether an origin is bookmarked is correct.
+
+ await PlacesTestUtils.addVisits([
+ {
+ uri: baseURL + "other1",
+ },
+ ]);
+ let context = createContext(search, { isPrivate: false });
+ await check_results({
+ context,
+ matches: [
+ makeSearchResult(context, {
+ engineName: SUGGESTIONS_ENGINE_NAME,
+ providerName: HEURISTIC_FALLBACK_PROVIDERNAME,
+ heuristic: true,
+ }),
+ ],
+ });
+
+ await PlacesTestUtils.addVisits([
+ {
+ uri: bookmarkedURL,
+ },
+ ]);
+ context = createContext(search, { isPrivate: false });
+ await check_results({
+ context,
+ matches: [
+ makeSearchResult(context, {
+ engineName: SUGGESTIONS_ENGINE_NAME,
+ providerName: HEURISTIC_FALLBACK_PROVIDERNAME,
+ heuristic: true,
+ }),
+ ],
+ });
+
+ await PlacesTestUtils.addVisits([
+ {
+ uri: baseURL + "other2",
+ },
+ ]);
+ context = createContext(search, { isPrivate: false });
+ await check_results({
+ context,
+ matches: [
+ makeSearchResult(context, {
+ engineName: SUGGESTIONS_ENGINE_NAME,
+ providerName: HEURISTIC_FALLBACK_PROVIDERNAME,
+ heuristic: true,
+ }),
+ ],
+ });
+
+ // Now bookmark the second URL. It should be suggested and completed.
+ await PlacesTestUtils.addBookmarkWithDetails({
+ uri: bookmarkedURL,
+ });
+ context = createContext(search, { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: "example.com/",
+ completed: baseURL,
+ matches: [
+ makeVisitResult(context, {
+ uri: baseURL,
+ fallbackTitle: "example.com",
+ heuristic: true,
+ }),
+ makeBookmarkResult(context, {
+ uri: bookmarkedURL,
+ title: "A bookmark",
+ }),
+ ],
+ });
+
+ await cleanup();
+});
+
+// This is similar to suggestHistoryFalse_bookmark_prefix_0 in
+// autofill_test_autofill_originsAndQueries.js, but it adds unbookmarked visits
+// for multiple URLs with the same origin.
+add_task(async function suggestHistoryFalse_bookmark_prefix_multiple() {
+ // Force only bookmarked pages to be suggested and therefore only bookmarked
+ // pages to be completed.
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history", false);
+
+ let search = "http://ex";
+ let baseURL = "http://example.com/";
+ let bookmarkedURL = baseURL + "bookmarked";
+
+ // Add visits for three different URLs all sharing the same origin, and then
+ // bookmark the second one. After that, the origin should be autofilled. The
+ // reason for adding unbookmarked visits before and after adding the
+ // bookmarked visit is to make sure our aggregate SQL query for determining
+ // whether an origin is bookmarked is correct.
+
+ await PlacesTestUtils.addVisits([
+ {
+ uri: baseURL + "other1",
+ },
+ ]);
+ let context = createContext(search, { isPrivate: false });
+ await check_results({
+ context,
+ matches: [
+ makeVisitResult(context, {
+ source: UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
+ uri: `${search}/`,
+ fallbackTitle: `${search}/`,
+ iconUri: "",
+ heuristic: true,
+ providerName: HEURISTIC_FALLBACK_PROVIDERNAME,
+ }),
+ ],
+ });
+
+ await PlacesTestUtils.addVisits([
+ {
+ uri: bookmarkedURL,
+ },
+ ]);
+ context = createContext(search, { isPrivate: false });
+ await check_results({
+ context,
+ matches: [
+ makeVisitResult(context, {
+ source: UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
+ uri: `${search}/`,
+ fallbackTitle: `${search}/`,
+ iconUri: "",
+ heuristic: true,
+ providerName: HEURISTIC_FALLBACK_PROVIDERNAME,
+ }),
+ ],
+ });
+
+ await PlacesTestUtils.addVisits([
+ {
+ uri: baseURL + "other2",
+ },
+ ]);
+ context = createContext(search, { isPrivate: false });
+ await check_results({
+ context,
+ matches: [
+ makeVisitResult(context, {
+ source: UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
+ uri: `${search}/`,
+ fallbackTitle: `${search}/`,
+ iconUri: "",
+ heuristic: true,
+ providerName: HEURISTIC_FALLBACK_PROVIDERNAME,
+ }),
+ ],
+ });
+
+ // Now bookmark the second URL. It should be suggested and completed.
+ await PlacesTestUtils.addBookmarkWithDetails({
+ uri: bookmarkedURL,
+ });
+ context = createContext(search, { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: "http://example.com/",
+ completed: baseURL,
+ matches: [
+ makeVisitResult(context, {
+ uri: baseURL,
+ fallbackTitle: "example.com",
+ heuristic: true,
+ }),
+ makeBookmarkResult(context, {
+ uri: bookmarkedURL,
+ title: "A bookmark",
+ }),
+ ],
+ });
+
+ await cleanup();
+});
+
+// When the autofilled URL is `example.com/`, a visit for `example.com/?` should
+// not be included in the results since it dupes the autofill result.
+add_task(async function searchParams() {
+ await PlacesTestUtils.addVisits([
+ "http://example.com/",
+ "http://example.com/?",
+ "http://example.com/?foo",
+ ]);
+
+ // First, do a search with autofill disabled to make sure the visits were
+ // properly added. `example.com/?foo` has the highest frecency because it was
+ // added last; `example.com/?` has the next highest. `example.com/` dupes
+ // `example.com/?`, so it should not appear.
+ UrlbarPrefs.set("autoFill", false);
+ let context = createContext("ex", { isPrivate: false });
+ await check_results({
+ context,
+ matches: [
+ makeSearchResult(context, {
+ engineName: SUGGESTIONS_ENGINE_NAME,
+ providerName: HEURISTIC_FALLBACK_PROVIDERNAME,
+ heuristic: true,
+ }),
+ makeVisitResult(context, {
+ uri: "http://example.com/?foo",
+ title: "test visit for http://example.com/?foo",
+ }),
+ makeVisitResult(context, {
+ uri: "http://example.com/?",
+ title: "test visit for http://example.com/?",
+ }),
+ ],
+ });
+
+ // Now do a search with autofill enabled. This time `example.com/` will be
+ // autofilled, and since `example.com/?` dupes it, `example.com/?` should not
+ // appear.
+ UrlbarPrefs.clear("autoFill");
+ context = createContext("ex", { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: "example.com/",
+ completed: "http://example.com/",
+ matches: [
+ makeVisitResult(context, {
+ uri: "http://example.com/",
+ title: "test visit for http://example.com/",
+ heuristic: true,
+ }),
+ makeVisitResult(context, {
+ uri: "http://example.com/?foo",
+ title: "test visit for http://example.com/?foo",
+ }),
+ ],
+ });
+
+ await cleanup();
+});
+
+// When the autofilled URL is `example.com/`, a visit for `example.com/?` should
+// not be included in the results since it dupes the autofill result. (Same as
+// the previous task but with https URLs instead of http. There shouldn't be any
+// substantive difference.)
+add_task(async function searchParams_https() {
+ await PlacesTestUtils.addVisits([
+ "https://example.com/",
+ "https://example.com/?",
+ "https://example.com/?foo",
+ ]);
+
+ // First, do a search with autofill disabled to make sure the visits were
+ // properly added. `example.com/?foo` has the highest frecency because it was
+ // added last; `example.com/?` has the next highest. `example.com/` dupes
+ // `example.com/?`, so it should not appear.
+ UrlbarPrefs.set("autoFill", false);
+ let context = createContext("ex", { isPrivate: false });
+ await check_results({
+ context,
+ matches: [
+ makeSearchResult(context, {
+ engineName: SUGGESTIONS_ENGINE_NAME,
+ providerName: HEURISTIC_FALLBACK_PROVIDERNAME,
+ heuristic: true,
+ }),
+ makeVisitResult(context, {
+ uri: "https://example.com/?foo",
+ title: "test visit for https://example.com/?foo",
+ }),
+ makeVisitResult(context, {
+ uri: "https://example.com/?",
+ title: "test visit for https://example.com/?",
+ }),
+ ],
+ });
+
+ // Now do a search with autofill enabled. This time `example.com/` will be
+ // autofilled, and since `example.com/?` dupes it, `example.com/?` should not
+ // appear.
+ UrlbarPrefs.clear("autoFill");
+ context = createContext("ex", { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: "example.com/",
+ completed: "https://example.com/",
+ matches: [
+ makeVisitResult(context, {
+ uri: "https://example.com/",
+ title: "test visit for https://example.com/",
+ heuristic: true,
+ }),
+ makeVisitResult(context, {
+ uri: "https://example.com/?foo",
+ title: "test visit for https://example.com/?foo",
+ }),
+ ],
+ });
+
+ await cleanup();
+});
+
+// Checks an origin that looks like a prefix: a scheme with no dots + a port.
+add_task(async function originLooksLikePrefix() {
+ let hostAndPort = "localhost:8888";
+ let address = `http://${hostAndPort}/`;
+ await PlacesTestUtils.addVisits([{ uri: address }]);
+
+ // addTestSuggestionsEngine adds a search engine
+ // with localhost as a server, so we have to disable the
+ // TTS result or else it will show up as a second result
+ // when searching l to localhost
+ UrlbarPrefs.set("suggest.engines", false);
+
+ for (let search of ["lo", "localhost", "localhost:", "localhost:8888"]) {
+ let context = createContext(search, { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: hostAndPort + "/",
+ completed: address,
+ matches: [
+ makeVisitResult(context, {
+ uri: address,
+ title: `test visit for http://${hostAndPort}/`,
+ heuristic: true,
+ }),
+ ],
+ });
+ }
+ await cleanup();
+});
+
+// Checks an origin whose prefix is "about:".
+add_task(async function about() {
+ const testData = [
+ {
+ uri: "about:config",
+ input: "conf",
+ results: [
+ context =>
+ makeSearchResult(context, {
+ engineName: "Suggestions",
+ heuristic: true,
+ }),
+ context =>
+ makeBookmarkResult(context, {
+ uri: "about:config",
+ title: "A bookmark",
+ }),
+ ],
+ },
+ {
+ uri: "about:blank",
+ input: "about:blan",
+ results: [
+ context =>
+ makeVisitResult(context, {
+ uri: "about:blan",
+ fallbackTitle: "about:blan",
+ source: UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL,
+ heuristic: true,
+ }),
+ context =>
+ makeBookmarkResult(context, {
+ uri: "about:blank",
+ title: "A bookmark",
+ }),
+ ],
+ },
+ ];
+
+ for (const { uri, input, results } of testData) {
+ await PlacesTestUtils.addBookmarkWithDetails({ uri });
+
+ const context = createContext(input, { isPrivate: false });
+ await check_results({
+ context,
+ matches: results.map(f => f(context)),
+ });
+ await cleanup();
+ }
+});
+
+// Checks an origin whose prefix is "place:".
+add_task(async function place() {
+ const testData = [
+ {
+ uri: "place:transition=7&sort=4",
+ input: "tran",
+ },
+ {
+ uri: "place:transition=7&sort=4",
+ input: "place:tran",
+ },
+ ];
+
+ for (const { uri, input } of testData) {
+ await PlacesTestUtils.addBookmarkWithDetails({ uri });
+
+ const context = createContext(input, { isPrivate: false });
+ await check_results({
+ context,
+ matches: [
+ makeSearchResult(context, {
+ engineName: "Suggestions",
+ heuristic: true,
+ }),
+ ],
+ });
+ await cleanup();
+ }
+});
+
+add_task(async function nullTitle() {
+ await doTitleTest({
+ visits: [
+ {
+ uri: "http://example.com/",
+ // Set title of visits data to an empty string causes
+ // the title to be null in the database.
+ title: "",
+ frecency: 100,
+ },
+ {
+ uri: "https://www.example.com/",
+ title: "high frecency",
+ frecency: 50,
+ },
+ {
+ uri: "http://www.example.com/",
+ title: "low frecency",
+ frecency: 1,
+ },
+ ],
+ input: "example.com",
+ expected: {
+ autofilled: "example.com/",
+ completed: "http://example.com/",
+ matches: context => [
+ makeVisitResult(context, {
+ uri: "http://example.com/",
+ title: "high frecency",
+ heuristic: true,
+ }),
+ makeVisitResult(context, {
+ uri: "https://www.example.com/",
+ title: "high frecency",
+ }),
+ ],
+ },
+ });
+});
+
+add_task(async function domainTitle() {
+ await doTitleTest({
+ visits: [
+ {
+ uri: "http://example.com/",
+ title: "example.com",
+ frecency: 100,
+ },
+ {
+ uri: "https://www.example.com/",
+ title: "",
+ frecency: 50,
+ },
+ {
+ uri: "http://www.example.com/",
+ title: "lowest frecency but has title",
+ frecency: 1,
+ },
+ ],
+ input: "example.com",
+ expected: {
+ autofilled: "example.com/",
+ completed: "http://example.com/",
+ matches: context => [
+ makeVisitResult(context, {
+ uri: "http://example.com/",
+ title: "lowest frecency but has title",
+ heuristic: true,
+ }),
+ makeVisitResult(context, {
+ uri: "https://www.example.com/",
+ title: "www.example.com",
+ }),
+ ],
+ },
+ });
+});
+
+add_task(async function exactMatchedTitle() {
+ await doTitleTest({
+ visits: [
+ {
+ uri: "http://example.com/",
+ title: "exact match",
+ frecency: 50,
+ },
+ {
+ uri: "https://www.example.com/",
+ title: "high frecency uri",
+ frecency: 100,
+ },
+ ],
+ input: "http://example.com/",
+ expected: {
+ autofilled: "http://example.com/",
+ completed: "http://example.com/",
+ matches: context => [
+ makeVisitResult(context, {
+ uri: "http://example.com/",
+ title: "exact match",
+ heuristic: true,
+ }),
+ makeVisitResult(context, {
+ uri: "https://www.example.com/",
+ title: "high frecency uri",
+ }),
+ ],
+ },
+ });
+});
+
+async function doTitleTest({ visits, input, expected }) {
+ await PlacesTestUtils.addVisits(visits);
+ for (const { uri, frecency } of visits) {
+ // Prepare data.
+ await PlacesUtils.withConnectionWrapper("test::doTitleTest", async db => {
+ await db.execute(
+ `UPDATE moz_places SET frecency = :frecency, recalc_frecency=0 WHERE url = :url`,
+ {
+ frecency,
+ url: uri,
+ }
+ );
+ await db.executeCached("DELETE FROM moz_updateoriginsupdate_temp");
+ });
+ }
+
+ const context = createContext(input, { isPrivate: false });
+ await check_results({
+ context,
+ autofilled: expected.autofilled,
+ completed: expected.completed,
+ matches: expected.matches(context),
+ });
+
+ await cleanup();
+}