|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 /** |
|
6 Test download manager's interaction with the private browsing service. |
|
7 |
|
8 An overview of what this test does follows: |
|
9 |
|
10 * Create a download (Download-A) with specific details. |
|
11 * Check that Download-A is retrievable. |
|
12 * Enter private browsing mode. |
|
13 * Check that Download-A is not accessible. |
|
14 * Create another download (Download-B) with specific and different details. |
|
15 * Check that Download-B is retrievable. |
|
16 * Exit private browsing mode. |
|
17 * Check that Download-A is retrievable. |
|
18 * Check that Download-B is not accessible. |
|
19 * Create a new download (Download-C) with specific details. |
|
20 Start it and enter private browsing mode immediately after. |
|
21 * Check that Download-C has been paused. |
|
22 * Exit the private browsing mode. |
|
23 * Verify that Download-C resumes and finishes correctly now. |
|
24 **/ |
|
25 |
|
26 Components.utils.import("resource://gre/modules/Services.jsm"); |
|
27 |
|
28 this.__defineGetter__("dm", function() { |
|
29 delete this.dm; |
|
30 return this.dm = Cc["@mozilla.org/download-manager;1"]. |
|
31 getService(Ci.nsIDownloadManager); |
|
32 }); |
|
33 |
|
34 /** |
|
35 * Try to see if an active download is available using the |activeDownloads| |
|
36 * property. |
|
37 */ |
|
38 function is_active_download_available(aGUID, aSrc, aDst, aName, aPrivate) { |
|
39 let enumerator = aPrivate ? dm.activePrivateDownloads : dm.activeDownloads; |
|
40 while (enumerator.hasMoreElements()) { |
|
41 let download = enumerator.getNext(); |
|
42 if (download.guid == aGUID && |
|
43 download.source.spec == aSrc && |
|
44 download.targetFile.path == aDst.path && |
|
45 download.displayName == aName && |
|
46 download.isPrivate == aPrivate) |
|
47 return true; |
|
48 } |
|
49 return false; |
|
50 } |
|
51 |
|
52 function expect_download_present(aGUID, aSrc, aDst, aName, aPrivate) { |
|
53 is_download_available(aGUID, aSrc, aDst, aName, aPrivate, true); |
|
54 } |
|
55 |
|
56 function expect_download_absent(aGUID, aSrc, aDst, aName, aPrivate) { |
|
57 is_download_available(aGUID, aSrc, aDst, aName, aPrivate, false); |
|
58 } |
|
59 |
|
60 /** |
|
61 * Try to see if a download is available using the |getDownloadByGUID| method. The |
|
62 * download can both be active or inactive. |
|
63 */ |
|
64 function is_download_available(aGUID, aSrc, aDst, aName, aPrivate, present) { |
|
65 do_test_pending(); |
|
66 dm.getDownloadByGUID(aGUID, function(status, download) { |
|
67 if (!present) { |
|
68 do_check_eq(download, null); |
|
69 } else { |
|
70 do_check_neq(download, null); |
|
71 do_check_eq(download.guid, aGUID); |
|
72 do_check_eq(download.source.spec, aSrc); |
|
73 do_check_eq(download.targetFile.path, aDst.path); |
|
74 do_check_eq(download.displayName, aName); |
|
75 do_check_eq(download.isPrivate, aPrivate); |
|
76 } |
|
77 do_test_finished(); |
|
78 }); |
|
79 } |
|
80 |
|
81 function run_test() { |
|
82 if (oldDownloadManagerDisabled()) { |
|
83 return; |
|
84 } |
|
85 |
|
86 let prefBranch = Cc["@mozilla.org/preferences-service;1"]. |
|
87 getService(Ci.nsIPrefBranch); |
|
88 |
|
89 do_test_pending(); |
|
90 let httpserv = new HttpServer(); |
|
91 httpserv.registerDirectory("/", do_get_cwd()); |
|
92 httpserv.start(-1); |
|
93 |
|
94 let tmpDir = do_get_tempdir(); |
|
95 const nsIWBP = Ci.nsIWebBrowserPersist; |
|
96 |
|
97 // make sure we're starting with an empty DB |
|
98 do_check_eq(dm.activeDownloadCount, 0); |
|
99 do_check_eq(dm.activePrivateDownloadCount, 0); |
|
100 |
|
101 let listener = { |
|
102 phase: 1, |
|
103 handledC: false, |
|
104 onDownloadStateChange: function(aState, aDownload) |
|
105 { |
|
106 switch (aDownload.state) { |
|
107 case dm.DOWNLOAD_FAILED: |
|
108 case dm.DOWNLOAD_CANCELED: |
|
109 case dm.DOWNLOAD_DIRTY: |
|
110 case dm.DOWNLOAD_BLOCKED_POLICY: |
|
111 // Fail! |
|
112 if (aDownload.targetFile.exists()) |
|
113 aDownload.targetFile.remove(false); |
|
114 dm.removeListener(this); |
|
115 do_throw("Download failed (name: " + aDownload.displayName + ", state: " + aDownload.state + ")"); |
|
116 do_test_finished(); |
|
117 break; |
|
118 |
|
119 // We need to wait until Download-C has started, because otherwise it |
|
120 // won't be resumable, so the private browsing mode won't correctly pause it. |
|
121 case dm.DOWNLOAD_DOWNLOADING: |
|
122 if (aDownload.guid == downloadC && !this.handledC && this.phase == 2) { |
|
123 // Sanity check: Download-C must be resumable |
|
124 do_check_true(dlC.resumable); |
|
125 |
|
126 // Check that Download-A is accessible |
|
127 expect_download_present(downloadA, downloadASource, |
|
128 fileA, downloadAName, false); |
|
129 |
|
130 // Check that Download-B is not accessible |
|
131 expect_download_absent(downloadB, downloadBSource, |
|
132 fileB, downloadBName, true); |
|
133 |
|
134 // Check that Download-C is accessible |
|
135 expect_download_present(downloadC, downloadCSource, |
|
136 fileC, downloadCName, false); |
|
137 |
|
138 // only perform these checks the first time that Download-C is started |
|
139 this.handledC = true; |
|
140 } |
|
141 break; |
|
142 |
|
143 case dm.DOWNLOAD_FINISHED: |
|
144 do_check_true(aDownload.targetFile.exists()); |
|
145 aDownload.targetFile.remove(false); |
|
146 this.onDownloadFinished(); |
|
147 break; |
|
148 } |
|
149 }, |
|
150 onStateChange: function(a, b, c, d, e) { }, |
|
151 onProgressChange: function(a, b, c, d, e, f, g) { }, |
|
152 onSecurityChange: function(a, b, c, d) { }, |
|
153 onDownloadFinished: function () { |
|
154 switch (this.phase) { |
|
155 case 1: { |
|
156 do_check_eq(dm.activeDownloadCount, 0); |
|
157 |
|
158 // Create Download-B |
|
159 let dlB = addDownload(httpserv, { |
|
160 isPrivate: true, |
|
161 targetFile: fileB, |
|
162 sourceURI: downloadBSource, |
|
163 downloadName: downloadBName, |
|
164 runBeforeStart: function (aDownload) { |
|
165 // Check that Download-B is retrievable |
|
166 do_check_eq(dm.activePrivateDownloadCount, 1); |
|
167 do_check_eq(dm.activeDownloadCount, 0); |
|
168 do_check_true(is_active_download_available(aDownload.guid, |
|
169 downloadBSource, fileB, downloadBName, true)); |
|
170 expect_download_present(aDownload.guid, |
|
171 downloadBSource, fileB, downloadBName, true); |
|
172 } |
|
173 }); |
|
174 downloadB = dlB.guid; |
|
175 |
|
176 // wait for Download-B to finish |
|
177 ++this.phase; |
|
178 } |
|
179 break; |
|
180 |
|
181 case 2: { |
|
182 do_check_eq(dm.activeDownloadCount, 0); |
|
183 |
|
184 // Simulate last private browsing context triggering cleanup |
|
185 Services.obs.notifyObservers(null, "last-pb-context-exited", null); |
|
186 |
|
187 // Create Download-C |
|
188 dlC = addDownload(httpserv, { |
|
189 isPrivate: false, |
|
190 targetFile: fileC, |
|
191 sourceURI: downloadCSource, |
|
192 downloadName: downloadCName, |
|
193 runBeforeStart: function (aDownload) { |
|
194 // Check that Download-C is retrievable |
|
195 do_check_eq(dm.activePrivateDownloadCount, 0); |
|
196 do_check_true(is_active_download_available(aDownload.guid, |
|
197 downloadCSource, fileC, downloadCName, false)); |
|
198 expect_download_present(aDownload.guid, |
|
199 downloadCSource, fileC, downloadCName, false); |
|
200 } |
|
201 }); |
|
202 downloadC = dlC.guid; |
|
203 |
|
204 // wait for Download-C to finish |
|
205 ++this.phase; |
|
206 |
|
207 // Check that Download-A is accessible |
|
208 expect_download_present(downloadA, downloadASource, |
|
209 fileA, downloadAName, false); |
|
210 |
|
211 // Check that Download-B is not accessible |
|
212 expect_download_absent(downloadB, downloadBSource, |
|
213 fileB, downloadBName, true); |
|
214 } |
|
215 break; |
|
216 |
|
217 case 3: { |
|
218 do_check_eq(dm.activePrivateDownloadCount, 0); |
|
219 |
|
220 // Check that Download-A is accessible |
|
221 expect_download_present(downloadA, downloadASource, |
|
222 fileA, downloadAName, false); |
|
223 |
|
224 // Check that Download-B is not accessible |
|
225 expect_download_absent(downloadB, downloadBSource, |
|
226 fileB, downloadBName, true); |
|
227 |
|
228 // Check that Download-C is accessible |
|
229 expect_download_present(downloadC, downloadCSource, |
|
230 fileC, downloadCName, false); |
|
231 |
|
232 // cleanup |
|
233 dm.removeListener(this); |
|
234 httpserv.stop(do_test_finished); |
|
235 } |
|
236 break; |
|
237 |
|
238 default: |
|
239 do_throw("Unexpected phase: " + this.phase); |
|
240 break; |
|
241 } |
|
242 } |
|
243 }; |
|
244 |
|
245 dm.addPrivacyAwareListener(listener); |
|
246 dm.addPrivacyAwareListener(getDownloadListener()); |
|
247 |
|
248 // properties of Download-A |
|
249 let downloadA = -1; |
|
250 const downloadASource = "data:image/png;base64,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"; |
|
251 const downloadADest = "download-file-A"; |
|
252 const downloadAName = "download-A"; |
|
253 |
|
254 // properties of Download-B |
|
255 let downloadB = -1; |
|
256 const downloadBSource = "data:application/octet-stream;base64,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"; |
|
257 const downloadBDest = "download-file-B"; |
|
258 const downloadBName = "download-B"; |
|
259 |
|
260 // properties of Download-C |
|
261 let downloadC = -1; |
|
262 const downloadCSource = "http://localhost:" + |
|
263 httpserv.identity.primaryPort + |
|
264 "/head_download_manager.js"; |
|
265 const downloadCDest = "download-file-C"; |
|
266 const downloadCName = "download-C"; |
|
267 |
|
268 // Create all target files |
|
269 let fileA = tmpDir.clone(); |
|
270 fileA.append(downloadADest); |
|
271 fileA.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666); |
|
272 let fileB = tmpDir.clone(); |
|
273 fileB.append(downloadBDest); |
|
274 fileB.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666); |
|
275 let fileC = tmpDir.clone(); |
|
276 fileC.append(downloadCDest); |
|
277 fileC.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666); |
|
278 |
|
279 // use js closures to access dlC |
|
280 let dlC; |
|
281 |
|
282 // Create Download-A |
|
283 let dlA = addDownload(httpserv, { |
|
284 isPrivate: false, |
|
285 targetFile: fileA, |
|
286 sourceURI: downloadASource, |
|
287 downloadName: downloadAName, |
|
288 runBeforeStart: function (aDownload) { |
|
289 // Check that Download-A is retrievable |
|
290 do_check_eq(dm.activePrivateDownloadCount, 0); |
|
291 do_check_true(is_active_download_available(aDownload.guid, downloadASource, fileA, downloadAName, false)); |
|
292 expect_download_present(aDownload.guid, downloadASource, fileA, downloadAName, false); |
|
293 } |
|
294 }); |
|
295 downloadA = dlA.guid; |
|
296 |
|
297 // wait for Download-A to finish |
|
298 } |