diff options
Diffstat (limited to 'toolkit/components/search/tests/xpcshell/head_search.js')
-rw-r--r-- | toolkit/components/search/tests/xpcshell/head_search.js | 544 |
1 files changed, 0 insertions, 544 deletions
diff --git a/toolkit/components/search/tests/xpcshell/head_search.js b/toolkit/components/search/tests/xpcshell/head_search.js deleted file mode 100644 index 2f40d84f8..000000000 --- a/toolkit/components/search/tests/xpcshell/head_search.js +++ /dev/null @@ -1,544 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et: */ - -var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -Cu.import("resource://gre/modules/FileUtils.jsm"); -Cu.import("resource://gre/modules/osfile.jsm"); -Cu.import("resource://gre/modules/NetUtil.jsm"); -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/Task.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://testing-common/AppInfo.jsm"); -Cu.import("resource://testing-common/httpd.js"); - -const BROWSER_SEARCH_PREF = "browser.search."; -const NS_APP_SEARCH_DIR = "SrchPlugns"; - -const MODE_RDONLY = FileUtils.MODE_RDONLY; -const MODE_WRONLY = FileUtils.MODE_WRONLY; -const MODE_CREATE = FileUtils.MODE_CREATE; -const MODE_TRUNCATE = FileUtils.MODE_TRUNCATE; - -const CACHE_FILENAME = "search.json.mozlz4"; - -// nsSearchService.js uses Services.appinfo.name to build a salt for a hash. -var XULRuntime = Components.classesByID["{95d89e3e-a169-41a3-8e56-719978e15b12}"] - .getService(Ci.nsIXULRuntime); - -var isChild = XULRuntime.processType == XULRuntime.PROCESS_TYPE_CONTENT; - -updateAppInfo({ - name: "XPCShell", - ID: "xpcshell@test.mozilla.org", - version: "5", - platformVersion: "1.9", - // mirror OS from the base impl as some of the "location" tests rely on it - OS: XULRuntime.OS, - // mirror processType from the base implementation - extraProps: { - processType: XULRuntime.processType, - }, -}); - -var gProfD; -if (!isChild) { - // Need to create and register a profile folder. - gProfD = do_get_profile(); -} - -function dumpn(text) -{ - dump("search test: " + text + "\n"); -} - -/** - * Configure preferences to load engines from - * chrome://testsearchplugin/locale/searchplugins/ - */ -function configureToLoadJarEngines() -{ - let url = "chrome://testsearchplugin/locale/searchplugins/"; - let resProt = Services.io.getProtocolHandler("resource") - .QueryInterface(Ci.nsIResProtocolHandler); - resProt.setSubstitution("search-plugins", - Services.io.newURI(url, null, null)); - - // Ensure a test engine exists in the app dir anyway. - let dir = Services.dirsvc.get(NS_APP_SEARCH_DIR, Ci.nsIFile); - if (!dir.exists()) - dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); - do_get_file("data/engine-app.xml").copyTo(dir, "app.xml"); -} - -/** - * Fake the installation of an add-on in the profile, by creating the - * directory and registering it with the directory service. - */ -function installAddonEngine(name = "engine-addon") -{ - const XRE_EXTENSIONS_DIR_LIST = "XREExtDL"; - const profD = do_get_profile().QueryInterface(Ci.nsILocalFile); - - let dir = profD.clone(); - dir.append("extensions"); - if (!dir.exists()) - dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); - - dir.append("search-engine@tests.mozilla.org"); - dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); - - do_get_file("data/install.rdf").copyTo(dir, "install.rdf"); - let addonDir = dir.clone(); - dir.append("searchplugins"); - dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); - do_get_file("data/" + name + ".xml").copyTo(dir, "bug645970.xml"); - - Services.dirsvc.registerProvider({ - QueryInterface: XPCOMUtils.generateQI([Ci.nsIDirectoryServiceProvider, - Ci.nsIDirectoryServiceProvider2]), - - getFile: function (prop, persistant) { - throw Cr.NS_ERROR_FAILURE; - }, - - getFiles: function (prop) { - let result = []; - - switch (prop) { - case XRE_EXTENSIONS_DIR_LIST: - result.push(addonDir); - break; - default: - throw Cr.NS_ERROR_FAILURE; - } - - return { - QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]), - hasMoreElements: () => result.length > 0, - getNext: () => result.shift() - }; - } - }); -} - -/** - * Copy the engine-distribution.xml engine to a fake distribution - * created in the profile, and registered with the directory service. - */ -function installDistributionEngine() -{ - const XRE_APP_DISTRIBUTION_DIR = "XREAppDist"; - - const profD = do_get_profile().QueryInterface(Ci.nsILocalFile); - - let dir = profD.clone(); - dir.append("distribution"); - dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); - let distDir = dir.clone(); - - dir.append("searchplugins"); - dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); - - dir.append("common"); - dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); - - do_get_file("data/engine-override.xml").copyTo(dir, "bug645970.xml"); - - Services.dirsvc.registerProvider({ - getFile: function(aProp, aPersistent) { - aPersistent.value = true; - if (aProp == XRE_APP_DISTRIBUTION_DIR) - return distDir.clone(); - return null; - } - }); -} - -/** - * Clean the profile of any metadata files left from a previous run. - */ -function removeMetadata() -{ - let file = gProfD.clone(); - file.append("search-metadata.json"); - if (file.exists()) { - file.remove(false); - } - - file = gProfD.clone(); - file.append("search.sqlite"); - if (file.exists()) { - file.remove(false); - } -} - -function promiseCacheData() { - return new Promise(resolve => Task.spawn(function* () { - let path = OS.Path.join(OS.Constants.Path.profileDir, CACHE_FILENAME); - let bytes = yield OS.File.read(path, {compression: "lz4"}); - resolve(JSON.parse(new TextDecoder().decode(bytes))); - })); -} - -function promiseSaveCacheData(data) { - return OS.File.writeAtomic(OS.Path.join(OS.Constants.Path.profileDir, CACHE_FILENAME), - new TextEncoder().encode(JSON.stringify(data)), - {compression: "lz4"}); -} - -function promiseEngineMetadata() { - return new Promise(resolve => Task.spawn(function* () { - let cache = yield promiseCacheData(); - let data = {}; - for (let engine of cache.engines) { - data[engine._shortName] = engine._metaData; - } - resolve(data); - })); -} - -function promiseGlobalMetadata() { - return new Promise(resolve => Task.spawn(function* () { - let cache = yield promiseCacheData(); - resolve(cache.metaData); - })); -} - -function promiseSaveGlobalMetadata(globalData) { - return new Promise(resolve => Task.spawn(function* () { - let data = yield promiseCacheData(); - data.metaData = globalData; - yield promiseSaveCacheData(data); - resolve(); - })); -} - -var forceExpiration = Task.async(function* () { - let metadata = yield promiseGlobalMetadata(); - - // Make the current geodefaults expire 1s ago. - metadata.searchDefaultExpir = Date.now() - 1000; - yield promiseSaveGlobalMetadata(metadata); -}); - -/** - * Clean the profile of any cache file left from a previous run. - * Returns a boolean indicating if the cache file existed. - */ -function removeCacheFile() -{ - let file = gProfD.clone(); - file.append(CACHE_FILENAME); - if (file.exists()) { - file.remove(false); - return true; - } - return false; -} - -/** - * isUSTimezone taken from nsSearchService.js - */ -function isUSTimezone() { - // Timezone assumptions! We assume that if the system clock's timezone is - // between Newfoundland and Hawaii, that the user is in North America. - - // This includes all of South America as well, but we have relatively few - // en-US users there, so that's OK. - - // 150 minutes = 2.5 hours (UTC-2.5), which is - // Newfoundland Daylight Time (http://www.timeanddate.com/time/zones/ndt) - - // 600 minutes = 10 hours (UTC-10), which is - // Hawaii-Aleutian Standard Time (http://www.timeanddate.com/time/zones/hast) - - let UTCOffset = (new Date()).getTimezoneOffset(); - return UTCOffset >= 150 && UTCOffset <= 600; -} - -const kDefaultenginenamePref = "browser.search.defaultenginename"; -const kTestEngineName = "Test search engine"; -const kLocalePref = "general.useragent.locale"; - -function getDefaultEngineName(isUS) { - const nsIPLS = Ci.nsIPrefLocalizedString; - // Copy the logic from nsSearchService - let pref = kDefaultenginenamePref; - if (isUS === undefined) - isUS = Services.prefs.getCharPref(kLocalePref) == "en-US" && isUSTimezone(); - if (isUS) { - pref += ".US"; - } - return Services.prefs.getComplexValue(pref, nsIPLS).data; -} - -/** - * Waits for the cache file to be saved. - * @return {Promise} Resolved when the cache file is saved. - */ -function promiseAfterCache() { - return waitForSearchNotification("write-cache-to-disk-complete"); -} - -function parseJsonFromStream(aInputStream) { - const json = Cc["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON); - const data = json.decodeFromStream(aInputStream, aInputStream.available()); - return data; -} - -/** - * Read a JSON file and return the JS object - */ -function readJSONFile(aFile) { - let stream = Cc["@mozilla.org/network/file-input-stream;1"]. - createInstance(Ci.nsIFileInputStream); - try { - stream.init(aFile, MODE_RDONLY, FileUtils.PERMS_FILE, 0); - return parseJsonFromStream(stream, stream.available()); - } catch (ex) { - dumpn("readJSONFile: Error reading JSON file: " + ex); - } finally { - stream.close(); - } - return false; -} - -/** - * Recursively compare two objects and check that every property of expectedObj has the same value - * on actualObj. - */ -function isSubObjectOf(expectedObj, actualObj) { - for (let prop in expectedObj) { - if (expectedObj[prop] instanceof Object) { - do_check_eq(expectedObj[prop].length, actualObj[prop].length); - isSubObjectOf(expectedObj[prop], actualObj[prop]); - } else { - if (expectedObj[prop] != actualObj[prop]) - do_print("comparing property " + prop); - do_check_eq(expectedObj[prop], actualObj[prop]); - } - } -} - -// Can't set prefs if we're running in a child process, but the search service -// doesn't run in child processes anyways. -if (!isChild) { - // Expand the amount of information available in error logs - Services.prefs.setBoolPref("browser.search.log", true); - - // The geo-specific search tests assume certain prefs are already setup, which - // might not be true when run in comm-central etc. So create them here. - Services.prefs.setBoolPref("browser.search.geoSpecificDefaults", true); - Services.prefs.setIntPref("browser.search.geoip.timeout", 3000); - // But still disable geoip lookups - tests that need it will re-configure this. - Services.prefs.setCharPref("browser.search.geoip.url", ""); - // Also disable region defaults - tests using it will also re-configure it. - Services.prefs.getDefaultBranch(BROWSER_SEARCH_PREF).setCharPref("geoSpecificDefaults.url", ""); -} - -/** - * After useHttpServer() is called, this string contains the URL of the "data" - * directory, including the final slash. - */ -var gDataUrl; - -/** - * Initializes the HTTP server and ensures that it is terminated when tests end. - * - * @return The HttpServer object in case further customization is needed. - */ -function useHttpServer() { - let httpServer = new HttpServer(); - httpServer.start(-1); - httpServer.registerDirectory("/", do_get_cwd()); - gDataUrl = "http://localhost:" + httpServer.identity.primaryPort + "/data/"; - do_register_cleanup(() => httpServer.stop(() => {})); - return httpServer; -} - -/** - * Adds test engines and returns a promise resolved when they are installed. - * - * The engines are added in the given order. - * - * @param aItems - * Array of objects with the following properties: - * { - * name: Engine name, used to wait for it to be loaded. - * xmlFileName: Name of the XML file in the "data" folder. - * details: Array containing the parameters of addEngineWithDetails, - * except for the engine name. Alternative to xmlFileName. - * } - */ -var addTestEngines = Task.async(function* (aItems) { - if (!gDataUrl) { - do_throw("useHttpServer must be called before addTestEngines."); - } - - let engines = []; - - for (let item of aItems) { - do_print("Adding engine: " + item.name); - yield new Promise((resolve, reject) => { - Services.obs.addObserver(function obs(subject, topic, data) { - try { - let engine = subject.QueryInterface(Ci.nsISearchEngine); - do_print("Observed " + data + " for " + engine.name); - if (data != "engine-added" || engine.name != item.name) { - return; - } - - Services.obs.removeObserver(obs, "browser-search-engine-modified"); - engines.push(engine); - resolve(); - } catch (ex) { - reject(ex); - } - }, "browser-search-engine-modified", false); - - if (item.xmlFileName) { - Services.search.addEngine(gDataUrl + item.xmlFileName, - null, null, false); - } else { - Services.search.addEngineWithDetails(item.name, ...item.details); - } - }); - } - - return engines; -}); - -/** - * Installs a test engine into the test profile. - */ -function installTestEngine() { - removeMetadata(); - removeCacheFile(); - - do_check_false(Services.search.isInitialized); - - let engineDummyFile = gProfD.clone(); - engineDummyFile.append("searchplugins"); - engineDummyFile.append("test-search-engine.xml"); - let engineDir = engineDummyFile.parent; - engineDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); - - do_get_file("data/engine.xml").copyTo(engineDir, "engine.xml"); - - do_register_cleanup(function() { - removeMetadata(); - removeCacheFile(); - }); -} - -/** - * Set a localized preference on the default branch - * @param aPrefName - * The name of the pref to set. - */ -function setLocalizedDefaultPref(aPrefName, aValue) { - let value = "data:text/plain," + BROWSER_SEARCH_PREF + aPrefName + "=" + aValue; - Services.prefs.getDefaultBranch(BROWSER_SEARCH_PREF) - .setCharPref(aPrefName, value); -} - - -/** - * Installs two test engines, sets them as default for US vs. general. - */ -function setUpGeoDefaults() { - removeMetadata(); - removeCacheFile(); - - do_check_false(Services.search.isInitialized); - - let engineDummyFile = gProfD.clone(); - engineDummyFile.append("searchplugins"); - engineDummyFile.append("test-search-engine.xml"); - let engineDir = engineDummyFile.parent; - engineDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); - - do_get_file("data/engine.xml").copyTo(engineDir, "engine.xml"); - - engineDummyFile = gProfD.clone(); - engineDummyFile.append("searchplugins"); - engineDummyFile.append("test-search-engine2.xml"); - - do_get_file("data/engine2.xml").copyTo(engineDir, "engine2.xml"); - - setLocalizedDefaultPref("defaultenginename", "Test search engine"); - setLocalizedDefaultPref("defaultenginename.US", "A second test engine"); - - do_register_cleanup(function() { - removeMetadata(); - removeCacheFile(); - }); -} - -/** - * Returns a promise that is resolved when an observer notification from the - * search service fires with the specified data. - * - * @param aExpectedData - * The value the observer notification sends that causes us to resolve - * the promise. - */ -function waitForSearchNotification(aExpectedData) { - return new Promise(resolve => { - const SEARCH_SERVICE_TOPIC = "browser-search-service"; - Services.obs.addObserver(function observer(aSubject, aTopic, aData) { - if (aData != aExpectedData) - return; - - Services.obs.removeObserver(observer, SEARCH_SERVICE_TOPIC); - resolve(aSubject); - }, SEARCH_SERVICE_TOPIC, false); - }); -} - -function asyncInit() { - return new Promise(resolve => { - Services.search.init(function() { - do_check_true(Services.search.isInitialized); - resolve(); - }); - }); -} - -function asyncReInit() { - let promise = waitForSearchNotification("reinit-complete"); - - Services.search.QueryInterface(Ci.nsIObserver) - .observe(null, "nsPref:changed", kLocalePref); - - return promise; -} - -// This "enum" from nsSearchService.js -const TELEMETRY_RESULT_ENUM = { - SUCCESS: 0, - SUCCESS_WITHOUT_DATA: 1, - XHRTIMEOUT: 2, - ERROR: 3, -}; - -/** - * Checks the value of the SEARCH_SERVICE_COUNTRY_FETCH_RESULT probe. - * - * @param aExpectedValue - * If a value from TELEMETRY_RESULT_ENUM, we expect to see this value - * recorded exactly once in the probe. If |null|, we expect to see - * nothing recorded in the probe at all. - */ -function checkCountryResultTelemetry(aExpectedValue) { - let histogram = Services.telemetry.getHistogramById("SEARCH_SERVICE_COUNTRY_FETCH_RESULT"); - let snapshot = histogram.snapshot(); - // The probe is declared with 8 values, but we get 9 back from .counts - let expectedCounts = [0, 0, 0, 0, 0, 0, 0, 0, 0]; - if (aExpectedValue != null) { - expectedCounts[aExpectedValue] = 1; - } - deepEqual(snapshot.counts, expectedCounts); -} |