summaryrefslogtreecommitdiffstats
path: root/toolkit/components/places/tests/unifiedcomplete
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/places/tests/unifiedcomplete')
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/.eslintrc.js7
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/data/engine-rel-searchform.xml5
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/data/engine-suggestions.xml14
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/head_autocomplete.js505
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_416211.js22
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_416214.js39
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_417798.js51
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_418257.js67
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_422277.js19
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_autocomplete_functional.js171
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_autocomplete_on_value_removed_479089.js39
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_autofill_default_behavior.js310
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_avoid_middle_complete.js179
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_avoid_stripping_to_empty_tokens.js41
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_casing.js157
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_do_not_trim.js91
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_download_embed_bookmarks.js71
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_dupe_urls.js23
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_empty_search.js98
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_enabled.js68
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_escape_self.js31
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_extension_matches.js384
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_ignore_protocol.js24
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_keyword_search.js73
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_keyword_search_actions.js149
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_keywords.js78
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_match_beginning.js54
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_multi_word_search.js68
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_query_url.js68
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_remote_tab_matches.js203
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_search_engine_alias.js51
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_search_engine_current.js45
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_search_engine_host.js49
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_search_engine_restyle.js43
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_search_suggestions.js651
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_special_search.js447
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_swap_protocol.js153
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_tab_matches.js164
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_trimming.js313
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_typed.js84
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_visit_url.js186
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_word_boundary_search.js175
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/test_zero_frecency.js35
-rw-r--r--toolkit/components/places/tests/unifiedcomplete/xpcshell.ini49
44 files changed, 5554 insertions, 0 deletions
diff --git a/toolkit/components/places/tests/unifiedcomplete/.eslintrc.js b/toolkit/components/places/tests/unifiedcomplete/.eslintrc.js
new file mode 100644
index 000000000..d35787cd2
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+ "extends": [
+ "../../../../../testing/xpcshell/xpcshell.eslintrc.js"
+ ]
+};
diff --git a/toolkit/components/places/tests/unifiedcomplete/data/engine-rel-searchform.xml b/toolkit/components/places/tests/unifiedcomplete/data/engine-rel-searchform.xml
new file mode 100644
index 000000000..f4baad28a
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/data/engine-rel-searchform.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
+<ShortName>engine-rel-searchform.xml</ShortName>
+<Url type="text/html" method="GET" template="http://example.com/?search" rel="searchform"/>
+</SearchPlugin>
diff --git a/toolkit/components/places/tests/unifiedcomplete/data/engine-suggestions.xml b/toolkit/components/places/tests/unifiedcomplete/data/engine-suggestions.xml
new file mode 100644
index 000000000..a322a7c86
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/data/engine-suggestions.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
+<ShortName>engine-suggestions.xml</ShortName>
+<Url type="application/x-suggestions+json"
+ method="GET"
+ template="http://localhost:9000/suggest?{searchTerms}"/>
+<Url type="text/html"
+ method="GET"
+ template="http://localhost:9000/search"
+ rel="searchform"/>
+</SearchPlugin>
diff --git a/toolkit/components/places/tests/unifiedcomplete/head_autocomplete.js b/toolkit/components/places/tests/unifiedcomplete/head_autocomplete.js
new file mode 100644
index 000000000..11e917e18
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/head_autocomplete.js
@@ -0,0 +1,505 @@
+/* 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/. */
+
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cr = Components.results;
+var Cu = Components.utils;
+
+const FRECENCY_DEFAULT = 10000;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://testing-common/httpd.js");
+
+// Import common head.
+{
+ let commonFile = do_get_file("../head_common.js", false);
+ let uri = Services.io.newFileURI(commonFile);
+ Services.scriptloader.loadSubScript(uri.spec, this);
+}
+
+// Put any other stuff relative to this test folder below.
+
+const TITLE_SEARCH_ENGINE_SEPARATOR = " \u00B7\u2013\u00B7 ";
+
+function run_test() {
+ run_next_test();
+}
+
+function* cleanup() {
+ Services.prefs.clearUserPref("browser.urlbar.autocomplete.enabled");
+ Services.prefs.clearUserPref("browser.urlbar.autoFill");
+ Services.prefs.clearUserPref("browser.urlbar.autoFill.typed");
+ Services.prefs.clearUserPref("browser.urlbar.autoFill.searchEngines");
+ let suggestPrefs = [
+ "history",
+ "bookmark",
+ "history.onlyTyped",
+ "openpage",
+ "searches",
+ ];
+ for (let type of suggestPrefs) {
+ Services.prefs.clearUserPref("browser.urlbar.suggest." + type);
+ }
+ Services.prefs.clearUserPref("browser.search.suggest.enabled");
+ yield PlacesUtils.bookmarks.eraseEverything();
+ yield PlacesTestUtils.clearHistory();
+}
+do_register_cleanup(cleanup);
+
+/**
+ * @param aSearches
+ * Array of AutoCompleteSearch names.
+ */
+function AutoCompleteInput(aSearches) {
+ this.searches = aSearches;
+}
+AutoCompleteInput.prototype = {
+ popup: {
+ selectedIndex: -1,
+ invalidate: function () {},
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompletePopup])
+ },
+ popupOpen: false,
+
+ disableAutoComplete: false,
+ completeDefaultIndex: true,
+ completeSelectedIndex: true,
+ forceComplete: false,
+
+ minResultsForPopup: 0,
+ maxRows: 0,
+
+ showCommentColumn: false,
+ showImageColumn: false,
+
+ timeout: 10,
+ searchParam: "",
+
+ get searchCount() {
+ return this.searches.length;
+ },
+ getSearchAt: function(aIndex) {
+ return this.searches[aIndex];
+ },
+
+ textValue: "",
+ // Text selection range
+ _selStart: 0,
+ _selEnd: 0,
+ get selectionStart() {
+ return this._selStart;
+ },
+ get selectionEnd() {
+ return this._selEnd;
+ },
+ selectTextRange: function(aStart, aEnd) {
+ this._selStart = aStart;
+ this._selEnd = aEnd;
+ },
+
+ onSearchBegin: function () {},
+ onSearchComplete: function () {},
+
+ onTextEntered: () => false,
+ onTextReverted: () => false,
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteInput])
+}
+
+// A helper for check_autocomplete to check a specific match against data from
+// the controller.
+function _check_autocomplete_matches(match, result) {
+ let { uri, title, tags, style } = match;
+ if (tags)
+ title += " \u2013 " + tags.sort().join(", ");
+ if (style)
+ style = style.sort();
+ else
+ style = ["favicon"];
+
+ do_print(`Checking against expected "${uri.spec}", "${title}"`);
+ // Got a match on both uri and title?
+ if (stripPrefix(uri.spec) != stripPrefix(result.value) || title != result.comment) {
+ return false;
+ }
+
+ let actualStyle = result.style.split(/\s+/).sort();
+ if (style)
+ Assert.equal(actualStyle.toString(), style.toString(), "Match should have expected style");
+ if (uri.spec.startsWith("moz-action:")) {
+ Assert.ok(actualStyle.includes("action"), "moz-action results should always have 'action' in their style");
+ }
+
+ if (match.icon)
+ Assert.equal(result.image, match.icon, "Match should have expected image");
+
+ return true;
+}
+
+function* check_autocomplete(test) {
+ // At this point frecency could still be updating due to latest pages
+ // updates.
+ // This is not a problem in real life, but autocomplete tests should
+ // return reliable resultsets, thus we have to wait.
+ yield PlacesTestUtils.promiseAsyncUpdates();
+
+ // Make an AutoCompleteInput that uses our searches and confirms results.
+ let input = new AutoCompleteInput(["unifiedcomplete"]);
+ input.textValue = test.search;
+
+ if (test.searchParam)
+ input.searchParam = test.searchParam;
+
+ // Caret must be at the end for autoFill to happen.
+ let strLen = test.search.length;
+ input.selectTextRange(strLen, strLen);
+ Assert.equal(input.selectionStart, strLen, "Selection starts at end");
+ Assert.equal(input.selectionEnd, strLen, "Selection ends at the end");
+
+ let controller = Cc["@mozilla.org/autocomplete/controller;1"]
+ .getService(Ci.nsIAutoCompleteController);
+ controller.input = input;
+
+ let numSearchesStarted = 0;
+ input.onSearchBegin = () => {
+ do_print("onSearchBegin received");
+ numSearchesStarted++;
+ };
+ let searchCompletePromise = new Promise(resolve => {
+ input.onSearchComplete = () => {
+ do_print("onSearchComplete received");
+ resolve();
+ }
+ });
+ let expectedSearches = 1;
+ if (test.incompleteSearch) {
+ controller.startSearch(test.incompleteSearch);
+ expectedSearches++;
+ }
+
+ do_print("Searching for: '" + test.search + "'");
+ controller.startSearch(test.search);
+ yield searchCompletePromise;
+
+ Assert.equal(numSearchesStarted, expectedSearches, "All searches started");
+
+ // Check to see the expected uris and titles match up. If 'enable-actions'
+ // is specified, we check that the first specified match is the first
+ // controller value (as this is the "special" always selected item), but the
+ // rest can match in any order.
+ // If 'enable-actions' is not specified, they can match in any order.
+ if (test.matches) {
+ // Do not modify the test original matches.
+ let matches = test.matches.slice();
+
+ if (matches.length) {
+ let firstIndexToCheck = 0;
+ if (test.searchParam && test.searchParam.includes("enable-actions")) {
+ firstIndexToCheck = 1;
+ do_print("Checking first match is first autocomplete entry")
+ let result = {
+ value: controller.getValueAt(0),
+ comment: controller.getCommentAt(0),
+ style: controller.getStyleAt(0),
+ image: controller.getImageAt(0),
+ }
+ do_print(`First match is "${result.value}", "${result.comment}"`);
+ Assert.ok(_check_autocomplete_matches(matches[0], result), "first item is correct");
+ do_print("Checking rest of the matches");
+ }
+
+ for (let i = firstIndexToCheck; i < controller.matchCount; i++) {
+ let result = {
+ value: controller.getValueAt(i),
+ comment: controller.getCommentAt(i),
+ style: controller.getStyleAt(i),
+ image: controller.getImageAt(i),
+ }
+ do_print(`Looking for "${result.value}", "${result.comment}" in expected results...`);
+ let lowerBound = test.checkSorting ? i : firstIndexToCheck;
+ let upperBound = test.checkSorting ? i + 1 : matches.length;
+ let found = false;
+ for (let j = lowerBound; j < upperBound; ++j) {
+ // Skip processed expected results
+ if (matches[j] == undefined)
+ continue;
+ if (_check_autocomplete_matches(matches[j], result)) {
+ do_print("Got a match at index " + j + "!");
+ // Make it undefined so we don't process it again
+ matches[j] = undefined;
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ do_throw(`Didn't find the current result ("${result.value}", "${result.comment}") in matches`); // ' (Emacs syntax highlighting fix)
+ }
+ }
+
+ Assert.equal(controller.matchCount, matches.length,
+ "Got as many results as expected");
+
+ // If we expect results, make sure we got matches.
+ do_check_eq(controller.searchStatus, matches.length ?
+ Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH :
+ Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH);
+ }
+
+ if (test.autofilled) {
+ // Check the autoFilled result.
+ Assert.equal(input.textValue, test.autofilled,
+ "Autofilled value is correct");
+
+ // Now force completion and check correct casing of the result.
+ // This ensures the controller is able to do its magic case-preserving
+ // stuff and correct replacement of the user's casing with result's one.
+ controller.handleEnter(false);
+ Assert.equal(input.textValue, test.completed,
+ "Completed value is correct");
+ }
+}
+
+var addBookmark = Task.async(function* (aBookmarkObj) {
+ Assert.ok(!!aBookmarkObj.uri, "Bookmark object contains an uri");
+ let parentId = aBookmarkObj.parentId ? aBookmarkObj.parentId
+ : PlacesUtils.unfiledBookmarksFolderId;
+
+ let bm = yield PlacesUtils.bookmarks.insert({
+ parentGuid: (yield PlacesUtils.promiseItemGuid(parentId)),
+ title: aBookmarkObj.title || "A bookmark",
+ url: aBookmarkObj.uri
+ });
+ yield PlacesUtils.promiseItemId(bm.guid);
+
+ if (aBookmarkObj.keyword) {
+ yield PlacesUtils.keywords.insert({ keyword: aBookmarkObj.keyword,
+ url: aBookmarkObj.uri.spec,
+ postData: aBookmarkObj.postData
+ });
+ }
+
+ if (aBookmarkObj.tags) {
+ PlacesUtils.tagging.tagURI(aBookmarkObj.uri, aBookmarkObj.tags);
+ }
+});
+
+function addOpenPages(aUri, aCount=1, aUserContextId=0) {
+ let ac = Cc["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"]
+ .getService(Ci.mozIPlacesAutoComplete);
+ for (let i = 0; i < aCount; i++) {
+ ac.registerOpenPage(aUri, aUserContextId);
+ }
+}
+
+function removeOpenPages(aUri, aCount=1, aUserContextId=0) {
+ let ac = Cc["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"]
+ .getService(Ci.mozIPlacesAutoComplete);
+ for (let i = 0; i < aCount; i++) {
+ ac.unregisterOpenPage(aUri, aUserContextId);
+ }
+}
+
+function changeRestrict(aType, aChar) {
+ let branch = "browser.urlbar.";
+ // "title" and "url" are different from everything else, so special case them.
+ if (aType == "title" || aType == "url")
+ branch += "match.";
+ else
+ branch += "restrict.";
+
+ do_print("changing restrict for " + aType + " to '" + aChar + "'");
+ Services.prefs.setCharPref(branch + aType, aChar);
+}
+
+function resetRestrict(aType) {
+ let branch = "browser.urlbar.";
+ // "title" and "url" are different from everything else, so special case them.
+ if (aType == "title" || aType == "url")
+ branch += "match.";
+ else
+ branch += "restrict.";
+
+ Services.prefs.clearUserPref(branch + aType);
+}
+
+/**
+ * Strip prefixes from the URI that we don't care about for searching.
+ *
+ * @param spec
+ * The text to modify.
+ * @return the modified spec.
+ */
+function stripPrefix(spec)
+{
+ ["http://", "https://", "ftp://"].some(scheme => {
+ if (spec.startsWith(scheme)) {
+ spec = spec.slice(scheme.length);
+ return true;
+ }
+ return false;
+ });
+
+ if (spec.startsWith("www.")) {
+ spec = spec.slice(4);
+ }
+ return spec;
+}
+
+function makeActionURI(action, params) {
+ let encodedParams = {};
+ for (let key in params) {
+ encodedParams[key] = encodeURIComponent(params[key]);
+ }
+ let url = "moz-action:" + action + "," + JSON.stringify(encodedParams);
+ return NetUtil.newURI(url);
+}
+
+// Creates a full "match" entry for a search result, suitable for passing as
+// an entry to check_autocomplete.
+function makeSearchMatch(input, extra = {}) {
+ // Note that counter-intuitively, the order the object properties are defined
+ // in the object passed to makeActionURI is important for check_autocomplete
+ // to match them :(
+ let params = {
+ engineName: extra.engineName || "MozSearch",
+ input,
+ searchQuery: "searchQuery" in extra ? extra.searchQuery : input,
+ };
+ if ("alias" in extra) {
+ // May be undefined, which is expected, but in that case make sure it's not
+ // included in the params of the moz-action URL.
+ params.alias = extra.alias;
+ }
+ let style = [ "action", "searchengine" ];
+ if (Array.isArray(extra.style)) {
+ style.push(...extra.style);
+ }
+ if (extra.heuristic) {
+ style.push("heuristic");
+ }
+ return {
+ uri: makeActionURI("searchengine", params),
+ title: params.engineName,
+ style,
+ }
+}
+
+// Creates a full "match" entry for a search result, suitable for passing as
+// an entry to check_autocomplete.
+function makeVisitMatch(input, url, extra = {}) {
+ // Note that counter-intuitively, the order the object properties are defined
+ // in the object passed to makeActionURI is important for check_autocomplete
+ // to match them :(
+ let params = {
+ url,
+ input,
+ }
+ let style = [ "action", "visiturl" ];
+ if (extra.heuristic) {
+ style.push("heuristic");
+ }
+ return {
+ uri: makeActionURI("visiturl", params),
+ title: extra.title || url,
+ style,
+ }
+}
+
+function makeSwitchToTabMatch(url, extra = {}) {
+ return {
+ uri: makeActionURI("switchtab", {url}),
+ title: extra.title || url,
+ style: [ "action", "switchtab" ],
+ }
+}
+
+function makeExtensionMatch(extra = {}) {
+ let style = [ "action", "extension" ];
+ if (extra.heuristic) {
+ style.push("heuristic");
+ }
+
+ return {
+ uri: makeActionURI("extension", {
+ content: extra.content,
+ keyword: extra.keyword,
+ }),
+ title: extra.description,
+ style,
+ };
+}
+
+function setFaviconForHref(href, iconHref) {
+ return new Promise(resolve => {
+ PlacesUtils.favicons.setAndFetchFaviconForPage(
+ NetUtil.newURI(href),
+ NetUtil.newURI(iconHref),
+ true,
+ PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
+ resolve,
+ Services.scriptSecurityManager.getSystemPrincipal()
+ );
+ });
+}
+
+function makeTestServer(port=-1) {
+ let httpServer = new HttpServer();
+ httpServer.start(port);
+ do_register_cleanup(() => httpServer.stop(() => {}));
+ return httpServer;
+}
+
+function* addTestEngine(basename, httpServer=undefined) {
+ httpServer = httpServer || makeTestServer();
+ httpServer.registerDirectory("/", do_get_cwd());
+ let dataUrl =
+ "http://localhost:" + httpServer.identity.primaryPort + "/data/";
+
+ do_print("Adding engine: " + basename);
+ return yield new Promise(resolve => {
+ Services.obs.addObserver(function obs(subject, topic, data) {
+ let engine = subject.QueryInterface(Ci.nsISearchEngine);
+ do_print("Observed " + data + " for " + engine.name);
+ if (data != "engine-added" || engine.name != basename) {
+ return;
+ }
+
+ Services.obs.removeObserver(obs, "browser-search-engine-modified");
+ do_register_cleanup(() => Services.search.removeEngine(engine));
+ resolve(engine);
+ }, "browser-search-engine-modified", false);
+
+ do_print("Adding engine from URL: " + dataUrl + basename);
+ Services.search.addEngine(dataUrl + basename, null, null, false);
+ });
+}
+
+// Ensure we have a default search engine and the keyword.enabled preference
+// set.
+add_task(function* ensure_search_engine() {
+ // keyword.enabled is necessary for the tests to see keyword searches.
+ Services.prefs.setBoolPref("keyword.enabled", true);
+
+ // Initialize the search service, but first set this geo IP pref to a dummy
+ // string. When the search service is initialized, it contacts the URI named
+ // in this pref, which breaks the test since outside connections aren't
+ // allowed.
+ let geoPref = "browser.search.geoip.url";
+ Services.prefs.setCharPref(geoPref, "");
+ do_register_cleanup(() => Services.prefs.clearUserPref(geoPref));
+ yield new Promise(resolve => {
+ Services.search.init(resolve);
+ });
+
+ // Remove any existing engines before adding ours.
+ for (let engine of Services.search.getEngines()) {
+ Services.search.removeEngine(engine);
+ }
+ Services.search.addEngineWithDetails("MozSearch", "", "", "", "GET",
+ "http://s.example.com/search");
+ let engine = Services.search.getEngineByName("MozSearch");
+ Services.search.currentEngine = engine;
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_416211.js b/toolkit/components/places/tests/unifiedcomplete/test_416211.js
new file mode 100644
index 000000000..e02906ddc
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_416211.js
@@ -0,0 +1,22 @@
+/* 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/. */
+
+/*
+ * Test bug 416211 to make sure results that match the tag show the bookmark
+ * title instead of the page title.
+ */
+
+add_task(function* test_tag_match_has_bookmark_title() {
+ do_print("Make sure the tag match gives the bookmark title");
+ let uri = NetUtil.newURI("http://theuri/");
+ yield PlacesTestUtils.addVisits({ uri: uri, title: "Page title" });
+ yield addBookmark({ uri: uri,
+ title: "Bookmark title",
+ tags: [ "superTag" ]});
+ yield check_autocomplete({
+ search: "superTag",
+ matches: [ { uri: uri, title: "Bookmark title", tags: [ "superTag" ], style: [ "bookmark-tag" ] } ]
+ });
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_416214.js b/toolkit/components/places/tests/unifiedcomplete/test_416214.js
new file mode 100644
index 000000000..a30b3fe74
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_416214.js
@@ -0,0 +1,39 @@
+/* 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/. */
+
+/*
+ * Test autocomplete for non-English URLs that match the tag bug 416214. Also
+ * test bug 417441 by making sure escaped ascii characters like "+" remain
+ * escaped.
+ *
+ * - add a visit for a page with a non-English URL
+ * - add a tag for the page
+ * - search for the tag
+ * - test number of matches (should be exactly one)
+ * - make sure the url is decoded
+ */
+
+add_task(function* test_tag_match_url() {
+ do_print("Make sure tag matches return the right url as well as '+' remain escaped");
+ let uri1 = NetUtil.newURI("http://escaped/ユニコード");
+ let uri2 = NetUtil.newURI("http://asciiescaped/blocking-firefox3%2B");
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "title" },
+ { uri: uri2, title: "title" }
+ ]);
+ yield addBookmark({ uri: uri1,
+ title: "title",
+ tags: [ "superTag" ],
+ style: [ "bookmark-tag" ] });
+ yield addBookmark({ uri: uri2,
+ title: "title",
+ tags: [ "superTag" ],
+ style: [ "bookmark-tag" ] });
+ yield check_autocomplete({
+ search: "superTag",
+ matches: [ { uri: uri1, title: "title", tags: [ "superTag" ], style: [ "bookmark-tag" ] },
+ { uri: uri2, title: "title", tags: [ "superTag" ], style: [ "bookmark-tag" ] } ]
+ });
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_417798.js b/toolkit/components/places/tests/unifiedcomplete/test_417798.js
new file mode 100644
index 000000000..bed14b2ce
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_417798.js
@@ -0,0 +1,51 @@
+/* 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/. */
+
+/**
+ * Test for bug 417798 to make sure javascript: URIs don't show up unless the
+ * user searches for javascript: explicitly.
+ */
+
+add_task(function* test_javascript_match() {
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.searchEngines", false);
+
+ let uri1 = NetUtil.newURI("http://abc/def");
+ let uri2 = NetUtil.newURI("javascript:5");
+ yield PlacesTestUtils.addVisits([ { uri: uri1, title: "Title with javascript:" } ]);
+ yield addBookmark({ uri: uri2,
+ title: "Title with javascript:" });
+
+ do_print("Match non-javascript: with plain search");
+ yield check_autocomplete({
+ search: "a",
+ matches: [ { uri: uri1, title: "Title with javascript:" } ]
+ });
+
+ do_print("Match non-javascript: with almost javascript:");
+ yield check_autocomplete({
+ search: "javascript",
+ matches: [ { uri: uri1, title: "Title with javascript:" } ]
+ });
+
+ do_print("Match javascript:");
+ yield check_autocomplete({
+ search: "javascript:",
+ matches: [ { uri: uri1, title: "Title with javascript:" },
+ { uri: uri2, title: "Title with javascript:", style: [ "bookmark" ]} ]
+ });
+
+ do_print("Match nothing with non-first javascript:");
+ yield check_autocomplete({
+ search: "5 javascript:",
+ matches: [ ]
+ });
+
+ do_print("Match javascript: with multi-word search");
+ yield check_autocomplete({
+ search: "javascript: 5",
+ matches: [ { uri: uri2, title: "Title with javascript:", style: [ "bookmark" ]} ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_418257.js b/toolkit/components/places/tests/unifiedcomplete/test_418257.js
new file mode 100644
index 000000000..323c2a7af
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_418257.js
@@ -0,0 +1,67 @@
+/* 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/. */
+
+/**
+ * Test bug 418257 by making sure tags are returned with the title as part of
+ * the "comment" if there are tags even if we didn't match in the tags. They
+ * are separated from the title by a endash.
+ */
+
+add_task(function* test_javascript_match() {
+ let uri1 = NetUtil.newURI("http://page1");
+ let uri2 = NetUtil.newURI("http://page2");
+ let uri3 = NetUtil.newURI("http://page3");
+ let uri4 = NetUtil.newURI("http://page4");
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "tagged" },
+ { uri: uri2, title: "tagged" },
+ { uri: uri3, title: "tagged" },
+ { uri: uri4, title: "tagged" }
+ ]);
+ yield addBookmark({ uri: uri1,
+ title: "tagged",
+ tags: [ "tag1" ] });
+ yield addBookmark({ uri: uri2,
+ title: "tagged",
+ tags: [ "tag1", "tag2" ] });
+ yield addBookmark({ uri: uri3,
+ title: "tagged",
+ tags: [ "tag1", "tag3" ] });
+ yield addBookmark({ uri: uri4,
+ title: "tagged",
+ tags: [ "tag1", "tag2", "tag3" ] });
+
+ do_print("Make sure tags come back in the title when matching tags");
+ yield check_autocomplete({
+ search: "page1 tag",
+ matches: [ { uri: uri1, title: "tagged", tags: [ "tag1" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("Check tags in title for page2");
+ yield check_autocomplete({
+ search: "page2 tag",
+ matches: [ { uri: uri2, title: "tagged", tags: [ "tag1", "tag2" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("Make sure tags appear even when not matching the tag");
+ yield check_autocomplete({
+ search: "page3",
+ matches: [ { uri: uri3, title: "tagged", tags: [ "tag1", "tag3" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("Multiple tags come in commas for page4");
+ yield check_autocomplete({
+ search: "page4",
+ matches: [ { uri: uri4, title: "tagged", tags: [ "tag1", "tag2", "tag3" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("Extra test just to make sure we match the title");
+ yield check_autocomplete({
+ search: "tag2",
+ matches: [ { uri: uri2, title: "tagged", tags: [ "tag1", "tag2" ], style: [ "bookmark-tag" ] },
+ { uri: uri4, title: "tagged", tags: [ "tag1", "tag2", "tag3" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_422277.js b/toolkit/components/places/tests/unifiedcomplete/test_422277.js
new file mode 100644
index 000000000..df6f7601a
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_422277.js
@@ -0,0 +1,19 @@
+/* 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/. */
+
+/**
+ * Test bug 422277 to make sure bad escaped uris don't get escaped. This makes
+ * sure we don't hit an assertion for "not a UTF8 string".
+ */
+
+add_task(function* test_javascript_match() {
+ do_print("Bad escaped uri stays escaped");
+ let uri1 = NetUtil.newURI("http://site/%EAid");
+ yield PlacesTestUtils.addVisits([ { uri: uri1, title: "title" } ]);
+ yield check_autocomplete({
+ search: "site",
+ matches: [ { uri: uri1, title: "title" } ]
+ });
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_autocomplete_functional.js b/toolkit/components/places/tests/unifiedcomplete/test_autocomplete_functional.js
new file mode 100644
index 000000000..cd2dfdb17
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_autocomplete_functional.js
@@ -0,0 +1,171 @@
+/* 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/. */
+
+// Functional tests for inline autocomplete
+
+const PREF_AUTOCOMPLETE_ENABLED = "browser.urlbar.autocomplete.enabled";
+
+add_task(function* test_disabling_autocomplete() {
+ do_print("Check disabling autocomplete disables autofill");
+ Services.prefs.setBoolPref(PREF_AUTOCOMPLETE_ENABLED, false);
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://visit.mozilla.org"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "vis",
+ autofilled: "vis",
+ completed: "vis"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_urls_order() {
+ do_print("Add urls, check for correct order");
+ let places = [{ uri: NetUtil.newURI("http://visit1.mozilla.org") },
+ { uri: NetUtil.newURI("http://visit2.mozilla.org"),
+ transition: TRANSITION_TYPED }];
+ yield PlacesTestUtils.addVisits(places);
+ yield check_autocomplete({
+ search: "vis",
+ autofilled: "visit2.mozilla.org/",
+ completed: "visit2.mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_ignore_prefix() {
+ do_print("Add urls, make sure www and http are ignored");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield PlacesTestUtils.addVisits(NetUtil.newURI("http://www.visit1.mozilla.org"));
+ yield check_autocomplete({
+ search: "visit1",
+ autofilled: "visit1.mozilla.org/",
+ completed: "visit1.mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_after_host() {
+ do_print("Autocompleting after an existing host completes to the url");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield PlacesTestUtils.addVisits(NetUtil.newURI("http://www.visit3.mozilla.org"));
+ yield check_autocomplete({
+ search: "visit3.mozilla.org/",
+ autofilled: "visit3.mozilla.org/",
+ completed: "visit3.mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_respect_www() {
+ do_print("Searching for www.me should yield www.me.mozilla.org/");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield PlacesTestUtils.addVisits(NetUtil.newURI("http://www.me.mozilla.org"));
+ yield check_autocomplete({
+ search: "www.me",
+ autofilled: "www.me.mozilla.org/",
+ completed: "www.me.mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_bookmark_first() {
+ do_print("With a bookmark and history, the query result should be the bookmark");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield addBookmark({ uri: NetUtil.newURI("http://bookmark1.mozilla.org/") });
+ yield PlacesTestUtils.addVisits(NetUtil.newURI("http://bookmark1.mozilla.org/foo"));
+ yield check_autocomplete({
+ search: "bookmark",
+ autofilled: "bookmark1.mozilla.org/",
+ completed: "bookmark1.mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_full_path() {
+ do_print("Check to make sure we get the proper results with full paths");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ let places = [{ uri: NetUtil.newURI("http://smokey.mozilla.org/foo/bar/baz?bacon=delicious") },
+ { uri: NetUtil.newURI("http://smokey.mozilla.org/foo/bar/baz?bacon=smokey") }];
+ yield PlacesTestUtils.addVisits(places);
+ yield check_autocomplete({
+ search: "smokey",
+ autofilled: "smokey.mozilla.org/",
+ completed: "smokey.mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_complete_to_slash() {
+ do_print("Check to make sure we autocomplete to the following '/'");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ let places = [{ uri: NetUtil.newURI("http://smokey.mozilla.org/foo/bar/baz?bacon=delicious") },
+ { uri: NetUtil.newURI("http://smokey.mozilla.org/foo/bar/baz?bacon=smokey") }];
+ yield PlacesTestUtils.addVisits(places);
+ yield check_autocomplete({
+ search: "smokey.mozilla.org/fo",
+ autofilled: "smokey.mozilla.org/foo/",
+ completed: "http://smokey.mozilla.org/foo/",
+ });
+ yield cleanup();
+});
+
+add_task(function* test_complete_to_slash_with_www() {
+ do_print("Check to make sure we autocomplete to the following '/'");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ let places = [{ uri: NetUtil.newURI("http://www.smokey.mozilla.org/foo/bar/baz?bacon=delicious") },
+ { uri: NetUtil.newURI("http://www.smokey.mozilla.org/foo/bar/baz?bacon=smokey") }];
+ yield PlacesTestUtils.addVisits(places);
+ yield check_autocomplete({
+ search: "smokey.mozilla.org/fo",
+ autofilled: "smokey.mozilla.org/foo/",
+ completed: "http://www.smokey.mozilla.org/foo/",
+ });
+ yield cleanup();
+});
+
+add_task(function* test_complete_querystring() {
+ do_print("Check to make sure we autocomplete after ?");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield PlacesTestUtils.addVisits(NetUtil.newURI("http://smokey.mozilla.org/foo?bacon=delicious"));
+ yield check_autocomplete({
+ search: "smokey.mozilla.org/foo?",
+ autofilled: "smokey.mozilla.org/foo?bacon=delicious",
+ completed: "http://smokey.mozilla.org/foo?bacon=delicious",
+ });
+ yield cleanup();
+});
+
+add_task(function* test_complete_fragment() {
+ do_print("Check to make sure we autocomplete after #");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield PlacesTestUtils.addVisits(NetUtil.newURI("http://smokey.mozilla.org/foo?bacon=delicious#bar"));
+ yield check_autocomplete({
+ search: "smokey.mozilla.org/foo?bacon=delicious#bar",
+ autofilled: "smokey.mozilla.org/foo?bacon=delicious#bar",
+ completed: "http://smokey.mozilla.org/foo?bacon=delicious#bar",
+ });
+ yield cleanup();
+});
+
+add_task(function* test_autocomplete_enabled_pref() {
+ Services.prefs.setBoolPref(PREF_AUTOCOMPLETE_ENABLED, false);
+ let types = ["history", "bookmark", "openpage"];
+ for (type of types) {
+ do_check_eq(Services.prefs.getBoolPref("browser.urlbar.suggest." + type), false,
+ "suggest." + type + "pref should be false");
+ }
+ Services.prefs.setBoolPref(PREF_AUTOCOMPLETE_ENABLED, true);
+ for (type of types) {
+ do_check_eq(Services.prefs.getBoolPref("browser.urlbar.suggest." + type), true,
+ "suggest." + type + "pref should be true");
+ }
+
+ // Clear prefs.
+ Services.prefs.clearUserPref(PREF_AUTOCOMPLETE_ENABLED);
+ for (type of types) {
+ Services.prefs.clearUserPref("browser.urlbar.suggest." + type);
+ }
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_autocomplete_on_value_removed_479089.js b/toolkit/components/places/tests/unifiedcomplete/test_autocomplete_on_value_removed_479089.js
new file mode 100644
index 000000000..ecc96266b
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_autocomplete_on_value_removed_479089.js
@@ -0,0 +1,39 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* 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/. */
+
+/*
+ * Need to test that removing a page from autocomplete actually removes a page
+ * Description From Shawn Wilsher :sdwilsh 2009-02-18 11:29:06 PST
+ * We don't test the code path of onValueRemoved
+ * for the autocomplete implementation
+ * Bug 479089
+ */
+
+add_task(function* test_autocomplete_on_value_removed() {
+ let listener = Cc["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"].
+ getService(Components.interfaces.nsIAutoCompleteSimpleResultListener);
+
+ let testUri = NetUtil.newURI("http://foo.mozilla.com/");
+ yield PlacesTestUtils.addVisits({
+ uri: testUri,
+ referrer: uri("http://mozilla.com/")
+ });
+
+ let query = PlacesUtils.history.getNewQuery();
+ let options = PlacesUtils.history.getNewQueryOptions();
+ // look for this uri only
+ query.uri = testUri;
+
+ let root = PlacesUtils.history.executeQuery(query, options).root;
+ root.containerOpen = true;
+ Assert.equal(root.childCount, 1);
+ // call the untested code path
+ listener.onValueRemoved(null, testUri.spec, true);
+ // make sure it is GONE from the DB
+ Assert.equal(root.childCount, 0);
+ // close the container
+ root.containerOpen = false;
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_autofill_default_behavior.js b/toolkit/components/places/tests/unifiedcomplete/test_autofill_default_behavior.js
new file mode 100644
index 000000000..482fcf485
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_autofill_default_behavior.js
@@ -0,0 +1,310 @@
+/* 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/. */
+
+/**
+ * Test autoFill for different default behaviors.
+ */
+
+add_task(function* test_default_behavior_host() {
+ let uri1 = NetUtil.newURI("http://typed/");
+ let uri2 = NetUtil.newURI("http://visited/");
+ let uri3 = NetUtil.newURI("http://bookmarked/");
+ let uri4 = NetUtil.newURI("http://tpbk/");
+ let uri5 = NetUtil.newURI("http://tagged/");
+
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "typed", transition: TRANSITION_TYPED },
+ { uri: uri2, title: "visited" },
+ { uri: uri4, title: "tpbk", transition: TRANSITION_TYPED },
+ ]);
+ yield addBookmark( { uri: uri3, title: "bookmarked" } );
+ yield addBookmark( { uri: uri4, title: "tpbk" } );
+ yield addBookmark( { uri: uri5, title: "title", tags: ["foo"] } );
+
+ yield setFaviconForHref(uri1.spec, "chrome://global/skin/icons/information-16.png");
+ yield setFaviconForHref(uri3.spec, "chrome://global/skin/icons/error-16.png");
+
+ // RESTRICT TO HISTORY.
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history", true);
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history.onlyTyped", false);
+ Services.prefs.setBoolPref("browser.urlbar.suggest.bookmark", false);
+
+ do_print("Restrict history, common visit, should not autoFill");
+ yield check_autocomplete({
+ search: "vi",
+ matches: [ { uri: uri2, title: "visited" } ],
+ autofilled: "vi",
+ completed: "vi"
+ });
+
+ do_print("Restrict history, typed visit, should autoFill");
+ yield check_autocomplete({
+ search: "ty",
+ matches: [ { uri: uri1, title: "typed", style: [ "autofill", "heuristic" ],
+ icon: "chrome://global/skin/icons/information-16.png" } ],
+ autofilled: "typed/",
+ completed: "typed/"
+ });
+
+ // Don't autoFill this one cause it's not typed.
+ do_print("Restrict history, bookmark, should not autoFill");
+ yield check_autocomplete({
+ search: "bo",
+ matches: [ ],
+ autofilled: "bo",
+ completed: "bo"
+ });
+
+ // Note we don't show this one cause it's not typed.
+ do_print("Restrict history, typed bookmark, should autoFill");
+ yield check_autocomplete({
+ search: "tp",
+ matches: [ { uri: uri4, title: "tpbk", style: [ "autofill", "heuristic" ] } ],
+ autofilled: "tpbk/",
+ completed: "tpbk/"
+ });
+
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+
+ // We are not restricting on typed, so we autoFill the bookmark even if we
+ // are restricted to history. We accept that cause not doing that
+ // would be a perf hit and the privacy implications are very weak.
+ do_print("Restrict history, bookmark, autoFill.typed = false, should autoFill");
+ yield check_autocomplete({
+ search: "bo",
+ matches: [ { uri: uri3, title: "bookmarked", style: [ "autofill", "heuristic" ],
+ icon: "chrome://global/skin/icons/error-16.png" } ],
+ autofilled: "bookmarked/",
+ completed: "bookmarked/"
+ });
+
+ do_print("Restrict history, common visit, autoFill.typed = false, should autoFill");
+ yield check_autocomplete({
+ search: "vi",
+ matches: [ { uri: uri2, title: "visited", style: [ "autofill", "heuristic" ] } ],
+ autofilled: "visited/",
+ completed: "visited/"
+ });
+
+ // RESTRICT TO TYPED.
+ // This should basically ignore autoFill.typed and acts as if it would be set.
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history.onlyTyped", true);
+
+ // Typed behavior basically acts like history, but filters on typed.
+ do_print("Restrict typed, common visit, autoFill.typed = false, should not autoFill");
+ yield check_autocomplete({
+ search: "vi",
+ matches: [ ],
+ autofilled: "vi",
+ completed: "vi"
+ });
+
+ do_print("Restrict typed, typed visit, autofill.typed = false, should autoFill");
+ yield check_autocomplete({
+ search: "ty",
+ matches: [ { uri: uri1, title: "typed", style: [ "autofill", "heuristic" ],
+ icon: "chrome://global/skin/icons/information-16.png"} ],
+ autofilled: "typed/",
+ completed: "typed/"
+ });
+
+ do_print("Restrict typed, bookmark, autofill.typed = false, should not autoFill");
+ yield check_autocomplete({
+ search: "bo",
+ matches: [ ],
+ autofilled: "bo",
+ completed: "bo"
+ });
+
+ do_print("Restrict typed, typed bookmark, autofill.typed = false, should autoFill");
+ yield check_autocomplete({
+ search: "tp",
+ matches: [ { uri: uri4, title: "tpbk", style: [ "autofill", "heuristic" ] } ],
+ autofilled: "tpbk/",
+ completed: "tpbk/"
+ });
+
+ // RESTRICT BOOKMARKS.
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history", false);
+ Services.prefs.setBoolPref("browser.urlbar.suggest.bookmark", true);
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", true);
+
+ do_print("Restrict bookmarks, common visit, should not autoFill");
+ yield check_autocomplete({
+ search: "vi",
+ matches: [ ],
+ autofilled: "vi",
+ completed: "vi"
+ });
+
+ do_print("Restrict bookmarks, typed visit, should not autoFill");
+ yield check_autocomplete({
+ search: "ty",
+ matches: [ ],
+ autofilled: "ty",
+ completed: "ty"
+ });
+
+ // Don't autoFill this one cause it's not typed.
+ do_print("Restrict bookmarks, bookmark, should not autoFill");
+ yield check_autocomplete({
+ search: "bo",
+ matches: [ { uri: uri3, title: "bookmarked", style: [ "bookmark" ],
+ icon: "chrome://global/skin/icons/error-16.png"} ],
+ autofilled: "bo",
+ completed: "bo"
+ });
+
+ // Note we don't show this one cause it's not typed.
+ do_print("Restrict bookmarks, typed bookmark, should autoFill");
+ yield check_autocomplete({
+ search: "tp",
+ matches: [ { uri: uri4, title: "tpbk", style: [ "autofill", "heuristic" ] } ],
+ autofilled: "tpbk/",
+ completed: "tpbk/"
+ });
+
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+
+ do_print("Restrict bookmarks, bookmark, autofill.typed = false, should autoFill");
+ yield check_autocomplete({
+ search: "bo",
+ matches: [ { uri: uri3, title: "bookmarked", style: [ "autofill", "heuristic" ],
+ icon: "chrome://global/skin/icons/error-16.png" } ],
+ autofilled: "bookmarked/",
+ completed: "bookmarked/"
+ });
+
+ // Don't autofill because it's a title.
+ do_print("Restrict bookmarks, title, autofill.typed = false, should not autoFill");
+ yield check_autocomplete({
+ search: "# ta",
+ matches: [ ],
+ autofilled: "# ta",
+ completed: "# ta"
+ });
+
+ // Don't autofill because it's a tag.
+ do_print("Restrict bookmarks, tag, autofill.typed = false, should not autoFill");
+ yield check_autocomplete({
+ search: "+ ta",
+ matches: [ { uri: uri5, title: "title", tags: [ "foo" ], style: [ "tag" ] } ],
+ autofilled: "+ ta",
+ completed: "+ ta"
+ });
+
+ yield cleanup();
+});
+
+add_task(function* test_default_behavior_url() {
+ let uri1 = NetUtil.newURI("http://typed/ty/");
+ let uri2 = NetUtil.newURI("http://visited/vi/");
+ let uri3 = NetUtil.newURI("http://bookmarked/bo/");
+ let uri4 = NetUtil.newURI("http://tpbk/tp/");
+
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "typed", transition: TRANSITION_TYPED },
+ { uri: uri2, title: "visited" },
+ { uri: uri4, title: "tpbk", transition: TRANSITION_TYPED },
+ ]);
+ yield addBookmark( { uri: uri3, title: "bookmarked" } );
+ yield addBookmark( { uri: uri4, title: "tpbk" } );
+
+ yield setFaviconForHref(uri1.spec, "chrome://global/skin/icons/information-16.png");
+ yield setFaviconForHref(uri3.spec, "chrome://global/skin/icons/error-16.png");
+
+ // RESTRICT TO HISTORY.
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history", true);
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history.onlyTyped", false);
+ Services.prefs.setBoolPref("browser.urlbar.suggest.bookmark", false);
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", true);
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.searchEngines", false);
+
+ do_print("URL: Restrict history, common visit, should not autoFill");
+ yield check_autocomplete({
+ search: "visited/v",
+ matches: [ { uri: uri2, title: "visited" } ],
+ autofilled: "visited/v",
+ completed: "visited/v"
+ });
+
+ do_print("URL: Restrict history, typed visit, should autoFill");
+ yield check_autocomplete({
+ search: "typed/t",
+ matches: [ { uri: uri1, title: "typed/ty/", style: [ "autofill", "heuristic" ],
+ icon: "chrome://global/skin/icons/information-16.png"} ],
+ autofilled: "typed/ty/",
+ completed: "http://typed/ty/"
+ });
+
+ // Don't autoFill this one cause it's not typed.
+ do_print("URL: Restrict history, bookmark, should not autoFill");
+ yield check_autocomplete({
+ search: "bookmarked/b",
+ matches: [ ],
+ autofilled: "bookmarked/b",
+ completed: "bookmarked/b"
+ });
+
+ // Note we don't show this one cause it's not typed.
+ do_print("URL: Restrict history, typed bookmark, should autoFill");
+ yield check_autocomplete({
+ search: "tpbk/t",
+ matches: [ { uri: uri4, title: "tpbk/tp/", style: [ "autofill", "heuristic" ] } ],
+ autofilled: "tpbk/tp/",
+ completed: "http://tpbk/tp/"
+ });
+
+ // RESTRICT BOOKMARKS.
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history", false);
+ Services.prefs.setBoolPref("browser.urlbar.suggest.bookmark", true);
+
+ do_print("URL: Restrict bookmarks, common visit, should not autoFill");
+ yield check_autocomplete({
+ search: "visited/v",
+ matches: [ ],
+ autofilled: "visited/v",
+ completed: "visited/v"
+ });
+
+ do_print("URL: Restrict bookmarks, typed visit, should not autoFill");
+ yield check_autocomplete({
+ search: "typed/t",
+ matches: [ ],
+ autofilled: "typed/t",
+ completed: "typed/t"
+ });
+
+ // Don't autoFill this one cause it's not typed.
+ do_print("URL: Restrict bookmarks, bookmark, should not autoFill");
+ yield check_autocomplete({
+ search: "bookmarked/b",
+ matches: [ { uri: uri3, title: "bookmarked", style: [ "bookmark" ],
+ icon: "chrome://global/skin/icons/error-16.png" } ],
+ autofilled: "bookmarked/b",
+ completed: "bookmarked/b"
+ });
+
+ // Note we don't show this one cause it's not typed.
+ do_print("URL: Restrict bookmarks, typed bookmark, should autoFill");
+ yield check_autocomplete({
+ search: "tpbk/t",
+ matches: [ { uri: uri4, title: "tpbk/tp/", style: [ "autofill", "heuristic" ] } ],
+ autofilled: "tpbk/tp/",
+ completed: "http://tpbk/tp/"
+ });
+
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+
+ do_print("URL: Restrict bookmarks, bookmark, autofill.typed = false, should autoFill");
+ yield check_autocomplete({
+ search: "bookmarked/b",
+ matches: [ { uri: uri3, title: "bookmarked/bo/", style: [ "autofill", "heuristic" ],
+ icon: "chrome://global/skin/icons/error-16.png" } ],
+ autofilled: "bookmarked/bo/",
+ completed: "http://bookmarked/bo/"
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_avoid_middle_complete.js b/toolkit/components/places/tests/unifiedcomplete/test_avoid_middle_complete.js
new file mode 100644
index 000000000..54fc343ca
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_avoid_middle_complete.js
@@ -0,0 +1,179 @@
+/* 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/. */
+
+add_task(function* test_prefix_space_noautofill() {
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://moz.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+
+ do_print("Should not try to autoFill if search string contains a space");
+ yield check_autocomplete({
+ search: " mo",
+ autofilled: " mo",
+ completed: " mo"
+ });
+
+ yield cleanup();
+});
+
+add_task(function* test_trailing_space_noautofill() {
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://moz.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+
+ do_print("Should not try to autoFill if search string contains a space");
+ yield check_autocomplete({
+ search: "mo ",
+ autofilled: "mo ",
+ completed: "mo "
+ });
+
+ yield cleanup();
+});
+
+add_task(function* test_searchEngine_autofill() {
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.searchEngines", true);
+ Services.search.addEngineWithDetails("CakeSearch", "", "", "",
+ "GET", "http://cake.search/");
+ let engine = Services.search.getEngineByName("CakeSearch");
+ engine.addParam("q", "{searchTerms}", null);
+ do_register_cleanup(() => Services.search.removeEngine(engine));
+
+ do_print("Should autoFill search engine if search string does not contains a space");
+ yield check_autocomplete({
+ search: "ca",
+ autofilled: "cake.search",
+ completed: "http://cake.search"
+ });
+
+ yield cleanup();
+});
+
+add_task(function* test_searchEngine_prefix_space_noautofill() {
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.searchEngines", true);
+ Services.search.addEngineWithDetails("CupcakeSearch", "", "", "",
+ "GET", "http://cupcake.search/");
+ let engine = Services.search.getEngineByName("CupcakeSearch");
+ engine.addParam("q", "{searchTerms}", null);
+ do_register_cleanup(() => Services.search.removeEngine(engine));
+
+ do_print("Should not try to autoFill search engine if search string contains a space");
+ yield check_autocomplete({
+ search: " cu",
+ autofilled: " cu",
+ completed: " cu"
+ });
+
+ yield cleanup();
+});
+
+add_task(function* test_searchEngine_trailing_space_noautofill() {
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.searchEngines", true);
+ Services.search.addEngineWithDetails("BaconSearch", "", "", "",
+ "GET", "http://bacon.search/");
+ let engine = Services.search.getEngineByName("BaconSearch");
+ engine.addParam("q", "{searchTerms}", null);
+ do_register_cleanup(() => Services.search.removeEngine(engine));
+
+ do_print("Should not try to autoFill search engine if search string contains a space");
+ yield check_autocomplete({
+ search: "ba ",
+ autofilled: "ba ",
+ completed: "ba "
+ });
+
+ yield cleanup();
+});
+
+add_task(function* test_searchEngine_www_noautofill() {
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.searchEngines", true);
+ Services.search.addEngineWithDetails("HamSearch", "", "", "",
+ "GET", "http://ham.search/");
+ let engine = Services.search.getEngineByName("HamSearch");
+ engine.addParam("q", "{searchTerms}", null);
+ do_register_cleanup(() => Services.search.removeEngine(engine));
+
+ do_print("Should not autoFill search engine if search string contains www. but engine doesn't");
+ yield check_autocomplete({
+ search: "www.ham",
+ autofilled: "www.ham",
+ completed: "www.ham"
+ });
+
+ yield cleanup();
+});
+
+add_task(function* test_searchEngine_different_scheme_noautofill() {
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.searchEngines", true);
+ Services.search.addEngineWithDetails("PieSearch", "", "", "",
+ "GET", "https://pie.search/");
+ let engine = Services.search.getEngineByName("PieSearch");
+ engine.addParam("q", "{searchTerms}", null);
+ do_register_cleanup(() => Services.search.removeEngine(engine));
+
+ do_print("Should not autoFill search engine if search string has a different scheme.");
+ yield check_autocomplete({
+ search: "http://pie",
+ autofilled: "http://pie",
+ completed: "http://pie"
+ });
+
+ yield cleanup();
+});
+
+add_task(function* test_searchEngine_matching_prefix_autofill() {
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.searchEngines", true);
+ Services.search.addEngineWithDetails("BeanSearch", "", "", "",
+ "GET", "http://www.bean.search/");
+ let engine = Services.search.getEngineByName("BeanSearch");
+ engine.addParam("q", "{searchTerms}", null);
+ do_register_cleanup(() => Services.search.removeEngine(engine));
+
+
+ do_print("Should autoFill search engine if search string has matching prefix.");
+ yield check_autocomplete({
+ search: "http://www.be",
+ autofilled: "http://www.bean.search",
+ completed: "http://www.bean.search"
+ })
+
+ do_print("Should autoFill search engine if search string has www prefix.");
+ yield check_autocomplete({
+ search: "www.be",
+ autofilled: "www.bean.search",
+ completed: "http://www.bean.search"
+ });
+
+ do_print("Should autoFill search engine if search string has matching scheme.");
+ yield check_autocomplete({
+ search: "http://be",
+ autofilled: "http://bean.search",
+ completed: "http://www.bean.search"
+ });
+
+ yield cleanup();
+});
+
+add_task(function* test_prefix_autofill() {
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://moz.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+
+ do_print("Should not try to autoFill in-the-middle if a search is canceled immediately");
+ yield check_autocomplete({
+ incompleteSearch: "moz",
+ search: "mozi",
+ autofilled: "mozilla.org/",
+ completed: "mozilla.org/"
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_avoid_stripping_to_empty_tokens.js b/toolkit/components/places/tests/unifiedcomplete/test_avoid_stripping_to_empty_tokens.js
new file mode 100644
index 000000000..1fcfe1c75
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_avoid_stripping_to_empty_tokens.js
@@ -0,0 +1,41 @@
+/* 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/. */
+
+add_task(function* test_protocol_trimming() {
+ for (let prot of ["http", "https", "ftp"]) {
+ let visit = {
+ // Include the protocol in the query string to ensure we get matches (see bug 1059395)
+ uri: NetUtil.newURI(prot + "://www.mozilla.org/test/?q=" + prot + encodeURIComponent("://") + "www.foo"),
+ title: "Test title",
+ transition: TRANSITION_TYPED
+ };
+ yield PlacesTestUtils.addVisits(visit);
+ let matches = [{uri: visit.uri, title: visit.title}];
+
+ let inputs = [
+ prot + "://",
+ prot + ":// ",
+ prot + ":// mo",
+ prot + "://mo te",
+ prot + "://www.",
+ prot + "://www. ",
+ prot + "://www. mo",
+ prot + "://www.mo te",
+ "www.",
+ "www. ",
+ "www. mo",
+ "www.mo te"
+ ];
+ for (let input of inputs) {
+ do_print("Searching for: " + input);
+ yield check_autocomplete({
+ search: input,
+ matches: matches
+ });
+ }
+
+ yield cleanup();
+ }
+});
+
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_casing.js b/toolkit/components/places/tests/unifiedcomplete/test_casing.js
new file mode 100644
index 000000000..585b51be1
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_casing.js
@@ -0,0 +1,157 @@
+/* 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/. */
+
+add_task(function* test_casing_1() {
+ do_print("Searching for cased entry 1");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "MOZ",
+ autofilled: "MOZilla.org/",
+ completed: "mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_casing_2() {
+ do_print("Searching for cased entry 2");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mozilla.org/T",
+ autofilled: "mozilla.org/T",
+ completed: "mozilla.org/T"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_casing_3() {
+ do_print("Searching for cased entry 3");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/Test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mozilla.org/T",
+ autofilled: "mozilla.org/Test/",
+ completed: "http://mozilla.org/Test/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_casing_4() {
+ do_print("Searching for cased entry 4");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/Test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mOzilla.org/t",
+ autofilled: "mOzilla.org/t",
+ completed: "mOzilla.org/t"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_casing_5() {
+ do_print("Searching for cased entry 5");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/Test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mOzilla.org/T",
+ autofilled: "mOzilla.org/Test/",
+ completed: "http://mozilla.org/Test/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untrimmed_casing() {
+ do_print("Searching for untrimmed cased entry");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/Test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "http://mOz",
+ autofilled: "http://mOzilla.org/",
+ completed: "http://mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untrimmed_www_casing() {
+ do_print("Searching for untrimmed cased entry with www");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://www.mozilla.org/Test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "http://www.mOz",
+ autofilled: "http://www.mOzilla.org/",
+ completed: "http://www.mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untrimmed_path_casing() {
+ do_print("Searching for untrimmed cased entry with path");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/Test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "http://mOzilla.org/t",
+ autofilled: "http://mOzilla.org/t",
+ completed: "http://mOzilla.org/t"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untrimmed_path_casing_2() {
+ do_print("Searching for untrimmed cased entry with path 2");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/Test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "http://mOzilla.org/T",
+ autofilled: "http://mOzilla.org/Test/",
+ completed: "http://mozilla.org/Test/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untrimmed_path_www_casing() {
+ do_print("Searching for untrimmed cased entry with www and path");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://www.mozilla.org/Test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "http://www.mOzilla.org/t",
+ autofilled: "http://www.mOzilla.org/t",
+ completed: "http://www.mOzilla.org/t"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untrimmed_path_www_casing_2() {
+ do_print("Searching for untrimmed cased entry with www and path 2");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://www.mozilla.org/Test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "http://www.mOzilla.org/T",
+ autofilled: "http://www.mOzilla.org/Test/",
+ completed: "http://www.mozilla.org/Test/"
+ });
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_do_not_trim.js b/toolkit/components/places/tests/unifiedcomplete/test_do_not_trim.js
new file mode 100644
index 000000000..014d74998
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_do_not_trim.js
@@ -0,0 +1,91 @@
+/* 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/. */
+
+// Inline should never return matches shorter than the search string, since
+// that largely confuses completeDefaultIndex
+
+add_task(function* test_not_autofill_ws_1() {
+ do_print("Do not autofill whitespaced entry 1");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/link/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mozilla.org ",
+ autofilled: "mozilla.org ",
+ completed: "mozilla.org "
+ });
+ yield cleanup();
+});
+
+add_task(function* test_not_autofill_ws_2() {
+ do_print("Do not autofill whitespaced entry 2");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/link/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mozilla.org/ ",
+ autofilled: "mozilla.org/ ",
+ completed: "mozilla.org/ "
+ });
+ yield cleanup();
+});
+
+add_task(function* test_not_autofill_ws_3() {
+ do_print("Do not autofill whitespaced entry 3");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/link/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mozilla.org/link ",
+ autofilled: "mozilla.org/link ",
+ completed: "mozilla.org/link "
+ });
+ yield cleanup();
+});
+
+add_task(function* test_not_autofill_ws_4() {
+ do_print("Do not autofill whitespaced entry 4");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/link/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mozilla.org/link/ ",
+ autofilled: "mozilla.org/link/ ",
+ completed: "mozilla.org/link/ "
+ });
+ yield cleanup();
+});
+
+
+add_task(function* test_not_autofill_ws_5() {
+ do_print("Do not autofill whitespaced entry 5");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/link/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "moz illa ",
+ autofilled: "moz illa ",
+ completed: "moz illa "
+ });
+ yield cleanup();
+});
+
+add_task(function* test_not_autofill_ws_6() {
+ do_print("Do not autofill whitespaced entry 6");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/link/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: " mozilla",
+ autofilled: " mozilla",
+ completed: " mozilla"
+ });
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_download_embed_bookmarks.js b/toolkit/components/places/tests/unifiedcomplete/test_download_embed_bookmarks.js
new file mode 100644
index 000000000..72661d075
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_download_embed_bookmarks.js
@@ -0,0 +1,71 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * vim:set ts=2 sw=2 sts=2 et:
+ * 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/. */
+
+/**
+ * Tests bug 449406 to ensure that TRANSITION_DOWNLOAD, TRANSITION_EMBED and
+ * TRANSITION_FRAMED_LINK bookmarked uri's show up in the location bar.
+ */
+
+add_task(function* test_download_embed_bookmarks() {
+ let uri1 = NetUtil.newURI("http://download/bookmarked");
+ let uri2 = NetUtil.newURI("http://embed/bookmarked");
+ let uri3 = NetUtil.newURI("http://framed/bookmarked");
+ let uri4 = NetUtil.newURI("http://download");
+ let uri5 = NetUtil.newURI("http://embed");
+ let uri6 = NetUtil.newURI("http://framed");
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "download-bookmark", transition: TRANSITION_DOWNLOAD },
+ { uri: uri2, title: "embed-bookmark", transition: TRANSITION_EMBED },
+ { uri: uri3, title: "framed-bookmark", transition: TRANSITION_FRAMED_LINK},
+ { uri: uri4, title: "download2", transition: TRANSITION_DOWNLOAD },
+ { uri: uri5, title: "embed2", transition: TRANSITION_EMBED },
+ { uri: uri6, title: "framed2", transition: TRANSITION_FRAMED_LINK }
+ ]);
+ yield addBookmark({ uri: uri1,
+ title: "download-bookmark" });
+ yield addBookmark({ uri: uri2,
+ title: "embed-bookmark" });
+ yield addBookmark({ uri: uri3,
+ title: "framed-bookmark" });
+
+ do_print("Searching for bookmarked download uri matches");
+ yield check_autocomplete({
+ search: "download-bookmark",
+ matches: [ { uri: uri1, title: "download-bookmark", style: [ "bookmark" ] } ]
+ });
+
+ do_print("Searching for bookmarked embed uri matches");
+ yield check_autocomplete({
+ search: "embed-bookmark",
+ matches: [ { uri: uri2, title: "embed-bookmark", style: [ "bookmark" ] } ]
+ });
+
+ do_print("Searching for bookmarked framed uri matches");
+ yield check_autocomplete({
+ search: "framed-bookmark",
+ matches: [ { uri: uri3, title: "framed-bookmark", style: [ "bookmark" ] } ]
+ });
+
+ do_print("Searching for download uri does not match");
+ yield check_autocomplete({
+ search: "download2",
+ matches: [ ]
+ });
+
+ do_print("Searching for embed uri does not match");
+ yield check_autocomplete({
+ search: "embed2",
+ matches: [ ]
+ });
+
+ do_print("Searching for framed uri does not match");
+ yield check_autocomplete({
+ search: "framed2",
+ matches: [ ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_dupe_urls.js b/toolkit/components/places/tests/unifiedcomplete/test_dupe_urls.js
new file mode 100644
index 000000000..a39c15236
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_dupe_urls.js
@@ -0,0 +1,23 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Ensure inline autocomplete doesn't return zero frecency pages.
+
+add_task(function* test_dupe_urls() {
+ do_print("Searching for urls with dupes should only show one");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/"),
+ transition: TRANSITION_TYPED
+ }, {
+ uri: NetUtil.newURI("http://mozilla.org/?")
+ });
+ yield check_autocomplete({
+ search: "moz",
+ autofilled: "mozilla.org/",
+ completed: "mozilla.org/",
+ matches: [ { uri: NetUtil.newURI("http://mozilla.org/"),
+ title: "mozilla.org",
+ style: [ "autofill", "heuristic" ] } ]
+ });
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_empty_search.js b/toolkit/components/places/tests/unifiedcomplete/test_empty_search.js
new file mode 100644
index 000000000..ef1159705
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_empty_search.js
@@ -0,0 +1,98 @@
+/* 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/. */
+
+/**
+ * Test for bug 426864 that makes sure the empty search (drop down list) only
+ * shows typed pages from history.
+ */
+
+add_task(function* test_javascript_match() {
+ let uri1 = NetUtil.newURI("http://t.foo/0");
+ let uri2 = NetUtil.newURI("http://t.foo/1");
+ let uri3 = NetUtil.newURI("http://t.foo/2");
+ let uri4 = NetUtil.newURI("http://t.foo/3");
+ let uri5 = NetUtil.newURI("http://t.foo/4");
+ let uri6 = NetUtil.newURI("http://t.foo/5");
+ let uri7 = NetUtil.newURI("http://t.foo/6");
+
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "title" },
+ { uri: uri2, title: "title" },
+ { uri: uri3, title: "title", transition: TRANSITION_TYPED},
+ { uri: uri4, title: "title", transition: TRANSITION_TYPED },
+ { uri: uri6, title: "title", transition: TRANSITION_TYPED },
+ { uri: uri7, title: "title" }
+ ]);
+
+ yield addBookmark({ uri: uri2,
+ title: "title" });
+ yield addBookmark({ uri: uri4,
+ title: "title" });
+ yield addBookmark({ uri: uri5,
+ title: "title" });
+ yield addBookmark({ uri: uri6,
+ title: "title" });
+
+ addOpenPages(uri7, 1);
+
+ // Now remove page 6 from history, so it is an unvisited bookmark.
+ PlacesUtils.history.removePage(uri6);
+
+ do_print("Match everything");
+ yield check_autocomplete({
+ search: "foo",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("foo", { heuristic: true }),
+ { uri: uri1, title: "title" },
+ { uri: uri2, title: "title", style: ["bookmark"] },
+ { uri: uri3, title: "title" },
+ { uri: uri4, title: "title", style: ["bookmark"] },
+ { uri: uri5, title: "title", style: ["bookmark"] },
+ { uri: uri6, title: "title", style: ["bookmark"] },
+ makeSwitchToTabMatch("http://t.foo/6", { title: "title" }),
+ ]
+ });
+
+ // Note the next few tests do *not* get a search result as enable-actions
+ // isn't specified.
+ do_print("Match only typed history");
+ yield check_autocomplete({
+ search: "foo ^ ~",
+ matches: [ { uri: uri3, title: "title" },
+ { uri: uri4, title: "title" } ]
+ });
+
+ do_print("Drop-down empty search matches only typed history");
+ yield check_autocomplete({
+ search: "",
+ matches: [ { uri: uri3, title: "title" },
+ { uri: uri4, title: "title" } ]
+ });
+
+ do_print("Drop-down empty search matches only bookmarks");
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history", false);
+ Services.prefs.setBoolPref("browser.urlbar.suggest.bookmark", true);
+ yield check_autocomplete({
+ search: "",
+ matches: [ { uri: uri2, title: "title", style: ["bookmark"] },
+ { uri: uri4, title: "title", style: ["bookmark"] },
+ { uri: uri5, title: "title", style: ["bookmark"] },
+ { uri: uri6, title: "title", style: ["bookmark"] } ]
+ });
+
+ do_print("Drop-down empty search matches only open tabs");
+ Services.prefs.setBoolPref("browser.urlbar.suggest.bookmark", false);
+ yield check_autocomplete({
+ search: "",
+ searchParam: "enable-actions",
+ matches: [
+ makeSwitchToTabMatch("http://t.foo/6", { title: "title" }),
+ ]
+ });
+
+ Services.prefs.clearUserPref("browser.urlbar.suggest.history");
+ Services.prefs.clearUserPref("browser.urlbar.suggest.bookmark");
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_enabled.js b/toolkit/components/places/tests/unifiedcomplete/test_enabled.js
new file mode 100644
index 000000000..dee8df8ec
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_enabled.js
@@ -0,0 +1,68 @@
+add_task(function* test_enabled() {
+ // Test for bug 471903 to make sure searching in autocomplete can be turned on
+ // and off. Also test bug 463535 for pref changing search.
+ let uri = NetUtil.newURI("http://url/0");
+ yield PlacesTestUtils.addVisits([ { uri: uri, title: "title" } ]);
+
+ do_print("plain search");
+ yield check_autocomplete({
+ search: "url",
+ matches: [ { uri: uri, title: "title" } ]
+ });
+
+ do_print("search disabled");
+ Services.prefs.setBoolPref("browser.urlbar.autocomplete.enabled", false);
+ yield check_autocomplete({
+ search: "url",
+ matches: [ ]
+ });
+
+ do_print("resume normal search");
+ Services.prefs.setBoolPref("browser.urlbar.autocomplete.enabled", true);
+ yield check_autocomplete({
+ search: "url",
+ matches: [ { uri: uri, title: "title" } ]
+ });
+
+ yield cleanup();
+});
+
+add_task(function* test_sync_enabled() {
+ // Initialize unified complete.
+ Cc["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"]
+ .getService(Ci.mozIPlacesAutoComplete);
+
+ let types = [ "history", "bookmark", "openpage", "searches" ];
+
+ // Test the service keeps browser.urlbar.autocomplete.enabled synchronized
+ // with browser.urlbar.suggest prefs.
+ for (let type of types) {
+ Services.prefs.setBoolPref("browser.urlbar.suggest." + type, true);
+ }
+ Assert.equal(Services.prefs.getBoolPref("browser.urlbar.autocomplete.enabled"), true);
+
+ // Disable autocomplete and check all the suggest prefs are set to false.
+ Services.prefs.setBoolPref("browser.urlbar.autocomplete.enabled", false);
+ for (let type of types) {
+ Assert.equal(Services.prefs.getBoolPref("browser.urlbar.suggest." + type), false);
+ }
+
+ // Setting even a single suggest pref to true should enable autocomplete.
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history", true);
+ for (let type of types.filter(t => t != "history")) {
+ Assert.equal(Services.prefs.getBoolPref("browser.urlbar.suggest." + type), false);
+ }
+ Assert.equal(Services.prefs.getBoolPref("browser.urlbar.autocomplete.enabled"), true);
+
+ // Disable autocoplete again, then re-enable it and check suggest prefs
+ // have been reset.
+ Services.prefs.setBoolPref("browser.urlbar.autocomplete.enabled", false);
+ Services.prefs.setBoolPref("browser.urlbar.autocomplete.enabled", true);
+ for (let type of types.filter(t => t != "history")) {
+ if (type == "searches") {
+ Assert.equal(Services.prefs.getBoolPref("browser.urlbar.suggest." + type), false);
+ } else {
+ Assert.equal(Services.prefs.getBoolPref("browser.urlbar.suggest." + type), true);
+ }
+ }
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_escape_self.js b/toolkit/components/places/tests/unifiedcomplete/test_escape_self.js
new file mode 100644
index 000000000..ff6e5f929
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_escape_self.js
@@ -0,0 +1,31 @@
+/* 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/. */
+
+/**
+ * Test bug 422698 to make sure searches with urls from the location bar
+ * correctly match itself when it contains escaped characters.
+ */
+
+add_task(function* test_escape() {
+ let uri1 = NetUtil.newURI("http://unescapeduri/");
+ let uri2 = NetUtil.newURI("http://escapeduri/%40/");
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "title" },
+ { uri: uri2, title: "title" }
+ ]);
+
+ do_print("Unescaped location matches itself");
+ yield check_autocomplete({
+ search: "http://unescapeduri/",
+ matches: [ { uri: uri1, title: "title" } ]
+ });
+
+ do_print("Escaped location matches itself");
+ yield check_autocomplete({
+ search: "http://escapeduri/%40/",
+ matches: [ { uri: uri2, title: "title" } ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_extension_matches.js b/toolkit/components/places/tests/unifiedcomplete/test_extension_matches.js
new file mode 100644
index 000000000..76af20558
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_extension_matches.js
@@ -0,0 +1,384 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * vim:set ts=2 sw=2 sts=2 et:
+ * 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/. */
+
+Cu.import("resource://gre/modules/ExtensionSearchHandler.jsm");
+
+let controller = Cc["@mozilla.org/autocomplete/controller;1"].getService(Ci.nsIAutoCompleteController);
+
+add_task(function* test_correct_errors_are_thrown() {
+ let keyword = "foo";
+ let anotherKeyword = "bar";
+ let unregisteredKeyword = "baz";
+
+ // Register a keyword.
+ ExtensionSearchHandler.registerKeyword(keyword, { emit: () => {} });
+
+ // Try registering the keyword again.
+ Assert.throws(() => ExtensionSearchHandler.registerKeyword(keyword, { emit: () => {} }));
+
+ // Register a different keyword.
+ ExtensionSearchHandler.registerKeyword(anotherKeyword, { emit: () => {} });
+
+ // Try calling handleSearch for an unregistered keyword.
+ Assert.throws(() => ExtensionSearchHandler.handleSearch(unregisteredKeyword, `${unregisteredKeyword} `, () => {}));
+
+ // Try calling handleSearch without a callback.
+ Assert.throws(() => ExtensionSearchHandler.handleSearch(unregisteredKeyword, `${unregisteredKeyword} `));
+
+ // Try getting the description for a keyword which isn't registered.
+ Assert.throws(() => ExtensionSearchHandler.getDescription(unregisteredKeyword));
+
+ // Try getting the extension name for a keyword which isn't registered.
+ Assert.throws(() => ExtensionSearchHandler.getExtensionName(unregisteredKeyword));
+
+ // Try setting the default suggestion for a keyword which isn't registered.
+ Assert.throws(() => ExtensionSearchHandler.setDefaultSuggestion(unregisteredKeyword, "suggestion"));
+
+ // Try calling handleInputCancelled when there is no active input session.
+ Assert.throws(() => ExtensionSearchHandler.handleInputCancelled());
+
+ // Try calling handleInputEntered when there is no active input session.
+ Assert.throws(() => ExtensionSearchHandler.handleInputEntered(anotherKeyword, `${anotherKeyword} test`, "tab"));
+
+ // Start a session by calling handleSearch with the registered keyword.
+ ExtensionSearchHandler.handleSearch(keyword, `${keyword} test`, () => {});
+
+ // Try providing suggestions for an unregistered keyword.
+ Assert.throws(() => ExtensionSearchHandler.addSuggestions(unregisteredKeyword, 0, []));
+
+ // Try providing suggestions for an inactive keyword.
+ Assert.throws(() => ExtensionSearchHandler.addSuggestions(anotherKeyword, 0, []));
+
+ // Try calling handleSearch for an inactive keyword.
+ Assert.throws(() => ExtensionSearchHandler.handleSearch(anotherKeyword, `${anotherKeyword} `, () => {}));
+
+ // Try calling addSuggestions with an old callback ID.
+ Assert.throws(() => ExtensionSearchHandler.addSuggestions(keyword, 0, []));
+
+ // Add suggestions with a valid callback ID.
+ ExtensionSearchHandler.addSuggestions(keyword, 1, []);
+
+ // Add suggestions again with a valid callback ID.
+ ExtensionSearchHandler.addSuggestions(keyword, 1, []);
+
+ // Try calling addSuggestions with a future callback ID.
+ Assert.throws(() => ExtensionSearchHandler.addSuggestions(keyword, 2, []));
+
+ // End the input session by calling handleInputCancelled.
+ ExtensionSearchHandler.handleInputCancelled();
+
+ // Try calling handleInputCancelled after the session has ended.
+ Assert.throws(() => ExtensionSearchHandler.handleInputCancelled());
+
+ // Try calling handleSearch that doesn't have a space after the keyword.
+ Assert.throws(() => ExtensionSearchHandler.handleSearch(anotherKeyword, `${anotherKeyword}`, () => {}));
+
+ // Try calling handleSearch with text starting with the wrong keyword.
+ Assert.throws(() => ExtensionSearchHandler.handleSearch(anotherKeyword, `${keyword} test`, () => {}));
+
+ // Start a new session by calling handleSearch with a different keyword
+ ExtensionSearchHandler.handleSearch(anotherKeyword, `${anotherKeyword} test`, () => {});
+
+ // Try adding suggestions again with the same callback ID now that the input session has ended.
+ Assert.throws(() => ExtensionSearchHandler.addSuggestions(keyword, 1, []));
+
+ // Add suggestions with a valid callback ID.
+ ExtensionSearchHandler.addSuggestions(anotherKeyword, 2, []);
+
+ // Try adding suggestions with a valid callback ID but a different keyword.
+ Assert.throws(() => ExtensionSearchHandler.addSuggestions(keyword, 2, []));
+
+ // Try adding suggestions with a valid callback ID but an unregistered keyword.
+ Assert.throws(() => ExtensionSearchHandler.addSuggestions(unregisteredKeyword, 2, []));
+
+ // Set the default suggestion.
+ ExtensionSearchHandler.setDefaultSuggestion(anotherKeyword, {description: "test result"});
+
+ // Try ending the session using handleInputEntered with a different keyword.
+ Assert.throws(() => ExtensionSearchHandler.handleInputEntered(keyword, `${keyword} test`, "tab"));
+
+ // Try calling handleInputEntered with invalid text.
+ Assert.throws(() => ExtensionSearchHandler.handleInputEntered(anotherKeyword, ` test`, "tab"));
+
+ // Try calling handleInputEntered with an invalid disposition.
+ Assert.throws(() => ExtensionSearchHandler.handleInputEntered(anotherKeyword, `${anotherKeyword} test`, "invalid"));
+
+ // End the session by calling handleInputEntered.
+ ExtensionSearchHandler.handleInputEntered(anotherKeyword, `${anotherKeyword} test`, "tab");
+
+ // Try calling handleInputEntered after the session has ended.
+ Assert.throws(() => ExtensionSearchHandler.handleInputEntered(anotherKeyword, `${anotherKeyword} test`, "tab"));
+
+ // Unregister the keyword.
+ ExtensionSearchHandler.unregisterKeyword(keyword);
+
+ // Try setting the default suggestion for the unregistered keyword.
+ Assert.throws(() => ExtensionSearchHandler.setDefaultSuggestion(keyword, {description: "test"}));
+
+ // Try handling a search with the unregistered keyword.
+ Assert.throws(() => ExtensionSearchHandler.handleSearch(keyword, `${keyword} test`, () => {}));
+
+ // Try unregistering the keyword again.
+ Assert.throws(() => ExtensionSearchHandler.unregisterKeyword(keyword));
+
+ // Unregister the other keyword.
+ ExtensionSearchHandler.unregisterKeyword(anotherKeyword);
+
+ // Try unregistering the word which was never registered.
+ Assert.throws(() => ExtensionSearchHandler.unregisterKeyword(unregisteredKeyword));
+
+ // Try setting the default suggestion for a word that was never registered.
+ Assert.throws(() => ExtensionSearchHandler.setDefaultSuggestion(unregisteredKeyword, {description: "test"}));
+
+ yield cleanup();
+});
+
+add_task(function* test_correct_events_are_emitted() {
+ let events = [];
+ function checkEvents(expectedEvents) {
+ Assert.equal(events.length, expectedEvents.length, "The correct number of events fired");
+ expectedEvents.forEach((e, i) => Assert.equal(e, events[i], `Expected "${e}" event to fire`));
+ events = [];
+ }
+
+ let mockExtension = { emit: message => events.push(message) };
+
+ let keyword = "foo";
+ let anotherKeyword = "bar";
+
+ ExtensionSearchHandler.registerKeyword(keyword, mockExtension);
+ ExtensionSearchHandler.registerKeyword(anotherKeyword, mockExtension);
+
+ ExtensionSearchHandler.handleSearch(keyword, `${keyword} `, () => {});
+ checkEvents([ExtensionSearchHandler.MSG_INPUT_STARTED]);
+
+ ExtensionSearchHandler.handleSearch(keyword, `${keyword} f`, () => {});
+ checkEvents([ExtensionSearchHandler.MSG_INPUT_CHANGED]);
+
+ ExtensionSearchHandler.handleInputEntered(keyword, `${keyword} f`, "tab");
+ checkEvents([ExtensionSearchHandler.MSG_INPUT_ENTERED]);
+
+ ExtensionSearchHandler.handleSearch(keyword, `${keyword} f`, () => {});
+ checkEvents([
+ ExtensionSearchHandler.MSG_INPUT_STARTED,
+ ExtensionSearchHandler.MSG_INPUT_CHANGED
+ ]);
+
+ ExtensionSearchHandler.handleInputCancelled();
+ checkEvents([ExtensionSearchHandler.MSG_INPUT_CANCELLED]);
+
+ ExtensionSearchHandler.handleSearch(anotherKeyword, `${anotherKeyword} baz`, () => {});
+ checkEvents([
+ ExtensionSearchHandler.MSG_INPUT_STARTED,
+ ExtensionSearchHandler.MSG_INPUT_CHANGED
+ ]);
+
+ ExtensionSearchHandler.handleInputEntered(anotherKeyword, `${anotherKeyword} baz`, "tab");
+ checkEvents([ExtensionSearchHandler.MSG_INPUT_ENTERED]);
+
+ ExtensionSearchHandler.unregisterKeyword(keyword);
+});
+
+add_task(function* test_removes_suggestion_if_its_content_is_typed_in() {
+ let keyword = "test";
+ let extensionName = "Foo Bar";
+
+ let mockExtension = {
+ name: extensionName,
+ emit(message, text, id) {
+ if (message === ExtensionSearchHandler.MSG_INPUT_CHANGED) {
+ ExtensionSearchHandler.addSuggestions(keyword, id, [
+ {content: "foo", description: "first suggestion"},
+ {content: "bar", description: "second suggestion"},
+ {content: "baz", description: "third suggestion"},
+ ]);
+ controller.stopSearch();
+ }
+ }
+ };
+
+ ExtensionSearchHandler.registerKeyword(keyword, mockExtension);
+
+ yield check_autocomplete({
+ search: `${keyword} unmatched`,
+ searchParam: "enable-actions",
+ matches: [
+ makeExtensionMatch({heuristic: true, keyword, description: extensionName, content: `${keyword} unmatched`}),
+ makeExtensionMatch({keyword, content: `${keyword} foo`, description: "first suggestion"}),
+ makeExtensionMatch({keyword, content: `${keyword} bar`, description: "second suggestion"}),
+ makeExtensionMatch({keyword, content: `${keyword} baz`, description: "third suggestion"})
+ ]
+ });
+
+ yield check_autocomplete({
+ search: `${keyword} foo`,
+ searchParam: "enable-actions",
+ matches: [
+ makeExtensionMatch({heuristic: true, keyword, description: extensionName, content: `${keyword} foo`}),
+ makeExtensionMatch({keyword, content: `${keyword} bar`, description: "second suggestion"}),
+ makeExtensionMatch({keyword, content: `${keyword} baz`, description: "third suggestion"})
+ ]
+ });
+
+ yield check_autocomplete({
+ search: `${keyword} bar`,
+ searchParam: "enable-actions",
+ matches: [
+ makeExtensionMatch({heuristic: true, keyword, description: extensionName, content: `${keyword} bar`}),
+ makeExtensionMatch({keyword, content: `${keyword} foo`, description: "first suggestion"}),
+ makeExtensionMatch({keyword, content: `${keyword} baz`, description: "third suggestion"})
+ ]
+ });
+
+ yield check_autocomplete({
+ search: `${keyword} baz`,
+ searchParam: "enable-actions",
+ matches: [
+ makeExtensionMatch({heuristic: true, keyword, description: extensionName, content: `${keyword} baz`}),
+ makeExtensionMatch({keyword, content: `${keyword} foo`, description: "first suggestion"}),
+ makeExtensionMatch({keyword, content: `${keyword} bar`, description: "second suggestion"})
+ ]
+ });
+
+ ExtensionSearchHandler.unregisterKeyword(keyword);
+ yield cleanup();
+});
+
+add_task(function* test_extension_results_should_come_first() {
+ let keyword = "test";
+ let extensionName = "Omnibox Example";
+
+ let uri = NetUtil.newURI(`http://a.com/b`);
+ yield PlacesTestUtils.addVisits([
+ { uri, title: `${keyword} -` },
+ ]);
+
+ let mockExtension = {
+ name: extensionName,
+ emit(message, text, id) {
+ if (message === ExtensionSearchHandler.MSG_INPUT_CHANGED) {
+ ExtensionSearchHandler.addSuggestions(keyword, id, [
+ {content: "foo", description: "first suggestion"},
+ {content: "bar", description: "second suggestion"},
+ {content: "baz", description: "third suggestion"},
+ ]);
+ }
+ controller.stopSearch();
+ }
+ };
+
+ ExtensionSearchHandler.registerKeyword(keyword, mockExtension);
+
+ // Start an input session before testing MSG_INPUT_CHANGED.
+ ExtensionSearchHandler.handleSearch(keyword, `${keyword} `, () => {});
+
+ yield check_autocomplete({
+ search: `${keyword} -`,
+ searchParam: "enable-actions",
+ matches: [
+ makeExtensionMatch({heuristic: true, keyword, description: extensionName, content: `${keyword} -`}),
+ makeExtensionMatch({keyword, content: `${keyword} foo`, description: "first suggestion"}),
+ makeExtensionMatch({keyword, content: `${keyword} bar`, description: "second suggestion"}),
+ makeExtensionMatch({keyword, content: `${keyword} baz`, description: "third suggestion"}),
+ { uri, title: `${keyword} -` }
+ ]
+ });
+
+ ExtensionSearchHandler.unregisterKeyword(keyword);
+ yield cleanup();
+});
+
+add_task(function* test_setting_the_default_suggestion() {
+ let keyword = "test";
+ let extensionName = "Omnibox Example";
+
+ let mockExtension = {
+ name: extensionName,
+ emit(message, text, id) {
+ if (message === ExtensionSearchHandler.MSG_INPUT_CHANGED) {
+ ExtensionSearchHandler.addSuggestions(keyword, id, []);
+ }
+ controller.stopSearch();
+ }
+ };
+
+ ExtensionSearchHandler.registerKeyword(keyword, mockExtension);
+
+ ExtensionSearchHandler.setDefaultSuggestion(keyword, {
+ description: "hello world"
+ });
+
+ let searchString = `${keyword} search query`;
+ yield check_autocomplete({
+ search: searchString,
+ searchParam: "enable-actions",
+ matches: [
+ makeExtensionMatch({heuristic: true, keyword, description: "hello world", content: searchString}),
+ ]
+ });
+
+ ExtensionSearchHandler.setDefaultSuggestion(keyword, {
+ description: "foo bar"
+ });
+
+ yield check_autocomplete({
+ search: searchString,
+ searchParam: "enable-actions",
+ matches: [
+ makeExtensionMatch({heuristic: true, keyword, description: "foo bar", content: searchString}),
+ ]
+ });
+
+ ExtensionSearchHandler.unregisterKeyword(keyword);
+ yield cleanup();
+});
+
+add_task(function* test_maximum_number_of_suggestions_is_enforced() {
+ let keyword = "test";
+ let extensionName = "Omnibox Example";
+
+ let mockExtension = {
+ name: extensionName,
+ emit(message, text, id) {
+ if (message === ExtensionSearchHandler.MSG_INPUT_CHANGED) {
+ ExtensionSearchHandler.addSuggestions(keyword, id, [
+ {content: "a", description: "first suggestion"},
+ {content: "b", description: "second suggestion"},
+ {content: "c", description: "third suggestion"},
+ {content: "d", description: "fourth suggestion"},
+ {content: "e", description: "fifth suggestion"},
+ {content: "f", description: "sixth suggestion"},
+ {content: "g", description: "seventh suggestion"},
+ {content: "h", description: "eigth suggestion"},
+ {content: "i", description: "ninth suggestion"},
+ {content: "j", description: "tenth suggestion"},
+ ]);
+ controller.stopSearch();
+ }
+ }
+ };
+
+ ExtensionSearchHandler.registerKeyword(keyword, mockExtension);
+
+ // Start an input session before testing MSG_INPUT_CHANGED.
+ ExtensionSearchHandler.handleSearch(keyword, `${keyword} `, () => {});
+
+ yield check_autocomplete({
+ search: `${keyword} #`,
+ searchParam: "enable-actions",
+ matches: [
+ makeExtensionMatch({heuristic: true, keyword, description: extensionName, content: `${keyword} #`}),
+ makeExtensionMatch({keyword, content: `${keyword} a`, description: "first suggestion"}),
+ makeExtensionMatch({keyword, content: `${keyword} b`, description: "second suggestion"}),
+ makeExtensionMatch({keyword, content: `${keyword} c`, description: "third suggestion"}),
+ makeExtensionMatch({keyword, content: `${keyword} d`, description: "fourth suggestion"}),
+ makeExtensionMatch({keyword, content: `${keyword} e`, description: "fifth suggestion"}),
+ ]
+ });
+
+ ExtensionSearchHandler.unregisterKeyword(keyword);
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_ignore_protocol.js b/toolkit/components/places/tests/unifiedcomplete/test_ignore_protocol.js
new file mode 100644
index 000000000..92e7f601a
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_ignore_protocol.js
@@ -0,0 +1,24 @@
+/* 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/. */
+
+/**
+ * Test bug 424509 to make sure searching for "h" doesn't match "http" of urls.
+ */
+
+add_task(function* test_escape() {
+ let uri1 = NetUtil.newURI("http://site/");
+ let uri2 = NetUtil.newURI("http://happytimes/");
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "title" },
+ { uri: uri2, title: "title" }
+ ]);
+
+ do_print("Searching for h matches site and not http://");
+ yield check_autocomplete({
+ search: "h",
+ matches: [ { uri: uri2, title: "title" } ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_keyword_search.js b/toolkit/components/places/tests/unifiedcomplete/test_keyword_search.js
new file mode 100644
index 000000000..12b7fea77
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_keyword_search.js
@@ -0,0 +1,73 @@
+/* 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/. */
+
+/**
+ * Test for bug 392143 that puts keyword results into the autocomplete. Makes
+ * sure that multiple parameter queries get spaces converted to +, + converted
+ * to %2B, non-ascii become escaped, and pages in history that match the
+ * keyword uses the page's title.
+ *
+ * Also test for bug 249468 by making sure multiple keyword bookmarks with the
+ * same keyword appear in the list.
+ */
+
+add_task(function* test_keyword_searc() {
+ let uri1 = NetUtil.newURI("http://abc/?search=%s");
+ let uri2 = NetUtil.newURI("http://abc/?search=ThisPageIsInHistory");
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "Generic page title" },
+ { uri: uri2, title: "Generic page title" }
+ ]);
+ yield addBookmark({ uri: uri1, title: "Bookmark title", keyword: "key"});
+
+ do_print("Plain keyword query");
+ yield check_autocomplete({
+ search: "key term",
+ matches: [ { uri: NetUtil.newURI("http://abc/?search=term"), title: "abc", style: ["keyword", "heuristic"] } ]
+ });
+
+ do_print("Plain keyword UC");
+ yield check_autocomplete({
+ search: "key TERM",
+ matches: [ { uri: NetUtil.newURI("http://abc/?search=TERM"), title: "abc", style: ["keyword", "heuristic"] } ]
+ });
+
+ do_print("Multi-word keyword query");
+ yield check_autocomplete({
+ search: "key multi word",
+ matches: [ { uri: NetUtil.newURI("http://abc/?search=multi%20word"), title: "abc", style: ["keyword", "heuristic"] } ]
+ });
+
+ do_print("Keyword query with +");
+ yield check_autocomplete({
+ search: "key blocking+",
+ matches: [ { uri: NetUtil.newURI("http://abc/?search=blocking%2B"), title: "abc", style: ["keyword", "heuristic"] } ]
+ });
+
+ do_print("Unescaped term in query");
+ yield check_autocomplete({
+ search: "key ユニコード",
+ matches: [ { uri: NetUtil.newURI("http://abc/?search=ユニコード"), title: "abc", style: ["keyword", "heuristic"] } ]
+ });
+
+ do_print("Keyword that happens to match a page");
+ yield check_autocomplete({
+ search: "key ThisPageIsInHistory",
+ matches: [ { uri: NetUtil.newURI("http://abc/?search=ThisPageIsInHistory"), title: "abc", style: ["keyword", "heuristic"] } ]
+ });
+
+ do_print("Keyword without query (without space)");
+ yield check_autocomplete({
+ search: "key",
+ matches: [ { uri: NetUtil.newURI("http://abc/?search="), title: "abc", style: ["keyword", "heuristic"] } ]
+ });
+
+ do_print("Keyword without query (with space)");
+ yield check_autocomplete({
+ search: "key ",
+ matches: [ { uri: NetUtil.newURI("http://abc/?search="), title: "abc", style: ["keyword", "heuristic"] } ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_keyword_search_actions.js b/toolkit/components/places/tests/unifiedcomplete/test_keyword_search_actions.js
new file mode 100644
index 000000000..61d98f72d
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_keyword_search_actions.js
@@ -0,0 +1,149 @@
+/* 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/. */
+
+/**
+ * Test for bug 392143 that puts keyword results into the autocomplete. Makes
+ * sure that multiple parameter queries get spaces converted to +, + converted
+ * to %2B, non-ascii become escaped, and pages in history that match the
+ * keyword uses the page's title.
+ *
+ * Also test for bug 249468 by making sure multiple keyword bookmarks with the
+ * same keyword appear in the list.
+ */
+
+add_task(function* test_keyword_search() {
+ let uri1 = NetUtil.newURI("http://abc/?search=%s");
+ let uri2 = NetUtil.newURI("http://abc/?search=ThisPageIsInHistory");
+ let uri3 = NetUtil.newURI("http://abc/?search=%s&raw=%S");
+ let uri4 = NetUtil.newURI("http://abc/?search=%s&raw=%S&mozcharset=ISO-8859-1");
+ yield PlacesTestUtils.addVisits([{ uri: uri1 },
+ { uri: uri2 },
+ { uri: uri3 }]);
+ yield addBookmark({ uri: uri1, title: "Keyword", keyword: "key"});
+ yield addBookmark({ uri: uri1, title: "Post", keyword: "post", postData: "post_search=%s"});
+ yield addBookmark({ uri: uri3, title: "Encoded", keyword: "encoded"});
+ yield addBookmark({ uri: uri4, title: "Charset", keyword: "charset"});
+ yield addBookmark({ uri: uri2, title: "Noparam", keyword: "noparam"});
+ yield addBookmark({ uri: uri2, title: "Noparam-Post", keyword: "post_noparam", postData: "noparam=1"});
+
+ do_print("Plain keyword query");
+ yield check_autocomplete({
+ search: "key term",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("keyword", {url: "http://abc/?search=term", input: "key term"}),
+ title: "abc", style: [ "action", "keyword", "heuristic" ] } ]
+ });
+
+ do_print("Plain keyword UC");
+ yield check_autocomplete({
+ search: "key TERM",
+ matches: [ { uri: NetUtil.newURI("http://abc/?search=TERM"),
+ title: "abc", style: ["keyword", "heuristic"] } ]
+ });
+
+ do_print("Multi-word keyword query");
+ yield check_autocomplete({
+ search: "key multi word",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("keyword", {url: "http://abc/?search=multi%20word", input: "key multi word"}),
+ title: "abc", style: [ "action", "keyword", "heuristic" ] } ]
+ });
+
+ do_print("Keyword query with +");
+ yield check_autocomplete({
+ search: "key blocking+",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("keyword", {url: "http://abc/?search=blocking%2B", input: "key blocking+"}),
+ title: "abc", style: [ "action", "keyword", "heuristic" ] } ]
+ });
+
+ do_print("Unescaped term in query");
+ // ... but note that UnifiedComplete calls encodeURIComponent() on the query
+ // string when it builds the URL, so the expected result will have the
+ // ユニコード substring encoded in the URL.
+ yield check_autocomplete({
+ search: "key ユニコード",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("keyword", {url: "http://abc/?search=" + encodeURIComponent("ユニコード"), input: "key ユニコード"}),
+ title: "abc", style: [ "action", "keyword", "heuristic" ] } ]
+ });
+
+ do_print("Keyword that happens to match a page");
+ yield check_autocomplete({
+ search: "key ThisPageIsInHistory",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("keyword", {url: "http://abc/?search=ThisPageIsInHistory", input: "key ThisPageIsInHistory"}),
+ title: "abc", style: [ "action", "keyword", "heuristic" ] } ]
+ });
+
+ do_print("Keyword without query (without space)");
+ yield check_autocomplete({
+ search: "key",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("keyword", {url: "http://abc/?search=", input: "key"}),
+ title: "abc", style: [ "action", "keyword", "heuristic" ] } ]
+ });
+
+ do_print("Keyword without query (with space)");
+ yield check_autocomplete({
+ search: "key ",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("keyword", {url: "http://abc/?search=", input: "key "}),
+ title: "abc", style: [ "action", "keyword", "heuristic" ] } ]
+ });
+
+ do_print("POST Keyword");
+ yield check_autocomplete({
+ search: "post foo",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("keyword", {url: "http://abc/?search=foo", input: "post foo", postData: "post_search=foo"}),
+ title: "abc", style: [ "action", "keyword", "heuristic" ] } ]
+ });
+
+ do_print("Bug 420328: no-param keyword with a param");
+ yield check_autocomplete({
+ search: "noparam foo",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("noparam foo", { heuristic: true }) ]
+ });
+ yield check_autocomplete({
+ search: "post_noparam foo",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("post_noparam foo", { heuristic: true }) ]
+ });
+
+ do_print("escaping with default UTF-8 charset");
+ yield check_autocomplete({
+ search: "encoded foé",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("keyword", {url: "http://abc/?search=fo%C3%A9&raw=foé", input: "encoded foé" }),
+ title: "abc", style: [ "action", "keyword", "heuristic" ] } ]
+ });
+
+ do_print("escaping with forced ISO-8859-1 charset");
+ yield check_autocomplete({
+ search: "charset foé",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("keyword", {url: "http://abc/?search=fo%E9&raw=foé", input: "charset foé" }),
+ title: "abc", style: [ "action", "keyword", "heuristic" ] } ]
+ });
+
+ do_print("Bug 359809: escaping +, / and @ with default UTF-8 charset");
+ yield check_autocomplete({
+ search: "encoded +/@",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("keyword", {url: "http://abc/?search=%2B%2F%40&raw=+/@", input: "encoded +/@" }),
+ title: "abc", style: [ "action", "keyword", "heuristic" ] } ]
+ });
+
+ do_print("Bug 359809: escaping +, / and @ with forced ISO-8859-1 charset");
+ yield check_autocomplete({
+ search: "charset +/@",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("keyword", {url: "http://abc/?search=%2B%2F%40&raw=+/@", input: "charset +/@" }),
+ title: "abc", style: [ "action", "keyword", "heuristic" ] } ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_keywords.js b/toolkit/components/places/tests/unifiedcomplete/test_keywords.js
new file mode 100644
index 000000000..93e8d7a6f
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_keywords.js
@@ -0,0 +1,78 @@
+/* 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/. */
+
+add_task(function* test_non_keyword() {
+ do_print("Searching for non-keyworded entry should autoFill it");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield addBookmark({ uri: NetUtil.newURI("http://mozilla.org/test/") });
+ yield check_autocomplete({
+ search: "moz",
+ autofilled: "mozilla.org/",
+ completed: "mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_keyword() {
+ do_print("Searching for keyworded entry should not autoFill it");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield addBookmark({ uri: NetUtil.newURI("http://mozilla.org/test/"), keyword: "moz" });
+ yield check_autocomplete({
+ search: "moz",
+ autofilled: "moz",
+ completed: "moz",
+ });
+ yield cleanup();
+});
+
+add_task(function* test_more_than_keyword() {
+ do_print("Searching for more than keyworded entry should autoFill it");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield addBookmark({ uri: NetUtil.newURI("http://mozilla.org/test/"), keyword: "moz" });
+ yield check_autocomplete({
+ search: "mozi",
+ autofilled: "mozilla.org/",
+ completed: "mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_less_than_keyword() {
+ do_print("Searching for less than keyworded entry should autoFill it");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield addBookmark({ uri: NetUtil.newURI("http://mozilla.org/test/"), keyword: "moz" });
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "mozilla.org/",
+ completed: "mozilla.org/",
+ });
+ yield cleanup();
+});
+
+add_task(function* test_keyword_casing() {
+ do_print("Searching for keyworded entry is case-insensitive");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield addBookmark({ uri: NetUtil.newURI("http://mozilla.org/test/"), keyword: "moz" });
+ yield check_autocomplete({
+ search: "MoZ",
+ autofilled: "MoZ",
+ completed: "MoZ"
+ });
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_match_beginning.js b/toolkit/components/places/tests/unifiedcomplete/test_match_beginning.js
new file mode 100644
index 000000000..57a1efaeb
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_match_beginning.js
@@ -0,0 +1,54 @@
+/* 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/. */
+
+/**
+ * Test bug 451760 which allows matching only at the beginning of urls or
+ * titles to simulate Firefox 2 functionality.
+ */
+
+add_task(function* test_match_beginning() {
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.searchEngines", false);
+
+ let uri1 = NetUtil.newURI("http://x.com/y");
+ let uri2 = NetUtil.newURI("https://y.com/x");
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "a b" },
+ { uri: uri2, title: "b a" }
+ ]);
+
+ do_print("Match at the beginning of titles");
+ Services.prefs.setIntPref("browser.urlbar.matchBehavior", 3);
+ yield check_autocomplete({
+ search: "a",
+ matches: [ { uri: uri1, title: "a b" } ]
+ });
+
+ do_print("Match at the beginning of titles");
+ yield check_autocomplete({
+ search: "b",
+ matches: [ { uri: uri2, title: "b a" } ]
+ });
+
+ do_print("Match at the beginning of urls");
+ yield check_autocomplete({
+ search: "x",
+ matches: [ { uri: uri1, title: "a b" } ]
+ });
+
+ do_print("Match at the beginning of urls");
+ yield check_autocomplete({
+ search: "y",
+ matches: [ { uri: uri2, title: "b a" } ]
+ });
+
+ do_print("Sanity check that matching anywhere finds more");
+ Services.prefs.setIntPref("browser.urlbar.matchBehavior", 1);
+ yield check_autocomplete({
+ search: "a",
+ matches: [ { uri: uri1, title: "a b" },
+ { uri: uri2, title: "b a" } ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_multi_word_search.js b/toolkit/components/places/tests/unifiedcomplete/test_multi_word_search.js
new file mode 100644
index 000000000..c6c9e952e
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_multi_word_search.js
@@ -0,0 +1,68 @@
+/* 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/. */
+
+/**
+ * Test for bug 401869 to allow multiple words separated by spaces to match in
+ * the page title, page url, or bookmark title to be considered a match. All
+ * terms must match but not all terms need to be in the title, etc.
+ *
+ * Test bug 424216 by making sure bookmark titles are always shown if one is
+ * available. Also bug 425056 makes sure matches aren't found partially in the
+ * page title and partially in the bookmark.
+ */
+
+add_task(function* test_match_beginning() {
+ let uri1 = NetUtil.newURI("http://a.b.c/d-e_f/h/t/p");
+ let uri2 = NetUtil.newURI("http://d.e.f/g-h_i/h/t/p");
+ let uri3 = NetUtil.newURI("http://g.h.i/j-k_l/h/t/p");
+ let uri4 = NetUtil.newURI("http://j.k.l/m-n_o/h/t/p");
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "f(o)o b<a>r" },
+ { uri: uri2, title: "b(a)r b<a>z" },
+ { uri: uri3, title: "f(o)o b<a>r" },
+ { uri: uri4, title: "f(o)o b<a>r" }
+ ]);
+ yield addBookmark({ uri: uri3, title: "f(o)o b<a>r" });
+ yield addBookmark({ uri: uri4, title: "b(a)r b<a>z" });
+
+ do_print("Match 2 terms all in url");
+ yield check_autocomplete({
+ search: "c d",
+ matches: [ { uri: uri1, title: "f(o)o b<a>r" } ]
+ });
+
+ do_print("Match 1 term in url and 1 term in title");
+ yield check_autocomplete({
+ search: "b e",
+ matches: [ { uri: uri1, title: "f(o)o b<a>r" },
+ { uri: uri2, title: "b(a)r b<a>z" } ]
+ });
+
+ do_print("Match 3 terms all in title; display bookmark title if matched");
+ yield check_autocomplete({
+ search: "b a z",
+ matches: [ { uri: uri2, title: "b(a)r b<a>z" },
+ { uri: uri4, title: "b(a)r b<a>z", style: [ "bookmark" ] } ]
+ });
+
+ do_print("Match 2 terms in url and 1 in title; make sure bookmark title is used for search");
+ yield check_autocomplete({
+ search: "k f t",
+ matches: [ { uri: uri3, title: "f(o)o b<a>r", style: [ "bookmark" ] } ]
+ });
+
+ do_print("Match 3 terms in url and 1 in title");
+ yield check_autocomplete({
+ search: "d i g z",
+ matches: [ { uri: uri2, title: "b(a)r b<a>z" } ]
+ });
+
+ do_print("Match nothing");
+ yield check_autocomplete({
+ search: "m o z i",
+ matches: [ ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_query_url.js b/toolkit/components/places/tests/unifiedcomplete/test_query_url.js
new file mode 100644
index 000000000..915ba770e
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_query_url.js
@@ -0,0 +1,68 @@
+/* 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/. */
+
+add_task(function* test_no_slash() {
+ do_print("Searching for host match without slash should match host");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://file.org/test/"),
+ transition: TRANSITION_TYPED
+ }, {
+ uri: NetUtil.newURI("file:///c:/test.html"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "file",
+ autofilled: "file.org/",
+ completed: "file.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_w_slash() {
+ do_print("Searching match with slash at the end should do nothing");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://file.org/test/"),
+ transition: TRANSITION_TYPED
+ }, {
+ uri: NetUtil.newURI("file:///c:/test.html"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "file.org/",
+ autofilled: "file.org/",
+ completed: "file.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_middle() {
+ do_print("Searching match with slash in the middle should match url");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://file.org/test/"),
+ transition: TRANSITION_TYPED
+ }, {
+ uri: NetUtil.newURI("file:///c:/test.html"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "file.org/t",
+ autofilled: "file.org/test/",
+ completed: "http://file.org/test/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_nonhost() {
+ do_print("Searching for non-host match without slash should not match url");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("file:///c:/test.html"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "file",
+ autofilled: "file",
+ completed: "file"
+ });
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_remote_tab_matches.js b/toolkit/components/places/tests/unifiedcomplete/test_remote_tab_matches.js
new file mode 100644
index 000000000..56998d4d6
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_remote_tab_matches.js
@@ -0,0 +1,203 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * vim:set ts=2 sw=2 sts=2 et:
+*/
+"use strict";
+
+Cu.import("resource://services-sync/main.js");
+
+Services.prefs.setCharPref("services.sync.username", "someone@somewhere.com");
+
+// A mock "Tabs" engine which autocomplete will use instead of the real
+// engine. We pass a constructor that Sync creates.
+function MockTabsEngine() {
+ this.clients = null; // We'll set this dynamically
+}
+
+MockTabsEngine.prototype = {
+ name: "tabs",
+
+ getAllClients() {
+ return this.clients;
+ },
+}
+
+// A clients engine that doesn't need to be a constructor.
+let MockClientsEngine = {
+ isMobile(guid) {
+ Assert.ok(guid.endsWith("desktop") || guid.endsWith("mobile"));
+ return guid.endsWith("mobile");
+ },
+}
+
+// Tell Sync about the mocks.
+Weave.Service.engineManager.register(MockTabsEngine);
+Weave.Service.clientsEngine = MockClientsEngine;
+
+// Tell the Sync XPCOM service it is initialized.
+let weaveXPCService = Cc["@mozilla.org/weave/service;1"]
+ .getService(Ci.nsISupports)
+ .wrappedJSObject;
+weaveXPCService.ready = true;
+
+// Configure the singleton engine for a test.
+function configureEngine(clients) {
+ // Configure the instance Sync created.
+ let engine = Weave.Service.engineManager.get("tabs");
+ engine.clients = clients;
+ // Send an observer that pretends the engine just finished a sync.
+ Services.obs.notifyObservers(null, "weave:engine:sync:finish", "tabs");
+}
+
+// Make a match object suitable for passing to check_autocomplete.
+function makeRemoteTabMatch(url, deviceName, extra = {}) {
+ return {
+ uri: makeActionURI("remotetab", {url, deviceName}),
+ title: extra.title || url,
+ style: [ "action", "remotetab" ],
+ icon: extra.icon,
+ }
+}
+
+// The tests.
+add_task(function* test_nomatch() {
+ // Nothing matches.
+ configureEngine({
+ guid_desktop: {
+ clientName: "My Desktop",
+ tabs: [{
+ urlHistory: ["http://foo.com/"],
+ }],
+ }
+ });
+
+ // No remote tabs match here, so we only expect search results.
+ yield check_autocomplete({
+ search: "ex",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("ex", { heuristic: true }) ],
+ });
+});
+
+add_task(function* test_minimal() {
+ // The minimal client and tabs info we can get away with.
+ configureEngine({
+ guid_desktop: {
+ clientName: "My Desktop",
+ tabs: [{
+ urlHistory: ["http://example.com/"],
+ }],
+ }
+ });
+
+ yield check_autocomplete({
+ search: "ex",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("ex", { heuristic: true }),
+ makeRemoteTabMatch("http://example.com/", "My Desktop") ],
+ });
+});
+
+add_task(function* test_maximal() {
+ // Every field that could possibly exist on a remote record.
+ configureEngine({
+ guid_mobile: {
+ clientName: "My Phone",
+ tabs: [{
+ urlHistory: ["http://example.com/"],
+ title: "An Example",
+ icon: "http://favicon",
+ }],
+ }
+ });
+
+ yield check_autocomplete({
+ search: "ex",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("ex", { heuristic: true }),
+ makeRemoteTabMatch("http://example.com/", "My Phone",
+ { title: "An Example",
+ icon: "moz-anno:favicon:http://favicon/"
+ }),
+ ],
+ });
+});
+
+add_task(function* test_noShowIcons() {
+ Services.prefs.setBoolPref("services.sync.syncedTabs.showRemoteIcons", false);
+ configureEngine({
+ guid_mobile: {
+ clientName: "My Phone",
+ tabs: [{
+ urlHistory: ["http://example.com/"],
+ title: "An Example",
+ icon: "http://favicon",
+ }],
+ }
+ });
+
+ yield check_autocomplete({
+ search: "ex",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("ex", { heuristic: true }),
+ makeRemoteTabMatch("http://example.com/", "My Phone",
+ { title: "An Example",
+ // expecting the default favicon due to that pref.
+ icon: "",
+ }),
+ ],
+ });
+ Services.prefs.clearUserPref("services.sync.syncedTabs.showRemoteIcons");
+});
+
+add_task(function* test_matches_title() {
+ // URL doesn't match search expression, should still match the title.
+ configureEngine({
+ guid_mobile: {
+ clientName: "My Phone",
+ tabs: [{
+ urlHistory: ["http://foo.com/"],
+ title: "An Example",
+ }],
+ }
+ });
+
+ yield check_autocomplete({
+ search: "ex",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("ex", { heuristic: true }),
+ makeRemoteTabMatch("http://foo.com/", "My Phone",
+ { title: "An Example" }),
+ ],
+ });
+});
+
+add_task(function* test_localtab_matches_override() {
+ // We have an open tab to the same page on a remote device, only "switch to
+ // tab" should appear as duplicate detection removed the remote one.
+
+ // First setup Sync to have the page as a remote tab.
+ configureEngine({
+ guid_mobile: {
+ clientName: "My Phone",
+ tabs: [{
+ urlHistory: ["http://foo.com/"],
+ title: "An Example",
+ }],
+ }
+ });
+
+ // Setup Places to think the tab is open locally.
+ let uri = NetUtil.newURI("http://foo.com/");
+ yield PlacesTestUtils.addVisits([
+ { uri: uri, title: "An Example" },
+ ]);
+ addOpenPages(uri, 1);
+
+ yield check_autocomplete({
+ search: "ex",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("ex", { heuristic: true }),
+ makeSwitchToTabMatch("http://foo.com/", { title: "An Example" }),
+ ],
+ });
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_search_engine_alias.js b/toolkit/components/places/tests/unifiedcomplete/test_search_engine_alias.js
new file mode 100644
index 000000000..f35242e21
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_search_engine_alias.js
@@ -0,0 +1,51 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+
+add_task(function*() {
+ // Note that head_autocomplete.js has already added a MozSearch engine.
+ // Here we add another engine with a search alias.
+ Services.search.addEngineWithDetails("AliasedGETMozSearch", "", "get", "",
+ "GET", "http://s.example.com/search");
+ Services.search.addEngineWithDetails("AliasedPOSTMozSearch", "", "post", "",
+ "POST", "http://s.example.com/search");
+
+ for (let alias of ["get", "post"]) {
+ yield check_autocomplete({
+ search: alias,
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch(alias, { engineName: `Aliased${alias.toUpperCase()}MozSearch`,
+ searchQuery: "", alias, heuristic: true }) ]
+ });
+
+ yield check_autocomplete({
+ search: `${alias} `,
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch(`${alias} `, { engineName: `Aliased${alias.toUpperCase()}MozSearch`,
+ searchQuery: "", alias, heuristic: true }) ]
+ });
+
+ yield check_autocomplete({
+ search: `${alias} mozilla`,
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch(`${alias} mozilla`, { engineName: `Aliased${alias.toUpperCase()}MozSearch`,
+ searchQuery: "mozilla", alias, heuristic: true }) ]
+ });
+
+ yield check_autocomplete({
+ search: `${alias} MoZiLlA`,
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch(`${alias} MoZiLlA`, { engineName: `Aliased${alias.toUpperCase()}MozSearch`,
+ searchQuery: "MoZiLlA", alias, heuristic: true }) ]
+ });
+
+ yield check_autocomplete({
+ search: `${alias} mozzarella mozilla`,
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch(`${alias} mozzarella mozilla`, { engineName: `Aliased${alias.toUpperCase()}MozSearch`,
+ searchQuery: "mozzarella mozilla", alias, heuristic: true }) ]
+ });
+ }
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_search_engine_current.js b/toolkit/components/places/tests/unifiedcomplete/test_search_engine_current.js
new file mode 100644
index 000000000..b41d9884b
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_search_engine_current.js
@@ -0,0 +1,45 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+
+add_task(function*() {
+ // Note that head_autocomplete.js has already added a MozSearch engine.
+ // Here we add another engine with a search alias.
+ Services.search.addEngineWithDetails("AliasedMozSearch", "", "doit", "",
+ "GET", "http://s.example.com/search");
+
+ do_print("search engine");
+ yield check_autocomplete({
+ search: "mozilla",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("mozilla", { heuristic: true }) ]
+ });
+
+ do_print("search engine, uri-like input");
+ yield check_autocomplete({
+ search: "http:///",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("http:///", { heuristic: true }) ]
+ });
+
+ do_print("search engine, multiple words");
+ yield check_autocomplete({
+ search: "mozzarella cheese",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("mozzarella cheese", { heuristic: true }) ]
+ });
+
+ do_print("search engine, after current engine has changed");
+ Services.search.addEngineWithDetails("MozSearch2", "", "", "", "GET",
+ "http://s.example.com/search2");
+ engine = Services.search.getEngineByName("MozSearch2");
+ notEqual(Services.search.currentEngine, engine, "New engine shouldn't be the current engine yet");
+ Services.search.currentEngine = engine;
+ yield check_autocomplete({
+ search: "mozilla",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("mozilla", { engineName: "MozSearch2", heuristic: true }) ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_search_engine_host.js b/toolkit/components/places/tests/unifiedcomplete/test_search_engine_host.js
new file mode 100644
index 000000000..61b9826f7
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_search_engine_host.js
@@ -0,0 +1,49 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+add_task(function* test_searchEngine_autoFill() {
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.searchEngines", true);
+ Services.search.addEngineWithDetails("MySearchEngine", "", "", "",
+ "GET", "http://my.search.com/");
+ let engine = Services.search.getEngineByName("MySearchEngine");
+ do_register_cleanup(() => Services.search.removeEngine(engine));
+
+ // Add an uri that matches the search string with high frecency.
+ let uri = NetUtil.newURI("http://www.example.com/my/");
+ let visits = [];
+ for (let i = 0; i < 100; ++i) {
+ visits.push({ uri, title: "Terms - SearchEngine Search" });
+ }
+ yield PlacesTestUtils.addVisits(visits);
+ yield addBookmark({ uri: uri, title: "Example bookmark" });
+ yield PlacesTestUtils.promiseAsyncUpdates();
+ ok(frecencyForUrl(uri) > 10000, "Added URI should have expected high frecency");
+
+ do_print("Check search domain is autoFilled even if there's an higher frecency match");
+ yield check_autocomplete({
+ search: "my",
+ autofilled: "my.search.com",
+ completed: "http://my.search.com"
+ });
+
+ yield cleanup();
+});
+
+add_task(function* test_searchEngine_noautoFill() {
+ let engineName = "engine-rel-searchform.xml";
+ let engine = yield addTestEngine(engineName);
+ equal(engine.searchForm, "http://example.com/?search");
+
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield PlacesTestUtils.addVisits(NetUtil.newURI("http://example.com/my/"));
+
+ do_print("Check search domain is not autoFilled if it matches a visited domain");
+ yield check_autocomplete({
+ search: "example",
+ autofilled: "example.com/",
+ completed: "example.com/"
+ });
+
+ yield cleanup();
+});
+
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_search_engine_restyle.js b/toolkit/components/places/tests/unifiedcomplete/test_search_engine_restyle.js
new file mode 100644
index 000000000..2a5f2d78e
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_search_engine_restyle.js
@@ -0,0 +1,43 @@
+/* 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/. */
+
+add_task(function* test_searchEngine() {
+ Services.search.addEngineWithDetails("SearchEngine", "", "", "",
+ "GET", "http://s.example.com/search");
+ let engine = Services.search.getEngineByName("SearchEngine");
+ engine.addParam("q", "{searchTerms}", null);
+ do_register_cleanup(() => Services.search.removeEngine(engine));
+
+ let uri1 = NetUtil.newURI("http://s.example.com/search?q=Terms&client=1");
+ let uri2 = NetUtil.newURI("http://s.example.com/search?q=Terms&client=2");
+ yield PlacesTestUtils.addVisits({ uri: uri1, title: "Terms - SearchEngine Search" });
+ yield addBookmark({ uri: uri2, title: "Terms - SearchEngine Search" });
+
+ do_print("Past search terms should be styled, unless bookmarked");
+ Services.prefs.setBoolPref("browser.urlbar.restyleSearches", true);
+ yield check_autocomplete({
+ search: "term",
+ matches: [
+ makeSearchMatch("Terms", {
+ engineName: "SearchEngine",
+ style: ["favicon"]
+ }),
+ {
+ uri: uri2,
+ title: "Terms - SearchEngine Search",
+ style: ["bookmark"]
+ }
+ ]
+ });
+
+ do_print("Past search terms should not be styled if restyling is disabled");
+ Services.prefs.setBoolPref("browser.urlbar.restyleSearches", false);
+ yield check_autocomplete({
+ search: "term",
+ matches: [ { uri: uri1, title: "Terms - SearchEngine Search" },
+ { uri: uri2, title: "Terms - SearchEngine Search", style: ["bookmark"] } ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_search_suggestions.js b/toolkit/components/places/tests/unifiedcomplete/test_search_suggestions.js
new file mode 100644
index 000000000..63b428cd4
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_search_suggestions.js
@@ -0,0 +1,651 @@
+Cu.import("resource://gre/modules/FormHistory.jsm");
+
+const ENGINE_NAME = "engine-suggestions.xml";
+const SERVER_PORT = 9000;
+const SUGGEST_PREF = "browser.urlbar.suggest.searches";
+const SUGGEST_ENABLED_PREF = "browser.search.suggest.enabled";
+const SUGGEST_RESTRICT_TOKEN = "$";
+
+var suggestionsFn;
+var previousSuggestionsFn;
+
+function setSuggestionsFn(fn) {
+ previousSuggestionsFn = suggestionsFn;
+ suggestionsFn = fn;
+}
+
+function* cleanUpSuggestions() {
+ yield cleanup();
+ if (previousSuggestionsFn) {
+ suggestionsFn = previousSuggestionsFn;
+ previousSuggestionsFn = null;
+ }
+}
+
+add_task(function* setUp() {
+ // Set up a server that provides some suggestions by appending strings onto
+ // the search query.
+ let server = makeTestServer(SERVER_PORT);
+ server.registerPathHandler("/suggest", (req, resp) => {
+ // URL query params are x-www-form-urlencoded, which converts spaces into
+ // plus signs, so un-convert any plus signs back to spaces.
+ let searchStr = decodeURIComponent(req.queryString.replace(/\+/g, " "));
+ let suggestions = suggestionsFn(searchStr);
+ let data = [searchStr, suggestions];
+ resp.setHeader("Content-Type", "application/json", false);
+ resp.write(JSON.stringify(data));
+ });
+ setSuggestionsFn(searchStr => {
+ let suffixes = ["foo", "bar"];
+ return suffixes.map(s => searchStr + " " + s);
+ });
+
+ // Install the test engine.
+ let oldCurrentEngine = Services.search.currentEngine;
+ do_register_cleanup(() => Services.search.currentEngine = oldCurrentEngine);
+ let engine = yield addTestEngine(ENGINE_NAME, server);
+ Services.search.currentEngine = engine;
+});
+
+add_task(function* disabled_urlbarSuggestions() {
+ Services.prefs.setBoolPref(SUGGEST_PREF, false);
+ Services.prefs.setBoolPref(SUGGEST_ENABLED_PREF, true);
+ yield check_autocomplete({
+ search: "hello",
+ searchParam: "enable-actions",
+ matches: [
+ makeSearchMatch("hello", { engineName: ENGINE_NAME, heuristic: true }),
+ ],
+ });
+ yield cleanUpSuggestions();
+});
+
+add_task(function* disabled_allSuggestions() {
+ Services.prefs.setBoolPref(SUGGEST_PREF, true);
+ Services.prefs.setBoolPref(SUGGEST_ENABLED_PREF, false);
+ yield check_autocomplete({
+ search: "hello",
+ searchParam: "enable-actions",
+ matches: [
+ makeSearchMatch("hello", { engineName: ENGINE_NAME, heuristic: true }),
+ ],
+ });
+ yield cleanUpSuggestions();
+});
+
+add_task(function* disabled_privateWindow() {
+ Services.prefs.setBoolPref(SUGGEST_PREF, true);
+ Services.prefs.setBoolPref(SUGGEST_ENABLED_PREF, true);
+ yield check_autocomplete({
+ search: "hello",
+ searchParam: "private-window enable-actions",
+ matches: [
+ makeSearchMatch("hello", { engineName: ENGINE_NAME, heuristic: true }),
+ ],
+ });
+ yield cleanUpSuggestions();
+});
+
+add_task(function* singleWordQuery() {
+ Services.prefs.setBoolPref(SUGGEST_PREF, true);
+ Services.prefs.setBoolPref(SUGGEST_ENABLED_PREF, true);
+
+ yield check_autocomplete({
+ search: "hello",
+ searchParam: "enable-actions",
+ matches: [
+ makeSearchMatch("hello", { engineName: ENGINE_NAME, heuristic: true }),
+ { uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "hello foo",
+ searchQuery: "hello",
+ searchSuggestion: "hello foo",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ }, {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "hello bar",
+ searchQuery: "hello",
+ searchSuggestion: "hello bar",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ }],
+ });
+
+ yield cleanUpSuggestions();
+});
+
+add_task(function* multiWordQuery() {
+ Services.prefs.setBoolPref(SUGGEST_PREF, true);
+ Services.prefs.setBoolPref(SUGGEST_ENABLED_PREF, true);
+
+ yield check_autocomplete({
+ search: "hello world",
+ searchParam: "enable-actions",
+ matches: [
+ makeSearchMatch("hello world", { engineName: ENGINE_NAME, heuristic: true }),
+ { uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "hello world foo",
+ searchQuery: "hello world",
+ searchSuggestion: "hello world foo",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ }, {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "hello world bar",
+ searchQuery: "hello world",
+ searchSuggestion: "hello world bar",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ }],
+ });
+
+ yield cleanUpSuggestions();
+});
+
+add_task(function* suffixMatch() {
+ Services.prefs.setBoolPref(SUGGEST_PREF, true);
+ Services.prefs.setBoolPref(SUGGEST_ENABLED_PREF, true);
+
+ setSuggestionsFn(searchStr => {
+ let prefixes = ["baz", "quux"];
+ return prefixes.map(p => p + " " + searchStr);
+ });
+
+ yield check_autocomplete({
+ search: "hello",
+ searchParam: "enable-actions",
+ matches: [
+ makeSearchMatch("hello", { engineName: ENGINE_NAME, heuristic: true }),
+ { uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "baz hello",
+ searchQuery: "hello",
+ searchSuggestion: "baz hello",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ }, {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "quux hello",
+ searchQuery: "hello",
+ searchSuggestion: "quux hello",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ }],
+ });
+
+ yield cleanUpSuggestions();
+});
+
+add_task(function* queryIsNotASubstring() {
+ Services.prefs.setBoolPref(SUGGEST_PREF, true);
+
+ setSuggestionsFn(searchStr => {
+ return ["aaa", "bbb"];
+ });
+
+ yield check_autocomplete({
+ search: "hello",
+ searchParam: "enable-actions",
+ matches: [
+ makeSearchMatch("hello", { engineName: ENGINE_NAME, heuristic: true }),
+ { uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "aaa",
+ searchQuery: "hello",
+ searchSuggestion: "aaa",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ }, {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "bbb",
+ searchQuery: "hello",
+ searchSuggestion: "bbb",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ }],
+ });
+
+ yield cleanUpSuggestions();
+});
+
+add_task(function* restrictToken() {
+ Services.prefs.setBoolPref(SUGGEST_PREF, true);
+ Services.prefs.setBoolPref(SUGGEST_ENABLED_PREF, true);
+
+ // Add a visit and a bookmark. Actually, make the bookmark visited too so
+ // that it's guaranteed, with its higher frecency, to appear above the search
+ // suggestions.
+ yield PlacesTestUtils.addVisits([
+ {
+ uri: NetUtil.newURI("http://example.com/hello-visit"),
+ title: "hello visit",
+ },
+ {
+ uri: NetUtil.newURI("http://example.com/hello-bookmark"),
+ title: "hello bookmark",
+ },
+ ]);
+
+ yield addBookmark({
+ uri: NetUtil.newURI("http://example.com/hello-bookmark"),
+ title: "hello bookmark",
+ });
+
+ // Do an unrestricted search to make sure everything appears in it, including
+ // the visit and bookmark.
+ yield check_autocomplete({
+ search: "hello",
+ searchParam: "enable-actions",
+ matches: [
+ makeSearchMatch("hello", { engineName: ENGINE_NAME, heuristic: true }),
+ {
+ uri: NetUtil.newURI("http://example.com/hello-visit"),
+ title: "hello visit",
+ },
+ {
+ uri: NetUtil.newURI("http://example.com/hello-bookmark"),
+ title: "hello bookmark",
+ style: ["bookmark"],
+ },
+ {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "hello foo",
+ searchQuery: "hello",
+ searchSuggestion: "hello foo",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ },
+ {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "hello bar",
+ searchQuery: "hello",
+ searchSuggestion: "hello bar",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ },
+ ],
+ });
+
+ // Now do a restricted search to make sure only suggestions appear.
+ yield check_autocomplete({
+ search: SUGGEST_RESTRICT_TOKEN + " hello",
+ searchParam: "enable-actions",
+ matches: [
+ // TODO (bug 1177895) This is wrong.
+ makeSearchMatch(SUGGEST_RESTRICT_TOKEN + " hello", { engineName: ENGINE_NAME, heuristic: true }),
+ {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "hello foo",
+ searchQuery: "hello",
+ searchSuggestion: "hello foo",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ },
+ {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "hello bar",
+ searchQuery: "hello",
+ searchSuggestion: "hello bar",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ }
+ ],
+ });
+
+ yield cleanUpSuggestions();
+});
+
+add_task(function* mixup_frecency() {
+ Services.prefs.setBoolPref(SUGGEST_PREF, true);
+
+ // Add a visit and a bookmark. Actually, make the bookmark visited too so
+ // that it's guaranteed, with its higher frecency, to appear above the search
+ // suggestions.
+ yield PlacesTestUtils.addVisits([
+ { uri: NetUtil.newURI("http://example.com/lo0"),
+ title: "low frecency 0" },
+ { uri: NetUtil.newURI("http://example.com/lo1"),
+ title: "low frecency 1" },
+ { uri: NetUtil.newURI("http://example.com/lo2"),
+ title: "low frecency 2" },
+ { uri: NetUtil.newURI("http://example.com/lo3"),
+ title: "low frecency 3" },
+ { uri: NetUtil.newURI("http://example.com/lo4"),
+ title: "low frecency 4" },
+ ]);
+
+ for (let i = 0; i < 4; i++) {
+ let href = `http://example.com/lo${i}`;
+ let frecency = frecencyForUrl(href);
+ Assert.ok(frecency < FRECENCY_DEFAULT,
+ `frecency for ${href}: ${frecency}, should be lower than ${FRECENCY_DEFAULT}`);
+ }
+
+ for (let i = 0; i < 5; i++) {
+ yield PlacesTestUtils.addVisits([
+ { uri: NetUtil.newURI("http://example.com/hi0"),
+ title: "high frecency 0",
+ transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("http://example.com/hi1"),
+ title: "high frecency 1",
+ transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("http://example.com/hi2"),
+ title: "high frecency 2",
+ transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("http://example.com/hi3"),
+ title: "high frecency 3",
+ transition: TRANSITION_TYPED },
+ ]);
+ }
+
+ for (let i = 0; i < 4; i++) {
+ let href = `http://example.com/hi${i}`;
+ yield addBookmark({ uri: href, title: `high frecency ${i}` });
+ let frecency = frecencyForUrl(href);
+ Assert.ok(frecency > FRECENCY_DEFAULT,
+ `frecency for ${href}: ${frecency}, should be higher than ${FRECENCY_DEFAULT}`);
+ }
+
+ // Do an unrestricted search to make sure everything appears in it, including
+ // the visit and bookmark.
+ yield check_autocomplete({
+ checkSorting: true,
+ search: "frecency",
+ searchParam: "enable-actions",
+ matches: [
+ makeSearchMatch("frecency", { engineName: ENGINE_NAME, heuristic: true }),
+ { uri: NetUtil.newURI("http://example.com/hi3"),
+ title: "high frecency 3",
+ style: [ "bookmark" ] },
+ { uri: NetUtil.newURI("http://example.com/hi2"),
+ title: "high frecency 2",
+ style: [ "bookmark" ] },
+ { uri: NetUtil.newURI("http://example.com/hi1"),
+ title: "high frecency 1",
+ style: [ "bookmark" ] },
+ { uri: NetUtil.newURI("http://example.com/hi0"),
+ title: "high frecency 0",
+ style: [ "bookmark" ] },
+ { uri: NetUtil.newURI("http://example.com/lo4"),
+ title: "low frecency 4" },
+ {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "frecency foo",
+ searchQuery: "frecency",
+ searchSuggestion: "frecency foo",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ },
+ {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "frecency bar",
+ searchQuery: "frecency",
+ searchSuggestion: "frecency bar",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ },
+ { uri: NetUtil.newURI("http://example.com/lo3"),
+ title: "low frecency 3" },
+ { uri: NetUtil.newURI("http://example.com/lo2"),
+ title: "low frecency 2" },
+ { uri: NetUtil.newURI("http://example.com/lo1"),
+ title: "low frecency 1" },
+ { uri: NetUtil.newURI("http://example.com/lo0"),
+ title: "low frecency 0" },
+ ],
+ });
+
+ yield cleanUpSuggestions();
+});
+
+add_task(function* prohibit_suggestions() {
+ Services.prefs.setBoolPref(SUGGEST_PREF, true);
+
+ yield check_autocomplete({
+ search: "localhost",
+ searchParam: "enable-actions",
+ matches: [
+ makeSearchMatch("localhost", { engineName: ENGINE_NAME, heuristic: true }),
+ {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "localhost foo",
+ searchQuery: "localhost",
+ searchSuggestion: "localhost foo",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ },
+ {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "localhost bar",
+ searchQuery: "localhost",
+ searchSuggestion: "localhost bar",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ },
+ ],
+ });
+ Services.prefs.setBoolPref("browser.fixup.domainwhitelist.localhost", true);
+ do_register_cleanup(() => {
+ Services.prefs.clearUserPref("browser.fixup.domainwhitelist.localhost");
+ });
+ yield check_autocomplete({
+ search: "localhost",
+ searchParam: "enable-actions",
+ matches: [
+ makeVisitMatch("localhost", "http://localhost/", { heuristic: true }),
+ makeSearchMatch("localhost", { engineName: ENGINE_NAME, heuristic: false })
+ ],
+ });
+
+ // When using multiple words, we should still get suggestions:
+ yield check_autocomplete({
+ search: "localhost other",
+ searchParam: "enable-actions",
+ matches: [
+ makeSearchMatch("localhost other", { engineName: ENGINE_NAME, heuristic: true }),
+ {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "localhost other foo",
+ searchQuery: "localhost other",
+ searchSuggestion: "localhost other foo",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ },
+ {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "localhost other bar",
+ searchQuery: "localhost other",
+ searchSuggestion: "localhost other bar",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ },
+ ],
+ });
+
+ // Clear the whitelist for localhost, and try preferring DNS for any single
+ // word instead:
+ Services.prefs.clearUserPref("browser.fixup.domainwhitelist.localhost");
+ Services.prefs.setBoolPref("browser.fixup.dns_first_for_single_words", true);
+ do_register_cleanup(() => {
+ Services.prefs.clearUserPref("browser.fixup.dns_first_for_single_words");
+ });
+
+ yield check_autocomplete({
+ search: "localhost",
+ searchParam: "enable-actions",
+ matches: [
+ makeVisitMatch("localhost", "http://localhost/", { heuristic: true }),
+ makeSearchMatch("localhost", { engineName: ENGINE_NAME, heuristic: false })
+ ],
+ });
+
+ yield check_autocomplete({
+ search: "somethingelse",
+ searchParam: "enable-actions",
+ matches: [
+ makeVisitMatch("somethingelse", "http://somethingelse/", { heuristic: true }),
+ makeSearchMatch("somethingelse", { engineName: ENGINE_NAME, heuristic: false })
+ ],
+ });
+
+ // When using multiple words, we should still get suggestions:
+ yield check_autocomplete({
+ search: "localhost other",
+ searchParam: "enable-actions",
+ matches: [
+ makeSearchMatch("localhost other", { engineName: ENGINE_NAME, heuristic: true }),
+ {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "localhost other foo",
+ searchQuery: "localhost other",
+ searchSuggestion: "localhost other foo",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ },
+ {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "localhost other bar",
+ searchQuery: "localhost other",
+ searchSuggestion: "localhost other bar",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ },
+ ],
+ });
+
+ Services.prefs.clearUserPref("browser.fixup.dns_first_for_single_words");
+
+ yield check_autocomplete({
+ search: "1.2.3.4",
+ searchParam: "enable-actions",
+ matches: [
+ makeVisitMatch("1.2.3.4", "http://1.2.3.4/", { heuristic: true }),
+ ],
+ });
+ yield check_autocomplete({
+ search: "[2001::1]:30",
+ searchParam: "enable-actions",
+ matches: [
+ makeVisitMatch("[2001::1]:30", "http://[2001::1]:30/", { heuristic: true }),
+ ],
+ });
+ yield check_autocomplete({
+ search: "user:pass@test",
+ searchParam: "enable-actions",
+ matches: [
+ makeVisitMatch("user:pass@test", "http://user:pass@test/", { heuristic: true }),
+ ],
+ });
+ yield check_autocomplete({
+ search: "test/test",
+ searchParam: "enable-actions",
+ matches: [
+ makeVisitMatch("test/test", "http://test/test", { heuristic: true }),
+ ],
+ });
+ yield check_autocomplete({
+ search: "data:text/plain,Content",
+ searchParam: "enable-actions",
+ matches: [
+ makeVisitMatch("data:text/plain,Content", "data:text/plain,Content", { heuristic: true }),
+ ],
+ });
+
+ yield check_autocomplete({
+ search: "a",
+ searchParam: "enable-actions",
+ matches: [
+ makeSearchMatch("a", { engineName: ENGINE_NAME, heuristic: true }),
+ ],
+ });
+
+ yield cleanUpSuggestions();
+});
+
+add_task(function* avoid_url_suggestions() {
+ Services.prefs.setBoolPref(SUGGEST_PREF, true);
+
+ setSuggestionsFn(searchStr => {
+ let suffixes = [".com", "/test", ":1]", "@test", ". com"];
+ return suffixes.map(s => searchStr + s);
+ });
+
+ yield check_autocomplete({
+ search: "test",
+ searchParam: "enable-actions",
+ matches: [
+ makeSearchMatch("test", { engineName: ENGINE_NAME, heuristic: true }),
+ {
+ uri: makeActionURI(("searchengine"), {
+ engineName: ENGINE_NAME,
+ input: "test. com",
+ searchQuery: "test",
+ searchSuggestion: "test. com",
+ }),
+ title: ENGINE_NAME,
+ style: ["action", "searchengine"],
+ icon: "",
+ },
+ ],
+ });
+
+ yield cleanUpSuggestions();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_special_search.js b/toolkit/components/places/tests/unifiedcomplete/test_special_search.js
new file mode 100644
index 000000000..21df7046c
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_special_search.js
@@ -0,0 +1,447 @@
+/* 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/. */
+
+/**
+ * Test for bug 395161 that allows special searches that restrict results to
+ * history/bookmark/tagged items and title/url matches.
+ *
+ * Test 485122 by making sure results don't have tags when restricting result
+ * to just history either by default behavior or dynamic query restrict.
+ */
+
+function setSuggestPrefsToFalse() {
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history", false);
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history.onlyTyped", false);
+ Services.prefs.setBoolPref("browser.urlbar.suggest.bookmark", false);
+}
+
+add_task(function* test_special_searches() {
+ let uri1 = NetUtil.newURI("http://url/");
+ let uri2 = NetUtil.newURI("http://url/2");
+ let uri3 = NetUtil.newURI("http://foo.bar/");
+ let uri4 = NetUtil.newURI("http://foo.bar/2");
+ let uri5 = NetUtil.newURI("http://url/star");
+ let uri6 = NetUtil.newURI("http://url/star/2");
+ let uri7 = NetUtil.newURI("http://foo.bar/star");
+ let uri8 = NetUtil.newURI("http://foo.bar/star/2");
+ let uri9 = NetUtil.newURI("http://url/tag");
+ let uri10 = NetUtil.newURI("http://url/tag/2");
+ let uri11 = NetUtil.newURI("http://foo.bar/tag");
+ let uri12 = NetUtil.newURI("http://foo.bar/tag/2");
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "title", transition: TRANSITION_TYPED },
+ { uri: uri2, title: "foo.bar" },
+ { uri: uri3, title: "title" },
+ { uri: uri4, title: "foo.bar", transition: TRANSITION_TYPED },
+ { uri: uri6, title: "foo.bar" },
+ { uri: uri11, title: "title", transition: TRANSITION_TYPED }
+ ]);
+ yield addBookmark( { uri: uri5, title: "title" } );
+ yield addBookmark( { uri: uri6, title: "foo.bar" } );
+ yield addBookmark( { uri: uri7, title: "title" } );
+ yield addBookmark( { uri: uri8, title: "foo.bar" } );
+ yield addBookmark( { uri: uri9, title: "title", tags: [ "foo.bar" ] } );
+ yield addBookmark( { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ] } );
+ yield addBookmark( { uri: uri11, title: "title", tags: [ "foo.bar" ] } );
+ yield addBookmark( { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ] } );
+
+ // Test restricting searches
+ do_print("History restrict");
+ yield check_autocomplete({
+ search: "^",
+ matches: [ { uri: uri1, title: "title" },
+ { uri: uri2, title: "foo.bar" },
+ { uri: uri3, title: "title" },
+ { uri: uri4, title: "foo.bar" },
+ { uri: uri6, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("Star restrict");
+ yield check_autocomplete({
+ search: "*",
+ matches: [ { uri: uri5, title: "title", style: [ "bookmark" ] },
+ { uri: uri6, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri7, title: "title", style: [ "bookmark" ] },
+ { uri: uri8, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri9, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar"], style: [ "bookmark-tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("Tag restrict");
+ yield check_autocomplete({
+ search: "+",
+ matches: [ { uri: uri9, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ // Test specials as any word position
+ do_print("Special as first word");
+ yield check_autocomplete({
+ search: "^ foo bar",
+ matches: [ { uri: uri2, title: "foo.bar" },
+ { uri: uri3, title: "title" },
+ { uri: uri4, title: "foo.bar" },
+ { uri: uri6, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("Special as middle word");
+ yield check_autocomplete({
+ search: "foo ^ bar",
+ matches: [ { uri: uri2, title: "foo.bar" },
+ { uri: uri3, title: "title" },
+ { uri: uri4, title: "foo.bar" },
+ { uri: uri6, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("Special as last word");
+ yield check_autocomplete({
+ search: "foo bar ^",
+ matches: [ { uri: uri2, title: "foo.bar" },
+ { uri: uri3, title: "title" },
+ { uri: uri4, title: "foo.bar" },
+ { uri: uri6, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ // Test restricting and matching searches with a term
+ do_print("foo ^ -> history");
+ yield check_autocomplete({
+ search: "foo ^",
+ matches: [ { uri: uri2, title: "foo.bar" },
+ { uri: uri3, title: "title" },
+ { uri: uri4, title: "foo.bar" },
+ { uri: uri6, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo | -> history (change pref)");
+ changeRestrict("history", "|");
+ yield check_autocomplete({
+ search: "foo |",
+ matches: [ { uri: uri2, title: "foo.bar" },
+ { uri: uri3, title: "title" },
+ { uri: uri4, title: "foo.bar" },
+ { uri: uri6, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo * -> is star");
+ resetRestrict("history");
+ yield check_autocomplete({
+ search: "foo *",
+ matches: [ { uri: uri6, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri7, title: "title", style: [ "bookmark" ] },
+ { uri: uri8, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri9, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("foo | -> is star (change pref)");
+ changeRestrict("bookmark", "|");
+ yield check_autocomplete({
+ search: "foo |",
+ matches: [ { uri: uri6, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri7, title: "title", style: [ "bookmark" ] },
+ { uri: uri8, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri9, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("foo # -> in title");
+ resetRestrict("bookmark");
+ yield check_autocomplete({
+ search: "foo #",
+ matches: [ { uri: uri2, title: "foo.bar" },
+ { uri: uri4, title: "foo.bar" },
+ { uri: uri6, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri8, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri9, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo | -> in title (change pref)");
+ changeRestrict("title", "|");
+ yield check_autocomplete({
+ search: "foo |",
+ matches: [ { uri: uri2, title: "foo.bar" },
+ { uri: uri4, title: "foo.bar" },
+ { uri: uri6, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri8, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri9, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo @ -> in url");
+ resetRestrict("title");
+ yield check_autocomplete({
+ search: "foo @",
+ matches: [ { uri: uri3, title: "title" },
+ { uri: uri4, title: "foo.bar" },
+ { uri: uri7, title: "title", style: [ "bookmark" ] },
+ { uri: uri8, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo | -> in url (change pref)");
+ changeRestrict("url", "|");
+ yield check_autocomplete({
+ search: "foo |",
+ matches: [ { uri: uri3, title: "title" },
+ { uri: uri4, title: "foo.bar" },
+ { uri: uri7, title: "title", style: [ "bookmark" ] },
+ { uri: uri8, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo + -> is tag");
+ resetRestrict("url");
+ yield check_autocomplete({
+ search: "foo +",
+ matches: [ { uri: uri9, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo | -> is tag (change pref)");
+ changeRestrict("tag", "|");
+ yield check_autocomplete({
+ search: "foo |",
+ matches: [ { uri: uri9, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo ~ -> is typed");
+ resetRestrict("tag");
+ yield check_autocomplete({
+ search: "foo ~",
+ matches: [ { uri: uri4, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo | -> is typed (change pref)");
+ changeRestrict("typed", "|");
+ yield check_autocomplete({
+ search: "foo |",
+ matches: [ { uri: uri4, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ // Test various pairs of special searches
+ do_print("foo ^ * -> history, is star");
+ resetRestrict("typed");
+ yield check_autocomplete({
+ search: "foo ^ *",
+ matches: [ { uri: uri6, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("foo ^ # -> history, in title");
+ yield check_autocomplete({
+ search: "foo ^ #",
+ matches: [ { uri: uri2, title: "foo.bar" },
+ { uri: uri4, title: "foo.bar" },
+ { uri: uri6, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo ^ @ -> history, in url");
+ yield check_autocomplete({
+ search: "foo ^ @",
+ matches: [ { uri: uri3, title: "title" },
+ { uri: uri4, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo ^ + -> history, is tag");
+ yield check_autocomplete({
+ search: "foo ^ +",
+ matches: [ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo ^ ~ -> history, is typed");
+ yield check_autocomplete({
+ search: "foo ^ ~",
+ matches: [ { uri: uri4, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo * # -> is star, in title");
+ yield check_autocomplete({
+ search: "foo * #",
+ matches: [ { uri: uri6, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri8, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri9, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("foo * @ -> is star, in url");
+ yield check_autocomplete({
+ search: "foo * @",
+ matches: [ { uri: uri7, title: "title", style: [ "bookmark" ] },
+ { uri: uri8, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("foo * + -> same as +");
+ yield check_autocomplete({
+ search: "foo * +",
+ matches: [ { uri: uri9, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("foo * ~ -> is star, is typed");
+ yield check_autocomplete({
+ search: "foo * ~",
+ matches: [ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("foo # @ -> in title, in url");
+ yield check_autocomplete({
+ search: "foo # @",
+ matches: [ { uri: uri4, title: "foo.bar" },
+ { uri: uri8, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo # + -> in title, is tag");
+ yield check_autocomplete({
+ search: "foo # +",
+ matches: [ { uri: uri9, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo # ~ -> in title, is typed");
+ yield check_autocomplete({
+ search: "foo # ~",
+ matches: [ { uri: uri4, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo @ + -> in url, is tag");
+ yield check_autocomplete({
+ search: "foo @ +",
+ matches: [ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo @ ~ -> in url, is typed");
+ yield check_autocomplete({
+ search: "foo @ ~",
+ matches: [ { uri: uri4, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ do_print("foo + ~ -> is tag, is typed");
+ yield check_autocomplete({
+ search: "foo + ~",
+ matches: [ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "tag" ] } ]
+ });
+
+ // Disable autoFill for the next tests, see test_autoFill_default_behavior.js
+ // for specific tests.
+ Services.prefs.setBoolPref("browser.urlbar.autoFill", false);
+
+ // Test default usage by setting certain browser.urlbar.suggest.* prefs
+ do_print("foo -> default history");
+ setSuggestPrefsToFalse();
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history", true);
+ yield check_autocomplete({
+ search: "foo",
+ matches: [ { uri: uri2, title: "foo.bar" },
+ { uri: uri3, title: "title" },
+ { uri: uri4, title: "foo.bar" },
+ { uri: uri6, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: ["foo.bar"], style: [ "tag" ] } ]
+ });
+
+ do_print("foo -> default history, is star");
+ setSuggestPrefsToFalse();
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history", true);
+ Services.prefs.setBoolPref("browser.urlbar.suggest.bookmark", true);
+ yield check_autocomplete({
+ search: "foo",
+ matches: [ { uri: uri2, title: "foo.bar" },
+ { uri: uri3, title: "title" },
+ { uri: uri4, title: "foo.bar" },
+ { uri: uri6, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri7, title: "title", style: [ "bookmark" ] },
+ { uri: uri8, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri9, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar"], style: [ "bookmark-tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("foo -> default history, is star, is typed");
+ setSuggestPrefsToFalse();
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history", true);
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history.onlyTyped", true);
+ Services.prefs.setBoolPref("browser.urlbar.suggest.bookmark", true);
+ yield check_autocomplete({
+ search: "foo",
+ matches: [ { uri: uri4, title: "foo.bar" },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("foo -> is star");
+ setSuggestPrefsToFalse();
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history", false);
+ Services.prefs.setBoolPref("browser.urlbar.suggest.bookmark", true);
+ yield check_autocomplete({
+ search: "foo",
+ matches: [ { uri: uri6, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri7, title: "title", style: [ "bookmark" ] },
+ { uri: uri8, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri9, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("foo -> is star, is typed");
+ setSuggestPrefsToFalse();
+ // only typed should be ignored
+ Services.prefs.setBoolPref("browser.urlbar.suggest.history.onlyTyped", true);
+ Services.prefs.setBoolPref("browser.urlbar.suggest.bookmark", true);
+ yield check_autocomplete({
+ search: "foo",
+ matches: [ { uri: uri6, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri7, title: "title", style: [ "bookmark" ] },
+ { uri: uri8, title: "foo.bar", style: [ "bookmark" ] },
+ { uri: uri9, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri10, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri11, title: "title", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] },
+ { uri: uri12, title: "foo.bar", tags: [ "foo.bar" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_swap_protocol.js b/toolkit/components/places/tests/unifiedcomplete/test_swap_protocol.js
new file mode 100644
index 000000000..89ccc3206
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_swap_protocol.js
@@ -0,0 +1,153 @@
+/* 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/. */
+
+/**
+ * Test bug 424717 to make sure searching with an existing location like
+ * http://site/ also matches https://site/ or ftp://site/. Same thing for
+ * ftp://site/ and https://site/.
+ *
+ * Test bug 461483 to make sure a search for "w" doesn't match the "www." from
+ * site subdomains.
+ */
+
+add_task(function* test_swap_protocol() {
+ let uri1 = NetUtil.newURI("http://www.site/");
+ let uri2 = NetUtil.newURI("http://site/");
+ let uri3 = NetUtil.newURI("ftp://ftp.site/");
+ let uri4 = NetUtil.newURI("ftp://site/");
+ let uri5 = NetUtil.newURI("https://www.site/");
+ let uri6 = NetUtil.newURI("https://site/");
+ let uri7 = NetUtil.newURI("http://woohoo/");
+ let uri8 = NetUtil.newURI("http://wwwwwwacko/");
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "title" },
+ { uri: uri2, title: "title" },
+ { uri: uri3, title: "title" },
+ { uri: uri4, title: "title" },
+ { uri: uri5, title: "title" },
+ { uri: uri6, title: "title" },
+ { uri: uri7, title: "title" },
+ { uri: uri8, title: "title" }
+ ]);
+
+ let allMatches = [
+ { uri: uri1, title: "title" },
+ { uri: uri2, title: "title" },
+ { uri: uri3, title: "title" },
+ { uri: uri4, title: "title" },
+ { uri: uri5, title: "title" },
+ { uri: uri6, title: "title" }
+ ];
+
+ // Disable autoFill to avoid handling the first result.
+ Services.prefs.setBoolPref("browser.urlbar.autoFill", "false");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.searchEngines", false);
+
+ do_print("http://www.site matches all site");
+ yield check_autocomplete({
+ search: "http://www.site",
+ matches: allMatches
+ });
+
+ do_print("http://site matches all site");
+ yield check_autocomplete({
+ search: "http://site",
+ matches: allMatches
+ });
+
+ do_print("ftp://ftp.site matches itself");
+ yield check_autocomplete({
+ search: "ftp://ftp.site",
+ matches: [ { uri: uri3, title: "title" } ]
+ });
+
+ do_print("ftp://site matches all site");
+ yield check_autocomplete({
+ search: "ftp://site",
+ matches: allMatches
+ });
+
+ do_print("https://www.site matches all site");
+ yield check_autocomplete({
+ search: "https://www.site",
+ matches: allMatches
+ });
+
+ do_print("https://site matches all site");
+ yield check_autocomplete({
+ search: "https://site",
+ matches: allMatches
+ });
+
+ do_print("www.site matches all site");
+ yield check_autocomplete({
+ search: "www.site",
+ matches: allMatches
+ });
+
+ do_print("w matches none of www.");
+ yield check_autocomplete({
+ search: "w",
+ matches: [ { uri: uri7, title: "title" },
+ { uri: uri8, title: "title" } ]
+ });
+
+ do_print("http://w matches none of www.");
+ yield check_autocomplete({
+ search: "http://w",
+ matches: [ { uri: uri7, title: "title" },
+ { uri: uri8, title: "title" } ]
+ });
+
+ do_print("http://w matches none of www.");
+ yield check_autocomplete({
+ search: "http://www.w",
+ matches: [ { uri: uri7, title: "title" },
+ { uri: uri8, title: "title" } ]
+ });
+
+ do_print("ww matches none of www.");
+ yield check_autocomplete({
+ search: "ww",
+ matches: [ { uri: uri8, title: "title" } ]
+ });
+
+ do_print("ww matches none of www.");
+ yield check_autocomplete({
+ search: "ww",
+ matches: [ { uri: uri8, title: "title" } ]
+ });
+
+ do_print("http://ww matches none of www.");
+ yield check_autocomplete({
+ search: "http://ww",
+ matches: [ { uri: uri8, title: "title" } ]
+ });
+
+ do_print("http://www.ww matches none of www.");
+ yield check_autocomplete({
+ search: "http://www.ww",
+ matches: [ { uri: uri8, title: "title" } ]
+ });
+
+ do_print("www matches none of www.");
+ yield check_autocomplete({
+ search: "www",
+ matches: [ { uri: uri8, title: "title" } ]
+ });
+
+ do_print("http://www matches none of www.");
+ yield check_autocomplete({
+ search: "http://www",
+ matches: [ { uri: uri8, title: "title" } ]
+ });
+
+ do_print("http://www.www matches none of www.");
+ yield check_autocomplete({
+ search: "http://www.www",
+ matches: [ { uri: uri8, title: "title" } ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_tab_matches.js b/toolkit/components/places/tests/unifiedcomplete/test_tab_matches.js
new file mode 100644
index 000000000..740b8d8ed
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_tab_matches.js
@@ -0,0 +1,164 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * vim:set ts=2 sw=2 sts=2 et:
+ * 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/. */
+
+var gTabRestrictChar = "%";
+
+add_task(function* test_tab_matches() {
+ let uri1 = NetUtil.newURI("http://abc.com/");
+ let uri2 = NetUtil.newURI("http://xyz.net/");
+ let uri3 = NetUtil.newURI("about:mozilla");
+ let uri4 = NetUtil.newURI("data:text/html,test");
+ let uri5 = NetUtil.newURI("http://foobar.org");
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "ABC rocks" },
+ { uri: uri2, title: "xyz.net - we're better than ABC" },
+ { uri: uri5, title: "foobar.org - much better than ABC, definitely better than XYZ" }
+ ]);
+ addOpenPages(uri1, 1);
+ // Pages that cannot be registered in history.
+ addOpenPages(uri3, 1);
+ addOpenPages(uri4, 1);
+
+ do_print("two results, normal result is a tab match");
+ yield check_autocomplete({
+ search: "abc.com",
+ searchParam: "enable-actions",
+ matches: [ makeVisitMatch("abc.com", "http://abc.com/", { heuristic: true }),
+ makeSwitchToTabMatch("http://abc.com/", { title: "ABC rocks" }),
+ makeSearchMatch("abc.com", { heuristic: false }) ]
+ });
+
+ do_print("three results, one tab match");
+ yield check_autocomplete({
+ search: "abc",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("abc", { heuristic: true }),
+ makeSwitchToTabMatch("http://abc.com/", { title: "ABC rocks" }),
+ { uri: uri2, title: "xyz.net - we're better than ABC", style: [ "favicon" ] },
+ { uri: uri5, title: "foobar.org - much better than ABC, definitely better than XYZ", style: [ "favicon" ] } ]
+ });
+
+ do_print("three results, both normal results are tab matches");
+ addOpenPages(uri2, 1);
+ yield check_autocomplete({
+ search: "abc",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("abc", { heuristic: true }),
+ makeSwitchToTabMatch("http://abc.com/", { title: "ABC rocks" }),
+ makeSwitchToTabMatch("http://xyz.net/", { title: "xyz.net - we're better than ABC" }),
+ { uri: uri5, title: "foobar.org - much better than ABC, definitely better than XYZ", style: [ "favicon" ] } ]
+ });
+
+ do_print("a container tab is not visible in 'switch to tab'");
+ addOpenPages(uri5, 1, /* userContextId: */ 3);
+ yield check_autocomplete({
+ search: "abc",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("abc", { heuristic: true }),
+ makeSwitchToTabMatch("http://abc.com/", { title: "ABC rocks" }),
+ makeSwitchToTabMatch("http://xyz.net/", { title: "xyz.net - we're better than ABC" }),
+ { uri: uri5, title: "foobar.org - much better than ABC, definitely better than XYZ", style: [ "favicon" ] } ]
+ });
+
+ do_print("a container tab should not see 'switch to tab' for other container tabs");
+ yield check_autocomplete({
+ search: "abc",
+ searchParam: "enable-actions user-context-id:3",
+ matches: [ makeSearchMatch("abc", { heuristic: true }),
+ makeSwitchToTabMatch("http://foobar.org/", { title: "foobar.org - much better than ABC, definitely better than XYZ" }),
+ { uri: uri1, title: "ABC rocks", style: [ "favicon" ] },
+ { uri: uri2, title: "xyz.net - we're better than ABC", style: [ "favicon" ] } ]
+ });
+
+ do_print("a different container tab should not see any 'switch to tab'");
+ yield check_autocomplete({
+ search: "abc",
+ searchParam: "enable-actions user-context-id:2",
+ matches: [ makeSearchMatch("abc", { heuristic: true }),
+ { uri: uri1, title: "ABC rocks", style: [ "favicon" ] },
+ { uri: uri2, title: "xyz.net - we're better than ABC", style: [ "favicon" ] },
+ { uri: uri5, title: "foobar.org - much better than ABC, definitely better than XYZ", style: [ "favicon" ] } ]
+ });
+
+ do_print("three results, both normal results are tab matches, one has multiple tabs");
+ addOpenPages(uri2, 5);
+ yield check_autocomplete({
+ search: "abc",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("abc", { heuristic: true }),
+ makeSwitchToTabMatch("http://abc.com/", { title: "ABC rocks" }),
+ makeSwitchToTabMatch("http://xyz.net/", { title: "xyz.net - we're better than ABC" }),
+ { uri: uri5, title: "foobar.org - much better than ABC, definitely better than XYZ", style: [ "favicon" ] } ]
+ });
+
+ do_print("three results, no tab matches (disable-private-actions)");
+ yield check_autocomplete({
+ search: "abc",
+ searchParam: "enable-actions disable-private-actions",
+ matches: [ makeSearchMatch("abc", { heuristic: true }),
+ { uri: uri1, title: "ABC rocks", style: [ "favicon" ] },
+ { uri: uri2, title: "xyz.net - we're better than ABC", style: [ "favicon" ] },
+ { uri: uri5, title: "foobar.org - much better than ABC, definitely better than XYZ", style: [ "favicon" ] } ]
+ });
+
+ do_print("two results (actions disabled)");
+ yield check_autocomplete({
+ search: "abc",
+ searchParam: "",
+ matches: [ { uri: uri1, title: "ABC rocks", style: [ "favicon" ] },
+ { uri: uri2, title: "xyz.net - we're better than ABC", style: [ "favicon" ] },
+ { uri: uri5, title: "foobar.org - much better than ABC, definitely better than XYZ", style: [ "favicon" ] } ]
+ });
+
+ do_print("three results, no tab matches");
+ removeOpenPages(uri1, 1);
+ removeOpenPages(uri2, 6);
+ yield check_autocomplete({
+ search: "abc",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("abc", { heuristic: true }),
+ { uri: uri1, title: "ABC rocks", style: [ "favicon" ] },
+ { uri: uri2, title: "xyz.net - we're better than ABC", style: [ "favicon" ] },
+ { uri: uri5, title: "foobar.org - much better than ABC, definitely better than XYZ", style: [ "favicon" ] } ]
+ });
+
+ do_print("tab match search with restriction character");
+ addOpenPages(uri1, 1);
+ yield check_autocomplete({
+ search: gTabRestrictChar + " abc",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch(gTabRestrictChar + " abc", { heuristic: true }),
+ makeSwitchToTabMatch("http://abc.com/", { title: "ABC rocks" }) ]
+ });
+
+ do_print("tab match with not-addable pages");
+ yield check_autocomplete({
+ search: "mozilla",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("mozilla", { heuristic: true }),
+ makeSwitchToTabMatch("about:mozilla") ]
+ });
+
+ do_print("tab match with not-addable pages and restriction character");
+ yield check_autocomplete({
+ search: gTabRestrictChar + " mozilla",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch(gTabRestrictChar + " mozilla", { heuristic: true }),
+ makeSwitchToTabMatch("about:mozilla") ]
+ });
+
+ do_print("tab match with not-addable pages and only restriction character");
+ yield check_autocomplete({
+ search: gTabRestrictChar,
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch(gTabRestrictChar, { heuristic: true }),
+ makeSwitchToTabMatch("http://abc.com/", { title: "ABC rocks" }),
+ makeSwitchToTabMatch("about:mozilla"),
+ makeSwitchToTabMatch("data:text/html,test") ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_trimming.js b/toolkit/components/places/tests/unifiedcomplete/test_trimming.js
new file mode 100644
index 000000000..e55b009ff
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_trimming.js
@@ -0,0 +1,313 @@
+/* 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/. */
+
+add_task(function* test_untrimmed_secure_www() {
+ do_print("Searching for untrimmed https://www entry");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("https://www.mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "mozilla.org/",
+ completed: "https://www.mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untrimmed_secure_www_path() {
+ do_print("Searching for untrimmed https://www entry with path");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("https://www.mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mozilla.org/t",
+ autofilled: "mozilla.org/test/",
+ completed: "https://www.mozilla.org/test/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untrimmed_secure() {
+ do_print("Searching for untrimmed https:// entry");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("https://mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "mozilla.org/",
+ completed: "https://mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untrimmed_secure_path() {
+ do_print("Searching for untrimmed https:// entry with path");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("https://mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mozilla.org/t",
+ autofilled: "mozilla.org/test/",
+ completed: "https://mozilla.org/test/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untrimmed_www() {
+ do_print("Searching for untrimmed http://www entry");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://www.mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "mozilla.org/",
+ completed: "www.mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untrimmed_www_path() {
+ do_print("Searching for untrimmed http://www entry with path");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://www.mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mozilla.org/t",
+ autofilled: "mozilla.org/test/",
+ completed: "http://www.mozilla.org/test/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untrimmed_ftp() {
+ do_print("Searching for untrimmed ftp:// entry");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("ftp://mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "mozilla.org/",
+ completed: "ftp://mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untrimmed_ftp_path() {
+ do_print("Searching for untrimmed ftp:// entry with path");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("ftp://mozilla.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "mozilla.org/t",
+ autofilled: "mozilla.org/test/",
+ completed: "ftp://mozilla.org/test/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_priority_1() {
+ do_print("Ensuring correct priority 1");
+ yield PlacesTestUtils.addVisits([
+ { uri: NetUtil.newURI("https://www.mozilla.org/test/"), transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("https://mozilla.org/test/"), transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("ftp://mozilla.org/test/"), transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("http://www.mozilla.org/test/"), transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("http://mozilla.org/test/"), transition: TRANSITION_TYPED }
+ ]);
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "mozilla.org/",
+ completed: "mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_periority_2() {
+ do_print( "Ensuring correct priority 2");
+ yield PlacesTestUtils.addVisits([
+ { uri: NetUtil.newURI("https://mozilla.org/test/"), transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("ftp://mozilla.org/test/"), transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("http://www.mozilla.org/test/"), transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("http://mozilla.org/test/"), transition: TRANSITION_TYPED }
+ ]);
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "mozilla.org/",
+ completed: "mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_periority_3() {
+ do_print("Ensuring correct priority 3");
+ yield PlacesTestUtils.addVisits([
+ { uri: NetUtil.newURI("ftp://mozilla.org/test/"), transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("http://www.mozilla.org/test/"), transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("http://mozilla.org/test/"), transition: TRANSITION_TYPED }
+ ]);
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "mozilla.org/",
+ completed: "mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_periority_4() {
+ do_print("Ensuring correct priority 4");
+ yield PlacesTestUtils.addVisits([
+ { uri: NetUtil.newURI("http://www.mozilla.org/test/"), transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("http://mozilla.org/test/"), transition: TRANSITION_TYPED }
+ ]);
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "mozilla.org/",
+ completed: "mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_priority_5() {
+ do_print("Ensuring correct priority 5");
+ yield PlacesTestUtils.addVisits([
+ { uri: NetUtil.newURI("ftp://mozilla.org/test/"), transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("ftp://www.mozilla.org/test/"), transition: TRANSITION_TYPED }
+ ]);
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "mozilla.org/",
+ completed: "ftp://mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_priority_6() {
+ do_print("Ensuring correct priority 6");
+ yield PlacesTestUtils.addVisits([
+ { uri: NetUtil.newURI("http://www.mozilla.org/test1/"), transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("http://www.mozilla.org/test2/"), transition: TRANSITION_TYPED }
+ ]);
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "mozilla.org/",
+ completed: "www.mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_longer_domain() {
+ do_print("Ensuring longer domain can't match");
+ // The .co should be preferred, but should not get the https from the .com.
+ // The .co domain must be added later to activate the trigger bug.
+ yield PlacesTestUtils.addVisits([
+ { uri: NetUtil.newURI("https://mozilla.com/"), transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("http://mozilla.co/"), transition: TRANSITION_TYPED },
+ { uri: NetUtil.newURI("http://mozilla.co/"), transition: TRANSITION_TYPED }
+ ]);
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "mozilla.co/",
+ completed: "mozilla.co/"
+ });
+
+ yield cleanup();
+});
+
+add_task(function* test_escaped_chars() {
+ do_print("Searching for URL with characters that are normally escaped");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("https://www.mozilla.org/啊-test"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "https://www.mozilla.org/啊-test",
+ autofilled: "https://www.mozilla.org/啊-test",
+ completed: "https://www.mozilla.org/啊-test"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_unsecure_secure() {
+ do_print("Don't return unsecure URL when searching for secure ones");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://test.moz.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "https://test.moz.org/t",
+ autofilled: "https://test.moz.org/test/",
+ completed: "https://test.moz.org/test/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_unsecure_secure_domain() {
+ do_print("Don't return unsecure domain when searching for secure ones");
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://test.moz.org/test/"),
+ transition: TRANSITION_TYPED
+ });
+ yield check_autocomplete({
+ search: "https://test.moz",
+ autofilled: "https://test.moz.org/",
+ completed: "https://test.moz.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untyped_www() {
+ do_print("Untyped is not accounted for www");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield PlacesTestUtils.addVisits({ uri: NetUtil.newURI("http://www.moz.org/test/") });
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "moz.org/",
+ completed: "moz.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untyped_ftp() {
+ do_print("Untyped is not accounted for ftp");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield PlacesTestUtils.addVisits({ uri: NetUtil.newURI("ftp://moz.org/test/") });
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "moz.org/",
+ completed: "moz.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untyped_secure() {
+ do_print("Untyped is not accounted for https");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield PlacesTestUtils.addVisits({ uri: NetUtil.newURI("https://moz.org/test/") });
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "moz.org/",
+ completed: "moz.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untyped_secure_www() {
+ do_print("Untyped is not accounted for https://www");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield PlacesTestUtils.addVisits({ uri: NetUtil.newURI("https://www.moz.org/test/") });
+ yield check_autocomplete({
+ search: "mo",
+ autofilled: "moz.org/",
+ completed: "moz.org/"
+ });
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_typed.js b/toolkit/components/places/tests/unifiedcomplete/test_typed.js
new file mode 100644
index 000000000..72f76159c
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_typed.js
@@ -0,0 +1,84 @@
+/* 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/. */
+
+// First do searches with typed behavior forced to false, so later tests will
+// ensure autocomplete is able to dinamically switch behavior.
+
+const FAVICON_HREF = NetUtil.newURI(do_get_file("../favicons/favicon-normal16.png")).spec;
+
+add_task(function* test_domain() {
+ do_print("Searching for domain should autoFill it");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield PlacesTestUtils.addVisits(NetUtil.newURI("http://mozilla.org/link/"));
+ yield setFaviconForHref("http://mozilla.org/link/", FAVICON_HREF);
+ yield check_autocomplete({
+ search: "moz",
+ autofilled: "mozilla.org/",
+ completed: "mozilla.org/",
+ icon: "moz-anno:favicon:" + FAVICON_HREF
+ });
+ yield cleanup();
+});
+
+add_task(function* test_url() {
+ do_print("Searching for url should autoFill it");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield PlacesTestUtils.addVisits(NetUtil.newURI("http://mozilla.org/link/"));
+ yield setFaviconForHref("http://mozilla.org/link/", FAVICON_HREF);
+ yield check_autocomplete({
+ search: "mozilla.org/li",
+ autofilled: "mozilla.org/link/",
+ completed: "http://mozilla.org/link/",
+ icon: "moz-anno:favicon:" + FAVICON_HREF
+ });
+ yield cleanup();
+});
+
+// Now do searches with typed behavior forced to true.
+
+add_task(function* test_untyped_domain() {
+ do_print("Searching for non-typed domain should not autoFill it");
+ yield PlacesTestUtils.addVisits(NetUtil.newURI("http://mozilla.org/link/"));
+ yield check_autocomplete({
+ search: "moz",
+ autofilled: "moz",
+ completed: "moz"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_typed_domain() {
+ do_print("Searching for typed domain should autoFill it");
+ yield PlacesTestUtils.addVisits({ uri: NetUtil.newURI("http://mozilla.org/typed/"),
+ transition: TRANSITION_TYPED });
+ yield check_autocomplete({
+ search: "moz",
+ autofilled: "mozilla.org/",
+ completed: "mozilla.org/"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_untyped_url() {
+ do_print("Searching for non-typed url should not autoFill it");
+ yield PlacesTestUtils.addVisits(NetUtil.newURI("http://mozilla.org/link/"));
+ yield check_autocomplete({
+ search: "mozilla.org/li",
+ autofilled: "mozilla.org/li",
+ completed: "mozilla.org/li"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_typed_url() {
+ do_print("Searching for typed url should autoFill it");
+ yield PlacesTestUtils.addVisits({ uri: NetUtil.newURI("http://mozilla.org/link/"),
+ transition: TRANSITION_TYPED });
+ yield check_autocomplete({
+ search: "mozilla.org/li",
+ autofilled: "mozilla.org/link/",
+ completed: "http://mozilla.org/link/"
+ });
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_visit_url.js b/toolkit/components/places/tests/unifiedcomplete/test_visit_url.js
new file mode 100644
index 000000000..eaccb23e5
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_visit_url.js
@@ -0,0 +1,186 @@
+add_task(function*() {
+ do_print("visit url, no protocol");
+ yield check_autocomplete({
+ search: "mozilla.org",
+ searchParam: "enable-actions",
+ matches: [
+ { uri: makeActionURI("visiturl", {url: "http://mozilla.org/", input: "mozilla.org"}), title: "http://mozilla.org/", style: [ "action", "visiturl", "heuristic" ] },
+ { uri: makeActionURI("searchengine", {engineName: "MozSearch", input: "mozilla.org", searchQuery: "mozilla.org"}), title: "MozSearch", style: ["action", "searchengine"] }
+ ]
+ });
+
+ do_print("visit url, no protocol but with 2 dots");
+ yield check_autocomplete({
+ search: "www.mozilla.org",
+ searchParam: "enable-actions",
+ matches: [
+ { uri: makeActionURI("visiturl", {url: "http://www.mozilla.org/", input: "www.mozilla.org"}), title: "http://www.mozilla.org/", style: [ "action", "visiturl", "heuristic" ] },
+ { uri: makeActionURI("searchengine", {engineName: "MozSearch", input: "www.mozilla.org", searchQuery: "www.mozilla.org"}), title: "MozSearch", style: ["action", "searchengine"] }
+ ]
+ });
+
+ do_print("visit url, no protocol but with 3 dots");
+ yield check_autocomplete({
+ search: "www.mozilla.org.tw",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("visiturl", {url: "http://www.mozilla.org.tw/", input: "www.mozilla.org.tw"}), title: "http://www.mozilla.org.tw/", style: [ "action", "visiturl", "heuristic" ] } ]
+ });
+
+ do_print("visit url, with protocol but with 2 dots");
+ yield check_autocomplete({
+ search: "https://www.mozilla.org",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("visiturl", {url: "https://www.mozilla.org/", input: "https://www.mozilla.org"}), title: "https://www.mozilla.org/", style: [ "action", "visiturl", "heuristic" ] } ]
+ });
+
+ do_print("visit url, with protocol but with 3 dots");
+ yield check_autocomplete({
+ search: "https://www.mozilla.org.tw",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("visiturl", {url: "https://www.mozilla.org.tw/", input: "https://www.mozilla.org.tw"}), title: "https://www.mozilla.org.tw/", style: [ "action", "visiturl", "heuristic" ] } ]
+ });
+
+ do_print("visit url, with protocol");
+ yield check_autocomplete({
+ search: "https://mozilla.org",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("visiturl", {url: "https://mozilla.org/", input: "https://mozilla.org"}), title: "https://mozilla.org/", style: [ "action", "visiturl", "heuristic" ] } ]
+ });
+
+ do_print("visit url, about: protocol (no host)");
+ yield check_autocomplete({
+ search: "about:config",
+ searchParam: "enable-actions",
+ matches: [ { uri: makeActionURI("visiturl", {url: "about:config", input: "about:config"}), title: "about:config", style: [ "action", "visiturl", "heuristic" ] } ]
+ });
+
+ // This is distinct because of how we predict being able to url autofill via
+ // host lookups.
+ do_print("visit url, host matching visited host but not visited url");
+ yield PlacesTestUtils.addVisits([
+ { uri: NetUtil.newURI("http://mozilla.org/wine/"), title: "Mozilla Wine", transition: TRANSITION_TYPED },
+ ]);
+ yield check_autocomplete({
+ search: "mozilla.org/rum",
+ searchParam: "enable-actions",
+ matches: [ makeVisitMatch("mozilla.org/rum", "http://mozilla.org/rum", { heuristic: true }) ]
+ });
+
+ // And hosts with no dot in them are special, due to requiring whitelisting.
+ do_print("non-whitelisted host");
+ yield check_autocomplete({
+ search: "firefox",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("firefox", { heuristic: true }) ]
+ });
+
+ do_print("url with non-whitelisted host");
+ yield check_autocomplete({
+ search: "firefox/get",
+ searchParam: "enable-actions",
+ matches: [ makeVisitMatch("firefox/get", "http://firefox/get", { heuristic: true }) ]
+ });
+
+ Services.prefs.setBoolPref("browser.fixup.domainwhitelist.firefox", true);
+ do_register_cleanup(() => {
+ Services.prefs.clearUserPref("browser.fixup.domainwhitelist.firefox");
+ });
+
+ do_print("whitelisted host");
+ yield check_autocomplete({
+ search: "firefox",
+ searchParam: "enable-actions",
+ matches: [
+ makeVisitMatch("firefox", "http://firefox/", { heuristic: true }),
+ makeSearchMatch("firefox", { heuristic: false })
+ ]
+ });
+
+ do_print("url with whitelisted host");
+ yield check_autocomplete({
+ search: "firefox/get",
+ searchParam: "enable-actions",
+ matches: [ makeVisitMatch("firefox/get", "http://firefox/get", { heuristic: true }) ]
+ });
+
+ do_print("visit url, host matching visited host but not visited url, whitelisted host");
+ Services.prefs.setBoolPref("browser.fixup.domainwhitelist.mozilla", true);
+ do_register_cleanup(() => {
+ Services.prefs.clearUserPref("browser.fixup.domainwhitelist.mozilla");
+ });
+ yield check_autocomplete({
+ search: "mozilla/rum",
+ searchParam: "enable-actions",
+ matches: [ makeVisitMatch("mozilla/rum", "http://mozilla/rum", { heuristic: true }) ]
+ });
+
+ // ipv4 and ipv6 literal addresses should offer to visit.
+ do_print("visit url, ipv4 literal");
+ yield check_autocomplete({
+ search: "127.0.0.1",
+ searchParam: "enable-actions",
+ matches: [ makeVisitMatch("127.0.0.1", "http://127.0.0.1/", { heuristic: true }) ]
+ });
+
+ do_print("visit url, ipv6 literal");
+ yield check_autocomplete({
+ search: "[2001:db8::1]",
+ searchParam: "enable-actions",
+ matches: [ makeVisitMatch("[2001:db8::1]", "http://[2001:db8::1]/", { heuristic: true }) ]
+ });
+
+ // Setting keyword.enabled to false should always try to visit.
+ let keywordEnabled = Services.prefs.getBoolPref("keyword.enabled");
+ Services.prefs.setBoolPref("keyword.enabled", false);
+ do_register_cleanup(() => {
+ Services.prefs.clearUserPref("keyword.enabled");
+ });
+ do_print("visit url, keyword.enabled = false");
+ yield check_autocomplete({
+ search: "bacon",
+ searchParam: "enable-actions",
+ matches: [ makeVisitMatch("bacon", "http://bacon/", { heuristic: true }) ]
+ });
+ do_print("visit two word query, keyword.enabled = false");
+ yield check_autocomplete({
+ search: "bacon lovers",
+ searchParam: "enable-actions",
+ matches: [ makeVisitMatch("bacon lovers", "bacon lovers", { heuristic: true }) ]
+ });
+ Services.prefs.setBoolPref("keyword.enabled", keywordEnabled);
+
+ do_print("visit url, scheme+host");
+ yield check_autocomplete({
+ search: "http://example",
+ searchParam: "enable-actions",
+ matches: [ makeVisitMatch("http://example", "http://example/", { heuristic: true }) ]
+ });
+
+ do_print("visit url, scheme+host");
+ yield check_autocomplete({
+ search: "ftp://example",
+ searchParam: "enable-actions",
+ matches: [ makeVisitMatch("ftp://example", "ftp://example/", { heuristic: true }) ]
+ });
+
+ do_print("visit url, host+port");
+ yield check_autocomplete({
+ search: "example:8080",
+ searchParam: "enable-actions",
+ matches: [ makeVisitMatch("example:8080", "http://example:8080/", { heuristic: true }) ]
+ });
+
+ do_print("numerical operations that look like urls should search");
+ yield check_autocomplete({
+ search: "123/12",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("123/12", { heuristic: true }) ]
+ });
+
+ do_print("numerical operations that look like urls should search");
+ yield check_autocomplete({
+ search: "123.12/12.1",
+ searchParam: "enable-actions",
+ matches: [ makeSearchMatch("123.12/12.1", { heuristic: true }) ]
+ });
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_word_boundary_search.js b/toolkit/components/places/tests/unifiedcomplete/test_word_boundary_search.js
new file mode 100644
index 000000000..f79573ae6
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_word_boundary_search.js
@@ -0,0 +1,175 @@
+/* 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/. */
+
+/**
+ * Test bug 393678 to make sure matches against the url, title, tags are only
+ * made on word boundaries instead of in the middle of words.
+ *
+ * Make sure we don't try matching one after a CamelCase because the upper-case
+ * isn't really a word boundary. (bug 429498)
+ *
+ * Bug 429531 provides switching between "must match on word boundary" and "can
+ * match," so leverage "must match" pref for checking word boundary logic and
+ * make sure "can match" matches anywhere.
+ */
+
+var katakana = ["\u30a8", "\u30c9"]; // E, Do
+var ideograph = ["\u4efb", "\u5929", "\u5802"]; // Nin Ten Do
+
+add_task(function* test_escape() {
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.searchEngines", false);
+
+ let uri1 = NetUtil.newURI("http://matchme/");
+ let uri2 = NetUtil.newURI("http://dontmatchme/");
+ let uri3 = NetUtil.newURI("http://title/1");
+ let uri4 = NetUtil.newURI("http://title/2");
+ let uri5 = NetUtil.newURI("http://tag/1");
+ let uri6 = NetUtil.newURI("http://tag/2");
+ let uri7 = NetUtil.newURI("http://crazytitle/");
+ let uri8 = NetUtil.newURI("http://katakana/");
+ let uri9 = NetUtil.newURI("http://ideograph/");
+ let uri10 = NetUtil.newURI("http://camel/pleaseMatchMe/");
+
+ yield PlacesTestUtils.addVisits([
+ { uri: uri1, title: "title1" },
+ { uri: uri2, title: "title1" },
+ { uri: uri3, title: "matchme2" },
+ { uri: uri4, title: "dontmatchme3" },
+ { uri: uri5, title: "title1" },
+ { uri: uri6, title: "title1" },
+ { uri: uri7, title: "!@#$%^&*()_+{}|:<>?word" },
+ { uri: uri8, title: katakana.join("") },
+ { uri: uri9, title: ideograph.join("") },
+ { uri: uri10, title: "title1" }
+ ]);
+ yield addBookmark( { uri: uri5, title: "title1", tags: [ "matchme2" ] } );
+ yield addBookmark( { uri: uri6, title: "title1", tags: [ "dontmatchme3" ] } );
+
+ // match only on word boundaries
+ Services.prefs.setIntPref("browser.urlbar.matchBehavior", 2);
+
+ do_print("Match 'match' at the beginning or after / or on a CamelCase");
+ yield check_autocomplete({
+ search: "match",
+ matches: [ { uri: uri1, title: "title1" },
+ { uri: uri3, title: "matchme2" },
+ { uri: uri5, title: "title1", tags: [ "matchme2" ], style: [ "bookmark-tag" ] },
+ { uri: uri10, title: "title1" } ]
+ });
+
+ do_print("Match 'dont' at the beginning or after /");
+ yield check_autocomplete({
+ search: "dont",
+ matches: [ { uri: uri2, title: "title1" },
+ { uri: uri4, title: "dontmatchme3" },
+ { uri: uri6, title: "title1", tags: [ "dontmatchme3" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("Match 'match' at the beginning or after / or on a CamelCase");
+ yield check_autocomplete({
+ search: "2",
+ matches: [ { uri: uri3, title: "matchme2" },
+ { uri: uri4, title: "dontmatchme3" },
+ { uri: uri5, title: "title1", tags: [ "matchme2" ], style: [ "bookmark-tag" ] },
+ { uri: uri6, title: "title1", tags: [ "dontmatchme3" ], style: [ "bookmark-tag" ] } ]
+ });
+
+ do_print("Match 't' at the beginning or after /");
+ yield check_autocomplete({
+ search: "t",
+ matches: [ { uri: uri1, title: "title1" },
+ { uri: uri2, title: "title1" },
+ { uri: uri3, title: "matchme2" },
+ { uri: uri4, title: "dontmatchme3" },
+ { uri: uri5, title: "title1", tags: [ "matchme2" ], style: [ "bookmark-tag" ] },
+ { uri: uri6, title: "title1", tags: [ "dontmatchme3" ], style: [ "bookmark-tag" ] },
+ { uri: uri10, title: "title1" } ]
+ });
+
+ do_print("Match 'word' after many consecutive word boundaries");
+ yield check_autocomplete({
+ search: "word",
+ matches: [ { uri: uri7, title: "!@#$%^&*()_+{}|:<>?word" } ]
+ });
+
+ do_print("Match a word boundary '/' for everything");
+ yield check_autocomplete({
+ search: "/",
+ matches: [ { uri: uri1, title: "title1" },
+ { uri: uri2, title: "title1" },
+ { uri: uri3, title: "matchme2" },
+ { uri: uri4, title: "dontmatchme3" },
+ { uri: uri5, title: "title1", tags: [ "matchme2" ], style: [ "bookmark-tag" ] },
+ { uri: uri6, title: "title1", tags: [ "dontmatchme3" ], style: [ "bookmark-tag" ] },
+ { uri: uri7, title: "!@#$%^&*()_+{}|:<>?word" },
+ { uri: uri8, title: katakana.join("") },
+ { uri: uri9, title: ideograph.join("") },
+ { uri: uri10, title: "title1" } ]
+ });
+
+ do_print("Match word boundaries '()_+' that are among word boundaries");
+ yield check_autocomplete({
+ search: "()_+",
+ matches: [ { uri: uri7, title: "!@#$%^&*()_+{}|:<>?word" } ]
+ });
+
+ do_print("Katakana characters form a string, so match the beginning");
+ yield check_autocomplete({
+ search: katakana[0],
+ matches: [ { uri: uri8, title: katakana.join("") } ]
+ });
+
+/*
+ do_print("Middle of a katakana word shouldn't be matched");
+ yield check_autocomplete({
+ search: katakana[1],
+ matches: [ ]
+ });
+*/
+ do_print("Ideographs are treated as words so 'nin' is one word");
+ yield check_autocomplete({
+ search: ideograph[0],
+ matches: [ { uri: uri9, title: ideograph.join("") } ]
+ });
+
+ do_print("Ideographs are treated as words so 'ten' is another word");
+ yield check_autocomplete({
+ search: ideograph[1],
+ matches: [ { uri: uri9, title: ideograph.join("") } ]
+ });
+
+ do_print("Ideographs are treated as words so 'do' is yet another word");
+ yield check_autocomplete({
+ search: ideograph[2],
+ matches: [ { uri: uri9, title: ideograph.join("") } ]
+ });
+
+ do_print("Extra negative assert that we don't match in the middle");
+ yield check_autocomplete({
+ search: "ch",
+ matches: [ ]
+ });
+
+ do_print("Don't match one character after a camel-case word boundary (bug 429498)");
+ yield check_autocomplete({
+ search: "atch",
+ matches: [ ]
+ });
+
+ // match against word boundaries and anywhere
+ Services.prefs.setIntPref("browser.urlbar.matchBehavior", 1);
+
+ yield check_autocomplete({
+ search: "tch",
+ matches: [ { uri: uri1, title: "title1" },
+ { uri: uri2, title: "title1" },
+ { uri: uri3, title: "matchme2" },
+ { uri: uri4, title: "dontmatchme3" },
+ { uri: uri5, title: "title1", tags: [ "matchme2" ], style: [ "bookmark-tag" ] },
+ { uri: uri6, title: "title1", tags: [ "dontmatchme3" ], style: [ "bookmark-tag" ] },
+ { uri: uri10, title: "title1" } ]
+ });
+
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/test_zero_frecency.js b/toolkit/components/places/tests/unifiedcomplete/test_zero_frecency.js
new file mode 100644
index 000000000..adf638886
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/test_zero_frecency.js
@@ -0,0 +1,35 @@
+/* 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/. */
+
+// Ensure inline autocomplete doesn't return zero frecency pages.
+
+add_task(function* test_zzero_frec_domain() {
+ do_print("Searching for zero frecency domain should not autoFill it");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/framed_link/"),
+ transition: TRANSITION_FRAMED_LINK
+ });
+ yield check_autocomplete({
+ search: "moz",
+ autofilled: "moz",
+ completed: "moz"
+ });
+ yield cleanup();
+});
+
+add_task(function* test_zzero_frec_url() {
+ do_print("Searching for zero frecency url should not autoFill it");
+ Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);
+ yield PlacesTestUtils.addVisits({
+ uri: NetUtil.newURI("http://mozilla.org/framed_link/"),
+ transition: TRANSITION_FRAMED_LINK
+ });
+ yield check_autocomplete({
+ search: "mozilla.org/f",
+ autofilled: "mozilla.org/f",
+ completed: "mozilla.org/f"
+ });
+ yield cleanup();
+});
diff --git a/toolkit/components/places/tests/unifiedcomplete/xpcshell.ini b/toolkit/components/places/tests/unifiedcomplete/xpcshell.ini
new file mode 100644
index 000000000..60ef8c48a
--- /dev/null
+++ b/toolkit/components/places/tests/unifiedcomplete/xpcshell.ini
@@ -0,0 +1,49 @@
+[DEFAULT]
+head = head_autocomplete.js
+tail =
+skip-if = toolkit == 'android'
+support-files =
+ data/engine-rel-searchform.xml
+ data/engine-suggestions.xml
+ !/toolkit/components/places/tests/favicons/favicon-normal16.png
+
+[test_416211.js]
+[test_416214.js]
+[test_417798.js]
+[test_418257.js]
+[test_422277.js]
+[test_autocomplete_functional.js]
+[test_autocomplete_on_value_removed_479089.js]
+[test_autofill_default_behavior.js]
+[test_avoid_middle_complete.js]
+[test_avoid_stripping_to_empty_tokens.js]
+[test_casing.js]
+[test_do_not_trim.js]
+[test_download_embed_bookmarks.js]
+[test_dupe_urls.js]
+[test_empty_search.js]
+[test_enabled.js]
+[test_escape_self.js]
+[test_extension_matches.js]
+[test_ignore_protocol.js]
+[test_keyword_search.js]
+[test_keyword_search_actions.js]
+[test_keywords.js]
+[test_match_beginning.js]
+[test_multi_word_search.js]
+[test_query_url.js]
+[test_remote_tab_matches.js]
+skip-if = !sync
+[test_search_engine_alias.js]
+[test_search_engine_current.js]
+[test_search_engine_host.js]
+[test_search_engine_restyle.js]
+[test_search_suggestions.js]
+[test_special_search.js]
+[test_swap_protocol.js]
+[test_tab_matches.js]
+[test_trimming.js]
+[test_typed.js]
+[test_visit_url.js]
+[test_word_boundary_search.js]
+[test_zero_frecency.js]