1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/downloads/test/unit/head_download_manager.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,233 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +// This file tests the download manager backend 1.9 + 1.10 +const Cc = Components.classes; 1.11 +const Ci = Components.interfaces; 1.12 +const Cu = Components.utils; 1.13 +const Cr = Components.results; 1.14 + 1.15 +do_get_profile(); 1.16 + 1.17 +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 1.18 +Cu.import("resource://gre/modules/Services.jsm"); 1.19 +Cu.import("resource://testing-common/httpd.js"); 1.20 +Cu.import("resource://gre/modules/PlacesUtils.jsm"); 1.21 +XPCOMUtils.defineLazyModuleGetter(this, "Promise", 1.22 + "resource://gre/modules/Promise.jsm"); 1.23 + 1.24 +var downloadUtils = { }; 1.25 +XPCOMUtils.defineLazyServiceGetter(downloadUtils, 1.26 + "downloadManager", 1.27 + "@mozilla.org/download-manager;1", 1.28 + Ci.nsIDownloadManager); 1.29 + 1.30 +function createURI(aObj) 1.31 +{ 1.32 + var ios = Cc["@mozilla.org/network/io-service;1"]. 1.33 + getService(Ci.nsIIOService); 1.34 + return (aObj instanceof Ci.nsIFile) ? ios.newFileURI(aObj) : 1.35 + ios.newURI(aObj, null, null); 1.36 +} 1.37 + 1.38 +var dirSvc = Cc["@mozilla.org/file/directory_service;1"]. 1.39 + getService(Ci.nsIProperties); 1.40 + 1.41 +var provider = { 1.42 + getFile: function(prop, persistent) { 1.43 + persistent.value = true; 1.44 + if (prop == "DLoads") { 1.45 + var file = dirSvc.get("ProfD", Ci.nsILocalFile); 1.46 + file.append("downloads.rdf"); 1.47 + return file; 1.48 + } 1.49 + print("*** Throwing trying to get " + prop); 1.50 + throw Cr.NS_ERROR_FAILURE; 1.51 + }, 1.52 + QueryInterface: function(iid) { 1.53 + if (iid.equals(Ci.nsIDirectoryServiceProvider) || 1.54 + iid.equals(Ci.nsISupports)) { 1.55 + return this; 1.56 + } 1.57 + throw Cr.NS_ERROR_NO_INTERFACE; 1.58 + } 1.59 +}; 1.60 +dirSvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider); 1.61 + 1.62 +var gDownloadCount = 0; 1.63 +/** 1.64 + * Adds a download to the DM, and starts it. 1.65 + * @param server: a HttpServer used to serve the sourceURI 1.66 + * @param aParams (optional): an optional object which contains the function 1.67 + * parameters: 1.68 + * resultFileName: leaf node for the target file 1.69 + * targetFile: nsIFile for the target (overrides resultFileName) 1.70 + * sourceURI: the download source URI 1.71 + * downloadName: the display name of the download 1.72 + * runBeforeStart: a function to run before starting the download 1.73 + * isPrivate: whether the download is private or not 1.74 + */ 1.75 +function addDownload(server, aParams) 1.76 +{ 1.77 + if (!server) 1.78 + do_throw("Must provide a valid server."); 1.79 + const PORT = server.identity.primaryPort; 1.80 + if (!aParams) 1.81 + aParams = {}; 1.82 + if (!("resultFileName" in aParams)) 1.83 + aParams.resultFileName = "download.result"; 1.84 + if (!("targetFile" in aParams)) { 1.85 + aParams.targetFile = dirSvc.get("ProfD", Ci.nsIFile); 1.86 + aParams.targetFile.append(aParams.resultFileName); 1.87 + } 1.88 + if (!("sourceURI" in aParams)) 1.89 + aParams.sourceURI = "http://localhost:" + PORT + "/head_download_manager.js"; 1.90 + if (!("downloadName" in aParams)) 1.91 + aParams.downloadName = null; 1.92 + if (!("runBeforeStart" in aParams)) 1.93 + aParams.runBeforeStart = function () {}; 1.94 + 1.95 + const nsIWBP = Ci.nsIWebBrowserPersist; 1.96 + var persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"] 1.97 + .createInstance(Ci.nsIWebBrowserPersist); 1.98 + persist.persistFlags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES | 1.99 + nsIWBP.PERSIST_FLAGS_BYPASS_CACHE | 1.100 + nsIWBP.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION; 1.101 + 1.102 + // it is part of the active downloads the moment addDownload is called 1.103 + gDownloadCount++; 1.104 + 1.105 + let dm = downloadUtils.downloadManager; 1.106 + var dl = dm.addDownload(Ci.nsIDownloadManager.DOWNLOAD_TYPE_DOWNLOAD, 1.107 + createURI(aParams.sourceURI), 1.108 + createURI(aParams.targetFile), aParams.downloadName, null, 1.109 + Math.round(Date.now() * 1000), null, persist, aParams.isPrivate); 1.110 + 1.111 + // This will throw if it isn't found, and that would mean test failure, so no 1.112 + // try catch block 1.113 + if (!aParams.isPrivate) 1.114 + var test = dm.getDownload(dl.id); 1.115 + 1.116 + aParams.runBeforeStart.call(undefined, dl); 1.117 + 1.118 + persist.progressListener = dl.QueryInterface(Ci.nsIWebProgressListener); 1.119 + persist.savePrivacyAwareURI(dl.source, null, null, null, null, dl.targetFile, 1.120 + aParams.isPrivate); 1.121 + 1.122 + return dl; 1.123 +} 1.124 + 1.125 +function getDownloadListener() 1.126 +{ 1.127 + return { 1.128 + onDownloadStateChange: function(aState, aDownload) 1.129 + { 1.130 + if (aDownload.state == Ci.nsIDownloadManager.DOWNLOAD_QUEUED) 1.131 + do_test_pending(); 1.132 + 1.133 + if (aDownload.state == Ci.nsIDownloadManager.DOWNLOAD_FINISHED || 1.134 + aDownload.state == Ci.nsIDownloadManager.DOWNLOAD_CANCELED || 1.135 + aDownload.state == Ci.nsIDownloadManager.DOWNLOAD_FAILED) { 1.136 + gDownloadCount--; 1.137 + do_test_finished(); 1.138 + } 1.139 + 1.140 + if (gDownloadCount == 0 && typeof httpserv != "undefined" && httpserv) 1.141 + { 1.142 + do_test_pending(); 1.143 + httpserv.stop(do_test_finished); 1.144 + } 1.145 + }, 1.146 + onStateChange: function(a, b, c, d, e) { }, 1.147 + onProgressChange: function(a, b, c, d, e, f, g) { }, 1.148 + onSecurityChange: function(a, b, c, d) { } 1.149 + }; 1.150 +} 1.151 + 1.152 +/** 1.153 + * Asynchronously adds visits to a page. 1.154 + * 1.155 + * @param aPlaceInfo 1.156 + * Can be an nsIURI, in such a case a single LINK visit will be added. 1.157 + * Otherwise can be an object describing the visit to add, or an array 1.158 + * of these objects: 1.159 + * { uri: nsIURI of the page, 1.160 + * transition: one of the TRANSITION_* from nsINavHistoryService, 1.161 + * [optional] title: title of the page, 1.162 + * [optional] visitDate: visit date in microseconds from the epoch 1.163 + * [optional] referrer: nsIURI of the referrer for this visit 1.164 + * } 1.165 + * 1.166 + * @return {Promise} 1.167 + * @resolves When all visits have been added successfully. 1.168 + * @rejects JavaScript exception. 1.169 + */ 1.170 +function promiseAddVisits(aPlaceInfo) 1.171 +{ 1.172 + let deferred = Promise.defer(); 1.173 + let places = []; 1.174 + if (aPlaceInfo instanceof Ci.nsIURI) { 1.175 + places.push({ uri: aPlaceInfo }); 1.176 + } 1.177 + else if (Array.isArray(aPlaceInfo)) { 1.178 + places = places.concat(aPlaceInfo); 1.179 + } else { 1.180 + places.push(aPlaceInfo) 1.181 + } 1.182 + 1.183 + // Create mozIVisitInfo for each entry. 1.184 + let now = Date.now(); 1.185 + for (let i = 0; i < places.length; i++) { 1.186 + if (!places[i].title) { 1.187 + places[i].title = "test visit for " + places[i].uri.spec; 1.188 + } 1.189 + places[i].visits = [{ 1.190 + transitionType: places[i].transition === undefined ? Ci.nsINavHistoryService.TRANSITION_LINK 1.191 + : places[i].transition, 1.192 + visitDate: places[i].visitDate || (now++) * 1000, 1.193 + referrerURI: places[i].referrer 1.194 + }]; 1.195 + } 1.196 + 1.197 + PlacesUtils.asyncHistory.updatePlaces( 1.198 + places, 1.199 + { 1.200 + handleError: function handleError(aResultCode, aPlaceInfo) { 1.201 + let ex = new Components.Exception("Unexpected error in adding visits.", 1.202 + aResultCode); 1.203 + deferred.reject(ex); 1.204 + }, 1.205 + handleResult: function () {}, 1.206 + handleCompletion: function handleCompletion() { 1.207 + deferred.resolve(); 1.208 + } 1.209 + } 1.210 + ); 1.211 + 1.212 + return deferred.promise; 1.213 +} 1.214 + 1.215 + 1.216 +XPCOMUtils.defineLazyGetter(this, "Services", function() { 1.217 + Cu.import("resource://gre/modules/Services.jsm"); 1.218 + return Services; 1.219 +}); 1.220 + 1.221 +// Disable alert service notifications 1.222 +Services.prefs.setBoolPref("browser.download.manager.showAlertOnComplete", false); 1.223 + 1.224 +do_register_cleanup(function() { 1.225 + Services.obs.notifyObservers(null, "quit-application", null); 1.226 +}); 1.227 + 1.228 +function oldDownloadManagerDisabled() { 1.229 + try { 1.230 + // This method throws an exception if the old Download Manager is disabled. 1.231 + Services.downloads.activeDownloadCount; 1.232 + } catch (ex) { 1.233 + return true; 1.234 + } 1.235 + return false; 1.236 +} 1.237 \ No newline at end of file