1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/downloads/test/unit/test_download_samename.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,169 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +// This file tests Bug 593815 - specifically that after downloading two files 1.8 +// with the same name, the download manager still points to the correct files 1.9 + 1.10 +Components.utils.import("resource://gre/modules/Services.jsm"); 1.11 +Components.utils.import("resource://gre/modules/NetUtil.jsm"); 1.12 +do_load_manifest("test_downloads.manifest"); 1.13 + 1.14 +let httpserver = null; 1.15 +let currentTest = 0; 1.16 + 1.17 +function WindowContext() { } 1.18 +WindowContext.prototype = { 1.19 + QueryInterface: XPCOMUtils.generateQI([Ci.nsIInterfaceRequestor]), 1.20 + getInterface: XPCOMUtils.generateQI([Ci.nsIURIContentListener, 1.21 + Ci.nsILoadGroup]), 1.22 + 1.23 + /* nsIURIContentListener */ 1.24 + onStartURIOpen: function (uri) { }, 1.25 + isPreferred: function (type, desiredtype) { return false; }, 1.26 + 1.27 + /* nsILoadGroup */ 1.28 + addRequest: function (request, context) { }, 1.29 + removeRequest: function (request, context, status) { } 1.30 +}; 1.31 + 1.32 +let DownloadListener = { 1.33 + set: null, 1.34 + prevFiles : [], 1.35 + 1.36 + init: function () { 1.37 + Services.obs.addObserver(this, "dl-start", true); 1.38 + Services.obs.addObserver(this, "dl-done", true); 1.39 + }, 1.40 + 1.41 + observe: function (aSubject, aTopic, aData) { 1.42 + 1.43 + if (aTopic == "dl-start") { 1.44 + // pause the download if requested 1.45 + if (this.set.doPause) { 1.46 + let dl = aSubject.QueryInterface(Ci.nsIDownload); 1.47 + // Don't pause immediately, otherwise the external helper app handler 1.48 + // won't be able to assign a permanent file name. 1.49 + do_execute_soon(function() { 1.50 + downloadUtils.downloadManager.pauseDownload(dl.id); 1.51 + do_timeout(1000, function() { 1.52 + downloadUtils.downloadManager.resumeDownload(dl.id); 1.53 + }); 1.54 + }); 1.55 + } 1.56 + } else if (aTopic == "dl-done") { 1.57 + // check that no two files have the same filename in the download manager 1.58 + let file = aSubject.QueryInterface(Ci.nsIDownload).targetFile; 1.59 + for each (let prevFile in this.prevFiles) { 1.60 + do_check_neq(file.leafName, prevFile.leafName); 1.61 + } 1.62 + this.prevFiles.push(file); 1.63 + 1.64 + // get the contents of the file 1.65 + let fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); 1.66 + fis.init(file, -1, -1, 0); 1.67 + var cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream); 1.68 + cstream.init(fis, "UTF-8", 0, 0); 1.69 + 1.70 + let val = ""; 1.71 + let (str = {}) { 1.72 + let read = 0; 1.73 + do { 1.74 + read = cstream.readString(0xffffffff, str); 1.75 + val += str.value; 1.76 + } while (read != 0); 1.77 + } 1.78 + cstream.close(); 1.79 + 1.80 + // check if the file contents match the expected ones 1.81 + if (this.set.doPause) { 1.82 + do_check_eq(val, this.set.data + this.set.data); // files that have been paused have the same data twice 1.83 + } else { 1.84 + do_check_eq(val, this.set.data); 1.85 + } 1.86 + runNextTest(); // download the next file 1.87 + } 1.88 + }, 1.89 + 1.90 + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, 1.91 + Ci.nsISupportsWeakReference]) 1.92 +} 1.93 + 1.94 +/* 1.95 + Each test will download a file from the server. 1.96 +*/ 1.97 +function runNextTest() 1.98 +{ 1.99 + if (currentTest == tests.length) { 1.100 + for each (var file in DownloadListener.prevFiles) { 1.101 + try { 1.102 + file.remove(false); 1.103 + } catch (ex) { 1.104 + try { 1.105 + do_report_unexpected_exception(ex, "while removing " + file.path); 1.106 + } catch (ex if ex == Components.results.NS_ERROR_ABORT) { 1.107 + /* swallow */ 1.108 + } 1.109 + } 1.110 + } 1.111 + httpserver.stop(do_test_finished); 1.112 + return; 1.113 + } 1.114 + let set = DownloadListener.set = tests[currentTest]; 1.115 + currentTest++; 1.116 + 1.117 + let channel = NetUtil.newChannel("http://localhost:" + 1.118 + httpserver.identity.primaryPort + 1.119 + set.serverURL); 1.120 + let uriloader = Cc["@mozilla.org/uriloader;1"].getService(Ci.nsIURILoader); 1.121 + uriloader.openURI(channel, Ci.nsIURILoader.IS_CONTENT_PREFERRED, 1.122 + new WindowContext()); 1.123 +} 1.124 + 1.125 +// sends the responses for the files. sends the same content twice if we resume 1.126 +// the download 1.127 +function getResponse(aSet) { 1.128 + return function(aMetadata, aResponse) { 1.129 + aResponse.setHeader("Content-Type", "text/plain", false); 1.130 + if (aMetadata.hasHeader("Range")) { 1.131 + var matches = aMetadata.getHeader("Range").match(/^\s*bytes=(\d+)?-(\d+)?\s*$/); 1.132 + aResponse.setStatusLine(aMetadata.httpVersion, 206, "Partial Content"); 1.133 + aResponse.bodyOutputStream.write(aSet.data, aSet.data.length); 1.134 + return; 1.135 + } 1.136 + aResponse.setHeader("Accept-Ranges", "bytes", false); 1.137 + aResponse.setHeader("Content-Disposition", "attachment; filename=test.txt;", false); 1.138 + aResponse.bodyOutputStream.write(aSet.data, aSet.data.length); 1.139 + } 1.140 +} 1.141 + 1.142 +// files to be downloaded. All files will have the same suggested filename, but 1.143 +// should contain different data. doPause will cause the download to pause and resume 1.144 +// itself 1.145 +let tests = [ 1.146 + { serverURL: "/test1.html", data: "Test data 1", doPause: false }, 1.147 + { serverURL: "/test2.html", data: "Test data 2", doPause: false }, 1.148 + { serverURL: "/test3.html", data: "Test data 3", doPause: true } 1.149 +]; 1.150 + 1.151 +function run_test() { 1.152 + if (oldDownloadManagerDisabled()) { 1.153 + return; 1.154 + } 1.155 + 1.156 + // setup a download listener to run tests after each download finished 1.157 + DownloadListener.init(); 1.158 + Services.prefs.setBoolPref("browser.download.manager.showWhenStarting", false); 1.159 + 1.160 + httpserver = new HttpServer(); 1.161 + httpserver.start(-1); 1.162 + do_test_pending(); 1.163 + 1.164 + // setup files to be download, each with the same suggested filename 1.165 + // from the server, but with different contents 1.166 + for(let i = 0; i < tests.length; i++) { 1.167 + let set = tests[i]; 1.168 + httpserver.registerPathHandler(set.serverURL, getResponse(set)); 1.169 + } 1.170 + 1.171 + runNextTest(); // start downloading the first file 1.172 +}