Best Python code snippet using lisa_python
common_test_Download.js
Source:common_test_Download.js  
1/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */2/* vim: set ts=2 et sw=2 tw=80: */3/* Any copyright is dedicated to the Public Domain.4 * http://creativecommons.org/publicdomain/zero/1.0/ */5/**6 * This script is loaded by "test_DownloadCore.js" and "test_DownloadLegacy.js"7 * with different values of the gUseLegacySaver variable, to apply tests to both8 * the "copy" and "legacy" saver implementations.9 */10"use strict";11////////////////////////////////////////////////////////////////////////////////12//// Globals13const kDeleteTempFileOnExit = "browser.helperApps.deleteTempFileOnExit";14/**15 * Creates and starts a new download, using either DownloadCopySaver or16 * DownloadLegacySaver based on the current test run.17 *18 * @return {Promise}19 * @resolves The newly created Download object.  The download may be in progress20 *           or already finished.  The promiseDownloadStopped function can be21 *           used to wait for completion.22 * @rejects JavaScript exception.23 */24function promiseStartDownload(aSourceUrl) {25  if (gUseLegacySaver) {26    return promiseStartLegacyDownload(aSourceUrl);27  }28  return promiseNewDownload(aSourceUrl).then(download => {29    download.start();30    return download;31  });32}33/**34 * Creates and starts a new download, configured to keep partial data, and35 * returns only when the first part of "interruptible_resumable.txt" has been36 * saved to disk.  You must call "continueResponses" to allow the interruptible37 * request to continue.38 *39 * This function uses either DownloadCopySaver or DownloadLegacySaver based on40 * the current test run.41 *42 * @return {Promise}43 * @resolves The newly created Download object, still in progress.44 * @rejects JavaScript exception.45 */46function promiseStartDownload_tryToKeepPartialData() {47  return Task.spawn(function () {48    mustInterruptResponses();49    // Start a new download and configure it to keep partially downloaded data.50    let download;51    if (!gUseLegacySaver) {52      let targetFilePath = getTempFile(TEST_TARGET_FILE_NAME).path;53      download = yield Downloads.createDownload({54        source: httpUrl("interruptible_resumable.txt"),55        target: { path: targetFilePath,56                  partFilePath: targetFilePath + ".part" },57      });58      download.tryToKeepPartialData = true;59      download.start();60    } else {61      // Start a download using nsIExternalHelperAppService, that is configured62      // to keep partially downloaded data by default.63      download = yield promiseStartExternalHelperAppServiceDownload();64    }65    yield promiseDownloadMidway(download);66    yield promisePartFileReady(download);67    throw new Task.Result(download);68  });69}70/**71 * This function should be called after the progress notification for a download72 * is received, and waits for the worker thread of BackgroundFileSaver to73 * receive the data to be written to the ".part" file on disk.74 *75 * @return {Promise}76 * @resolves When the ".part" file has been written to disk.77 * @rejects JavaScript exception.78 */79function promisePartFileReady(aDownload) {80  return Task.spawn(function () {81    // We don't have control over the file output code in BackgroundFileSaver.82    // After we receive the download progress notification, we may only check83    // that the ".part" file has been created, while its size cannot be84    // determined because the file is currently open.85    try {86      do {87        yield promiseTimeout(50);88      } while (!(yield OS.File.exists(aDownload.target.partFilePath)));89    } catch (ex if ex instanceof OS.File.Error) {90      // This indicates that the file has been created and cannot be accessed.91      // The specific error might vary with the platform.92      do_print("Expected exception while checking existence: " + ex.toString());93      // Wait some more time to allow the write to complete.94      yield promiseTimeout(100);95    }96  });97}98/**99 * Checks that the actual data written to disk matches the expected data as well100 * as the properties of the given DownloadTarget object.101 *102 * @param downloadTarget103 *        The DownloadTarget object whose details have to be verified.104 * @param expectedContents105 *        String containing the octets that are expected in the file.106 *107 * @return {Promise}108 * @resolves When the properties have been verified.109 * @rejects JavaScript exception.110 */111let promiseVerifyTarget = Task.async(function* (downloadTarget,112                                                expectedContents) {113  yield promiseVerifyContents(downloadTarget.path, expectedContents);114  do_check_true(downloadTarget.exists);115  do_check_eq(downloadTarget.size, expectedContents.length);116});117////////////////////////////////////////////////////////////////////////////////118//// Tests119/**120 * Executes a download and checks its basic properties after construction.121 * The download is started by constructing the simplest Download object with122 * the "copy" saver, or using the legacy nsITransfer interface.123 */124add_task(function test_basic()125{126  let targetFile = getTempFile(TEST_TARGET_FILE_NAME);127  let download;128  if (!gUseLegacySaver) {129    // When testing DownloadCopySaver, we have control over the download, thus130    // we can check its basic properties before it starts.131    download = yield Downloads.createDownload({132      source: { url: httpUrl("source.txt") },133      target: { path: targetFile.path },134      saver: { type: "copy" },135    });136    do_check_eq(download.source.url, httpUrl("source.txt"));137    do_check_eq(download.target.path, targetFile.path);138    yield download.start();139  } else {140    // When testing DownloadLegacySaver, the download is already started when it141    // is created, thus we must check its basic properties while in progress.142    download = yield promiseStartLegacyDownload(null,143                                                { targetFile: targetFile });144    do_check_eq(download.source.url, httpUrl("source.txt"));145    do_check_eq(download.target.path, targetFile.path);146    yield promiseDownloadStopped(download);147  }148  // Check additional properties on the finished download.149  do_check_true(download.source.referrer === null);150  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT);151});152/**153 * Executes a download with the tryToKeepPartialData property set, and ensures154 * that the file is saved correctly.  When testing DownloadLegacySaver, the155 * download is executed using the nsIExternalHelperAppService component.156 */157add_task(function test_basic_tryToKeepPartialData()158{159  let download = yield promiseStartDownload_tryToKeepPartialData();160  continueResponses();161  yield promiseDownloadStopped(download);162  // The target file should now have been created, and the ".part" file deleted.163  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT + TEST_DATA_SHORT);164  do_check_false(yield OS.File.exists(download.target.partFilePath));165  do_check_eq(32, download.saver.getSha256Hash().length);166});167/**168 * Tests the permissions of the final target file once the download finished.169 */170add_task(function test_unix_permissions()171{172  // This test is only executed on some Desktop systems.173  if (Services.appinfo.OS != "Darwin" && Services.appinfo.OS != "Linux" &&174      Services.appinfo.OS != "WINNT") {175    do_print("Skipping test.");176    return;177  }178  let launcherPath = getTempFile("app-launcher").path;179  for (let autoDelete of [false, true]) {180    for (let isPrivate of [false, true]) {181      for (let launchWhenSucceeded of [false, true]) {182        do_print("Checking " + JSON.stringify({ autoDelete,183                                                isPrivate,184                                                launchWhenSucceeded }));185        Services.prefs.setBoolPref(kDeleteTempFileOnExit, autoDelete);186        let download;187        if (!gUseLegacySaver) {188          download = yield Downloads.createDownload({189            source: { url: httpUrl("source.txt"), isPrivate },190            target: getTempFile(TEST_TARGET_FILE_NAME).path,191            launchWhenSucceeded,192            launcherPath,193          });194          yield download.start();195        } else {196          download = yield promiseStartLegacyDownload(httpUrl("source.txt"), {197            isPrivate,198            launchWhenSucceeded,199            launcherPath: launchWhenSucceeded && launcherPath,200          });201          yield promiseDownloadStopped(download);202        }203        let isTemporary = launchWhenSucceeded && (autoDelete || isPrivate);204        let stat = yield OS.File.stat(download.target.path);205        if (Services.appinfo.OS == "WINNT") {206          // On Windows207          // Temporary downloads should be read-only208          do_check_eq(stat.winAttributes.readOnly, isTemporary ? true : false);209        } else {210          // On Linux, Mac211          // Temporary downloads should be read-only and not accessible to other212          // users, while permanently downloaded files should be readable and213          // writable as specified by the system umask.214          do_check_eq(stat.unixMode,215                      isTemporary ? 0o400 : (0o666 & ~OS.Constants.Sys.umask));216        }217      }218    }219  }220  // Clean up the changes to the preference.221  Services.prefs.clearUserPref(kDeleteTempFileOnExit);222});223/**224 * Checks the referrer for downloads.225 */226add_task(function test_referrer()227{228  let sourcePath = "/test_referrer.txt";229  let sourceUrl = httpUrl("test_referrer.txt");230  let targetPath = getTempFile(TEST_TARGET_FILE_NAME).path;231  function cleanup() {232    gHttpServer.registerPathHandler(sourcePath, null);233  }234  do_register_cleanup(cleanup);235  gHttpServer.registerPathHandler(sourcePath, function (aRequest, aResponse) {236    aResponse.setHeader("Content-Type", "text/plain", false);237    do_check_true(aRequest.hasHeader("Referer"));238    do_check_eq(aRequest.getHeader("Referer"), TEST_REFERRER_URL);239  });240  let download = yield Downloads.createDownload({241    source: { url: sourceUrl, referrer: TEST_REFERRER_URL },242    target: targetPath,243  });244  do_check_eq(download.source.referrer, TEST_REFERRER_URL);245  yield download.start();246  download = yield Downloads.createDownload({247    source: { url: sourceUrl, referrer: TEST_REFERRER_URL,248              isPrivate: true },249    target: targetPath,250  });251  do_check_eq(download.source.referrer, TEST_REFERRER_URL);252  yield download.start();253  // Test the download still works for non-HTTP channel with referrer.254  sourceUrl = "data:text/html,<html><body></body></html>";255  download = yield Downloads.createDownload({256    source: { url: sourceUrl, referrer: TEST_REFERRER_URL },257    target: targetPath,258  });259  do_check_eq(download.source.referrer, TEST_REFERRER_URL);260  yield download.start();261  cleanup();262});263/**264 * Checks initial and final state and progress for a successful download.265 */266add_task(function test_initial_final_state()267{268  let download;269  if (!gUseLegacySaver) {270    // When testing DownloadCopySaver, we have control over the download, thus271    // we can check its state before it starts.272    download = yield promiseNewDownload();273    do_check_true(download.stopped);274    do_check_false(download.succeeded);275    do_check_false(download.canceled);276    do_check_true(download.error === null);277    do_check_eq(download.progress, 0);278    do_check_true(download.startTime === null);279    do_check_false(download.target.exists);280    do_check_eq(download.target.size, 0);281    yield download.start();282  } else {283    // When testing DownloadLegacySaver, the download is already started when it284    // is created, thus we cannot check its initial state.285    download = yield promiseStartLegacyDownload();286    yield promiseDownloadStopped(download);287  }288  do_check_true(download.stopped);289  do_check_true(download.succeeded);290  do_check_false(download.canceled);291  do_check_true(download.error === null);292  do_check_eq(download.progress, 100);293  do_check_true(isValidDate(download.startTime));294  do_check_true(download.target.exists);295  do_check_eq(download.target.size, TEST_DATA_SHORT.length);296});297/**298 * Checks the notification of the final download state.299 */300add_task(function test_final_state_notified()301{302  mustInterruptResponses();303  let download = yield promiseStartDownload(httpUrl("interruptible.txt"));304  let onchangeNotified = false;305  let lastNotifiedStopped;306  let lastNotifiedProgress;307  download.onchange = function () {308    onchangeNotified = true;309    lastNotifiedStopped = download.stopped;310    lastNotifiedProgress = download.progress;311  };312  // Allow the download to complete.313  let promiseAttempt = download.start();314  continueResponses();315  yield promiseAttempt;316  // The view should have been notified before the download completes.317  do_check_true(onchangeNotified);318  do_check_true(lastNotifiedStopped);319  do_check_eq(lastNotifiedProgress, 100);320});321/**322 * Checks intermediate progress for a successful download.323 */324add_task(function test_intermediate_progress()325{326  mustInterruptResponses();327  let download = yield promiseStartDownload(httpUrl("interruptible.txt"));328  yield promiseDownloadMidway(download);329  do_check_true(download.hasProgress);330  do_check_eq(download.currentBytes, TEST_DATA_SHORT.length);331  do_check_eq(download.totalBytes, TEST_DATA_SHORT.length * 2);332  // The final file size should not be computed for in-progress downloads.333  do_check_false(download.target.exists);334  do_check_eq(download.target.size, 0);335  // Continue after the first chunk of data is fully received.336  continueResponses();337  yield promiseDownloadStopped(download);338  do_check_true(download.stopped);339  do_check_eq(download.progress, 100);340  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT + TEST_DATA_SHORT);341});342/**343 * Downloads a file with a "Content-Length" of 0 and checks the progress.344 */345add_task(function test_empty_progress()346{347  let download = yield promiseStartDownload(httpUrl("empty.txt"));348  yield promiseDownloadStopped(download);349  do_check_true(download.stopped);350  do_check_true(download.hasProgress);351  do_check_eq(download.progress, 100);352  do_check_eq(download.currentBytes, 0);353  do_check_eq(download.totalBytes, 0);354  // We should have received the content type even for an empty file.355  do_check_eq(download.contentType, "text/plain");356  do_check_eq((yield OS.File.stat(download.target.path)).size, 0);357  do_check_true(download.target.exists);358  do_check_eq(download.target.size, 0);359});360/**361 * Downloads a file with a "Content-Length" of 0 with the tryToKeepPartialData362 * property set, and ensures that the file is saved correctly.363 */364add_task(function test_empty_progress_tryToKeepPartialData()365{366  // Start a new download and configure it to keep partially downloaded data.367  let download;368  if (!gUseLegacySaver) {369    let targetFilePath = getTempFile(TEST_TARGET_FILE_NAME).path;370    download = yield Downloads.createDownload({371      source: httpUrl("empty.txt"),372      target: { path: targetFilePath,373                partFilePath: targetFilePath + ".part" },374    });375    download.tryToKeepPartialData = true;376    download.start();377  } else {378    // Start a download using nsIExternalHelperAppService, that is configured379    // to keep partially downloaded data by default.380    download = yield promiseStartExternalHelperAppServiceDownload(381                                                         httpUrl("empty.txt"));382  }383  yield promiseDownloadStopped(download);384  // The target file should now have been created, and the ".part" file deleted.385  do_check_eq((yield OS.File.stat(download.target.path)).size, 0);386  do_check_true(download.target.exists);387  do_check_eq(download.target.size, 0);388  do_check_false(yield OS.File.exists(download.target.partFilePath));389  do_check_eq(32, download.saver.getSha256Hash().length);390});391/**392 * Downloads an empty file with no "Content-Length" and checks the progress.393 */394add_task(function test_empty_noprogress()395{396  let sourcePath = "/test_empty_noprogress.txt";397  let sourceUrl = httpUrl("test_empty_noprogress.txt");398  let deferRequestReceived = Promise.defer();399  // Register an interruptible handler that notifies us when the request occurs.400  function cleanup() {401    gHttpServer.registerPathHandler(sourcePath, null);402  }403  do_register_cleanup(cleanup);404  registerInterruptibleHandler(sourcePath,405    function firstPart(aRequest, aResponse) {406      aResponse.setHeader("Content-Type", "text/plain", false);407      deferRequestReceived.resolve();408    }, function secondPart(aRequest, aResponse) { });409  // Start the download, without allowing the request to finish.410  mustInterruptResponses();411  let download;412  if (!gUseLegacySaver) {413    // When testing DownloadCopySaver, we have control over the download, thus414    // we can hook its onchange callback that will be notified when the415    // download starts.416    download = yield promiseNewDownload(sourceUrl);417    download.onchange = function () {418      if (!download.stopped) {419        do_check_false(download.hasProgress);420        do_check_eq(download.currentBytes, 0);421        do_check_eq(download.totalBytes, 0);422      }423    };424    download.start();425  } else {426    // When testing DownloadLegacySaver, the download is already started when it427    // is created, and it may have already made all needed property change428    // notifications, thus there is no point in checking the onchange callback.429    download = yield promiseStartLegacyDownload(sourceUrl);430  }431  // Wait for the request to be received by the HTTP server, but don't allow the432  // request to finish yet.  Before checking the download state, wait for the433  // events to be processed by the client.434  yield deferRequestReceived.promise;435  yield promiseExecuteSoon();436  // Check that this download has no progress report.437  do_check_false(download.stopped);438  do_check_false(download.hasProgress);439  do_check_eq(download.currentBytes, 0);440  do_check_eq(download.totalBytes, 0);441  // Now allow the response to finish.442  continueResponses();443  yield promiseDownloadStopped(download);444  // We should have received the content type even if no progress is reported.445  do_check_eq(download.contentType, "text/plain");446  // Verify the state of the completed download.447  do_check_true(download.stopped);448  do_check_false(download.hasProgress);449  do_check_eq(download.progress, 100);450  do_check_eq(download.currentBytes, 0);451  do_check_eq(download.totalBytes, 0);452  do_check_true(download.target.exists);453  do_check_eq(download.target.size, 0);454  do_check_eq((yield OS.File.stat(download.target.path)).size, 0);455});456/**457 * Calls the "start" method two times before the download is finished.458 */459add_task(function test_start_twice()460{461  mustInterruptResponses();462  let download;463  if (!gUseLegacySaver) {464    // When testing DownloadCopySaver, we have control over the download, thus465    // we can start the download later during the test.466    download = yield promiseNewDownload(httpUrl("interruptible.txt"));467  } else {468    // When testing DownloadLegacySaver, the download is already started when it469    // is created.  Effectively, we are starting the download three times.470    download = yield promiseStartLegacyDownload(httpUrl("interruptible.txt"));471  }472  // Call the start method two times.473  let promiseAttempt1 = download.start();474  let promiseAttempt2 = download.start();475  // Allow the download to finish.476  continueResponses();477  // Both promises should now be resolved.478  yield promiseAttempt1;479  yield promiseAttempt2;480  do_check_true(download.stopped);481  do_check_true(download.succeeded);482  do_check_false(download.canceled);483  do_check_true(download.error === null);484  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT + TEST_DATA_SHORT);485});486/**487 * Cancels a download and verifies that its state is reported correctly.488 */489add_task(function test_cancel_midway()490{491  mustInterruptResponses();492  // In this test case, we execute different checks that are only possible with493  // DownloadCopySaver or DownloadLegacySaver respectively.494  let download;495  let options = {};496  if (!gUseLegacySaver) {497    download = yield promiseNewDownload(httpUrl("interruptible.txt"));498  } else {499    download = yield promiseStartLegacyDownload(httpUrl("interruptible.txt"),500                                                options);501  }502  // Cancel the download after receiving the first part of the response.503  let deferCancel = Promise.defer();504  let onchange = function () {505    if (!download.stopped && !download.canceled && download.progress == 50) {506      // Cancel the download immediately during the notification.507      deferCancel.resolve(download.cancel());508      // The state change happens immediately after calling "cancel", but509      // temporary files or part files may still exist at this point.510      do_check_true(download.canceled);511    }512  };513  // Register for the notification, but also call the function directly in514  // case the download already reached the expected progress.  This may happen515  // when using DownloadLegacySaver.516  download.onchange = onchange;517  onchange();518  let promiseAttempt;519  if (!gUseLegacySaver) {520    promiseAttempt = download.start();521  }522  // Wait on the promise returned by the "cancel" method to ensure that the523  // cancellation process finished and temporary files were removed.524  yield deferCancel.promise;525  if (gUseLegacySaver) {526    // The nsIWebBrowserPersist instance should have been canceled now.527    do_check_eq(options.outPersist.result, Cr.NS_ERROR_ABORT);528  }529  do_check_true(download.stopped);530  do_check_true(download.canceled);531  do_check_true(download.error === null);532  do_check_false(download.target.exists);533  do_check_eq(download.target.size, 0);534  do_check_false(yield OS.File.exists(download.target.path));535  // Progress properties are not reset by canceling.536  do_check_eq(download.progress, 50);537  do_check_eq(download.totalBytes, TEST_DATA_SHORT.length * 2);538  do_check_eq(download.currentBytes, TEST_DATA_SHORT.length);539  if (!gUseLegacySaver) {540    // The promise returned by "start" should have been rejected meanwhile.541    try {542      yield promiseAttempt;543      do_throw("The download should have been canceled.");544    } catch (ex if ex instanceof Downloads.Error) {545      do_check_false(ex.becauseSourceFailed);546      do_check_false(ex.becauseTargetFailed);547    }548  }549});550/**551 * Cancels a download while keeping partially downloaded data, and verifies that552 * both the target file and the ".part" file are deleted.553 */554add_task(function test_cancel_midway_tryToKeepPartialData()555{556  let download = yield promiseStartDownload_tryToKeepPartialData();557  do_check_true(yield OS.File.exists(download.target.path));558  do_check_true(yield OS.File.exists(download.target.partFilePath));559  yield download.cancel();560  yield download.removePartialData();561  do_check_true(download.stopped);562  do_check_true(download.canceled);563  do_check_true(download.error === null);564  do_check_false(yield OS.File.exists(download.target.path));565  do_check_false(yield OS.File.exists(download.target.partFilePath));566});567/**568 * Cancels a download right after starting it.569 */570add_task(function test_cancel_immediately()571{572  mustInterruptResponses();573  let download = yield promiseStartDownload(httpUrl("interruptible.txt"));574  let promiseAttempt = download.start();575  do_check_false(download.stopped);576  let promiseCancel = download.cancel();577  do_check_true(download.canceled);578  // At this point, we don't know whether the download has already stopped or579  // is still waiting for cancellation.  We can wait on the promise returned580  // by the "start" method to know for sure.581  try {582    yield promiseAttempt;583    do_throw("The download should have been canceled.");584  } catch (ex if ex instanceof Downloads.Error) {585    do_check_false(ex.becauseSourceFailed);586    do_check_false(ex.becauseTargetFailed);587  }588  do_check_true(download.stopped);589  do_check_true(download.canceled);590  do_check_true(download.error === null);591  do_check_false(yield OS.File.exists(download.target.path));592  // Check that the promise returned by the "cancel" method has been resolved.593  yield promiseCancel;594});595/**596 * Cancels and restarts a download sequentially.597 */598add_task(function test_cancel_midway_restart()599{600  mustInterruptResponses();601  let download = yield promiseStartDownload(httpUrl("interruptible.txt"));602  // The first time, cancel the download midway.603  yield promiseDownloadMidway(download);604  yield download.cancel();605  do_check_true(download.stopped);606  // The second time, we'll provide the entire interruptible response.607  continueResponses();608  download.onchange = null;609  let promiseAttempt = download.start();610  // Download state should have already been reset.611  do_check_false(download.stopped);612  do_check_false(download.canceled);613  do_check_true(download.error === null);614  // For the following test, we rely on the network layer reporting its progress615  // asynchronously.  Otherwise, there is nothing stopping the restarted616  // download from reaching the same progress as the first request already.617  do_check_eq(download.progress, 0);618  do_check_eq(download.totalBytes, 0);619  do_check_eq(download.currentBytes, 0);620  yield promiseAttempt;621  do_check_true(download.stopped);622  do_check_true(download.succeeded);623  do_check_false(download.canceled);624  do_check_true(download.error === null);625  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT + TEST_DATA_SHORT);626});627/**628 * Cancels a download and restarts it from where it stopped.629 */630add_task(function test_cancel_midway_restart_tryToKeepPartialData()631{632  let download = yield promiseStartDownload_tryToKeepPartialData();633  yield download.cancel();634  do_check_true(download.stopped);635  do_check_true(download.hasPartialData);636  // The target file should not exist, but we should have kept the partial data.637  do_check_false(yield OS.File.exists(download.target.path));638  yield promiseVerifyContents(download.target.partFilePath, TEST_DATA_SHORT);639  do_check_false(download.target.exists);640  do_check_eq(download.target.size, 0);641  // Verify that the server sent the response from the start.642  do_check_eq(gMostRecentFirstBytePos, 0);643  // The second time, we'll request and obtain the second part of the response,644  // but we still stop when half of the remaining progress is reached.645  let deferMidway = Promise.defer();646  download.onchange = function () {647    if (!download.stopped && !download.canceled &&648        download.currentBytes == Math.floor(TEST_DATA_SHORT.length * 3 / 2)) {649      download.onchange = null;650      deferMidway.resolve();651    }652  };653  mustInterruptResponses();654  let promiseAttempt = download.start();655  // Continue when the number of bytes we received is correct, then check that656  // progress is at about 75 percent.  The exact figure may vary because of657  // rounding issues, since the total number of bytes in the response might not658  // be a multiple of four.659  yield deferMidway.promise;660  do_check_true(download.progress > 72 && download.progress < 78);661  // Now we allow the download to finish.662  continueResponses();663  yield promiseAttempt;664  // Check that the server now sent the second part only.665  do_check_eq(gMostRecentFirstBytePos, TEST_DATA_SHORT.length);666  // The target file should now have been created, and the ".part" file deleted.667  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT + TEST_DATA_SHORT);668  do_check_false(yield OS.File.exists(download.target.partFilePath));669});670/**671 * Cancels a download while keeping partially downloaded data, then removes the672 * data and restarts the download from the beginning.673 */674add_task(function test_cancel_midway_restart_removePartialData()675{676  let download = yield promiseStartDownload_tryToKeepPartialData();677  yield download.cancel();678  do_check_true(download.hasPartialData);679  yield promiseVerifyContents(download.target.partFilePath, TEST_DATA_SHORT);680  do_check_false(download.target.exists);681  do_check_eq(download.target.size, 0);682  yield download.removePartialData();683  do_check_false(download.hasPartialData);684  do_check_false(yield OS.File.exists(download.target.partFilePath));685  do_check_false(download.target.exists);686  do_check_eq(download.target.size, 0);687  // The second time, we'll request and obtain the entire response again.688  continueResponses();689  yield download.start();690  // Verify that the server sent the response from the start.691  do_check_eq(gMostRecentFirstBytePos, 0);692  // The target file should now have been created, and the ".part" file deleted.693  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT + TEST_DATA_SHORT);694  do_check_false(yield OS.File.exists(download.target.partFilePath));695});696/**697 * Cancels a download while keeping partially downloaded data, then removes the698 * data and restarts the download from the beginning without keeping the partial699 * data anymore.700 */701add_task(function test_cancel_midway_restart_tryToKeepPartialData_false()702{703  let download = yield promiseStartDownload_tryToKeepPartialData();704  yield download.cancel();705  download.tryToKeepPartialData = false;706  // The above property change does not affect existing partial data.707  do_check_true(download.hasPartialData);708  yield promiseVerifyContents(download.target.partFilePath, TEST_DATA_SHORT);709  yield download.removePartialData();710  do_check_false(yield OS.File.exists(download.target.partFilePath));711  // Restart the download from the beginning.712  mustInterruptResponses();713  download.start();714  yield promiseDownloadMidway(download);715  yield promisePartFileReady(download);716  // While the download is in progress, we should still have a ".part" file.717  do_check_false(download.hasPartialData);718  do_check_true(yield OS.File.exists(download.target.partFilePath));719  // On Unix, verify that the file with the partially downloaded data is not720  // accessible by other users on the system.721  if (Services.appinfo.OS == "Darwin" || Services.appinfo.OS == "Linux") {722    do_check_eq((yield OS.File.stat(download.target.partFilePath)).unixMode,723                0o600);724  }725  yield download.cancel();726  // The ".part" file should be deleted now that the download is canceled.727  do_check_false(download.hasPartialData);728  do_check_false(yield OS.File.exists(download.target.partFilePath));729  // The third time, we'll request and obtain the entire response again.730  continueResponses();731  yield download.start();732  // Verify that the server sent the response from the start.733  do_check_eq(gMostRecentFirstBytePos, 0);734  // The target file should now have been created, and the ".part" file deleted.735  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT + TEST_DATA_SHORT);736  do_check_false(yield OS.File.exists(download.target.partFilePath));737});738/**739 * Cancels a download right after starting it, then restarts it immediately.740 */741add_task(function test_cancel_immediately_restart_immediately()742{743  mustInterruptResponses();744  let download = yield promiseStartDownload(httpUrl("interruptible.txt"));745  let promiseAttempt = download.start();746  do_check_false(download.stopped);747  download.cancel();748  do_check_true(download.canceled);749  let promiseRestarted = download.start();750  do_check_false(download.stopped);751  do_check_false(download.canceled);752  do_check_true(download.error === null);753  // For the following test, we rely on the network layer reporting its progress754  // asynchronously.  Otherwise, there is nothing stopping the restarted755  // download from reaching the same progress as the first request already.756  do_check_eq(download.hasProgress, false);757  do_check_eq(download.progress, 0);758  do_check_eq(download.totalBytes, 0);759  do_check_eq(download.currentBytes, 0);760  // Ensure the next request is now allowed to complete, regardless of whether761  // the canceled request was received by the server or not.762  continueResponses();763  try {764    yield promiseAttempt;765    // If we get here, it means that the first attempt actually succeeded.  In766    // fact, this could be a valid outcome, because the cancellation request may767    // not have been processed in time before the download finished.768    do_print("The download should have been canceled.");769  } catch (ex if ex instanceof Downloads.Error) {770    do_check_false(ex.becauseSourceFailed);771    do_check_false(ex.becauseTargetFailed);772  }773  yield promiseRestarted;774  do_check_true(download.stopped);775  do_check_true(download.succeeded);776  do_check_false(download.canceled);777  do_check_true(download.error === null);778  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT + TEST_DATA_SHORT);779});780/**781 * Cancels a download midway, then restarts it immediately.782 */783add_task(function test_cancel_midway_restart_immediately()784{785  mustInterruptResponses();786  let download = yield promiseStartDownload(httpUrl("interruptible.txt"));787  let promiseAttempt = download.start();788  // The first time, cancel the download midway.789  yield promiseDownloadMidway(download);790  download.cancel();791  do_check_true(download.canceled);792  let promiseRestarted = download.start();793  do_check_false(download.stopped);794  do_check_false(download.canceled);795  do_check_true(download.error === null);796  // For the following test, we rely on the network layer reporting its progress797  // asynchronously.  Otherwise, there is nothing stopping the restarted798  // download from reaching the same progress as the first request already.799  do_check_eq(download.hasProgress, false);800  do_check_eq(download.progress, 0);801  do_check_eq(download.totalBytes, 0);802  do_check_eq(download.currentBytes, 0);803  // The second request is allowed to complete.804  continueResponses();805  try {806    yield promiseAttempt;807    do_throw("The download should have been canceled.");808  } catch (ex if ex instanceof Downloads.Error) {809    do_check_false(ex.becauseSourceFailed);810    do_check_false(ex.becauseTargetFailed);811  }812  yield promiseRestarted;813  do_check_true(download.stopped);814  do_check_true(download.succeeded);815  do_check_false(download.canceled);816  do_check_true(download.error === null);817  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT + TEST_DATA_SHORT);818});819/**820 * Calls the "cancel" method on a successful download.821 */822add_task(function test_cancel_successful()823{824  let download = yield promiseStartDownload();825  yield promiseDownloadStopped(download);826  // The cancel method should succeed with no effect.827  yield download.cancel();828  do_check_true(download.stopped);829  do_check_true(download.succeeded);830  do_check_false(download.canceled);831  do_check_true(download.error === null);832  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT);833});834/**835 * Calls the "cancel" method two times in a row.836 */837add_task(function test_cancel_twice()838{839  mustInterruptResponses();840  let download = yield promiseStartDownload(httpUrl("interruptible.txt"));841  let promiseAttempt = download.start();842  do_check_false(download.stopped);843  let promiseCancel1 = download.cancel();844  do_check_true(download.canceled);845  let promiseCancel2 = download.cancel();846  try {847    yield promiseAttempt;848    do_throw("The download should have been canceled.");849  } catch (ex if ex instanceof Downloads.Error) {850    do_check_false(ex.becauseSourceFailed);851    do_check_false(ex.becauseTargetFailed);852  }853  // Both promises should now be resolved.854  yield promiseCancel1;855  yield promiseCancel2;856  do_check_true(download.stopped);857  do_check_false(download.succeeded);858  do_check_true(download.canceled);859  do_check_true(download.error === null);860  do_check_false(yield OS.File.exists(download.target.path));861});862/**863 * Checks the "refresh" method for succeeded downloads.864 */865add_task(function test_refresh_succeeded()866{867  let download = yield promiseStartDownload();868  yield promiseDownloadStopped(download);869  // The DownloadTarget properties should be the same after calling "refresh".870  yield download.refresh();871  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT);872  // If the file is removed, only the "exists" property should change, and the873  // "size" property should keep its previous value.874  yield OS.File.move(download.target.path, download.target.path + ".old");875  yield download.refresh();876  do_check_false(download.target.exists);877  do_check_eq(download.target.size, TEST_DATA_SHORT.length);878  // The DownloadTarget properties should be restored when the file is put back.879  yield OS.File.move(download.target.path + ".old", download.target.path);880  yield download.refresh();881  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT);882});883/**884 * Checks that a download cannot be restarted after the "finalize" method.885 */886add_task(function test_finalize()887{888  mustInterruptResponses();889  let download = yield promiseStartDownload(httpUrl("interruptible.txt"));890  let promiseFinalized = download.finalize();891  try {892    yield download.start();893    do_throw("It should not be possible to restart after finalization.");894  } catch (ex) { }895  yield promiseFinalized;896  do_check_true(download.stopped);897  do_check_false(download.succeeded);898  do_check_true(download.canceled);899  do_check_true(download.error === null);900  do_check_false(yield OS.File.exists(download.target.path));901});902/**903 * Checks that the "finalize" method can remove partially downloaded data.904 */905add_task(function test_finalize_tryToKeepPartialData()906{907  // Check finalization without removing partial data.908  let download = yield promiseStartDownload_tryToKeepPartialData();909  yield download.finalize();910  do_check_true(download.hasPartialData);911  do_check_true(yield OS.File.exists(download.target.partFilePath));912  // Clean up.913  yield download.removePartialData();914  // Check finalization while removing partial data.915  download = yield promiseStartDownload_tryToKeepPartialData();916  yield download.finalize(true);917  do_check_false(download.hasPartialData);918  do_check_false(yield OS.File.exists(download.target.partFilePath));919});920/**921 * Checks that whenSucceeded returns a promise that is resolved after a restart.922 */923add_task(function test_whenSucceeded_after_restart()924{925  mustInterruptResponses();926  let promiseSucceeded;927  let download;928  if (!gUseLegacySaver) {929    // When testing DownloadCopySaver, we have control over the download, thus930    // we can verify getting a reference before the first download attempt.931    download = yield promiseNewDownload(httpUrl("interruptible.txt"));932    promiseSucceeded = download.whenSucceeded();933    download.start();934  } else {935    // When testing DownloadLegacySaver, the download is already started when it936    // is created, thus we cannot get the reference before the first attempt.937    download = yield promiseStartLegacyDownload(httpUrl("interruptible.txt"));938    promiseSucceeded = download.whenSucceeded();939  }940  // Cancel the first download attempt.941  yield download.cancel();942  // The second request is allowed to complete.943  continueResponses();944  download.start();945  // Wait for the download to finish by waiting on the whenSucceeded promise.946  yield promiseSucceeded;947  do_check_true(download.stopped);948  do_check_true(download.succeeded);949  do_check_false(download.canceled);950  do_check_true(download.error === null);951  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT + TEST_DATA_SHORT);952});953/**954 * Ensures download error details are reported on network failures.955 */956add_task(function test_error_source()957{958  let serverSocket = startFakeServer();959  try {960    let sourceUrl = "http://localhost:" + serverSocket.port + "/source.txt";961    let download;962    try {963      if (!gUseLegacySaver) {964        // When testing DownloadCopySaver, we want to check that the promise965        // returned by the "start" method is rejected.966        download = yield promiseNewDownload(sourceUrl);967        do_check_true(download.error === null);968        yield download.start();969      } else {970        // When testing DownloadLegacySaver, we cannot be sure whether we are971        // testing the promise returned by the "start" method or we are testing972        // the "error" property checked by promiseDownloadStopped.  This happens973        // because we don't have control over when the download is started.974        download = yield promiseStartLegacyDownload(sourceUrl);975        yield promiseDownloadStopped(download);976      }977      do_throw("The download should have failed.");978    } catch (ex if ex instanceof Downloads.Error && ex.becauseSourceFailed) {979      // A specific error object is thrown when reading from the source fails.980    }981    // Check the properties now that the download stopped.982    do_check_true(download.stopped);983    do_check_false(download.canceled);984    do_check_true(download.error !== null);985    do_check_true(download.error.becauseSourceFailed);986    do_check_false(download.error.becauseTargetFailed);987    do_check_false(yield OS.File.exists(download.target.path));988    do_check_false(download.target.exists);989    do_check_eq(download.target.size, 0);990  } finally {991    serverSocket.close();992  }993});994/**995 * Ensures a download error is reported when receiving less bytes than what was996 * specified in the Content-Length header.997 */998add_task(function test_error_source_partial()999{1000  let sourceUrl = httpUrl("shorter-than-content-length-http-1-1.txt");1001  let enforcePref = Services.prefs.getBoolPref("network.http.enforce-framing.http1");1002  Services.prefs.setBoolPref("network.http.enforce-framing.http1", true);1003  function cleanup() {1004    Services.prefs.setBoolPref("network.http.enforce-framing.http1", enforcePref);1005  }1006  do_register_cleanup(cleanup);1007  let download;1008  try {1009    if (!gUseLegacySaver) {1010      // When testing DownloadCopySaver, we want to check that the promise1011      // returned by the "start" method is rejected.1012      download = yield promiseNewDownload(sourceUrl);1013      do_check_true(download.error === null);1014      yield download.start();1015    } else {1016      // When testing DownloadLegacySaver, we cannot be sure whether we are1017      // testing the promise returned by the "start" method or we are testing1018      // the "error" property checked by promiseDownloadStopped.  This happens1019      // because we don't have control over when the download is started.1020      download = yield promiseStartLegacyDownload(sourceUrl);1021      yield promiseDownloadStopped(download);1022    }1023    do_throw("The download should have failed.");1024  } catch (ex if ex instanceof Downloads.Error && ex.becauseSourceFailed) {1025    // A specific error object is thrown when reading from the source fails.1026  }1027  // Check the properties now that the download stopped.1028  do_check_true(download.stopped);1029  do_check_false(download.canceled);1030  do_check_true(download.error !== null);1031  do_check_true(download.error.becauseSourceFailed);1032  do_check_false(download.error.becauseTargetFailed);1033  do_check_eq(download.error.result, Cr.NS_ERROR_NET_PARTIAL_TRANSFER);1034  do_check_false(yield OS.File.exists(download.target.path));1035  do_check_false(download.target.exists);1036  do_check_eq(download.target.size, 0);1037});1038/**1039 * Ensures download error details are reported on local writing failures.1040 */1041add_task(function test_error_target()1042{1043  // Create a file without write access permissions before downloading.1044  let targetFile = getTempFile(TEST_TARGET_FILE_NAME);1045  targetFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0);1046  try {1047    let download;1048    try {1049      if (!gUseLegacySaver) {1050        // When testing DownloadCopySaver, we want to check that the promise1051        // returned by the "start" method is rejected.1052        download = yield Downloads.createDownload({1053          source: httpUrl("source.txt"),1054          target: targetFile,1055        });1056        yield download.start();1057      } else {1058        // When testing DownloadLegacySaver, we cannot be sure whether we are1059        // testing the promise returned by the "start" method or we are testing1060        // the "error" property checked by promiseDownloadStopped.  This happens1061        // because we don't have control over when the download is started.1062        download = yield promiseStartLegacyDownload(null,1063                                                    { targetFile: targetFile });1064        yield promiseDownloadStopped(download);1065      }1066      do_throw("The download should have failed.");1067    } catch (ex if ex instanceof Downloads.Error && ex.becauseTargetFailed) {1068      // A specific error object is thrown when writing to the target fails.1069    }1070    // Check the properties now that the download stopped.1071    do_check_true(download.stopped);1072    do_check_false(download.canceled);1073    do_check_true(download.error !== null);1074    do_check_true(download.error.becauseTargetFailed);1075    do_check_false(download.error.becauseSourceFailed);1076  } finally {1077    // Restore the default permissions to allow deleting the file on Windows.1078    if (targetFile.exists()) {1079      targetFile.permissions = FileUtils.PERMS_FILE;1080      targetFile.remove(false);1081    }1082  }1083});1084/**1085 * Restarts a failed download.1086 */1087add_task(function test_error_restart()1088{1089  let download;1090  // Create a file without write access permissions before downloading.1091  let targetFile = getTempFile(TEST_TARGET_FILE_NAME);1092  targetFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0);1093  try {1094    // Use DownloadCopySaver or DownloadLegacySaver based on the test run,1095    // specifying the target file we created.1096    if (!gUseLegacySaver) {1097      download = yield Downloads.createDownload({1098        source: httpUrl("source.txt"),1099        target: targetFile,1100      });1101      download.start();1102    } else {1103      download = yield promiseStartLegacyDownload(null,1104                                                  { targetFile: targetFile });1105    }1106    yield promiseDownloadStopped(download);1107    do_throw("The download should have failed.");1108  } catch (ex if ex instanceof Downloads.Error && ex.becauseTargetFailed) {1109    // A specific error object is thrown when writing to the target fails.1110  } finally {1111    // Restore the default permissions to allow deleting the file on Windows.1112    if (targetFile.exists()) {1113      targetFile.permissions = FileUtils.PERMS_FILE;1114      // Also for Windows, rename the file before deleting.  This makes the1115      // current file name available immediately for a new file, while deleting1116      // in place prevents creation of a file with the same name for some time.1117      targetFile.moveTo(null, targetFile.leafName + ".delete.tmp");1118      targetFile.remove(false);1119    }1120  }1121  // Restart the download and wait for completion.1122  yield download.start();1123  do_check_true(download.stopped);1124  do_check_true(download.succeeded);1125  do_check_false(download.canceled);1126  do_check_true(download.error === null);1127  do_check_eq(download.progress, 100);1128  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT);1129});1130/**1131 * Executes download in both public and private modes.1132 */1133add_task(function test_public_and_private()1134{1135  let sourcePath = "/test_public_and_private.txt";1136  let sourceUrl = httpUrl("test_public_and_private.txt");1137  let testCount = 0;1138  // Apply pref to allow all cookies.1139  Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);1140  function cleanup() {1141    Services.prefs.clearUserPref("network.cookie.cookieBehavior");1142    Services.cookies.removeAll();1143    gHttpServer.registerPathHandler(sourcePath, null);1144  }1145  do_register_cleanup(cleanup);1146  gHttpServer.registerPathHandler(sourcePath, function (aRequest, aResponse) {1147    aResponse.setHeader("Content-Type", "text/plain", false);1148    if (testCount == 0) {1149      // No cookies should exist for first public download.1150      do_check_false(aRequest.hasHeader("Cookie"));1151      aResponse.setHeader("Set-Cookie", "foobar=1", false);1152      testCount++;1153    } else if (testCount == 1) {1154      // The cookie should exists for second public download.1155      do_check_true(aRequest.hasHeader("Cookie"));1156      do_check_eq(aRequest.getHeader("Cookie"), "foobar=1");1157      testCount++;1158    } else if (testCount == 2)  {1159      // No cookies should exist for first private download.1160      do_check_false(aRequest.hasHeader("Cookie"));1161    }1162  });1163  let targetFile = getTempFile(TEST_TARGET_FILE_NAME);1164  yield Downloads.fetch(sourceUrl, targetFile);1165  yield Downloads.fetch(sourceUrl, targetFile);1166  if (!gUseLegacySaver) {1167    let download = yield Downloads.createDownload({1168      source: { url: sourceUrl, isPrivate: true },1169      target: targetFile,1170    });1171    yield download.start();1172  } else {1173    let download = yield promiseStartLegacyDownload(sourceUrl,1174                                                    { isPrivate: true });1175    yield promiseDownloadStopped(download);1176  }1177  cleanup();1178});1179/**1180 * Checks the startTime gets updated even after a restart.1181 */1182add_task(function test_cancel_immediately_restart_and_check_startTime()1183{1184  let download = yield promiseStartDownload();1185  let startTime = download.startTime;1186  do_check_true(isValidDate(download.startTime));1187  yield download.cancel();1188  do_check_eq(download.startTime.getTime(), startTime.getTime());1189  // Wait for a timeout.1190  yield promiseTimeout(10);1191  yield download.start();1192  do_check_true(download.startTime.getTime() > startTime.getTime());1193});1194/**1195 * Executes download with content-encoding.1196 */1197add_task(function test_with_content_encoding()1198{1199  let sourcePath = "/test_with_content_encoding.txt";1200  let sourceUrl = httpUrl("test_with_content_encoding.txt");1201  function cleanup() {1202    gHttpServer.registerPathHandler(sourcePath, null);1203  }1204  do_register_cleanup(cleanup);1205  gHttpServer.registerPathHandler(sourcePath, function (aRequest, aResponse) {1206    aResponse.setHeader("Content-Type", "text/plain", false);1207    aResponse.setHeader("Content-Encoding", "gzip", false);1208    aResponse.setHeader("Content-Length",1209                        "" + TEST_DATA_SHORT_GZIP_ENCODED.length, false);1210    let bos = new BinaryOutputStream(aResponse.bodyOutputStream);1211    bos.writeByteArray(TEST_DATA_SHORT_GZIP_ENCODED,1212                       TEST_DATA_SHORT_GZIP_ENCODED.length);1213  });1214  let download = yield promiseStartDownload(sourceUrl);1215  yield promiseDownloadStopped(download);1216  do_check_eq(download.progress, 100);1217  do_check_eq(download.totalBytes, TEST_DATA_SHORT_GZIP_ENCODED.length);1218  // Ensure the content matches the decoded test data.1219  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT);1220  cleanup();1221});1222/**1223 * Checks that the file is not decoded if the extension matches the encoding.1224 */1225add_task(function test_with_content_encoding_ignore_extension()1226{1227  let sourcePath = "/test_with_content_encoding_ignore_extension.gz";1228  let sourceUrl = httpUrl("test_with_content_encoding_ignore_extension.gz");1229  function cleanup() {1230    gHttpServer.registerPathHandler(sourcePath, null);1231  }1232  do_register_cleanup(cleanup);1233  gHttpServer.registerPathHandler(sourcePath, function (aRequest, aResponse) {1234    aResponse.setHeader("Content-Type", "text/plain", false);1235    aResponse.setHeader("Content-Encoding", "gzip", false);1236    aResponse.setHeader("Content-Length",1237                        "" + TEST_DATA_SHORT_GZIP_ENCODED.length, false);1238    let bos = new BinaryOutputStream(aResponse.bodyOutputStream);1239    bos.writeByteArray(TEST_DATA_SHORT_GZIP_ENCODED,1240                       TEST_DATA_SHORT_GZIP_ENCODED.length);1241  });1242  let download = yield promiseStartDownload(sourceUrl);1243  yield promiseDownloadStopped(download);1244  do_check_eq(download.progress, 100);1245  do_check_eq(download.totalBytes, TEST_DATA_SHORT_GZIP_ENCODED.length);1246  do_check_eq(download.target.size, TEST_DATA_SHORT_GZIP_ENCODED.length);1247  // Ensure the content matches the encoded test data.  We convert the data to a1248  // string before executing the content check.1249  yield promiseVerifyTarget(download.target,1250        String.fromCharCode.apply(String, TEST_DATA_SHORT_GZIP_ENCODED));1251  cleanup();1252});1253/**1254 * Cancels and restarts a download sequentially with content-encoding.1255 */1256add_task(function test_cancel_midway_restart_with_content_encoding()1257{1258  mustInterruptResponses();1259  let download = yield promiseStartDownload(httpUrl("interruptible_gzip.txt"));1260  // The first time, cancel the download midway.1261  let deferCancel = Promise.defer();1262  let onchange = function () {1263    if (!download.stopped && !download.canceled &&1264        download.currentBytes == TEST_DATA_SHORT_GZIP_ENCODED_FIRST.length) {1265      deferCancel.resolve(download.cancel());1266    }1267  };1268  // Register for the notification, but also call the function directly in1269  // case the download already reached the expected progress.1270  download.onchange = onchange;1271  onchange();1272  yield deferCancel.promise;1273  do_check_true(download.stopped);1274  // The second time, we'll provide the entire interruptible response.1275  continueResponses();1276  download.onchange = null;1277  yield download.start();1278  do_check_eq(download.progress, 100);1279  do_check_eq(download.totalBytes, TEST_DATA_SHORT_GZIP_ENCODED.length);1280  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT);1281});1282/**1283 * Download with parental controls enabled.1284 */1285add_task(function test_blocked_parental_controls()1286{1287  function cleanup() {1288    DownloadIntegration.shouldBlockInTest = false;1289  }1290  do_register_cleanup(cleanup);1291  DownloadIntegration.shouldBlockInTest = true;1292  let download;1293  try {1294    if (!gUseLegacySaver) {1295      // When testing DownloadCopySaver, we want to check that the promise1296      // returned by the "start" method is rejected.1297      download = yield promiseNewDownload();1298      yield download.start();1299    } else {1300      // When testing DownloadLegacySaver, we cannot be sure whether we are1301      // testing the promise returned by the "start" method or we are testing1302      // the "error" property checked by promiseDownloadStopped.  This happens1303      // because we don't have control over when the download is started.1304      download = yield promiseStartLegacyDownload();1305      yield promiseDownloadStopped(download);1306    }1307    do_throw("The download should have blocked.");1308  } catch (ex if ex instanceof Downloads.Error && ex.becauseBlocked) {1309    do_check_true(ex.becauseBlockedByParentalControls);1310    do_check_true(download.error.becauseBlockedByParentalControls);1311  }1312  // Now that the download stopped, the target file should not exist.1313  do_check_false(yield OS.File.exists(download.target.path));1314  cleanup();1315});1316/**1317 * Test a download that will be blocked by Windows parental controls by1318 * resulting in an HTTP status code of 450.1319 */1320add_task(function test_blocked_parental_controls_httpstatus450()1321{1322  let download;1323  try {1324    if (!gUseLegacySaver) {1325      download = yield promiseNewDownload(httpUrl("parentalblocked.zip"));1326      yield download.start();1327    }1328    else {1329      download = yield promiseStartLegacyDownload(httpUrl("parentalblocked.zip"));1330      yield promiseDownloadStopped(download);1331    }1332    do_throw("The download should have blocked.");1333  } catch (ex if ex instanceof Downloads.Error && ex.becauseBlocked) {1334    do_check_true(ex.becauseBlockedByParentalControls);1335    do_check_true(download.error.becauseBlockedByParentalControls);1336    do_check_true(download.stopped);1337  }1338  do_check_false(yield OS.File.exists(download.target.path));1339});1340/**1341 * Check that DownloadCopySaver can always retrieve the hash.1342 * DownloadLegacySaver can only retrieve the hash when1343 * nsIExternalHelperAppService is invoked.1344 */1345add_task(function test_getSha256Hash()1346{1347  if (!gUseLegacySaver) {1348    let download = yield promiseStartDownload(httpUrl("source.txt"));1349    yield promiseDownloadStopped(download);1350    do_check_true(download.stopped);1351    do_check_eq(32, download.saver.getSha256Hash().length);1352  }1353});1354/**1355 * Create a download which will be reputation blocked.1356 *1357 * @param options1358 *        {1359 *           keepPartialData: bool,1360 *           keepBlockedData: bool,1361 *        }1362 * @return {Promise}1363 * @resolves The reputation blocked download.1364 * @rejects JavaScript exception.1365 */1366let promiseBlockedDownload = Task.async(function* (options) {1367  function cleanup() {1368    DownloadIntegration.shouldBlockInTestForApplicationReputation = false;1369    DownloadIntegration.shouldKeepBlockedDataInTest = false;1370  }1371  do_register_cleanup(cleanup);1372  let {keepPartialData, keepBlockedData} = options;1373  DownloadIntegration.shouldBlockInTestForApplicationReputation = true;1374  DownloadIntegration.shouldKeepBlockedDataInTest = keepBlockedData;1375  let download;1376  try {1377    if (keepPartialData) {1378      download = yield promiseStartDownload_tryToKeepPartialData();1379      continueResponses();1380    } else if (gUseLegacySaver) {1381      download = yield promiseStartLegacyDownload();1382    } else {1383      download = yield promiseNewDownload();1384      yield download.start();1385      do_throw("The download should have blocked.");1386    }1387    yield promiseDownloadStopped(download);1388    do_throw("The download should have blocked.");1389  } catch (ex if ex instanceof Downloads.Error && ex.becauseBlocked) {1390    do_check_true(ex.becauseBlockedByReputationCheck);1391    do_check_true(download.error.becauseBlockedByReputationCheck);1392  }1393  do_check_true(download.stopped);1394  do_check_false(download.succeeded);1395  do_check_false(yield OS.File.exists(download.target.path));1396  cleanup();1397  return download;1398});1399/**1400 * Checks that application reputation blocks the download and the target file1401 * does not exist.1402 */1403add_task(function test_blocked_applicationReputation()1404{1405  let download = yield promiseBlockedDownload({1406    keepPartialData: false,1407    keepBlockedData: false,1408  });1409  // Now that the download is blocked, the target file should not exist.1410  do_check_false(yield OS.File.exists(download.target.path));1411  do_check_false(download.target.exists);1412  do_check_eq(download.target.size, 0);1413  // There should also be no blocked data in this case1414  do_check_false(download.hasBlockedData);1415});1416/**1417 * Checks that application reputation blocks the download but maintains the1418 * blocked data, which will be deleted when the block is confirmed.1419 */1420add_task(function test_blocked_applicationReputation_confirmBlock()1421{1422  let download = yield promiseBlockedDownload({1423    keepPartialData: true,1424    keepBlockedData: true,1425  });1426  do_check_true(download.hasBlockedData);1427  do_check_true(yield OS.File.exists(download.target.partFilePath));1428  yield download.confirmBlock();1429  // After confirming the block the download should be in a failed state and1430  // have no downloaded data left on disk.1431  do_check_true(download.stopped);1432  do_check_false(download.succeeded);1433  do_check_false(download.hasBlockedData);1434  do_check_false(yield OS.File.exists(download.target.partFilePath));1435  do_check_false(yield OS.File.exists(download.target.path));1436  do_check_false(download.target.exists);1437  do_check_eq(download.target.size, 0);1438});1439/**1440 * Checks that application reputation blocks the download but maintains the1441 * blocked data, which will be used to complete the download when unblocking.1442 */1443add_task(function test_blocked_applicationReputation_unblock()1444{1445  let download = yield promiseBlockedDownload({1446    keepPartialData: true,1447    keepBlockedData: true,1448  });1449  do_check_true(download.hasBlockedData);1450  do_check_true(yield OS.File.exists(download.target.partFilePath));1451  yield download.unblock();1452  // After unblocking the download should have succeeded and be1453  // present at the final path.1454  do_check_true(download.stopped);1455  do_check_true(download.succeeded);1456  do_check_false(download.hasBlockedData);1457  do_check_false(yield OS.File.exists(download.target.partFilePath));1458  yield promiseVerifyTarget(download.target, TEST_DATA_SHORT + TEST_DATA_SHORT);1459  // The only indication the download was previously blocked is the1460  // existence of the error, so we make sure it's still set.1461  do_check_true(download.error instanceof Downloads.Error);1462  do_check_true(download.error.becauseBlocked);1463  do_check_true(download.error.becauseBlockedByReputationCheck);1464});1465/**1466 * Check that calling cancel on a blocked download will not cause errors1467 */1468add_task(function test_blocked_applicationReputation_cancel()1469{1470  let download = yield promiseBlockedDownload({1471    keepPartialData: true,1472    keepBlockedData: true,1473  });1474  // This call should succeed on a blocked download.1475  yield download.cancel();1476  // Calling cancel should not have changed the current state, the download1477  // should still be blocked.1478  do_check_true(download.error.becauseBlockedByReputationCheck);1479  do_check_true(download.stopped);1480  do_check_false(download.succeeded);1481  do_check_true(download.hasBlockedData);1482});1483/**1484 * Checks that unblock and confirmBlock cannot race on a blocked download1485 */1486add_task(function test_blocked_applicationReputation_decisionRace()1487{1488  let download = yield promiseBlockedDownload({1489    keepPartialData: true,1490    keepBlockedData: true,1491  });1492  let unblockPromise = download.unblock();1493  let confirmBlockPromise = download.confirmBlock();1494  yield confirmBlockPromise.then(() => {1495    do_throw("confirmBlock should have failed.");1496  }, () => {});1497  yield unblockPromise;1498  // After unblocking the download should have succeeded and be1499  // present at the final path.1500  do_check_true(download.stopped);1501  do_check_true(download.succeeded);1502  do_check_false(download.hasBlockedData);1503  do_check_false(yield OS.File.exists(download.target.partFilePath));1504  do_check_true(yield OS.File.exists(download.target.path));1505  download = yield promiseBlockedDownload({1506    keepPartialData: true,1507    keepBlockedData: true,1508  });1509  confirmBlockPromise = download.confirmBlock();1510  unblockPromise = download.unblock();1511  yield unblockPromise.then(() => {1512    do_throw("unblock should have failed.");1513  }, () => {});1514  yield confirmBlockPromise;1515  // After confirming the block the download should be in a failed state and1516  // have no downloaded data left on disk.1517  do_check_true(download.stopped);1518  do_check_false(download.succeeded);1519  do_check_false(download.hasBlockedData);1520  do_check_false(yield OS.File.exists(download.target.partFilePath));1521  do_check_false(yield OS.File.exists(download.target.path));1522  do_check_false(download.target.exists);1523  do_check_eq(download.target.size, 0);1524});1525/**1526 * Checks that unblocking a blocked download fails if the blocked data has been1527 * removed.1528 */1529add_task(function test_blocked_applicationReputation_unblock()1530{1531  let download = yield promiseBlockedDownload({1532    keepPartialData: true,1533    keepBlockedData: true,1534  });1535  do_check_true(download.hasBlockedData);1536  do_check_true(yield OS.File.exists(download.target.partFilePath));1537  // Remove the blocked data without telling the download.1538  yield OS.File.remove(download.target.partFilePath);1539  let unblockPromise = download.unblock();1540  yield unblockPromise.then(() => {1541    do_throw("unblock should have failed.");1542  }, () => {});1543  // Even though unblocking failed the download state should have been updated1544  // to reflect the lack of blocked data.1545  do_check_false(download.hasBlockedData);1546  do_check_true(download.stopped);1547  do_check_false(download.succeeded);1548  do_check_false(download.target.exists);1549  do_check_eq(download.target.size, 0);1550});1551/**1552 * download.showContainingDirectory() action1553 */1554add_task(function test_showContainingDirectory() {1555  DownloadIntegration._deferTestShowDir = Promise.defer();1556  let targetPath = getTempFile(TEST_TARGET_FILE_NAME).path;1557  let download = yield Downloads.createDownload({1558    source: { url: httpUrl("source.txt") },1559    target: ""1560  });1561  try {1562    yield download.showContainingDirectory();1563    do_throw("Should have failed because of an invalid path.");1564  } catch (ex if ex instanceof Components.Exception) {1565    // Invalid paths on Windows are reported with NS_ERROR_FAILURE,1566    // but with NS_ERROR_FILE_UNRECOGNIZED_PATH on Mac/Linux1567    let validResult = ex.result == Cr.NS_ERROR_FILE_UNRECOGNIZED_PATH ||1568                      ex.result == Cr.NS_ERROR_FAILURE;1569    do_check_true(validResult);1570  }1571  download = yield Downloads.createDownload({1572    source: { url: httpUrl("source.txt") },1573    target: targetPath1574  });1575  DownloadIntegration._deferTestShowDir = Promise.defer();1576  download.showContainingDirectory();1577  let result = yield DownloadIntegration._deferTestShowDir.promise;1578  do_check_eq(result, "success");1579});1580/**1581 * download.launch() action1582 */1583add_task(function test_launch() {1584  let customLauncher = getTempFile("app-launcher");1585  // Test both with and without setting a custom application.1586  for (let launcherPath of [null, customLauncher.path]) {1587    let download;1588    if (!gUseLegacySaver) {1589      // When testing DownloadCopySaver, we have control over the download, thus1590      // we can test that file is not launched if download.succeeded is not set.1591      download = yield Downloads.createDownload({1592        source: httpUrl("source.txt"),1593        target: getTempFile(TEST_TARGET_FILE_NAME).path,1594        launcherPath: launcherPath,1595        launchWhenSucceeded: true1596      });1597      try {1598        yield download.launch();1599        do_throw("Can't launch download file as it has not completed yet");1600      } catch (ex) {1601        do_check_eq(ex.message,1602                    "launch can only be called if the download succeeded");1603      }1604      yield download.start();1605    } else {1606      // When testing DownloadLegacySaver, the download is already started when1607      // it is created, thus we don't test calling "launch" before starting.1608      download = yield promiseStartLegacyDownload(1609                                         httpUrl("source.txt"),1610                                         { launcherPath: launcherPath,1611                                           launchWhenSucceeded: true });1612      yield promiseDownloadStopped(download);1613    }1614    do_check_true(download.launchWhenSucceeded);1615    DownloadIntegration._deferTestOpenFile = Promise.defer();1616    download.launch();1617    let result = yield DownloadIntegration._deferTestOpenFile.promise;1618    // Verify that the results match the test case.1619    if (!launcherPath) {1620      // This indicates that the default handler has been chosen.1621      do_check_true(result === null);1622    } else {1623      // Check the nsIMIMEInfo instance that would have been used for launching.1624      do_check_eq(result.preferredAction, Ci.nsIMIMEInfo.useHelperApp);1625      do_check_true(result.preferredApplicationHandler1626                          .QueryInterface(Ci.nsILocalHandlerApp)1627                          .executable.equals(customLauncher));1628    }1629  }1630});1631/**1632 * Test passing an invalid path as the launcherPath property.1633 */1634add_task(function test_launcherPath_invalid() {1635  let download = yield Downloads.createDownload({1636    source: { url: httpUrl("source.txt") },1637    target: { path: getTempFile(TEST_TARGET_FILE_NAME).path },1638    launcherPath: " "1639  });1640  DownloadIntegration._deferTestOpenFile = Promise.defer();1641  yield download.start();1642  try {1643    download.launch();1644    result = yield DownloadIntegration._deferTestOpenFile.promise;1645    do_throw("Can't launch file with invalid custom launcher")1646  } catch (ex if ex instanceof Components.Exception) {1647    // Invalid paths on Windows are reported with NS_ERROR_FAILURE,1648    // but with NS_ERROR_FILE_UNRECOGNIZED_PATH on Mac/Linux1649    let validResult = ex.result == Cr.NS_ERROR_FILE_UNRECOGNIZED_PATH ||1650                      ex.result == Cr.NS_ERROR_FAILURE;1651    do_check_true(validResult);1652  }1653});1654/**1655 * Tests that download.launch() is automatically called after1656 * the download finishes if download.launchWhenSucceeded = true1657 */1658add_task(function test_launchWhenSucceeded() {1659  let customLauncher = getTempFile("app-launcher");1660  // Test both with and without setting a custom application.1661  for (let launcherPath of [null, customLauncher.path]) {1662    DownloadIntegration._deferTestOpenFile = Promise.defer();1663    if (!gUseLegacySaver) {1664      let download = yield Downloads.createDownload({1665        source: httpUrl("source.txt"),1666        target: getTempFile(TEST_TARGET_FILE_NAME).path,1667        launchWhenSucceeded: true,1668        launcherPath: launcherPath,1669      });1670      yield download.start();1671    } else {1672      let download = yield promiseStartLegacyDownload(1673                                             httpUrl("source.txt"),1674                                             { launcherPath: launcherPath,1675                                               launchWhenSucceeded: true });1676      yield promiseDownloadStopped(download);1677    }1678    let result = yield DownloadIntegration._deferTestOpenFile.promise;1679    // Verify that the results match the test case.1680    if (!launcherPath) {1681      // This indicates that the default handler has been chosen.1682      do_check_true(result === null);1683    } else {1684      // Check the nsIMIMEInfo instance that would have been used for launching.1685      do_check_eq(result.preferredAction, Ci.nsIMIMEInfo.useHelperApp);1686      do_check_true(result.preferredApplicationHandler1687                          .QueryInterface(Ci.nsILocalHandlerApp)1688                          .executable.equals(customLauncher));1689    }1690  }1691});1692/**1693 * Tests that the proper content type is set for a normal download.1694 */1695add_task(function test_contentType() {1696  let download = yield promiseStartDownload(httpUrl("source.txt"));1697  yield promiseDownloadStopped(download);1698  do_check_eq("text/plain", download.contentType);1699});1700/**1701 * Tests that the serialization/deserialization of the startTime Date1702 * object works correctly.1703 */1704add_task(function test_toSerializable_startTime()1705{1706  let download1 = yield promiseStartDownload(httpUrl("source.txt"));1707  yield promiseDownloadStopped(download1);1708  let serializable = download1.toSerializable();1709  let reserialized = JSON.parse(JSON.stringify(serializable));1710  let download2 = yield Downloads.createDownload(reserialized);1711  do_check_eq(download1.startTime.constructor.name, "Date");1712  do_check_eq(download2.startTime.constructor.name, "Date");1713  do_check_eq(download1.startTime.toJSON(), download2.startTime.toJSON());1714});1715/**1716 * This test will call the platform specific operations within1717 * DownloadPlatform::DownloadDone. While there is no test to verify the1718 * specific behaviours, this at least ensures that there is no error or crash.1719 */1720add_task(function test_platform_integration()1721{1722  let downloadFiles = [];1723  let oldDeviceStorageEnabled = false;1724  try {1725     oldDeviceStorageEnabled = Services.prefs.getBoolPref("device.storage.enabled");1726  } catch (e) {1727    // This happens if the pref doesn't exist.1728  }1729  let downloadWatcherNotified = false;1730  let observer = {1731    observe: function(subject, topic, data) {1732      do_check_eq(topic, "download-watcher-notify");1733      do_check_eq(data, "modified");1734      downloadWatcherNotified = true;1735    }1736  }1737  Services.obs.addObserver(observer, "download-watcher-notify", false);1738  Services.prefs.setBoolPref("device.storage.enabled", true);1739  function cleanup() {1740    for (let file of downloadFiles) {1741      file.remove(true);1742    }1743    Services.obs.removeObserver(observer, "download-watcher-notify");1744    Services.prefs.setBoolPref("device.storage.enabled", oldDeviceStorageEnabled);1745  }1746  do_register_cleanup(cleanup);1747  for (let isPrivate of [false, true]) {1748    DownloadIntegration.downloadDoneCalled = false;1749    // Some platform specific operations only operate on files outside the1750    // temporary directory or in the Downloads directory (such as setting1751    // the Windows searchable attribute, and the Mac Downloads icon bouncing),1752    // so use the system Downloads directory for the target file.1753    let targetFilePath = yield DownloadIntegration.getSystemDownloadsDirectory();1754    targetFilePath = OS.Path.join(targetFilePath,1755                                  "test" + (Math.floor(Math.random() * 1000000)));1756    let targetFile = new FileUtils.File(targetFilePath);1757    downloadFiles.push(targetFile);1758    let download;1759    if (gUseLegacySaver) {1760      download = yield promiseStartLegacyDownload(httpUrl("source.txt"),1761                                                  { targetFile: targetFile });1762    }1763    else {1764      download = yield Downloads.createDownload({1765        source: httpUrl("source.txt"),1766        target: targetFile,1767      });1768      download.start();1769    }1770    // Wait for the whenSucceeded promise to be resolved first.1771    // downloadDone should be called before the whenSucceeded promise is resolved.1772    yield download.whenSucceeded().then(function () {1773      do_check_true(DownloadIntegration.downloadDoneCalled);1774      do_check_true(downloadWatcherNotified);1775    });1776    // Then, wait for the promise returned by "start" to be resolved.1777    yield promiseDownloadStopped(download);1778    yield promiseVerifyTarget(download.target, TEST_DATA_SHORT);1779  }1780});1781/**1782 * Checks that downloads are added to browsing history when they start.1783 */1784add_task(function test_history()1785{1786  mustInterruptResponses();1787  // We will wait for the visit to be notified during the download.1788  yield PlacesTestUtils.clearHistory();1789  let promiseVisit = promiseWaitForVisit(httpUrl("interruptible.txt"));1790  // Start a download that is not allowed to finish yet.1791  let download = yield promiseStartDownload(httpUrl("interruptible.txt"));1792  // The history notifications should be received before the download completes.1793  let [time, transitionType] = yield promiseVisit;1794  do_check_eq(time, download.startTime.getTime() * 1000);1795  do_check_eq(transitionType, Ci.nsINavHistoryService.TRANSITION_DOWNLOAD);1796  // Restart and complete the download after clearing history.1797  yield PlacesTestUtils.clearHistory();1798  download.cancel();1799  continueResponses();1800  yield download.start();1801  // The restart should not have added a new history visit.1802  do_check_false(yield promiseIsURIVisited(httpUrl("interruptible.txt")));1803});1804/**1805 * Checks that downloads started by nsIHelperAppService are added to the1806 * browsing history when they start.1807 */1808add_task(function test_history_tryToKeepPartialData()1809{1810  // We will wait for the visit to be notified during the download.1811  yield PlacesTestUtils.clearHistory();1812  let promiseVisit =1813      promiseWaitForVisit(httpUrl("interruptible_resumable.txt"));1814  // Start a download that is not allowed to finish yet.1815  let beforeStartTimeMs = Date.now();1816  let download = yield promiseStartDownload_tryToKeepPartialData();1817  // The history notifications should be received before the download completes.1818  let [time, transitionType] = yield promiseVisit;1819  do_check_eq(transitionType, Ci.nsINavHistoryService.TRANSITION_DOWNLOAD);1820  // The time set by nsIHelperAppService may be different than the start time in1821  // the download object, thus we only check that it is a meaningful time.  Note1822  // that we subtract one second from the earliest time to account for rounding.1823  do_check_true(time >= beforeStartTimeMs * 1000 - 1000000);1824  // Complete the download before finishing the test.1825  continueResponses();1826  yield promiseDownloadStopped(download);1827});1828/**1829 * Tests that the temp download files are removed on exit and exiting private1830 * mode after they have been launched.1831 */1832add_task(function test_launchWhenSucceeded_deleteTempFileOnExit() {1833  const kDeleteTempFileOnExit = "browser.helperApps.deleteTempFileOnExit";1834  let customLauncherPath = getTempFile("app-launcher").path;1835  let autoDeleteTargetPathOne = getTempFile(TEST_TARGET_FILE_NAME).path;1836  let autoDeleteTargetPathTwo = getTempFile(TEST_TARGET_FILE_NAME).path;1837  let noAutoDeleteTargetPath = getTempFile(TEST_TARGET_FILE_NAME).path;1838  let autoDeleteDownloadOne = yield Downloads.createDownload({1839    source: { url: httpUrl("source.txt"), isPrivate: true },1840    target: autoDeleteTargetPathOne,1841    launchWhenSucceeded: true,1842    launcherPath: customLauncherPath,1843  });1844  yield autoDeleteDownloadOne.start();1845  Services.prefs.setBoolPref(kDeleteTempFileOnExit, true);1846  let autoDeleteDownloadTwo = yield Downloads.createDownload({1847    source: httpUrl("source.txt"),1848    target: autoDeleteTargetPathTwo,1849    launchWhenSucceeded: true,1850    launcherPath: customLauncherPath,1851  });1852  yield autoDeleteDownloadTwo.start();1853  Services.prefs.setBoolPref(kDeleteTempFileOnExit, false);1854  let noAutoDeleteDownload = yield Downloads.createDownload({1855    source: httpUrl("source.txt"),1856    target: noAutoDeleteTargetPath,1857    launchWhenSucceeded: true,1858    launcherPath: customLauncherPath,1859  });1860  yield noAutoDeleteDownload.start();1861  Services.prefs.clearUserPref(kDeleteTempFileOnExit);1862  do_check_true(yield OS.File.exists(autoDeleteTargetPathOne));1863  do_check_true(yield OS.File.exists(autoDeleteTargetPathTwo));1864  do_check_true(yield OS.File.exists(noAutoDeleteTargetPath));1865  // Simulate leaving private browsing mode1866  Services.obs.notifyObservers(null, "last-pb-context-exited", null);1867  do_check_false(yield OS.File.exists(autoDeleteTargetPathOne));1868  // Simulate browser shutdown1869  let expire = Cc["@mozilla.org/uriloader/external-helper-app-service;1"]1870                 .getService(Ci.nsIObserver);1871  expire.observe(null, "profile-before-change", null);1872  do_check_false(yield OS.File.exists(autoDeleteTargetPathTwo));1873  do_check_true(yield OS.File.exists(noAutoDeleteTargetPath));...test_DownloadList.js
Source:test_DownloadList.js  
1/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */2/* vim: set ts=2 et sw=2 tw=80: */3/* Any copyright is dedicated to the Public Domain.4 * http://creativecommons.org/publicdomain/zero/1.0/ */5/**6 * Tests the DownloadList object.7 */8"use strict";9////////////////////////////////////////////////////////////////////////////////10//// Globals11/**12 * Returns a PRTime in the past usable to add expirable visits.13 *14 * @note Expiration ignores any visit added in the last 7 days, but it's15 *       better be safe against DST issues, by going back one day more.16 */17function getExpirablePRTime()18{19  let dateObj = new Date();20  // Normalize to midnight21  dateObj.setHours(0);22  dateObj.setMinutes(0);23  dateObj.setSeconds(0);24  dateObj.setMilliseconds(0);25  dateObj = new Date(dateObj.getTime() - 8 * 86400000);26  return dateObj.getTime() * 1000;27}28/**29 * Adds an expirable history visit for a download.30 *31 * @param aSourceUrl32 *        String containing the URI for the download source, or null to use33 *        httpUrl("source.txt").34 *35 * @return {Promise}36 * @rejects JavaScript exception.37 */38function promiseExpirableDownloadVisit(aSourceUrl)39{40  let deferred = Promise.defer();41  PlacesUtils.asyncHistory.updatePlaces(42    {43      uri: NetUtil.newURI(aSourceUrl || httpUrl("source.txt")),44      visits: [{45        transitionType: Ci.nsINavHistoryService.TRANSITION_DOWNLOAD,46        visitDate: getExpirablePRTime(),47      }]48    },49    {50      handleError: function handleError(aResultCode, aPlaceInfo) {51        let ex = new Components.Exception("Unexpected error in adding visits.",52                                          aResultCode);53        deferred.reject(ex);54      },55      handleResult: function () {},56      handleCompletion: function handleCompletion() {57        deferred.resolve();58      }59    });60  return deferred.promise;61}62////////////////////////////////////////////////////////////////////////////////63//// Tests64/**65 * Checks the testing mechanism used to build different download lists.66 */67add_task(function test_construction()68{69  let downloadListOne = yield promiseNewList();70  let downloadListTwo = yield promiseNewList();71  let privateDownloadListOne = yield promiseNewList(true);72  let privateDownloadListTwo = yield promiseNewList(true);73  do_check_neq(downloadListOne, downloadListTwo);74  do_check_neq(privateDownloadListOne, privateDownloadListTwo);75  do_check_neq(downloadListOne, privateDownloadListOne);76});77/**78 * Checks the methods to add and retrieve items from the list.79 */80add_task(function test_add_getAll()81{82  let list = yield promiseNewList();83  let downloadOne = yield promiseNewDownload();84  yield list.add(downloadOne);85  let itemsOne = yield list.getAll();86  do_check_eq(itemsOne.length, 1);87  do_check_eq(itemsOne[0], downloadOne);88  let downloadTwo = yield promiseNewDownload();89  yield list.add(downloadTwo);90  let itemsTwo = yield list.getAll();91  do_check_eq(itemsTwo.length, 2);92  do_check_eq(itemsTwo[0], downloadOne);93  do_check_eq(itemsTwo[1], downloadTwo);94  // The first snapshot should not have been modified.95  do_check_eq(itemsOne.length, 1);96});97/**98 * Checks the method to remove items from the list.99 */100add_task(function test_remove()101{102  let list = yield promiseNewList();103  yield list.add(yield promiseNewDownload());104  yield list.add(yield promiseNewDownload());105  let items = yield list.getAll();106  yield list.remove(items[0]);107  // Removing an item that was never added should not raise an error.108  yield list.remove(yield promiseNewDownload());109  items = yield list.getAll();110  do_check_eq(items.length, 1);111});112/**113 * Tests that the "add", "remove", and "getAll" methods on the global114 * DownloadCombinedList object combine the contents of the global DownloadList115 * objects for public and private downloads.116 */117add_task(function test_DownloadCombinedList_add_remove_getAll()118{119  let publicList = yield promiseNewList();120  let privateList = yield Downloads.getList(Downloads.PRIVATE);121  let combinedList = yield Downloads.getList(Downloads.ALL);122  let publicDownload = yield promiseNewDownload();123  let privateDownload = yield Downloads.createDownload({124    source: { url: httpUrl("source.txt"), isPrivate: true },125    target: getTempFile(TEST_TARGET_FILE_NAME).path,126  });127  yield publicList.add(publicDownload);128  yield privateList.add(privateDownload);129  do_check_eq((yield combinedList.getAll()).length, 2);130  yield combinedList.remove(publicDownload);131  yield combinedList.remove(privateDownload);132  do_check_eq((yield combinedList.getAll()).length, 0);133  yield combinedList.add(publicDownload);134  yield combinedList.add(privateDownload);135  do_check_eq((yield publicList.getAll()).length, 1);136  do_check_eq((yield privateList.getAll()).length, 1);137  do_check_eq((yield combinedList.getAll()).length, 2);138  yield publicList.remove(publicDownload);139  yield privateList.remove(privateDownload);140  do_check_eq((yield combinedList.getAll()).length, 0);141});142/**143 * Checks that views receive the download add and remove notifications, and that144 * adding and removing views works as expected, both for a normal and a combined145 * list.146 */147add_task(function test_notifications_add_remove()148{149  for (let isCombined of [false, true]) {150    // Force creating a new list for both the public and combined cases.151    let list = yield promiseNewList();152    if (isCombined) {153      list = yield Downloads.getList(Downloads.ALL);154    }155    let downloadOne = yield promiseNewDownload();156    let downloadTwo = yield Downloads.createDownload({157      source: { url: httpUrl("source.txt"), isPrivate: true },158      target: getTempFile(TEST_TARGET_FILE_NAME).path,159    });160    yield list.add(downloadOne);161    yield list.add(downloadTwo);162    // Check that we receive add notifications for existing elements.163    let addNotifications = 0;164    let viewOne = {165      onDownloadAdded: function (aDownload) {166        // The first download to be notified should be the first that was added.167        if (addNotifications == 0) {168          do_check_eq(aDownload, downloadOne);169        } else if (addNotifications == 1) {170          do_check_eq(aDownload, downloadTwo);171        }172        addNotifications++;173      },174    };175    yield list.addView(viewOne);176    do_check_eq(addNotifications, 2);177    // Check that we receive add notifications for new elements.178    yield list.add(yield promiseNewDownload());179    do_check_eq(addNotifications, 3);180    // Check that we receive remove notifications.181    let removeNotifications = 0;182    let viewTwo = {183      onDownloadRemoved: function (aDownload) {184        do_check_eq(aDownload, downloadOne);185        removeNotifications++;186      },187    };188    yield list.addView(viewTwo);189    yield list.remove(downloadOne);190    do_check_eq(removeNotifications, 1);191    // We should not receive remove notifications after the view is removed.192    yield list.removeView(viewTwo);193    yield list.remove(downloadTwo);194    do_check_eq(removeNotifications, 1);195    // We should not receive add notifications after the view is removed.196    yield list.removeView(viewOne);197    yield list.add(yield promiseNewDownload());198    do_check_eq(addNotifications, 3);199  }200});201/**202 * Checks that views receive the download change notifications, both for a203 * normal and a combined list.204 */205add_task(function test_notifications_change()206{207  for (let isCombined of [false, true]) {208    // Force creating a new list for both the public and combined cases.209    let list = yield promiseNewList();210    if (isCombined) {211      list = yield Downloads.getList(Downloads.ALL);212    }213    let downloadOne = yield promiseNewDownload();214    let downloadTwo = yield Downloads.createDownload({215      source: { url: httpUrl("source.txt"), isPrivate: true },216      target: getTempFile(TEST_TARGET_FILE_NAME).path,217    });218    yield list.add(downloadOne);219    yield list.add(downloadTwo);220    // Check that we receive change notifications.221    let receivedOnDownloadChanged = false;222    yield list.addView({223      onDownloadChanged: function (aDownload) {224        do_check_eq(aDownload, downloadOne);225        receivedOnDownloadChanged = true;226      },227    });228    yield downloadOne.start();229    do_check_true(receivedOnDownloadChanged);230    // We should not receive change notifications after a download is removed.231    receivedOnDownloadChanged = false;232    yield list.remove(downloadTwo);233    yield downloadTwo.start();234    do_check_false(receivedOnDownloadChanged);235  }236});237/**238 * Checks that the reference to "this" is correct in the view callbacks.239 */240add_task(function test_notifications_this()241{242  let list = yield promiseNewList();243  // Check that we receive change notifications.244  let receivedOnDownloadAdded = false;245  let receivedOnDownloadChanged = false;246  let receivedOnDownloadRemoved = false;247  let view = {248    onDownloadAdded: function () {249      do_check_eq(this, view);250      receivedOnDownloadAdded = true;251    },252    onDownloadChanged: function () {253      // Only do this check once.254      if (!receivedOnDownloadChanged) {255        do_check_eq(this, view);256        receivedOnDownloadChanged = true;257      }258    },259    onDownloadRemoved: function () {260      do_check_eq(this, view);261      receivedOnDownloadRemoved = true;262    },263  };264  yield list.addView(view);265  let download = yield promiseNewDownload();266  yield list.add(download);267  yield download.start();268  yield list.remove(download);269  // Verify that we executed the checks.270  do_check_true(receivedOnDownloadAdded);271  do_check_true(receivedOnDownloadChanged);272  do_check_true(receivedOnDownloadRemoved);273});274/**275 * Checks that download is removed on history expiration.276 */277add_task(function test_history_expiration()278{279  mustInterruptResponses();280  function cleanup() {281    Services.prefs.clearUserPref("places.history.expiration.max_pages");282  }283  do_register_cleanup(cleanup);284  // Set max pages to 0 to make the download expire.285  Services.prefs.setIntPref("places.history.expiration.max_pages", 0);286  let list = yield promiseNewList();287  let downloadOne = yield promiseNewDownload();288  let downloadTwo = yield promiseNewDownload(httpUrl("interruptible.txt"));289  let deferred = Promise.defer();290  let removeNotifications = 0;291  let downloadView = {292    onDownloadRemoved: function (aDownload) {293      if (++removeNotifications == 2) {294        deferred.resolve();295      }296    },297  };298  yield list.addView(downloadView);299  // Work with one finished download and one canceled download.300  yield downloadOne.start();301  downloadTwo.start();302  yield downloadTwo.cancel();303  // We must replace the visits added while executing the downloads with visits304  // that are older than 7 days, otherwise they will not be expired.305  yield PlacesTestUtils.clearHistory();306  yield promiseExpirableDownloadVisit();307  yield promiseExpirableDownloadVisit(httpUrl("interruptible.txt"));308  // After clearing history, we can add the downloads to be removed to the list.309  yield list.add(downloadOne);310  yield list.add(downloadTwo);311  // Force a history expiration.312  Cc["@mozilla.org/places/expiration;1"]313    .getService(Ci.nsIObserver).observe(null, "places-debug-start-expiration", -1);314  // Wait for both downloads to be removed.315  yield deferred.promise;316  cleanup();317});318/**319 * Checks all downloads are removed after clearing history.320 */321add_task(function test_history_clear()322{323  let list = yield promiseNewList();324  let downloadOne = yield promiseNewDownload();325  let downloadTwo = yield promiseNewDownload();326  yield list.add(downloadOne);327  yield list.add(downloadTwo);328  let deferred = Promise.defer();329  let removeNotifications = 0;330  let downloadView = {331    onDownloadRemoved: function (aDownload) {332      if (++removeNotifications == 2) {333        deferred.resolve();334      }335    },336  };337  yield list.addView(downloadView);338  yield downloadOne.start();339  yield downloadTwo.start();340  yield PlacesTestUtils.clearHistory();341  // Wait for the removal notifications that may still be pending.342  yield deferred.promise;343});344/**345 * Tests the removeFinished method to ensure that it only removes346 * finished downloads.347 */348add_task(function test_removeFinished()349{350  let list = yield promiseNewList();351  let downloadOne = yield promiseNewDownload();352  let downloadTwo = yield promiseNewDownload();353  let downloadThree = yield promiseNewDownload();354  let downloadFour = yield promiseNewDownload();355  yield list.add(downloadOne);356  yield list.add(downloadTwo);357  yield list.add(downloadThree);358  yield list.add(downloadFour);359  let deferred = Promise.defer();360  let removeNotifications = 0;361  let downloadView = {362    onDownloadRemoved: function (aDownload) {363      do_check_true(aDownload == downloadOne ||364                    aDownload == downloadTwo ||365                    aDownload == downloadThree);366      do_check_true(removeNotifications < 3);367      if (++removeNotifications == 3) {368        deferred.resolve();369      }370    },371  };372  yield list.addView(downloadView);373  // Start three of the downloads, but don't start downloadTwo, then set374  // downloadFour to have partial data. All downloads except downloadFour375  // should be removed.376  yield downloadOne.start();377  yield downloadThree.start();378  yield downloadFour.start();379  downloadFour.hasPartialData = true;380  list.removeFinished();381  yield deferred.promise;382  let downloads = yield list.getAll()383  do_check_eq(downloads.length, 1);384});385/**386 * Tests the global DownloadSummary objects for the public, private, and387 * combined download lists.388 */389add_task(function test_DownloadSummary()390{391  mustInterruptResponses();392  let publicList = yield promiseNewList();393  let privateList = yield Downloads.getList(Downloads.PRIVATE);394  let publicSummary = yield Downloads.getSummary(Downloads.PUBLIC);395  let privateSummary = yield Downloads.getSummary(Downloads.PRIVATE);396  let combinedSummary = yield Downloads.getSummary(Downloads.ALL);397  // Add a public download that has succeeded.398  let succeededPublicDownload = yield promiseNewDownload();399  yield succeededPublicDownload.start();400  yield publicList.add(succeededPublicDownload);401  // Add a public download that has been canceled midway.402  let canceledPublicDownload =403      yield promiseNewDownload(httpUrl("interruptible.txt"));404  canceledPublicDownload.start();405  yield promiseDownloadMidway(canceledPublicDownload);406  yield canceledPublicDownload.cancel();407  yield publicList.add(canceledPublicDownload);408  // Add a public download that is in progress.409  let inProgressPublicDownload =410      yield promiseNewDownload(httpUrl("interruptible.txt"));411  inProgressPublicDownload.start();412  yield promiseDownloadMidway(inProgressPublicDownload);413  yield publicList.add(inProgressPublicDownload);414  // Add a private download that is in progress.415  let inProgressPrivateDownload = yield Downloads.createDownload({416    source: { url: httpUrl("interruptible.txt"), isPrivate: true },417    target: getTempFile(TEST_TARGET_FILE_NAME).path,418  });419  inProgressPrivateDownload.start();420  yield promiseDownloadMidway(inProgressPrivateDownload);421  yield privateList.add(inProgressPrivateDownload);422  // Verify that the summary includes the total number of bytes and the423  // currently transferred bytes only for the downloads that are not stopped.424  // For simplicity, we assume that after a download is added to the list, its425  // current state is immediately propagated to the summary object, which is426  // true in the current implementation, though it is not guaranteed as all the427  // download operations may happen asynchronously.428  do_check_false(publicSummary.allHaveStopped);429  do_check_eq(publicSummary.progressTotalBytes, TEST_DATA_SHORT.length * 2);430  do_check_eq(publicSummary.progressCurrentBytes, TEST_DATA_SHORT.length);431  do_check_false(privateSummary.allHaveStopped);432  do_check_eq(privateSummary.progressTotalBytes, TEST_DATA_SHORT.length * 2);433  do_check_eq(privateSummary.progressCurrentBytes, TEST_DATA_SHORT.length);434  do_check_false(combinedSummary.allHaveStopped);435  do_check_eq(combinedSummary.progressTotalBytes, TEST_DATA_SHORT.length * 4);436  do_check_eq(combinedSummary.progressCurrentBytes, TEST_DATA_SHORT.length * 2);437  yield inProgressPublicDownload.cancel();438  // Stopping the download should have excluded it from the summary.439  do_check_true(publicSummary.allHaveStopped);440  do_check_eq(publicSummary.progressTotalBytes, 0);441  do_check_eq(publicSummary.progressCurrentBytes, 0);442  do_check_false(privateSummary.allHaveStopped);443  do_check_eq(privateSummary.progressTotalBytes, TEST_DATA_SHORT.length * 2);444  do_check_eq(privateSummary.progressCurrentBytes, TEST_DATA_SHORT.length);445  do_check_false(combinedSummary.allHaveStopped);446  do_check_eq(combinedSummary.progressTotalBytes, TEST_DATA_SHORT.length * 2);447  do_check_eq(combinedSummary.progressCurrentBytes, TEST_DATA_SHORT.length);448  yield inProgressPrivateDownload.cancel();449  // All the downloads should be stopped now.450  do_check_true(publicSummary.allHaveStopped);451  do_check_eq(publicSummary.progressTotalBytes, 0);452  do_check_eq(publicSummary.progressCurrentBytes, 0);453  do_check_true(privateSummary.allHaveStopped);454  do_check_eq(privateSummary.progressTotalBytes, 0);455  do_check_eq(privateSummary.progressCurrentBytes, 0);456  do_check_true(combinedSummary.allHaveStopped);457  do_check_eq(combinedSummary.progressTotalBytes, 0);458  do_check_eq(combinedSummary.progressCurrentBytes, 0);459});460/**461 * Checks that views receive the summary change notification.  This is tested on462 * the combined summary when adding a public download, as we assume that if we463 * pass the test in this case we will also pass it in the others.464 */465add_task(function test_DownloadSummary_notifications()466{467  let list = yield promiseNewList();468  let summary = yield Downloads.getSummary(Downloads.ALL);469  let download = yield promiseNewDownload();470  yield list.add(download);471  // Check that we receive change notifications.472  let receivedOnSummaryChanged = false;473  yield summary.addView({474    onSummaryChanged: function () {475      receivedOnSummaryChanged = true;476    },477  });478  yield download.start();479  do_check_true(receivedOnSummaryChanged);480});481////////////////////////////////////////////////////////////////////////////////482//// Termination483let tailFile = do_get_file("tail.js");...bg.js
Source:bg.js  
...71            if (downloadLinks && downloadLinks.length !== 0) {72                downloadInterval = setInterval(() => {73                    if (downloadLinks.length !== 0) {74                        updateDownloadIds();75                        download(downloadLinks.shift());76                    } else {77                        beginDownload();78                    }79                }, 1000);80            } else {81                clearInterval(downloadInterval);82                chrome.storage.local.clear(() => lsManager.initStorage());83            }84        })85        .catch(err => {86            console.error(err);87        });88}89const onLoggedIn = (loginLink, callback) => {90    const baseLink = loginLink.match(/^(http)s?:\/\/.[^\/]*\//g)[0];91    if (windowIds[baseLink] && !visited[baseLink]) {92        chrome.tabs.query({93            windowId: windowIds[baseLink]94        }, (tabs) => {95            if (tabs.length == 0) {96                visiting[baseLink] = false;97            }98        });99    }100    if (!visited[baseLink] && visiting[baseLink]) {101        return;102    } else if (!visited[baseLink]) {103        visiting[baseLink] = true;104        chrome.windows.create({105            url: [loginLink],106            type: 'popup'107        }, (loginWindow) => {108            windowIds[baseLink] = loginWindow.id;109            function loginDownload(item) {110                chrome.downloads.cancel(item.id);111                visited[baseLink] = true;112                visiting[baseLink] = false;113                chrome.windows.remove(loginWindow.id);114                chrome.downloads.onCreated.removeListener(loginDownload);115                chrome.tabs.onUpdated.removeListener(granuleOpenedinBrowser);116                callback();117                // return true;118            }119            function granuleOpenedinBrowser(tabId, changeInfo, tab) {120                if (121                    tabId == loginWindow.tabs[0].id &&122                    tab.url == tab.title &&123                    tab.url == loginLink124                ) {125                    visited[baseLink] = true;126                    chrome.windows.remove(loginWindow.id);127                    chrome.tabs.onUpdated.removeListener(granuleOpenedinBrowser);128                    chrome.downloads.onCreated.removeListener(loginDownload);129                    callback();130                    // return true;131                }132            }133            chrome.downloads.onCreated.addListener(loginDownload);134            chrome.tabs.onUpdated.addListener(granuleOpenedinBrowser);135        })136        // chrome.windows.create({137        //     url: [loginLink]138        // }, (loginWindow)=>{139        //     chrome.downloads.onCreated.addListener(function loginDownload(item){140        //         chrome.downloads.cancel(141        //             function(item){142        //                 console.log("deleting loginDownload");143        //             });144        //         chrome.windows.remove(loginWindow.id);145        //         chrome.downloads.onCreated.removeListener(loginDownload);146        //         visited[baseLink] = true;147        //         callback();148        //     });149        // })150    } else {151        callback();152        // return true;153    }154};155chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {156    request.message = request.message.toLowerCase();157    if (typeof(request) === "object") {158        if (request.message == "start-download") {159            downloadData.datasetName = request.datasetName;160            initDownload(request);161        } else if (request.message == "cancel-download") {162            // pauseAll();163            // if (confirm("Are you sure you want to cancel downloads?")) {164            //     cancelAll();165            // } else {166            //     resumeAll();167            // }168            cancelAll();169        } else if (request.message == "pause-download") {170            pauseAll();171        } else if (request.message == "resume-download") {172            resumeAll();173        } else if (request.message == "update-popup") {174            if (popupManager) {175                popupManager.postPogress();176            }177        } else if (request.message == "swal-fire") {178            closeSwal(sender);179        } else if (request.message == "update-granuleCount") {180            downloadData.totalNoofFiles = request.granuleCount;181            popupManager.updateGranuleCount(request.granuleCount);182        } else if (request.message == "download-completed") {183            reset(true);184        }185    }186});187function closeSwal(sender) {188    chrome.downloads.onCreated.addListener(function sendSwalMessage() {189        chrome.tabs.sendMessage(190            sender.tab.id, { message: "clear-swal-fire" },191            function(response) {192                if (response.message == "swal-closed") {193                    chrome.downloads.onCreated.removeListener(sendSwalMessage);194                }195            });196    })197}198function download(downloadLink) {199    let filename = downloadLink.substring(downloadLink.lastIndexOf('/') + 1);200    let foldername = "Earthdata-BulkDownloads";201    chrome.storage.sync.get(['mainFolderName'], function(name) {202        if (name) {203            directoryName = name.mainFolderName;204        }205    });206    console.log(directoryName);207    const dataSetname = downloadData.datasetName;208    if (directoryName) {209        path = directoryName + '/' + dataSetname + "/" + filename;210    } else {211        path = foldername + '/' + dataSetname + "/" + filename;212    }213    console.log(path);214    console.log(foldername);215    chrome.downloads.download({216        url: downloadLink,217        filename: path218    }, function(downloadId) {219        if (cancelledJobs[jobId]) {220            chrome.downloads.cancel(downloadId);221        } else if (pausedJobs[jobId]) {222            modifyDownload(downloadId, pause);223        }224        downloadIds[downloadId] = downloadLink;225    });226}227function handleUndefined(variable, callback) {228    console.log(variable);229    if (variable === undefined || variable === "undefined") {...FileDownload.js
Source:FileDownload.js  
...146		{147		    url = nexacro._toString(url);		  148		    url = nexacro._getImageLocation(url);149150		    nexacro._download(url, this._hidden_frame_handle, initname, targetpath);151		    ret = true;152		}	153   		else if (downloadurl && downloadurl != undefined && downloadurl != "")154		{155   			downloadurl = nexacro._getServiceLocation(downloadurl);156   			nexacro._download(downloadurl, this._hidden_frame_handle, initname, targetpath);157		    ret = true;158   		}159		return ret;160	};161162    //===============================================================163    // nexacro.FileDownload : Events164    //===============================================================165    _pFileDownload.on_fire_onsuccess = function (url, targetfullpath)166    {167    	var application = nexacro.getApplication();168    	if (application)169			application._endCommProgress();170171        if (this.onsuccess && this.onsuccess._has_handlers && url != "")172        {173            var evt = new nexacro.FileDownloadEventInfo(this, "onsuccess", url, targetfullpath);174            return this.onsuccess._fireEvent(this, evt);175        }176    };177178    _pFileDownload.on_fire_onerror = function (obj, errortype, errormsg, errorobj, statuscode, requesturi, locationuri)179    {180    	var application = nexacro.getApplication();181    	if (application)182	        application._endCommProgress();183184        if (this.onerror && this.onerror._has_handlers)185        {186            var evt = new nexacro.FileDownloadErrorEventInfo(obj, "onerror", errortype, errormsg, errorobj, statuscode, requesturi, locationuri);187            return this.onerror._fireEvent(this, evt);188        }189    };190191    _pFileDownload.on_load = function (status, data, url, errcode, httpcode, errmsg)192    {193        nexacro._onHttpSystemError(this, true, this, errcode, url, httpcode, url, null);194        if (status < 0)195        {196            var errormsg = nexacro._GetSystemErrorMsg(this, errcode);197            this.on_fire_onerror(this, "ObjectError", errormsg, this, 9901, null, null);198        }199        else200        {201            this.on_fire_onsuccess(url, data);202        }203    };204205    _pFileDownload.on_fire_onclick = function (button, alt_key, ctrl_key, shift_key, screenX, screenY, canvasX, canvasY, clientX, clientY, from_comp, from_refer_comp)206    {207        var ret = nexacro.Component.prototype.on_fire_onclick.call(this, button, alt_key, ctrl_key, shift_key, screenX, screenY, canvasX, canvasY, clientX, clientY, from_comp, from_refer_comp);208        this.download();209        return ret;210    };211212    _pFileDownload.on_fire_sys_onkeyup = function (key_code, alt_key, ctrl_key, shift_key, from_comp, from_refer_comp)213    {214        var ret = nexacro.Component.prototype.on_fire_sys_onkeyup.call(this, key_code, alt_key, ctrl_key, shift_key, from_comp, from_refer_comp);215        216        if (key_code == 13 || key_code == 32)217        {218            this.on_fire_onclick("none", false, false, false, -1, -1, -1, -1, -1, -1, this, this);219        }220221        return ret;222    };
...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
