Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* 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/. */
function run_test() {
//* *************************************************************************//
// Constants
const handlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"].getService(
Ci.nsIHandlerService
);
const mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
const protoSvc = Cc[
"@mozilla.org/uriloader/external-protocol-service;1"
].getService(Ci.nsIExternalProtocolService);
const prefSvc = Services.prefs;
let noMailto = false;
if (mozinfo.os == "win") {
// Check mailto handler from registry.
// If registry entry is nothing, no mailto handler
let regSvc = Cc["@mozilla.org/windows-registry-key;1"].createInstance(
Ci.nsIWindowsRegKey
);
try {
regSvc.open(regSvc.ROOT_KEY_CLASSES_ROOT, "mailto", regSvc.ACCESS_READ);
noMailto = false;
} catch (ex) {
noMailto = true;
}
regSvc.close();
}
if (mozinfo.os == "linux") {
// Check mailto handler from GIO
// If there isn't one, then we have no mailto handler
let gIOSvc = Cc["@mozilla.org/gio-service;1"].createInstance(
Ci.nsIGIOService
);
try {
gIOSvc.getAppForURIScheme("mailto");
noMailto = false;
} catch (ex) {
noMailto = true;
}
}
//* *************************************************************************//
// Sample Data
// It doesn't matter whether or not this nsIFile is actually executable,
// only that it has a path and exists. Since we don't know any executable
// that exists on all platforms (except possibly the application being
// tested, but there doesn't seem to be a way to get a reference to that
// from the directory service), we use the temporary directory itself.
var executable = Services.dirsvc.get("TmpD", Ci.nsIFile);
// XXX We could, of course, create an actual executable in the directory:
// executable.append("localhandler");
// if (!executable.exists())
// executable.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o755);
var localHandler = Cc[
"@mozilla.org/uriloader/local-handler-app;1"
].createInstance(Ci.nsILocalHandlerApp);
localHandler.name = "Local Handler";
localHandler.executable = executable;
var webHandler = Cc[
"@mozilla.org/uriloader/web-handler-app;1"
].createInstance(Ci.nsIWebHandlerApp);
webHandler.name = "Web Handler";
webHandler.uriTemplate = "http://www.example.com/?%s";
// FIXME: these tests create and manipulate enough variables that it would
// make sense to move each test into its own scope so we don't run the risk
// of one test stomping on another's data.
//* *************************************************************************//
// Test Default Properties
// Get a handler info for a MIME type that neither the application nor
// the OS knows about and make sure its properties are set to the proper
// default values.
var handlerInfo = mimeSvc.getFromTypeAndExtension("nonexistent/type", null);
// Make sure it's also an nsIHandlerInfo.
Assert.ok(handlerInfo instanceof Ci.nsIHandlerInfo);
Assert.equal(handlerInfo.type, "nonexistent/type");
// Deprecated property, but we should still make sure it's set correctly.
Assert.equal(handlerInfo.MIMEType, "nonexistent/type");
// These properties are the ones the handler service knows how to store.
Assert.equal(handlerInfo.preferredAction, Ci.nsIHandlerInfo.saveToDisk);
Assert.equal(handlerInfo.preferredApplicationHandler, null);
Assert.equal(handlerInfo.possibleApplicationHandlers.length, 0);
Assert.equal(
handlerInfo.alwaysAskBeforeHandling,
prefSvc.getBoolPref(
"browser.download.always_ask_before_handling_new_types",
false
)
);
// These properties are initialized to default values by the service,
// so we might as well make sure they're initialized to the right defaults.
Assert.equal(handlerInfo.description, "");
Assert.equal(handlerInfo.hasDefaultHandler, false);
Assert.equal(handlerInfo.defaultDescription, "");
const kExternalWarningDefault =
"network.protocol-handler.warn-external-default";
prefSvc.setBoolPref(kExternalWarningDefault, true);
// XXX add more thorough protocol info property checking
// no OS default handler exists
var protoInfo = protoSvc.getProtocolHandlerInfo("x-moz-rheet");
Assert.equal(protoInfo.preferredAction, protoInfo.alwaysAsk);
Assert.ok(protoInfo.alwaysAskBeforeHandling);
// OS default exists, injected default does not exist,
// explicit warning pref: false
const kExternalWarningPrefPrefix = "network.protocol-handler.warn-external.";
prefSvc.setBoolPref(kExternalWarningPrefPrefix + "http", false);
protoInfo = protoSvc.getProtocolHandlerInfo("http");
Assert.equal(0, protoInfo.possibleApplicationHandlers.length);
// NOTE: this assertion will fail if the system executing the test does not
// have a handler registered for the http protocol. This is very unlikely to
// actually happen except on certain configurations of Linux, but one of
// those configurations is the default WSL Ubuntu install. So, if you are
// running this test locally and seeing a failure here, it might not be
// anything to really worry about.
Assert.ok(!protoInfo.alwaysAskBeforeHandling);
// OS default exists, injected default does not exist,
// explicit warning pref: true
prefSvc.setBoolPref(kExternalWarningPrefPrefix + "http", true);
protoInfo = protoSvc.getProtocolHandlerInfo("http");
// OS handler isn't included in possibleApplicationHandlers, so length is 0
// Once they become instances of nsILocalHandlerApp, this number will need
// to change.
Assert.equal(0, protoInfo.possibleApplicationHandlers.length);
Assert.ok(protoInfo.alwaysAskBeforeHandling);
// OS default exists, injected default exists, explicit warning pref: false
prefSvc.setBoolPref(kExternalWarningPrefPrefix + "mailto", false);
protoInfo = protoSvc.getProtocolHandlerInfo("mailto");
if (AppConstants.MOZ_APP_NAME == "thunderbird") {
Assert.equal(0, protoInfo.possibleApplicationHandlers.length);
} else {
Assert.equal(1, protoInfo.possibleApplicationHandlers.length);
}
// Win7+ or Linux's GIO might not have a default mailto: handler
if (noMailto) {
Assert.ok(protoInfo.alwaysAskBeforeHandling);
} else {
Assert.ok(!protoInfo.alwaysAskBeforeHandling);
}
// OS default exists, injected default exists, explicit warning pref: true
prefSvc.setBoolPref(kExternalWarningPrefPrefix + "mailto", true);
protoInfo = protoSvc.getProtocolHandlerInfo("mailto");
if (AppConstants.MOZ_APP_NAME == "thunderbird") {
Assert.equal(0, protoInfo.possibleApplicationHandlers.length);
} else {
Assert.equal(1, protoInfo.possibleApplicationHandlers.length);
// Win7+ or Linux's GIO may have no default mailto: handler, so we'd ask
// anyway. Otherwise, the default handlers will not have stored preferred
// actions etc., so re-requesting them after the warning pref has changed
// will use the updated pref value. So both when we have and do not have
// a default mailto: handler, we'll ask:
Assert.ok(protoInfo.alwaysAskBeforeHandling);
// As soon as anyone actually stores updated defaults into the profile
// database, that default will stop tracking the warning pref.
}
// Now set the value stored in RDF to true, and the pref to false, to make
// sure we still get the right value. (Basically, same thing as above but
// with the values reversed.)
prefSvc.setBoolPref(kExternalWarningPrefPrefix + "mailto", false);
protoInfo.alwaysAskBeforeHandling = true;
handlerSvc.store(protoInfo);
protoInfo = protoSvc.getProtocolHandlerInfo("mailto");
if (AppConstants.MOZ_APP_NAME == "thunderbird") {
Assert.equal(0, protoInfo.possibleApplicationHandlers.length);
} else {
Assert.equal(1, protoInfo.possibleApplicationHandlers.length);
Assert.ok(protoInfo.alwaysAskBeforeHandling);
}
//* *************************************************************************//
// Test Round-Trip Data Integrity
// Test round-trip data integrity by setting the properties of the handler
// info object to different values, telling the handler service to store the
// object, and then retrieving a new info object for the same type and making
// sure its properties are identical.
handlerInfo.preferredAction = Ci.nsIHandlerInfo.useHelperApp;
handlerInfo.preferredApplicationHandler = localHandler;
handlerInfo.alwaysAskBeforeHandling = false;
handlerSvc.store(handlerInfo);
handlerInfo = mimeSvc.getFromTypeAndExtension("nonexistent/type", null);
Assert.equal(handlerInfo.preferredAction, Ci.nsIHandlerInfo.useHelperApp);
Assert.notEqual(handlerInfo.preferredApplicationHandler, null);
var preferredHandler = handlerInfo.preferredApplicationHandler;
Assert.equal(typeof preferredHandler, "object");
Assert.equal(preferredHandler.name, "Local Handler");
Assert.ok(preferredHandler instanceof Ci.nsILocalHandlerApp);
preferredHandler.QueryInterface(Ci.nsILocalHandlerApp);
Assert.equal(preferredHandler.executable.path, localHandler.executable.path);
Assert.ok(!handlerInfo.alwaysAskBeforeHandling);
// Make sure the handler service's enumerate method lists all known handlers.
var handlerInfo2 = mimeSvc.getFromTypeAndExtension("nonexistent/type2", null);
handlerSvc.store(handlerInfo2);
var handlerTypes = ["nonexistent/type", "nonexistent/type2"];
handlerTypes.push("mailto");
for (let handler of handlerSvc.enumerate()) {
Assert.notEqual(handlerTypes.indexOf(handler.type), -1);
handlerTypes.splice(handlerTypes.indexOf(handler.type), 1);
}
Assert.equal(handlerTypes.length, 0);
// Make sure the handler service's remove method removes a handler record.
handlerSvc.remove(handlerInfo2);
let handlers = handlerSvc.enumerate();
while (handlers.hasMoreElements()) {
Assert.notEqual(
handlers.getNext().QueryInterface(Ci.nsIHandlerInfo).type,
handlerInfo2.type
);
}
// Make sure we can store and retrieve a handler info object with no preferred
// handler.
var noPreferredHandlerInfo = mimeSvc.getFromTypeAndExtension(
"nonexistent/no-preferred-handler",
null
);
handlerSvc.store(noPreferredHandlerInfo);
noPreferredHandlerInfo = mimeSvc.getFromTypeAndExtension(
"nonexistent/no-preferred-handler",
null
);
Assert.equal(noPreferredHandlerInfo.preferredApplicationHandler, null);
// Make sure that the handler service removes an existing handler record
// if we store a handler info object with no preferred handler.
var removePreferredHandlerInfo = mimeSvc.getFromTypeAndExtension(
"nonexistent/rem-preferred-handler",
null
);
removePreferredHandlerInfo.preferredApplicationHandler = localHandler;
handlerSvc.store(removePreferredHandlerInfo);
removePreferredHandlerInfo = mimeSvc.getFromTypeAndExtension(
"nonexistent/rem-preferred-handler",
null
);
removePreferredHandlerInfo.preferredApplicationHandler = null;
handlerSvc.store(removePreferredHandlerInfo);
removePreferredHandlerInfo = mimeSvc.getFromTypeAndExtension(
"nonexistent/rem-preferred-handler",
null
);
Assert.equal(removePreferredHandlerInfo.preferredApplicationHandler, null);
// Make sure we can store and retrieve a handler info object with possible
// handlers. We test both adding and removing handlers.
// Get a handler info and make sure it has no possible handlers.
var possibleHandlersInfo = mimeSvc.getFromTypeAndExtension(
"nonexistent/possible-handlers",
null
);
Assert.equal(possibleHandlersInfo.possibleApplicationHandlers.length, 0);
// Store and re-retrieve the handler and make sure it still has no possible
// handlers.
handlerSvc.store(possibleHandlersInfo);
possibleHandlersInfo = mimeSvc.getFromTypeAndExtension(
"nonexistent/possible-handlers",
null
);
Assert.equal(possibleHandlersInfo.possibleApplicationHandlers.length, 0);
// Add two handlers, store the object, re-retrieve it, and make sure it has
// two handlers.
possibleHandlersInfo.possibleApplicationHandlers.appendElement(localHandler);
possibleHandlersInfo.possibleApplicationHandlers.appendElement(webHandler);
handlerSvc.store(possibleHandlersInfo);
possibleHandlersInfo = mimeSvc.getFromTypeAndExtension(
"nonexistent/possible-handlers",
null
);
Assert.equal(possibleHandlersInfo.possibleApplicationHandlers.length, 2);
// Figure out which is the local and which is the web handler and the index
// in the array of the local handler, which is the one we're going to remove
// to test removal of a handler.
var handler1 =
possibleHandlersInfo.possibleApplicationHandlers.queryElementAt(
0,
Ci.nsIHandlerApp
);
var handler2 =
possibleHandlersInfo.possibleApplicationHandlers.queryElementAt(
1,
Ci.nsIHandlerApp
);
var localPossibleHandler, webPossibleHandler, localIndex;
if (handler1 instanceof Ci.nsILocalHandlerApp) {
[localPossibleHandler, webPossibleHandler, localIndex] = [
handler1,
handler2,
0,
];
} else {
[localPossibleHandler, webPossibleHandler, localIndex] = [
handler2,
handler1,
1,
];
}
localPossibleHandler.QueryInterface(Ci.nsILocalHandlerApp);
webPossibleHandler.QueryInterface(Ci.nsIWebHandlerApp);
// Make sure the two handlers are the ones we stored.
Assert.equal(localPossibleHandler.name, localHandler.name);
Assert.ok(localPossibleHandler.equals(localHandler));
Assert.equal(webPossibleHandler.name, webHandler.name);
Assert.ok(webPossibleHandler.equals(webHandler));
// Remove a handler, store the object, re-retrieve it, and make sure
// it only has one handler.
possibleHandlersInfo.possibleApplicationHandlers.removeElementAt(localIndex);
handlerSvc.store(possibleHandlersInfo);
possibleHandlersInfo = mimeSvc.getFromTypeAndExtension(
"nonexistent/possible-handlers",
null
);
Assert.equal(possibleHandlersInfo.possibleApplicationHandlers.length, 1);
// Make sure the handler is the one we didn't remove.
webPossibleHandler =
possibleHandlersInfo.possibleApplicationHandlers.queryElementAt(
0,
Ci.nsIWebHandlerApp
);
Assert.equal(webPossibleHandler.name, webHandler.name);
Assert.ok(webPossibleHandler.equals(webHandler));
// ////////////////////////////////////////////////////
// handler info command line parameters and equality
var localApp = Cc[
"@mozilla.org/uriloader/local-handler-app;1"
].createInstance(Ci.nsILocalHandlerApp);
var handlerApp = localApp.QueryInterface(Ci.nsIHandlerApp);
Assert.ok(handlerApp.equals(localApp));
localApp.executable = executable;
Assert.equal(0, localApp.parameterCount);
localApp.appendParameter("-test1");
Assert.equal(1, localApp.parameterCount);
localApp.appendParameter("-test2");
Assert.equal(2, localApp.parameterCount);
Assert.ok(localApp.parameterExists("-test1"));
Assert.ok(localApp.parameterExists("-test2"));
Assert.ok(!localApp.parameterExists("-false"));
localApp.clearParameters();
Assert.equal(0, localApp.parameterCount);
var localApp2 = Cc[
"@mozilla.org/uriloader/local-handler-app;1"
].createInstance(Ci.nsILocalHandlerApp);
localApp2.executable = executable;
localApp.clearParameters();
Assert.ok(localApp.equals(localApp2));
// equal:
// cut -d 1 -f 2
// cut -d 1 -f 2
localApp.appendParameter("-test1");
localApp.appendParameter("-test2");
localApp.appendParameter("-test3");
localApp2.appendParameter("-test1");
localApp2.appendParameter("-test2");
localApp2.appendParameter("-test3");
Assert.ok(localApp.equals(localApp2));
// not equal:
// cut -d 1 -f 2
// cut -f 1 -d 2
localApp.clearParameters();
localApp2.clearParameters();
localApp.appendParameter("-test1");
localApp.appendParameter("-test2");
localApp.appendParameter("-test3");
localApp2.appendParameter("-test2");
localApp2.appendParameter("-test1");
localApp2.appendParameter("-test3");
Assert.ok(!localApp2.equals(localApp));
var str;
str = localApp.getParameter(0);
Assert.equal(str, "-test1");
str = localApp.getParameter(1);
Assert.equal(str, "-test2");
str = localApp.getParameter(2);
Assert.equal(str, "-test3");
// FIXME: test round trip integrity for a protocol.
// FIXME: test round trip integrity for a handler info with a web handler.
//* *************************************************************************//
// getTypeFromExtension tests
// test nonexistent extension
var lolType = handlerSvc.getTypeFromExtension("lolcat");
Assert.equal(lolType, "");
// add a handler for the extension
var lolHandler = mimeSvc.getFromTypeAndExtension("application/lolcat", null);
Assert.ok(!lolHandler.extensionExists("lolcat"));
lolHandler.preferredAction = Ci.nsIHandlerInfo.useHelperApp;
lolHandler.preferredApplicationHandler = localHandler;
lolHandler.alwaysAskBeforeHandling = false;
lolHandler.appendExtension("lolcat");
// store the handler
Assert.ok(!handlerSvc.exists(lolHandler));
handlerSvc.store(lolHandler);
Assert.ok(handlerSvc.exists(lolHandler));
// test now-existent extension
lolType = handlerSvc.getTypeFromExtension("lolcat");
Assert.equal(lolType, "application/lolcat");
// test mailcap entries with needsterminal are ignored on non-Windows non-Mac.
if (mozinfo.os != "win" && mozinfo.os != "mac") {
prefSvc.setStringPref(
"helpers.private_mailcap_file",
do_get_file("mailcap").path
);
handlerInfo = mimeSvc.getFromTypeAndExtension("text/plain", null);
Assert.equal(handlerInfo.preferredAction, Ci.nsIHandlerInfo.saveToDisk);
Assert.equal(handlerInfo.defaultDescription, "sed");
}
}