Bug 567267 - unit tests for ipc uriloader/download/external-app-handling, r=dwitte, blocking-fennec2.0b1=mfinkle

This commit is contained in:
Brian Crowder 2010-09-15 15:55:08 -07:00
parent 6d2f11959b
commit 68b2dc2b98
2 changed files with 262 additions and 0 deletions

View File

@ -51,6 +51,10 @@ MODULE = test_uriloader_exthandler
XPCSHELL_TESTS = unit
ifdef MOZ_IPC
XPCSHELL_TESTS += unit_ipc
endif
CPPSRCS = \
WriteArgument.cpp \
$(NULL)

View File

@ -0,0 +1,258 @@
do_get_profile();
do_load_httpd_js();
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
// Dynamically generates a classID for our component, registers it to mask
// the existing component, and stored the masked components classID to be
// restored later, when we unregister.
function registerTemporaryComponent(comp)
{
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
if (!comp.prototype.classID) {
let uuidgen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
comp.prototype.classID = uuidgen.generateUUID();
}
comp.prototype.maskedClassID = Components.ID(Cc[comp.prototype.contractID].number);
if (!comp.prototype.factory)
comp.prototype.factory = getFactory(comp);
registrar.registerFactory(comp.prototype.classID, "", comp.prototype.contractID, comp.prototype.factory);
}
function unregisterTemporaryComponent(comp)
{
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
registrar.unregisterFactory(comp.prototype.classID, comp.prototype.factory);
registrar.registerFactory(comp.prototype.maskedClassID, "", comp.prototype.contractID, null);
}
let DownloadListener = {
init: function () {
let obs = Services.obs;
obs.addObserver(this, "dl-done", true);
},
observe: function (subject, topic, data) {
this.onFinished(subject, topic, data);
},
QueryInterface: function (iid) {
if (iid.equals(Ci.nsIObserver) ||
iid.equals(Ci.nsISupportsWeakReference) ||
iid.equals(Ci.nsISupports))
return this;
throw Cr.NS_ERROR_NO_INTERFACE;
}
}
DownloadListener.init();
function HelperAppDlg() { }
HelperAppDlg.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIHelperAppLauncherDialog]),
contractID: "@mozilla.org/helperapplauncherdialog;1",
show: function (launcher, ctx, reason) {
launcher.MIMEInfo.preferredAction = Ci.nsIMIMEInfo.saveToFile;
launcher.launchWithApplication(null, false);
},
promptForSaveToFile: function (launcher, ctx, defaultFile, suggestedExtension, forcePrompt) { }
}
// Stolen from XPCOMUtils, since this handy function is not public there
function getFactory(comp)
{
return {
createInstance: function (outer, iid) {
if (outer)
throw Cr.NS_ERROR_NO_AGGREGATION;
return (new comp()).QueryInterface(iid);
}
}
}
registerTemporaryComponent(HelperAppDlg);
function initChildTestEnv()
{
sendCommand(' \
const Cc = Components.classes; \
const Ci = Components.interfaces; \
const Cr = Components.results; \
function WindowContext() { } \
\
WindowContext.prototype = { \
getInterface: function (iid) { \
if (iid.equals(Ci.nsIInterfaceRequestor) || \
iid.equals(Ci.nsIURIContentListener) || \
iid.equals(Ci.nsILoadGroup) || \
iid.equals(Ci.nsIDocumentLoader) || \
iid.equals(Ci.nsIDOMWindow)) \
return this; \
\
throw Cr.NS_ERROR_NO_INTERFACE; \
}, \
\
/* nsIURIContentListener */ \
onStartURIOpen: function (uri) { }, \
isPreferred: function (type, desiredtype) { return false; }, \
\
/* nsILoadGroup */ \
addRequest: function (request, context) { }, \
removeRequest: function (request, context, status) { } \
}; \
\
var ioservice = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);\
var uriloader = Cc["@mozilla.org/uriloader;1"].getService(Ci.nsIURILoader);\
');
}
function testFinisher(endFunc) {
let ef = endFunc;
return function (file) {
ef(file);
runNextTest();
}
}
function runChildTestSet(set)
{
DownloadListener.onFinished = testFinisher(set[2]);
sendCommand('\
let uri = ioservice.newURI("http://localhost:4444' + set[0] + '", null, null);\
let channel = ioservice.newChannelFromURI(uri); \
uriloader.openURI(channel, true, new WindowContext()); \
');
}
var httpserver = null;
let currentTest = 0;
function runNextTest()
{
if (currentTest == tests.length) {
httpserver.stop(do_test_finished);
return;
}
let set = tests[currentTest++];
runChildTestSet(set);
}
const responseBody = [0x1f, 0x8b, 0x08, 0x00, 0x16, 0x5a, 0x8a, 0x48, 0x02,
0x03, 0x2b, 0x49, 0x2d, 0x2e, 0xe1, 0x02, 0x00, 0xc6,
0x35, 0xb9, 0x3b, 0x05, 0x00, 0x00, 0x00];
/*
* First test: a file with Content-Type application/x-gzip and Content-Encoding gzip
* should not be decoded in a round-trip
*/
function testResponse1(metadata, response) {
response.setHeader("Content-Type", "application/x-gzip", false);
response.setHeader("Content-Encoding", "gzip", false);
response.setHeader("Content-Disposition", "attachment", false);
var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIBinaryOutputStream);
bos.setOutputStream(response.bodyOutputStream);
bos.writeByteArray(responseBody, responseBody.length);
}
function finishTest1(subject, topic, data) {
let file = subject.QueryInterface(Ci.nsIDownload).targetFile;
do_check_true(file.path.search("test1.gz") != 0);
let fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
fis.init(file, -1, -1, 0);
let bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
bis.setInputStream(fis);
let str = bis.readByteArray(bis.available());
do_check_true(str.length == responseBody.length);
let cmp = 0;
for (i = 0; i < str.length; i++) {
cmp += str[i] - responseBody[i];
if (cmp != 0) break;
}
do_check_true(cmp == 0);
}
/*
* Second test: a file with Content-Type text/html and Content-Encoding gzip
* should not be decoded in a round-trip, if its filename ends in ".gz".
* We specify a Content-disposition header to force it to be saved as a file.
*/
function testResponse2(metadata, response) {
response.setHeader("Content-Type", "text/html", false);
response.setHeader("Content-Encoding", "gzip", false);
response.setHeader("Content-Disposition", "attachment", false);
var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIBinaryOutputStream);
bos.setOutputStream(response.bodyOutputStream);
bos.writeByteArray(responseBody, responseBody.length);
}
function finishTest2(subject, topic, data) {
let file = subject.QueryInterface(Ci.nsIDownload).targetFile;
do_check_true(file.path.search("test2.gz") != 0);
let fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
fis.init(file, -1, -1, 0);
let bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
bis.setInputStream(fis);
let str = bis.readByteArray(bis.available());
do_check_true(str.length == responseBody.length);
let cmp = 0;
for (i = 0; i < str.length; i++) {
cmp += str[i] - responseBody[i];
if (cmp != 0) break;
}
do_check_true(cmp == 0);
}
function testResponse3(metadata, response) {
response.setHeader("Content-Type", "text/html", false);
response.setHeader("Content-Encoding", "gzip", false);
response.setHeader("Content-Disposition", "attachment", false);
var bos = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIBinaryOutputStream);
bos.setOutputStream(response.bodyOutputStream);
bos.writeByteArray(responseBody, responseBody.length);
}
function finishTest3(subject, topic, data) {
let file = subject.QueryInterface(Ci.nsIDownload).targetFile;
do_check_true(file.path.search("test3.txt") != 0);
let fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
fis.init(file, -1, -1, 0);
let bis = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
bis.setInputStream(fis);
let str = bis.readByteArray(bis.available());
let decodedBody = [ 116, 101, 115, 116, 10 ]; // 't','e','s','t','\n'
do_check_true(str.length == decodedBody.length);
let cmp = 0;
for (i = 0; i < str.length; i++) {
cmp += str[i] - decodedBody[i];
if (cmp != 0) break;
}
do_check_true(cmp == 0);
}
let tests = [
[ "/test1.gz", testResponse1, finishTest1 ],
[ "/test2.gz", testResponse2, finishTest2 ],
[ "/test3.txt", testResponse3, finishTest3 ],
];
function run_test() {
// do_load_child_test_harness();
httpserver = new nsHttpServer();
httpserver.start(4444);
do_test_pending();
initChildTestEnv();
for each (set in tests)
httpserver.registerPathHandler(set[0], set[1]);
runNextTest();
}