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