Bug 900973 - Extend unit test coverage for action execution. r=enn

This commit is contained in:
Paolo Amadini 2013-08-03 13:04:39 +02:00
parent 75f74cc362
commit 952b96845e
5 changed files with 143 additions and 93 deletions

View File

@ -311,10 +311,11 @@ Download.prototype = {
}
}
// This function propragates download properties from the DownloadSaver
// This function propagates download properties from the DownloadSaver
// object, unless it comes in late from a download attempt that was
// replaced by a new one.
function DS_setDownloadProperties(aOptions) {
function DS_setProperties(aOptions)
{
if (this._currentAttempt && this._currentAttempt != currentAttempt) {
return;
}
@ -359,7 +360,7 @@ Download.prototype = {
try {
// Execute the actual download through the saver object.
yield this.saver.execute(DS_setProgressBytes.bind(this),
DS_setDownloadProperties.bind(this));
DS_setProperties.bind(this));
// Update the status properties for a successful download.
this.progress = 100;
@ -1018,7 +1019,7 @@ DownloadSaver.prototype = {
* transferred (or -1 if unknown), the third indicates whether the
* partially downloaded data can be used when restarting the download
* if it fails or is canceled.
* @parem aSetPropertiesFn
* @param aSetPropertiesFn
* This function may be called by the saver to report information
* about new download properties discovered by the saver during the
* download process. It takes an object where the keys represents
@ -1233,13 +1234,13 @@ DownloadCopySaver.prototype = {
onStartRequest: function (aRequest, aContext) {
backgroundFileSaver.onStartRequest(aRequest, aContext);
aSetPropertiesFn({ contentType: channel.contentType });
// Ensure we report the value of "Content-Length", if available,
// even if the download doesn't generate any progress events
// later.
if (aRequest instanceof Ci.nsIChannel &&
aRequest.contentLength >= 0) {
aSetProgressBytesFn(0, aRequest.contentLength);
aSetPropertiesFn({ contentType: aRequest.contentType });
if (channel.contentLength >= 0) {
aSetProgressBytesFn(0, channel.contentLength);
}
if (keepPartialData) {

View File

@ -343,24 +343,26 @@ this.DownloadIntegration = {
}
// Custom application chosen
mimeInfo.preferredAction = Ci.nsIMIMEInfo.useHelperApp;
let localHandlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"]
.createInstance(Ci.nsILocalHandlerApp);
localHandlerApp.executable = new FileUtils.File(aDownload.launcherPath);
mimeInfo.preferredApplicationHandler = localHandlerApp;
mimeInfo.preferredAction = Ci.nsIMIMEInfo.useHelperApp;
// In test mode, allow the test to verify the nsIMIMEInfo instance.
if (this.dontOpenFileAndFolder) {
throw new Task.Result("chosen-app");
throw new Task.Result(mimeInfo);
}
mimeInfo.launchWithFile(file);
return;
}
// No custom application chosen, let's launch the file with the
// default handler
// No custom application chosen, let's launch the file with the default
// handler. In test mode, we indicate this with a null value.
if (this.dontOpenFileAndFolder) {
throw new Task.Result("default-handler");
throw new Task.Result(null);
}
// First let's try to launch it through the MIME service application

View File

@ -164,16 +164,16 @@ DownloadLegacyTransfer.prototype = {
init: function DLT_init(aSource, aTarget, aDisplayName, aMIMEInfo, aStartTime,
aTempFile, aCancelable, aIsPrivate)
{
let launchWhenSuccedded = false, contentType = null, launcherPath = null;
let launchWhenSucceeded = false, contentType = null, launcherPath = null;
if (aMIMEInfo instanceof Ci.nsIMIMEInfo) {
launchWhenSuccedded = aMIMEInfo.preferredAction != Ci.nsIMIMEInfo.saveToDisk;
launchWhenSucceeded =
aMIMEInfo.preferredAction != Ci.nsIMIMEInfo.saveToDisk;
contentType = aMIMEInfo.type;
let appHandler = aMIMEInfo.preferredApplicationHandler;
let appHandler = aMIMEInfo.preferredApplicationHandler;
if (appHandler instanceof Ci.nsILocalHandlerApp) {
launcherPath = localHandler.executable.path;
launcherPath = appHandler.executable.path;
}
}
@ -185,7 +185,7 @@ DownloadLegacyTransfer.prototype = {
target: { path: aTarget.QueryInterface(Ci.nsIFileURL).file.path,
partFilePath: aTempFile && aTempFile.path },
saver: "legacy",
launchWhenSuccedded: launchWhenSuccedded,
launchWhenSucceeded: launchWhenSucceeded,
contentType: contentType,
launcherPath: launcherPath
}).then(function DLT_I_onDownload(aDownload) {

View File

@ -354,6 +354,9 @@ add_task(function test_empty_progress()
do_check_eq(download.currentBytes, 0);
do_check_eq(download.totalBytes, 0);
// We should have received the content type even for an empty file.
do_check_eq(download.contentType, "text/plain");
do_check_eq((yield OS.File.stat(download.target.path)).size, 0);
});
@ -419,6 +422,9 @@ add_task(function test_empty_noprogress()
continueResponses();
yield promiseDownloadStopped(download);
// We should have received the content type even if no progress is reported.
do_check_eq(download.contentType, "text/plain");
// Verify the state of the completed download.
do_check_true(download.stopped);
do_check_false(download.hasProgress);
@ -1401,35 +1407,65 @@ add_task(function test_showContainingDirectory() {
* download.launch() action
*/
add_task(function test_launch() {
let targetPath = getTempFile(TEST_TARGET_FILE_NAME).path;
let customLauncher = getTempFile("app-launcher");
// Test both with and without setting a custom application.
for (let launcherPath of [null, customLauncher.path]) {
let download;
if (!gUseLegacySaver) {
// When testing DownloadCopySaver, we have control over the download, thus
// we can test that file is not launched if download.succeeded is not set.
download = yield Downloads.createDownload({
source: httpUrl("source.txt"),
target: getTempFile(TEST_TARGET_FILE_NAME).path,
launcherPath: launcherPath,
});
try {
yield download.launch();
do_throw("Can't launch download file as it has not completed yet");
} catch (ex) {
do_check_eq(ex.message,
"launch can only be called if the download succeeded");
}
yield download.start();
} else {
// When testing DownloadLegacySaver, the download is already started when
// it is created, thus we don't test calling "launch" before starting.
download = yield promiseStartLegacyDownload(
httpUrl("source.txt"),
{ launcherPath: launcherPath });
yield promiseDownloadStopped(download);
}
do_check_false(download.launchWhenSucceeded);
DownloadIntegration._deferTestOpenFile = Promise.defer();
download.launch();
let result = yield DownloadIntegration._deferTestOpenFile.promise;
// Verify that the results match the test case.
if (!launcherPath) {
// This indicates that the default handler has been chosen.
do_check_true(result === null);
} else {
// Check the nsIMIMEInfo instance that would have been used for launching.
do_check_eq(result.preferredAction, Ci.nsIMIMEInfo.useHelperApp);
do_check_true(result.preferredApplicationHandler
.QueryInterface(Ci.nsILocalHandlerApp)
.executable.equals(customLauncher));
}
}
});
/**
* Test passing an invalid path as the launcherPath property.
*/
add_task(function test_launcherPath_invalid() {
let download = yield Downloads.createDownload({
source: { url: httpUrl("source.txt") },
target: { path: targetPath }
});
// Test that file is not launched if this.succeeded is not set.
// i.e., download has not yet completed.
try {
yield download.launch();
do_throw("Can't launch download file as it has not completed yet");
} catch (ex) {
do_check_eq(ex.message, "launch can only be called if the download succeeded")
}
// Test that the file can be launched after download is completed.
DownloadIntegration._deferTestOpenFile = Promise.defer();
yield download.start();
download.launch();
let result = yield DownloadIntegration._deferTestOpenFile.promise;
do_check_eq(result, "default-handler");
// Test that a proper error will be thrown if an invalid
// custom handler was chosen.
download = yield Downloads.createDownload({
source: { url: httpUrl("source.txt") },
target: { path: targetPath },
target: { path: getTempFile(TEST_TARGET_FILE_NAME).path },
launcherPath: " "
});
@ -1446,21 +1482,6 @@ add_task(function test_launch() {
ex.result == Cr.NS_ERROR_FAILURE;
do_check_true(validResult);
}
// Test that the custom app chosen will be used
// if launcherPath is set.
download = yield Downloads.createDownload({
source: { url: httpUrl("source.txt") },
target: { path: targetPath },
launcherPath: getTempFile("app-launcher").path
});
DownloadIntegration._deferTestOpenFile = Promise.defer();
yield download.start();
download.launch();
result = yield DownloadIntegration._deferTestOpenFile.promise;
do_check_eq(result, "chosen-app");
});
/**
@ -1468,44 +1489,50 @@ add_task(function test_launch() {
* the download finishes if download.launchWhenSucceeded = true
*/
add_task(function test_launchWhenSucceeded() {
let targetPath = getTempFile(TEST_TARGET_FILE_NAME).path;
let customLauncher = getTempFile("app-launcher");
let download = yield Downloads.createDownload({
source: { url: httpUrl("source.txt") },
target: { path: targetPath },
launchWhenSucceeded: true,
});
// Test both with and without setting a custom application.
for (let launcherPath of [null, customLauncher.path]) {
DownloadIntegration._deferTestOpenFile = Promise.defer();
// Test that the default handler will be used if no
// custom handler was chosen.
DownloadIntegration._deferTestOpenFile = Promise.defer();
download.start();
let result = yield DownloadIntegration._deferTestOpenFile.promise;
do_check_eq(result, "default-handler");
if (!gUseLegacySaver) {
let download = yield Downloads.createDownload({
source: httpUrl("source.txt"),
target: getTempFile(TEST_TARGET_FILE_NAME).path,
launchWhenSucceeded: true,
launcherPath: launcherPath,
});
yield download.start();
} else {
let download = yield promiseStartLegacyDownload(
httpUrl("source.txt"),
{ launcherPath: launcherPath,
launchWhenSucceeded: true });
yield promiseDownloadStopped(download);
}
let result = yield DownloadIntegration._deferTestOpenFile.promise;
// Test that the custom app chosen will be used
// if launcherPath is set.
download = yield Downloads.createDownload({
source: { url: httpUrl("source.txt") },
target: { path: targetPath },
launchWhenSucceeded: true,
launcherPath: getTempFile("app-launcher").path
});
DownloadIntegration._deferTestOpenFile = Promise.defer();
yield download.start();
result = yield DownloadIntegration._deferTestOpenFile.promise;
do_check_eq(result, "chosen-app");
// Verify that the results match the test case.
if (!launcherPath) {
// This indicates that the default handler has been chosen.
do_check_true(result === null);
} else {
// Check the nsIMIMEInfo instance that would have been used for launching.
do_check_eq(result.preferredAction, Ci.nsIMIMEInfo.useHelperApp);
do_check_true(result.preferredApplicationHandler
.QueryInterface(Ci.nsILocalHandlerApp)
.executable.equals(customLauncher));
}
}
});
/**
* Tests that the proper content type is set for a download.
* Tests that the proper content type is set for a normal download.
*/
add_task(function test_contentType() {
let download = yield promiseStartDownload(httpUrl("source.txt"));
yield promiseDownloadStopped(download);
do_check_eq("text/plain", download.contentType);
});

View File

@ -203,6 +203,10 @@ function promiseNewDownload(aSourceUrl) {
* targetFile: nsIFile for the target, or null to use a temporary file.
* outPersist: Receives a reference to the created nsIWebBrowserPersist
* instance.
* launchWhenSucceeded: Boolean indicating whether the target should
* be launched when it has completed successfully.
* launcherPath: String containing the path of the custom executable to
* use to launch the target of the download.
* }
*
* @return {Promise}
@ -229,11 +233,27 @@ function promiseStartLegacyDownload(aSourceUrl, aOptions) {
if (fileExtension) {
try {
mimeInfo = gMIMEService.getFromTypeAndExtension(null,
fileExtension);
mimeInfo = gMIMEService.getFromTypeAndExtension(null, fileExtension);
mimeInfo.preferredAction = Ci.nsIMIMEInfo.saveToDisk;
} catch (ex) { }
}
if (aOptions && aOptions.launcherPath) {
do_check_true(mimeInfo != null);
let localHandlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"]
.createInstance(Ci.nsILocalHandlerApp);
localHandlerApp.executable = new FileUtils.File(aOptions.launcherPath);
mimeInfo.preferredApplicationHandler = localHandlerApp;
}
if (aOptions && aOptions.launchWhenSucceeded) {
do_check_true(mimeInfo != null);
mimeInfo.preferredAction = Ci.nsIMIMEInfo.useHelperApp;
}
// Apply decoding if required by the "Content-Encoding" header.
persist.persistFlags &= ~Ci.nsIWebBrowserPersist.PERSIST_FLAGS_NO_CONVERSION;
@ -268,8 +288,8 @@ function promiseStartLegacyDownload(aSourceUrl, aOptions) {
// Initialize the components so they reference each other. This will cause
// the Download object to be created and added to the public downloads.
transfer.init(sourceURI, NetUtil.newURI(targetFile), null, mimeInfo, null, null,
persist, isPrivate);
transfer.init(sourceURI, NetUtil.newURI(targetFile), null, mimeInfo, null,
null, persist, isPrivate);
persist.progressListener = transfer;
// Start the actual download process.