Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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/. */
5 // This file tests message ports and semantics of the frameworker which aren't
6 // directly related to the sandbox. See also browser_frameworker_sandbox.js.
8 function makeWorkerUrl(runner) {
9 let prefix = "http://example.com/browser/toolkit/components/social/test/browser/echo.sjs?";
10 if (typeof runner == "function") {
11 runner = "var run=" + runner.toSource() + ";run();";
12 }
13 return prefix + encodeURI(runner);
14 }
16 var getFrameWorkerHandle;
17 function test() {
18 waitForExplicitFinish();
20 let scope = {};
21 Cu.import("resource://gre/modules/FrameWorker.jsm", scope);
22 getFrameWorkerHandle = scope.getFrameWorkerHandle;
24 runTests(tests);
25 }
27 let tests = {
28 testSimple: function(cbnext) {
29 let run = function() {
30 onconnect = function(e) {
31 let port = e.ports[0];
32 port.onmessage = function(e) {
33 if (e.data.topic == "ping") {
34 port.postMessage({topic: "pong"});
35 }
36 }
37 }
38 }
40 let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSimple");
42 worker.port.onmessage = function(e) {
43 if (e.data.topic == "pong") {
44 worker.terminate();
45 cbnext();
46 }
47 }
48 worker.port.postMessage({topic: "ping"})
49 },
51 // when the client closes early but the worker tries to send anyway...
52 // XXX - disabled due to bug 919878 - we close the frameworker before the
53 // remote browser has completed initializing, leading to failures. Given
54 // this can realistically only happen in this synthesized test environment,
55 // disabling just this test seems OK for now.
56 /***
57 testEarlyClose: function(cbnext) {
58 let run = function() {
59 onconnect = function(e) {
60 let port = e.ports[0];
61 port.postMessage({topic: "oh hai"});
62 }
63 }
65 let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testEarlyClose");
66 worker.port.close();
67 worker.terminate();
68 cbnext();
69 },
70 ***/
72 // Check we do get a social.port-closing message as the port is closed.
73 testPortClosingMessage: function(cbnext) {
74 // We use 2 ports - we close the first and report success via the second.
75 let run = function() {
76 let firstPort, secondPort;
77 onconnect = function(e) {
78 let port = e.ports[0];
79 if (firstPort === undefined) {
80 firstPort = port;
81 port.onmessage = function(e) {
82 if (e.data.topic == "social.port-closing") {
83 secondPort.postMessage({topic: "got-closing"});
84 }
85 }
86 } else {
87 secondPort = port;
88 // now both ports are connected we can trigger the client side
89 // closing the first.
90 secondPort.postMessage({topic: "connected"});
91 }
92 }
93 }
94 let workerurl = makeWorkerUrl(run);
95 let worker1 = getFrameWorkerHandle(workerurl, undefined, "testPortClosingMessage worker1");
96 let worker2 = getFrameWorkerHandle(workerurl, undefined, "testPortClosingMessage worker2");
97 worker2.port.onmessage = function(e) {
98 if (e.data.topic == "connected") {
99 // both ports connected, so close the first.
100 worker1.port.close();
101 } else if (e.data.topic == "got-closing") {
102 worker2.terminate();
103 cbnext();
104 }
105 }
106 },
108 // Tests that prototypes added to core objects work with data sent over
109 // the message ports.
110 testPrototypes: function(cbnext) {
111 let run = function() {
112 // Modify the Array prototype...
113 Array.prototype.customfunction = function() {};
114 onconnect = function(e) {
115 let port = e.ports[0];
116 port.onmessage = function(e) {
117 // Check the data we get via the port has the prototype modification
118 if (e.data.topic == "hello" && e.data.data.customfunction) {
119 port.postMessage({topic: "hello", data: [1,2,3]});
120 }
121 }
122 }
123 }
124 // hrmph - this kinda sucks as it is really just testing the actual
125 // implementation rather than the end result, but is OK for now.
126 // Really we are just testing that JSON.parse in the client window
127 // is called.
128 let fakeWindow = {
129 JSON: {
130 parse: function(s) {
131 let data = JSON.parse(s);
132 data.data.somextrafunction = function() {};
133 return data;
134 }
135 }
136 }
137 let worker = getFrameWorkerHandle(makeWorkerUrl(run), fakeWindow, "testPrototypes");
138 worker.port.onmessage = function(e) {
139 if (e.data.topic == "hello") {
140 ok(e.data.data.somextrafunction, "have someextrafunction")
141 worker.terminate();
142 cbnext();
143 }
144 }
145 worker.port.postMessage({topic: "hello", data: [1,2,3]});
146 },
148 testSameOriginImport: function(cbnext) {
149 let run = function() {
150 onconnect = function(e) {
151 let port = e.ports[0];
152 port.onmessage = function(e) {
153 if (e.data.topic == "ping") {
154 try {
155 importScripts("http://mochi.test:8888/error");
156 } catch(ex) {
157 port.postMessage({topic: "pong", data: ex});
158 return;
159 }
160 port.postMessage({topic: "pong", data: null});
161 }
162 }
163 }
164 }
166 let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSameOriginImport");
167 worker.port.onmessage = function(e) {
168 if (e.data.topic == "pong") {
169 isnot(e.data.data, null, "check same-origin applied to importScripts");
170 worker.terminate();
171 cbnext();
172 }
173 }
174 worker.port.postMessage({topic: "ping"})
175 },
177 testRelativeImport: function(cbnext) {
178 let url = "https://example.com/browser/toolkit/components/social/test/browser/worker_relative.js";
179 let worker = getFrameWorkerHandle(url, undefined, "testSameOriginImport");
180 worker.port.onmessage = function(e) {
181 if (e.data.topic == "done") {
182 is(e.data.result, "ok", "check relative url in importScripts");
183 worker.terminate();
184 cbnext();
185 }
186 }
187 },
189 testNavigator: function(cbnext) {
190 let run = function() {
191 let port;
192 ononline = function() {
193 port.postMessage({topic: "ononline", data: navigator.onLine});
194 }
195 onoffline = function() {
196 port.postMessage({topic: "onoffline", data: navigator.onLine});
197 }
198 onconnect = function(e) {
199 port = e.ports[0];
200 port.postMessage({topic: "ready",
201 data: {
202 appName: navigator.appName,
203 appVersion: navigator.appVersion,
204 platform: navigator.platform,
205 userAgent: navigator.userAgent,
206 }
207 });
208 }
209 }
210 let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService2);
211 let oldManage = ioService.manageOfflineStatus;
212 let oldOffline = ioService.offline;
214 ioService.manageOfflineStatus = false;
215 let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testNavigator");
216 let expected_topic = "onoffline";
217 let expected_data = false;
218 worker.port.onmessage = function(e) {
219 is(e.data.topic, "ready");
220 for each (let attr in ['appName', 'appVersion', 'platform', 'userAgent']) {
221 // each attribute must be a string with length > 0.
222 is(typeof e.data.data[attr], "string");
223 ok(e.data.data[attr].length > 0);
224 }
226 worker.port.onmessage = function(e) {
227 // a handler specifically for the offline notification.
228 is(e.data.topic, "onoffline");
229 is(e.data.data, false);
231 // add another handler specifically for the 'online' case.
232 worker.port.onmessage = function(e) {
233 is(e.data.topic, "ononline");
234 is(e.data.data, true);
235 // all good!
236 ioService.manageOfflineStatus = oldManage;
237 ioService.offline = oldOffline;
238 worker.terminate();
239 cbnext();
240 }
241 ioService.offline = false;
242 }
243 ioService.offline = true;
244 }
245 },
247 testMissingWorker: function(cbnext) {
248 // don't ever create this file! We want a 404.
249 let url = "https://example.com/browser/toolkit/components/social/test/browser/worker_is_missing.js";
250 let worker = getFrameWorkerHandle(url, undefined, "testMissingWorker");
251 Services.obs.addObserver(function handleError(subj, topic, data) {
252 Services.obs.removeObserver(handleError, "social:frameworker-error");
253 is(data, worker._worker.origin, "social:frameworker-error was handled");
254 worker.terminate();
255 cbnext();
256 }, 'social:frameworker-error', false);
257 worker.port.onmessage = function(e) {
258 ok(false, "social:frameworker-error was handled");
259 cbnext();
260 }
261 },
263 testNoConnectWorker: function(cbnext) {
264 let worker = getFrameWorkerHandle(makeWorkerUrl(function () {}),
265 undefined, "testNoConnectWorker");
266 Services.obs.addObserver(function handleError(subj, topic, data) {
267 Services.obs.removeObserver(handleError, "social:frameworker-error");
268 is(data, worker._worker.origin, "social:frameworker-error was handled");
269 worker.terminate();
270 cbnext();
271 }, 'social:frameworker-error', false);
272 worker.port.onmessage = function(e) {
273 ok(false, "social:frameworker-error was handled");
274 cbnext();
275 }
276 },
278 testEmptyWorker: function(cbnext) {
279 let worker = getFrameWorkerHandle(makeWorkerUrl(''),
280 undefined, "testEmptyWorker");
281 Services.obs.addObserver(function handleError(subj, topic, data) {
282 Services.obs.removeObserver(handleError, "social:frameworker-error");
283 is(data, worker._worker.origin, "social:frameworker-error was handled");
284 worker.terminate();
285 cbnext();
286 }, 'social:frameworker-error', false);
287 worker.port.onmessage = function(e) {
288 ok(false, "social:frameworker-error was handled");
289 cbnext();
290 }
291 },
293 testWorkerConnectError: function(cbnext) {
294 let run = function () {
295 onconnect = function(e) {
296 throw new Error("worker failure");
297 }
298 }
299 let worker = getFrameWorkerHandle(makeWorkerUrl(run),
300 undefined, "testWorkerConnectError");
301 Services.obs.addObserver(function handleError(subj, topic, data) {
302 Services.obs.removeObserver(handleError, "social:frameworker-error");
303 is(data, worker._worker.origin, "social:frameworker-error was handled");
304 worker.terminate();
305 cbnext();
306 }, 'social:frameworker-error', false);
307 worker.port.onmessage = function(e) {
308 ok(false, "social:frameworker-error was handled");
309 cbnext();
310 }
311 },
313 // This will create the worker, then send a message to the port, then close
314 // the port - all before the worker has actually initialized.
315 testCloseFirstSend: function(cbnext) {
316 let run = function() {
317 let numPings = 0, numCloses = 0;
318 onconnect = function(e) {
319 let port = e.ports[0];
320 port.onmessage = function(e) {
321 if (e.data.topic == "ping") {
322 numPings += 1;
323 } else if (e.data.topic == "social.port-closing") {
324 numCloses += 1;
325 } else if (e.data.topic == "get-counts") {
326 port.postMessage({topic: "result",
327 result: {ping: numPings, close: numCloses}});
328 }
329 }
330 }
331 }
333 let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSendAndClose");
334 worker.port.postMessage({topic: "ping"});
335 worker.port.close();
336 let newPort = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSendAndClose").port;
337 newPort.onmessage = function(e) {
338 if (e.data.topic == "result") {
339 is(e.data.result.ping, 1, "the worker got the ping");
340 is(e.data.result.close, 1, "the worker got 1 close message");
341 worker.terminate();
342 cbnext();
343 }
344 }
345 newPort.postMessage({topic: "get-counts"});
346 },
348 // Like testCloseFirstSend, although in this test the worker has already
349 // initialized (so the "connect pending ports" part of the worker isn't
350 // what needs to handle this case.)
351 testCloseAfterInit: function(cbnext) {
352 let run = function() {
353 let numPings = 0, numCloses = 0;
354 onconnect = function(e) {
355 let port = e.ports[0];
356 port.onmessage = function(e) {
357 if (e.data.topic == "ping") {
358 numPings += 1;
359 } else if (e.data.topic == "social.port-closing") {
360 numCloses += 1;
361 } else if (e.data.topic == "get-counts") {
362 port.postMessage({topic: "result",
363 result: {ping: numPings, close: numCloses}});
364 } else if (e.data.topic == "get-ready") {
365 port.postMessage({topic: "ready"});
366 }
367 }
368 }
369 }
371 let worker = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSendAndClose");
372 worker.port.onmessage = function(e) {
373 if (e.data.topic == "ready") {
374 let newPort = getFrameWorkerHandle(makeWorkerUrl(run), undefined, "testSendAndClose").port;
375 newPort.postMessage({topic: "ping"});
376 newPort.close();
377 worker.port.postMessage({topic: "get-counts"});
378 } else if (e.data.topic == "result") {
379 is(e.data.result.ping, 1, "the worker got the ping");
380 is(e.data.result.close, 1, "the worker got 1 close message");
381 worker.terminate();
382 cbnext();
383 }
384 }
385 worker.port.postMessage({topic: "get-ready"});
386 },
387 }