toolkit/components/jsdownloads/test/unit/test_DownloadIntegration.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 * http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 /**
michael@0 5 * Tests the DownloadIntegration object.
michael@0 6 */
michael@0 7
michael@0 8 "use strict";
michael@0 9
michael@0 10 ////////////////////////////////////////////////////////////////////////////////
michael@0 11 //// Globals
michael@0 12
michael@0 13 /**
michael@0 14 * Enable test mode for the _confirmCancelDownloads method to return
michael@0 15 * the number of downloads instead of showing the prompt to cancel or not.
michael@0 16 */
michael@0 17 function enableObserversTestMode() {
michael@0 18 DownloadIntegration.testMode = true;
michael@0 19 DownloadIntegration.dontLoadObservers = false;
michael@0 20 function cleanup() {
michael@0 21 DownloadIntegration.testMode = false;
michael@0 22 DownloadIntegration.dontLoadObservers = true;
michael@0 23 }
michael@0 24 do_register_cleanup(cleanup);
michael@0 25 }
michael@0 26
michael@0 27 /**
michael@0 28 * Notifies the prompt observers and verify the expected downloads count.
michael@0 29 *
michael@0 30 * @param aIsPrivate
michael@0 31 * Flag to know is test private observers.
michael@0 32 * @param aExpectedCount
michael@0 33 * the expected downloads count for quit and offline observers.
michael@0 34 * @param aExpectedPBCount
michael@0 35 * the expected downloads count for private browsing observer.
michael@0 36 */
michael@0 37 function notifyPromptObservers(aIsPrivate, aExpectedCount, aExpectedPBCount) {
michael@0 38 let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].
michael@0 39 createInstance(Ci.nsISupportsPRBool);
michael@0 40
michael@0 41 // Notify quit application requested observer.
michael@0 42 DownloadIntegration.testPromptDownloads = -1;
michael@0 43 Services.obs.notifyObservers(cancelQuit, "quit-application-requested", null);
michael@0 44 do_check_eq(DownloadIntegration.testPromptDownloads, aExpectedCount);
michael@0 45
michael@0 46 // Notify offline requested observer.
michael@0 47 DownloadIntegration.testPromptDownloads = -1;
michael@0 48 Services.obs.notifyObservers(cancelQuit, "offline-requested", null);
michael@0 49 do_check_eq(DownloadIntegration.testPromptDownloads, aExpectedCount);
michael@0 50
michael@0 51 if (aIsPrivate) {
michael@0 52 // Notify last private browsing requested observer.
michael@0 53 DownloadIntegration.testPromptDownloads = -1;
michael@0 54 Services.obs.notifyObservers(cancelQuit, "last-pb-context-exiting", null);
michael@0 55 do_check_eq(DownloadIntegration.testPromptDownloads, aExpectedPBCount);
michael@0 56 }
michael@0 57 }
michael@0 58
michael@0 59 ////////////////////////////////////////////////////////////////////////////////
michael@0 60 //// Tests
michael@0 61
michael@0 62 XPCOMUtils.defineLazyGetter(this, "gStringBundle", function() {
michael@0 63 return Services.strings.
michael@0 64 createBundle("chrome://mozapps/locale/downloads/downloads.properties");
michael@0 65 });
michael@0 66
michael@0 67 /**
michael@0 68 * Tests that the getSystemDownloadsDirectory returns a valid download
michael@0 69 * directory string path.
michael@0 70 */
michael@0 71 add_task(function test_getSystemDownloadsDirectory()
michael@0 72 {
michael@0 73 // Enable test mode for the getSystemDownloadsDirectory method to return
michael@0 74 // temp directory instead so we can check whether the desired directory
michael@0 75 // is created or not.
michael@0 76 DownloadIntegration.testMode = true;
michael@0 77 function cleanup() {
michael@0 78 DownloadIntegration.testMode = false;
michael@0 79 }
michael@0 80 do_register_cleanup(cleanup);
michael@0 81
michael@0 82 let tempDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
michael@0 83 let downloadDir;
michael@0 84
michael@0 85 // OSX / Linux / Windows but not XP/2k
michael@0 86 if (Services.appinfo.OS == "Darwin" ||
michael@0 87 Services.appinfo.OS == "Linux" ||
michael@0 88 (Services.appinfo.OS == "WINNT" &&
michael@0 89 parseFloat(Services.sysinfo.getProperty("version")) >= 6)) {
michael@0 90 downloadDir = yield DownloadIntegration.getSystemDownloadsDirectory();
michael@0 91 do_check_eq(downloadDir, tempDir.path);
michael@0 92 do_check_true(yield OS.File.exists(downloadDir));
michael@0 93
michael@0 94 let info = yield OS.File.stat(downloadDir);
michael@0 95 do_check_true(info.isDir);
michael@0 96 } else {
michael@0 97 let targetPath = OS.Path.join(tempDir.path,
michael@0 98 gStringBundle.GetStringFromName("downloadsFolder"));
michael@0 99 try {
michael@0 100 yield OS.File.removeEmptyDir(targetPath);
michael@0 101 } catch(e) {}
michael@0 102 downloadDir = yield DownloadIntegration.getSystemDownloadsDirectory();
michael@0 103 do_check_eq(downloadDir, targetPath);
michael@0 104 do_check_true(yield OS.File.exists(downloadDir));
michael@0 105
michael@0 106 let info = yield OS.File.stat(downloadDir);
michael@0 107 do_check_true(info.isDir);
michael@0 108 yield OS.File.removeEmptyDir(targetPath);
michael@0 109 }
michael@0 110
michael@0 111 let downloadDirBefore = yield DownloadIntegration.getSystemDownloadsDirectory();
michael@0 112 cleanup();
michael@0 113 let downloadDirAfter = yield DownloadIntegration.getSystemDownloadsDirectory();
michael@0 114 do_check_neq(downloadDirBefore, downloadDirAfter);
michael@0 115 });
michael@0 116
michael@0 117 /**
michael@0 118 * Tests that the getPreferredDownloadsDirectory returns a valid download
michael@0 119 * directory string path.
michael@0 120 */
michael@0 121 add_task(function test_getPreferredDownloadsDirectory()
michael@0 122 {
michael@0 123 let folderListPrefName = "browser.download.folderList";
michael@0 124 let dirPrefName = "browser.download.dir";
michael@0 125 function cleanup() {
michael@0 126 Services.prefs.clearUserPref(folderListPrefName);
michael@0 127 Services.prefs.clearUserPref(dirPrefName);
michael@0 128 }
michael@0 129 do_register_cleanup(cleanup);
michael@0 130
michael@0 131 // Should return the system downloads directory.
michael@0 132 Services.prefs.setIntPref(folderListPrefName, 1);
michael@0 133 let systemDir = yield DownloadIntegration.getSystemDownloadsDirectory();
michael@0 134 let downloadDir = yield DownloadIntegration.getPreferredDownloadsDirectory();
michael@0 135 do_check_neq(downloadDir, "");
michael@0 136 do_check_eq(downloadDir, systemDir);
michael@0 137
michael@0 138 // Should return the desktop directory.
michael@0 139 Services.prefs.setIntPref(folderListPrefName, 0);
michael@0 140 downloadDir = yield DownloadIntegration.getPreferredDownloadsDirectory();
michael@0 141 do_check_neq(downloadDir, "");
michael@0 142 do_check_eq(downloadDir, Services.dirsvc.get("Desk", Ci.nsIFile).path);
michael@0 143
michael@0 144 // Should return the system downloads directory because the dir preference
michael@0 145 // is not set.
michael@0 146 Services.prefs.setIntPref(folderListPrefName, 2);
michael@0 147 let downloadDir = yield DownloadIntegration.getPreferredDownloadsDirectory();
michael@0 148 do_check_neq(downloadDir, "");
michael@0 149 do_check_eq(downloadDir, systemDir);
michael@0 150
michael@0 151 // Should return the directory which is listed in the dir preference.
michael@0 152 let time = (new Date()).getTime();
michael@0 153 let tempDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
michael@0 154 tempDir.append(time);
michael@0 155 Services.prefs.setComplexValue("browser.download.dir", Ci.nsIFile, tempDir);
michael@0 156 downloadDir = yield DownloadIntegration.getPreferredDownloadsDirectory();
michael@0 157 do_check_neq(downloadDir, "");
michael@0 158 do_check_eq(downloadDir, tempDir.path);
michael@0 159 do_check_true(yield OS.File.exists(downloadDir));
michael@0 160 yield OS.File.removeEmptyDir(tempDir.path);
michael@0 161
michael@0 162 // Should return the system downloads directory beacause the path is invalid
michael@0 163 // in the dir preference.
michael@0 164 tempDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
michael@0 165 tempDir.append("dir_not_exist");
michael@0 166 tempDir.append(time);
michael@0 167 Services.prefs.setComplexValue("browser.download.dir", Ci.nsIFile, tempDir);
michael@0 168 downloadDir = yield DownloadIntegration.getPreferredDownloadsDirectory();
michael@0 169 do_check_eq(downloadDir, systemDir);
michael@0 170
michael@0 171 // Should return the system downloads directory because the folderList
michael@0 172 // preference is invalid
michael@0 173 Services.prefs.setIntPref(folderListPrefName, 999);
michael@0 174 let downloadDir = yield DownloadIntegration.getPreferredDownloadsDirectory();
michael@0 175 do_check_eq(downloadDir, systemDir);
michael@0 176
michael@0 177 cleanup();
michael@0 178 });
michael@0 179
michael@0 180 /**
michael@0 181 * Tests that the getTemporaryDownloadsDirectory returns a valid download
michael@0 182 * directory string path.
michael@0 183 */
michael@0 184 add_task(function test_getTemporaryDownloadsDirectory()
michael@0 185 {
michael@0 186 let downloadDir = yield DownloadIntegration.getTemporaryDownloadsDirectory();
michael@0 187 do_check_neq(downloadDir, "");
michael@0 188
michael@0 189 if ("nsILocalFileMac" in Ci) {
michael@0 190 let preferredDownloadDir = yield DownloadIntegration.getPreferredDownloadsDirectory();
michael@0 191 do_check_eq(downloadDir, preferredDownloadDir);
michael@0 192 } else {
michael@0 193 let tempDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
michael@0 194 do_check_eq(downloadDir, tempDir.path);
michael@0 195 }
michael@0 196 });
michael@0 197
michael@0 198 ////////////////////////////////////////////////////////////////////////////////
michael@0 199 //// Tests DownloadObserver
michael@0 200
michael@0 201 /**
michael@0 202 * Tests notifications prompts when observers are notified if there are public
michael@0 203 * and private active downloads.
michael@0 204 */
michael@0 205 add_task(function test_notifications()
michael@0 206 {
michael@0 207 enableObserversTestMode();
michael@0 208
michael@0 209 for (let isPrivate of [false, true]) {
michael@0 210 mustInterruptResponses();
michael@0 211
michael@0 212 let list = yield promiseNewList(isPrivate);
michael@0 213 let download1 = yield promiseNewDownload(httpUrl("interruptible.txt"));
michael@0 214 let download2 = yield promiseNewDownload(httpUrl("interruptible.txt"));
michael@0 215 let download3 = yield promiseNewDownload(httpUrl("interruptible.txt"));
michael@0 216 let promiseAttempt1 = download1.start();
michael@0 217 let promiseAttempt2 = download2.start();
michael@0 218 download3.start();
michael@0 219
michael@0 220 // Add downloads to list.
michael@0 221 yield list.add(download1);
michael@0 222 yield list.add(download2);
michael@0 223 yield list.add(download3);
michael@0 224 // Cancel third download
michael@0 225 yield download3.cancel();
michael@0 226
michael@0 227 notifyPromptObservers(isPrivate, 2, 2);
michael@0 228
michael@0 229 // Allow the downloads to complete.
michael@0 230 continueResponses();
michael@0 231 yield promiseAttempt1;
michael@0 232 yield promiseAttempt2;
michael@0 233
michael@0 234 // Clean up.
michael@0 235 yield list.remove(download1);
michael@0 236 yield list.remove(download2);
michael@0 237 yield list.remove(download3);
michael@0 238 }
michael@0 239 });
michael@0 240
michael@0 241 /**
michael@0 242 * Tests that notifications prompts observers are not notified if there are no
michael@0 243 * public or private active downloads.
michael@0 244 */
michael@0 245 add_task(function test_no_notifications()
michael@0 246 {
michael@0 247 enableObserversTestMode();
michael@0 248
michael@0 249 for (let isPrivate of [false, true]) {
michael@0 250 let list = yield promiseNewList(isPrivate);
michael@0 251 let download1 = yield promiseNewDownload(httpUrl("interruptible.txt"));
michael@0 252 let download2 = yield promiseNewDownload(httpUrl("interruptible.txt"));
michael@0 253 download1.start();
michael@0 254 download2.start();
michael@0 255
michael@0 256 // Add downloads to list.
michael@0 257 yield list.add(download1);
michael@0 258 yield list.add(download2);
michael@0 259
michael@0 260 yield download1.cancel();
michael@0 261 yield download2.cancel();
michael@0 262
michael@0 263 notifyPromptObservers(isPrivate, 0, 0);
michael@0 264
michael@0 265 // Clean up.
michael@0 266 yield list.remove(download1);
michael@0 267 yield list.remove(download2);
michael@0 268 }
michael@0 269 });
michael@0 270
michael@0 271 /**
michael@0 272 * Tests notifications prompts when observers are notified if there are public
michael@0 273 * and private active downloads at the same time.
michael@0 274 */
michael@0 275 add_task(function test_mix_notifications()
michael@0 276 {
michael@0 277 enableObserversTestMode();
michael@0 278 mustInterruptResponses();
michael@0 279
michael@0 280 let publicList = yield promiseNewList();
michael@0 281 let privateList = yield Downloads.getList(Downloads.PRIVATE);
michael@0 282 let download1 = yield promiseNewDownload(httpUrl("interruptible.txt"));
michael@0 283 let download2 = yield promiseNewDownload(httpUrl("interruptible.txt"));
michael@0 284 let promiseAttempt1 = download1.start();
michael@0 285 let promiseAttempt2 = download2.start();
michael@0 286
michael@0 287 // Add downloads to lists.
michael@0 288 yield publicList.add(download1);
michael@0 289 yield privateList.add(download2);
michael@0 290
michael@0 291 notifyPromptObservers(true, 2, 1);
michael@0 292
michael@0 293 // Allow the downloads to complete.
michael@0 294 continueResponses();
michael@0 295 yield promiseAttempt1;
michael@0 296 yield promiseAttempt2;
michael@0 297
michael@0 298 // Clean up.
michael@0 299 yield publicList.remove(download1);
michael@0 300 yield privateList.remove(download2);
michael@0 301 });
michael@0 302
michael@0 303 /**
michael@0 304 * Tests suspending and resuming as well as going offline and then online again.
michael@0 305 * The downloads should stop when suspending and start again when resuming.
michael@0 306 */
michael@0 307 add_task(function test_suspend_resume()
michael@0 308 {
michael@0 309 enableObserversTestMode();
michael@0 310
michael@0 311 // The default wake delay is 10 seconds, so set the wake delay to be much
michael@0 312 // faster for these tests.
michael@0 313 Services.prefs.setIntPref("browser.download.manager.resumeOnWakeDelay", 5);
michael@0 314
michael@0 315 let addDownload = function(list)
michael@0 316 {
michael@0 317 return Task.spawn(function () {
michael@0 318 let download = yield promiseNewDownload(httpUrl("interruptible.txt"));
michael@0 319 download.start();
michael@0 320 list.add(download);
michael@0 321 throw new Task.Result(download);
michael@0 322 });
michael@0 323 }
michael@0 324
michael@0 325 let publicList = yield promiseNewList();
michael@0 326 let privateList = yield promiseNewList(true);
michael@0 327
michael@0 328 let download1 = yield addDownload(publicList);
michael@0 329 let download2 = yield addDownload(publicList);
michael@0 330 let download3 = yield addDownload(privateList);
michael@0 331 let download4 = yield addDownload(privateList);
michael@0 332 let download5 = yield addDownload(publicList);
michael@0 333
michael@0 334 // First, check that the downloads are all canceled when going to sleep.
michael@0 335 Services.obs.notifyObservers(null, "sleep_notification", null);
michael@0 336 do_check_true(download1.canceled);
michael@0 337 do_check_true(download2.canceled);
michael@0 338 do_check_true(download3.canceled);
michael@0 339 do_check_true(download4.canceled);
michael@0 340 do_check_true(download5.canceled);
michael@0 341
michael@0 342 // Remove a download. It should not be started again.
michael@0 343 publicList.remove(download5);
michael@0 344 do_check_true(download5.canceled);
michael@0 345
michael@0 346 // When waking up again, the downloads start again after the wake delay. To be
michael@0 347 // more robust, don't check after a delay but instead just wait for the
michael@0 348 // downloads to finish.
michael@0 349 Services.obs.notifyObservers(null, "wake_notification", null);
michael@0 350 yield download1.whenSucceeded();
michael@0 351 yield download2.whenSucceeded();
michael@0 352 yield download3.whenSucceeded();
michael@0 353 yield download4.whenSucceeded();
michael@0 354
michael@0 355 // Downloads should no longer be canceled. However, as download5 was removed
michael@0 356 // from the public list, it will not be restarted.
michael@0 357 do_check_false(download1.canceled);
michael@0 358 do_check_true(download5.canceled);
michael@0 359
michael@0 360 // Create four new downloads and check for going offline and then online again.
michael@0 361
michael@0 362 download1 = yield addDownload(publicList);
michael@0 363 download2 = yield addDownload(publicList);
michael@0 364 download3 = yield addDownload(privateList);
michael@0 365 download4 = yield addDownload(privateList);
michael@0 366
michael@0 367 // Going offline should cancel the downloads.
michael@0 368 Services.obs.notifyObservers(null, "network:offline-about-to-go-offline", null);
michael@0 369 do_check_true(download1.canceled);
michael@0 370 do_check_true(download2.canceled);
michael@0 371 do_check_true(download3.canceled);
michael@0 372 do_check_true(download4.canceled);
michael@0 373
michael@0 374 // Going back online should start the downloads again.
michael@0 375 Services.obs.notifyObservers(null, "network:offline-status-changed", "online");
michael@0 376 yield download1.whenSucceeded();
michael@0 377 yield download2.whenSucceeded();
michael@0 378 yield download3.whenSucceeded();
michael@0 379 yield download4.whenSucceeded();
michael@0 380
michael@0 381 Services.prefs.clearUserPref("browser.download.manager.resumeOnWakeDelay");
michael@0 382 });
michael@0 383
michael@0 384 /**
michael@0 385 * Tests both the downloads list and the in-progress downloads are clear when
michael@0 386 * private browsing observer is notified.
michael@0 387 */
michael@0 388 add_task(function test_exit_private_browsing()
michael@0 389 {
michael@0 390 enableObserversTestMode();
michael@0 391 mustInterruptResponses();
michael@0 392
michael@0 393 let privateList = yield promiseNewList(true);
michael@0 394 let download1 = yield promiseNewDownload(httpUrl("source.txt"));
michael@0 395 let download2 = yield promiseNewDownload(httpUrl("interruptible.txt"));
michael@0 396 let promiseAttempt1 = download1.start();
michael@0 397 let promiseAttempt2 = download2.start();
michael@0 398
michael@0 399 // Add downloads to list.
michael@0 400 yield privateList.add(download1);
michael@0 401 yield privateList.add(download2);
michael@0 402
michael@0 403 // Complete the download.
michael@0 404 yield promiseAttempt1;
michael@0 405
michael@0 406 do_check_eq((yield privateList.getAll()).length, 2);
michael@0 407
michael@0 408 // Simulate exiting the private browsing.
michael@0 409 DownloadIntegration._deferTestClearPrivateList = Promise.defer();
michael@0 410 Services.obs.notifyObservers(null, "last-pb-context-exited", null);
michael@0 411 let result = yield DownloadIntegration._deferTestClearPrivateList.promise;
michael@0 412
michael@0 413 do_check_eq(result, "success");
michael@0 414 do_check_eq((yield privateList.getAll()).length, 0);
michael@0 415
michael@0 416 continueResponses();
michael@0 417 });
michael@0 418
michael@0 419 ////////////////////////////////////////////////////////////////////////////////
michael@0 420 //// Termination
michael@0 421
michael@0 422 let tailFile = do_get_file("tail.js");
michael@0 423 Services.scriptloader.loadSubScript(NetUtil.newURI(tailFile).spec);

mercurial