|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 // This file tests Bug 593815 - specifically that after downloading two files |
|
5 // with the same name, the download manager still points to the correct files |
|
6 |
|
7 Components.utils.import("resource://gre/modules/Services.jsm"); |
|
8 Components.utils.import("resource://gre/modules/NetUtil.jsm"); |
|
9 do_load_manifest("test_downloads.manifest"); |
|
10 |
|
11 let httpserver = null; |
|
12 let currentTest = 0; |
|
13 |
|
14 function WindowContext() { } |
|
15 WindowContext.prototype = { |
|
16 QueryInterface: XPCOMUtils.generateQI([Ci.nsIInterfaceRequestor]), |
|
17 getInterface: XPCOMUtils.generateQI([Ci.nsIURIContentListener, |
|
18 Ci.nsILoadGroup]), |
|
19 |
|
20 /* nsIURIContentListener */ |
|
21 onStartURIOpen: function (uri) { }, |
|
22 isPreferred: function (type, desiredtype) { return false; }, |
|
23 |
|
24 /* nsILoadGroup */ |
|
25 addRequest: function (request, context) { }, |
|
26 removeRequest: function (request, context, status) { } |
|
27 }; |
|
28 |
|
29 let DownloadListener = { |
|
30 set: null, |
|
31 prevFiles : [], |
|
32 |
|
33 init: function () { |
|
34 Services.obs.addObserver(this, "dl-start", true); |
|
35 Services.obs.addObserver(this, "dl-done", true); |
|
36 }, |
|
37 |
|
38 observe: function (aSubject, aTopic, aData) { |
|
39 |
|
40 if (aTopic == "dl-start") { |
|
41 // pause the download if requested |
|
42 if (this.set.doPause) { |
|
43 let dl = aSubject.QueryInterface(Ci.nsIDownload); |
|
44 // Don't pause immediately, otherwise the external helper app handler |
|
45 // won't be able to assign a permanent file name. |
|
46 do_execute_soon(function() { |
|
47 downloadUtils.downloadManager.pauseDownload(dl.id); |
|
48 do_timeout(1000, function() { |
|
49 downloadUtils.downloadManager.resumeDownload(dl.id); |
|
50 }); |
|
51 }); |
|
52 } |
|
53 } else if (aTopic == "dl-done") { |
|
54 // check that no two files have the same filename in the download manager |
|
55 let file = aSubject.QueryInterface(Ci.nsIDownload).targetFile; |
|
56 for each (let prevFile in this.prevFiles) { |
|
57 do_check_neq(file.leafName, prevFile.leafName); |
|
58 } |
|
59 this.prevFiles.push(file); |
|
60 |
|
61 // get the contents of the file |
|
62 let fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); |
|
63 fis.init(file, -1, -1, 0); |
|
64 var cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream); |
|
65 cstream.init(fis, "UTF-8", 0, 0); |
|
66 |
|
67 let val = ""; |
|
68 let (str = {}) { |
|
69 let read = 0; |
|
70 do { |
|
71 read = cstream.readString(0xffffffff, str); |
|
72 val += str.value; |
|
73 } while (read != 0); |
|
74 } |
|
75 cstream.close(); |
|
76 |
|
77 // check if the file contents match the expected ones |
|
78 if (this.set.doPause) { |
|
79 do_check_eq(val, this.set.data + this.set.data); // files that have been paused have the same data twice |
|
80 } else { |
|
81 do_check_eq(val, this.set.data); |
|
82 } |
|
83 runNextTest(); // download the next file |
|
84 } |
|
85 }, |
|
86 |
|
87 QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, |
|
88 Ci.nsISupportsWeakReference]) |
|
89 } |
|
90 |
|
91 /* |
|
92 Each test will download a file from the server. |
|
93 */ |
|
94 function runNextTest() |
|
95 { |
|
96 if (currentTest == tests.length) { |
|
97 for each (var file in DownloadListener.prevFiles) { |
|
98 try { |
|
99 file.remove(false); |
|
100 } catch (ex) { |
|
101 try { |
|
102 do_report_unexpected_exception(ex, "while removing " + file.path); |
|
103 } catch (ex if ex == Components.results.NS_ERROR_ABORT) { |
|
104 /* swallow */ |
|
105 } |
|
106 } |
|
107 } |
|
108 httpserver.stop(do_test_finished); |
|
109 return; |
|
110 } |
|
111 let set = DownloadListener.set = tests[currentTest]; |
|
112 currentTest++; |
|
113 |
|
114 let channel = NetUtil.newChannel("http://localhost:" + |
|
115 httpserver.identity.primaryPort + |
|
116 set.serverURL); |
|
117 let uriloader = Cc["@mozilla.org/uriloader;1"].getService(Ci.nsIURILoader); |
|
118 uriloader.openURI(channel, Ci.nsIURILoader.IS_CONTENT_PREFERRED, |
|
119 new WindowContext()); |
|
120 } |
|
121 |
|
122 // sends the responses for the files. sends the same content twice if we resume |
|
123 // the download |
|
124 function getResponse(aSet) { |
|
125 return function(aMetadata, aResponse) { |
|
126 aResponse.setHeader("Content-Type", "text/plain", false); |
|
127 if (aMetadata.hasHeader("Range")) { |
|
128 var matches = aMetadata.getHeader("Range").match(/^\s*bytes=(\d+)?-(\d+)?\s*$/); |
|
129 aResponse.setStatusLine(aMetadata.httpVersion, 206, "Partial Content"); |
|
130 aResponse.bodyOutputStream.write(aSet.data, aSet.data.length); |
|
131 return; |
|
132 } |
|
133 aResponse.setHeader("Accept-Ranges", "bytes", false); |
|
134 aResponse.setHeader("Content-Disposition", "attachment; filename=test.txt;", false); |
|
135 aResponse.bodyOutputStream.write(aSet.data, aSet.data.length); |
|
136 } |
|
137 } |
|
138 |
|
139 // files to be downloaded. All files will have the same suggested filename, but |
|
140 // should contain different data. doPause will cause the download to pause and resume |
|
141 // itself |
|
142 let tests = [ |
|
143 { serverURL: "/test1.html", data: "Test data 1", doPause: false }, |
|
144 { serverURL: "/test2.html", data: "Test data 2", doPause: false }, |
|
145 { serverURL: "/test3.html", data: "Test data 3", doPause: true } |
|
146 ]; |
|
147 |
|
148 function run_test() { |
|
149 if (oldDownloadManagerDisabled()) { |
|
150 return; |
|
151 } |
|
152 |
|
153 // setup a download listener to run tests after each download finished |
|
154 DownloadListener.init(); |
|
155 Services.prefs.setBoolPref("browser.download.manager.showWhenStarting", false); |
|
156 |
|
157 httpserver = new HttpServer(); |
|
158 httpserver.start(-1); |
|
159 do_test_pending(); |
|
160 |
|
161 // setup files to be download, each with the same suggested filename |
|
162 // from the server, but with different contents |
|
163 for(let i = 0; i < tests.length; i++) { |
|
164 let set = tests[i]; |
|
165 httpserver.registerPathHandler(set.serverURL, getResponse(set)); |
|
166 } |
|
167 |
|
168 runNextTest(); // start downloading the first file |
|
169 } |