|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 var MockFilePicker = SpecialPowers.MockFilePicker; |
|
5 MockFilePicker.init(window); |
|
6 |
|
7 // Trigger a save of a link in public mode, then trigger an identical save |
|
8 // in private mode and ensure that the second request is differentiated from |
|
9 // the first by checking that cookies set by the first response are not sent |
|
10 // during the second request. |
|
11 function triggerSave(aWindow, aCallback) { |
|
12 info("started triggerSave"); |
|
13 var fileName; |
|
14 let testBrowser = aWindow.gBrowser.selectedBrowser; |
|
15 // This page sets a cookie if and only if a cookie does not exist yet |
|
16 let testURI = "http://mochi.test:8888/browser/browser/base/content/test/general/bug792517-2.html"; |
|
17 testBrowser.loadURI(testURI); |
|
18 testBrowser.addEventListener("pageshow", function pageShown(event) { |
|
19 info("got pageshow with " + event.target.location); |
|
20 if (event.target.location != testURI) { |
|
21 info("try again!"); |
|
22 testBrowser.loadURI(testURI); |
|
23 return; |
|
24 } |
|
25 info("found our page!"); |
|
26 testBrowser.removeEventListener("pageshow", pageShown, false); |
|
27 |
|
28 waitForFocus(function () { |
|
29 info("register to handle popupshown"); |
|
30 aWindow.document.addEventListener("popupshown", contextMenuOpened, false); |
|
31 |
|
32 var link = testBrowser.contentDocument.getElementById("fff"); |
|
33 info("link: " + link); |
|
34 EventUtils.synthesizeMouseAtCenter(link, |
|
35 { type: "contextmenu", button: 2 }, |
|
36 testBrowser.contentWindow); |
|
37 info("right clicked!"); |
|
38 }, testBrowser.contentWindow); |
|
39 }, false); |
|
40 |
|
41 function contextMenuOpened(event) { |
|
42 info("contextMenuOpened"); |
|
43 aWindow.document.removeEventListener("popupshown", contextMenuOpened); |
|
44 |
|
45 // Create the folder the link will be saved into. |
|
46 var destDir = createTemporarySaveDirectory(); |
|
47 var destFile = destDir.clone(); |
|
48 |
|
49 MockFilePicker.displayDirectory = destDir; |
|
50 MockFilePicker.showCallback = function(fp) { |
|
51 info("showCallback"); |
|
52 fileName = fp.defaultString; |
|
53 info("fileName: " + fileName); |
|
54 destFile.append (fileName); |
|
55 MockFilePicker.returnFiles = [destFile]; |
|
56 MockFilePicker.filterIndex = 1; // kSaveAsType_URL |
|
57 info("done showCallback"); |
|
58 }; |
|
59 |
|
60 mockTransferCallback = function(downloadSuccess) { |
|
61 info("mockTransferCallback"); |
|
62 onTransferComplete(aWindow, downloadSuccess, destDir); |
|
63 destDir.remove(true); |
|
64 ok(!destDir.exists(), "Destination dir should be removed"); |
|
65 ok(!destFile.exists(), "Destination file should be removed"); |
|
66 mockTransferCallback = null; |
|
67 info("done mockTransferCallback"); |
|
68 } |
|
69 |
|
70 // Select "Save Link As" option from context menu |
|
71 var saveLinkCommand = aWindow.document.getElementById("context-savelink"); |
|
72 info("saveLinkCommand: " + saveLinkCommand); |
|
73 saveLinkCommand.doCommand(); |
|
74 |
|
75 event.target.hidePopup(); |
|
76 info("popup hidden"); |
|
77 } |
|
78 |
|
79 function onTransferComplete(aWindow, downloadSuccess, destDir) { |
|
80 ok(downloadSuccess, "Link should have been downloaded successfully"); |
|
81 aWindow.close(); |
|
82 |
|
83 executeSoon(function() aCallback()); |
|
84 } |
|
85 } |
|
86 |
|
87 function test() { |
|
88 info("Start the test"); |
|
89 waitForExplicitFinish(); |
|
90 |
|
91 var gNumSet = 0; |
|
92 function testOnWindow(options, callback) { |
|
93 info("testOnWindow(" + options + ")"); |
|
94 var win = OpenBrowserWindow(options); |
|
95 info("got " + win); |
|
96 whenDelayedStartupFinished(win, () => callback(win)); |
|
97 } |
|
98 |
|
99 function whenDelayedStartupFinished(aWindow, aCallback) { |
|
100 info("whenDelayedStartupFinished"); |
|
101 Services.obs.addObserver(function observer(aSubject, aTopic) { |
|
102 info("whenDelayedStartupFinished, got topic: " + aTopic + ", got subject: " + aSubject + ", waiting for " + aWindow); |
|
103 if (aWindow == aSubject) { |
|
104 Services.obs.removeObserver(observer, aTopic); |
|
105 executeSoon(aCallback); |
|
106 info("whenDelayedStartupFinished found our window"); |
|
107 } |
|
108 }, "browser-delayed-startup-finished", false); |
|
109 } |
|
110 |
|
111 mockTransferRegisterer.register(); |
|
112 |
|
113 registerCleanupFunction(function () { |
|
114 info("Running the cleanup code"); |
|
115 mockTransferRegisterer.unregister(); |
|
116 MockFilePicker.cleanup(); |
|
117 Services.obs.removeObserver(observer, "http-on-modify-request"); |
|
118 Services.obs.removeObserver(observer, "http-on-examine-response"); |
|
119 info("Finished running the cleanup code"); |
|
120 }); |
|
121 |
|
122 function observer(subject, topic, state) { |
|
123 info("observer called with " + topic); |
|
124 if (topic == "http-on-modify-request") { |
|
125 onModifyRequest(subject); |
|
126 } else if (topic == "http-on-examine-response") { |
|
127 onExamineResponse(subject); |
|
128 } |
|
129 } |
|
130 |
|
131 function onExamineResponse(subject) { |
|
132 let channel = subject.QueryInterface(Ci.nsIHttpChannel); |
|
133 info("onExamineResponse with " + channel.URI.spec); |
|
134 if (channel.URI.spec != "http://mochi.test:8888/browser/browser/base/content/test/general/bug792517.sjs") { |
|
135 info("returning"); |
|
136 return; |
|
137 } |
|
138 try { |
|
139 let cookies = channel.getResponseHeader("set-cookie"); |
|
140 // From browser/base/content/test/general/bug792715.sjs, we receive a Set-Cookie |
|
141 // header with foopy=1 when there are no cookies for that domain. |
|
142 is(cookies, "foopy=1", "Cookie should be foopy=1"); |
|
143 gNumSet += 1; |
|
144 info("gNumSet = " + gNumSet); |
|
145 } catch (ex if ex.result == Cr.NS_ERROR_NOT_AVAILABLE) { |
|
146 info("onExamineResponse caught NOTAVAIL" + ex); |
|
147 } catch (ex) { |
|
148 info("ionExamineResponse caught " + ex); |
|
149 } |
|
150 } |
|
151 |
|
152 function onModifyRequest(subject) { |
|
153 let channel = subject.QueryInterface(Ci.nsIHttpChannel); |
|
154 info("onModifyRequest with " + channel.URI.spec); |
|
155 if (channel.URI.spec != "http://mochi.test:8888/browser/browser/base/content/test/general/bug792517.sjs") { |
|
156 return; |
|
157 } |
|
158 try { |
|
159 let cookies = channel.getRequestHeader("cookie"); |
|
160 info("cookies: " + cookies); |
|
161 // From browser/base/content/test/general/bug792715.sjs, we should never send a |
|
162 // cookie because we are making only 2 requests: one in public mode, and |
|
163 // one in private mode. |
|
164 throw "We should never send a cookie in this test"; |
|
165 } catch (ex if ex.result == Cr.NS_ERROR_NOT_AVAILABLE) { |
|
166 info("onModifyRequest caught NOTAVAIL" + ex); |
|
167 } catch (ex) { |
|
168 info("ionModifyRequest caught " + ex); |
|
169 } |
|
170 } |
|
171 |
|
172 Services.obs.addObserver(observer, "http-on-modify-request", false); |
|
173 Services.obs.addObserver(observer, "http-on-examine-response", false); |
|
174 |
|
175 testOnWindow(undefined, function(win) { |
|
176 // The first save from a regular window sets a cookie. |
|
177 triggerSave(win, function() { |
|
178 is(gNumSet, 1, "1 cookie should be set"); |
|
179 |
|
180 // The second save from a private window also sets a cookie. |
|
181 testOnWindow({private: true}, function(win) { |
|
182 triggerSave(win, function() { |
|
183 is(gNumSet, 2, "2 cookies should be set"); |
|
184 finish(); |
|
185 }); |
|
186 }); |
|
187 }); |
|
188 }); |
|
189 } |
|
190 |
|
191 Cc["@mozilla.org/moz/jssubscript-loader;1"] |
|
192 .getService(Ci.mozIJSSubScriptLoader) |
|
193 .loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js", |
|
194 this); |
|
195 |
|
196 function createTemporarySaveDirectory() { |
|
197 var saveDir = Cc["@mozilla.org/file/directory_service;1"] |
|
198 .getService(Ci.nsIProperties) |
|
199 .get("TmpD", Ci.nsIFile); |
|
200 saveDir.append("testsavedir"); |
|
201 if (!saveDir.exists()) { |
|
202 info("create testsavedir!"); |
|
203 saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755); |
|
204 } |
|
205 info("return from createTempSaveDir: " + saveDir.path); |
|
206 return saveDir; |
|
207 } |