Bug 1173751 - Add unit tests for search suggestions in awesomebar. r=mak

This commit is contained in:
Drew Willcoxon 2015-06-16 12:51:09 -07:00
Родитель 7f6848365c
Коммит ffc5396c41
5 изменённых файлов: 218 добавлений и 41 удалений

Просмотреть файл

@ -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>

Просмотреть файл

@ -8,6 +8,7 @@ const Cr = Components.results;
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://testing-common/httpd.js");
// Import common head.
{
@ -29,7 +30,14 @@ function* cleanup() {
Services.prefs.clearUserPref("browser.urlbar.autoFill");
Services.prefs.clearUserPref("browser.urlbar.autoFill.typed");
Services.prefs.clearUserPref("browser.urlbar.autoFill.searchEngines");
for (let type of ["history", "bookmark", "history.onlyTyped", "openpage"]) {
let suggestPrefs = [
"history",
"bookmark",
"history.onlyTyped",
"openpage",
"searches",
];
for (let type of suggestPrefs) {
Services.prefs.clearUserPref("browser.urlbar.suggest." + type);
}
yield PlacesUtils.bookmarks.eraseEverything();
@ -222,7 +230,7 @@ function* check_autocomplete(test) {
// We didn't hit the break, so we must have not found it
if (j == matches.length)
do_throw(`Didn't find the current result ("${result.value}", "${result.comment}") in matches`);
do_throw(`Didn't find the current result ("${result.value}", "${result.comment}") in matches`); //' (Emacs syntax highlighting fix)
}
Assert.equal(controller.matchCount, matches.length,
@ -393,12 +401,56 @@ function setFaviconForHref(href, iconHref) {
});
}
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,
Ci.nsISearchEngine.DATA_XML, 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);

Просмотреть файл

@ -1,42 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://testing-common/httpd.js");
function* addTestEngines(items) {
let httpServer = new HttpServer();
httpServer.start(-1);
httpServer.registerDirectory("/", do_get_cwd());
let gDataUrl = "http://localhost:" + httpServer.identity.primaryPort + "/data/";
do_register_cleanup(() => httpServer.stop(() => {}));
let engines = [];
for (let item of items) {
do_print("Adding engine: " + item);
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 != item) {
return;
}
Services.obs.removeObserver(obs, "browser-search-engine-modified");
engines.push(engine);
resolve();
}, "browser-search-engine-modified", false);
do_print("`Adding engine from URL: " + gDataUrl + item);
Services.search.addEngine(gDataUrl + item,
Ci.nsISearchEngine.DATA_XML, null, false);
});
}
return engines;
}
add_task(function* test_searchEngine_autoFill() {
Services.prefs.setBoolPref("browser.urlbar.autoFill.searchEngines", true);
Services.search.addEngineWithDetails("MySearchEngine", "", "", "",
@ -67,8 +31,7 @@ add_task(function* test_searchEngine_autoFill() {
add_task(function* test_searchEngine_noautoFill() {
let engineName = "engine-rel-searchform.xml";
let [engine] = yield addTestEngines([engineName]);
do_register_cleanup(() => Services.search.removeEngine(engine));
let engine = yield addTestEngine(engineName);
equal(engine.searchForm, "http://example.com/?search");
Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false);

Просмотреть файл

@ -0,0 +1,147 @@
Cu.import("resource://gre/modules/FormHistory.jsm");
const ENGINE_NAME = "engine-suggestions.xml";
const SERVER_PORT = 9000;
const SUGGEST_PREF = "browser.urlbar.suggest.searches";
// Set this to some other function to change how the server converts search
// strings into suggestions.
let suggestionsFromSearchString = searchStr => {
let suffixes = ["foo", "bar"];
return suffixes.map(s => searchStr + " " + s);
};
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 = suggestionsFromSearchString(searchStr);
let data = [searchStr, suggestions];
resp.setHeader("Content-Type", "application/json", false);
resp.write(JSON.stringify(data));
});
// 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;
yield cleanup();
});
add_task(function* disabled() {
Services.prefs.setBoolPref(SUGGEST_PREF, false);
yield check_autocomplete({
search: "hello",
matches: [],
});
yield cleanup();
});
add_task(function* singleWordQuery() {
Services.prefs.setBoolPref(SUGGEST_PREF, true);
let searchStr = "hello";
yield check_autocomplete({
search: searchStr,
matches: [{
uri: makeActionURI(("searchengine"), {
engineName: ENGINE_NAME,
input: searchStr,
searchQuery: searchStr,
searchSuggestion: "hello foo",
}),
title: ENGINE_NAME,
style: ["action", "searchengine"],
icon: "",
}, {
uri: makeActionURI(("searchengine"), {
engineName: ENGINE_NAME,
input: searchStr,
searchQuery: searchStr,
searchSuggestion: "hello bar",
}),
title: ENGINE_NAME,
style: ["action", "searchengine"],
icon: "",
}],
});
yield cleanup();
});
add_task(function* multiWordQuery() {
Services.prefs.setBoolPref(SUGGEST_PREF, true);
let searchStr = "hello world";
yield check_autocomplete({
search: searchStr,
matches: [{
uri: makeActionURI(("searchengine"), {
engineName: ENGINE_NAME,
input: searchStr,
searchQuery: searchStr,
searchSuggestion: "hello world foo",
}),
title: ENGINE_NAME,
style: ["action", "searchengine"],
icon: "",
}, {
uri: makeActionURI(("searchengine"), {
engineName: ENGINE_NAME,
input: searchStr,
searchQuery: searchStr,
searchSuggestion: "hello world bar",
}),
title: ENGINE_NAME,
style: ["action", "searchengine"],
icon: "",
}],
});
yield cleanup();
});
add_task(function* suffixMatch() {
Services.prefs.setBoolPref(SUGGEST_PREF, true);
let oldFn = suggestionsFromSearchString;
suggestionsFromSearchString = searchStr => {
let prefixes = ["baz", "quux"];
return prefixes.map(p => p + " " + searchStr);
};
let searchStr = "hello";
yield check_autocomplete({
search: searchStr,
matches: [{
uri: makeActionURI(("searchengine"), {
engineName: ENGINE_NAME,
input: searchStr,
searchQuery: searchStr,
searchSuggestion: "baz hello",
}),
title: ENGINE_NAME,
style: ["action", "searchengine"],
icon: "",
}, {
uri: makeActionURI(("searchengine"), {
engineName: ENGINE_NAME,
input: searchStr,
searchQuery: searchStr,
searchSuggestion: "quux hello",
}),
title: ENGINE_NAME,
style: ["action", "searchengine"],
icon: "",
}],
});
suggestionsFromSearchString = oldFn;
yield cleanup();
});

Просмотреть файл

@ -4,7 +4,7 @@ tail =
skip-if = toolkit == 'android' || toolkit == 'gonk'
support-files =
data/engine-rel-searchform.xml
data/engine-suggestions.xml
[test_416211.js]
[test_416214.js]
@ -34,6 +34,7 @@ support-files =
[test_searchEngine_current.js]
[test_searchEngine_host.js]
[test_searchEngine_restyle.js]
[test_searchSuggestions.js]
[test_special_search.js]
[test_swap_protocol.js]
[test_tabmatches.js]