From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- .../urlbar/tests/unit/test_autofill_origins.js | 1041 ++++++++++++++++++++ 1 file changed, 1041 insertions(+) create mode 100644 browser/components/urlbar/tests/unit/test_autofill_origins.js (limited to 'browser/components/urlbar/tests/unit/test_autofill_origins.js') 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(); +} -- cgit v1.2.3