|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <!-- |
|
4 https://bugzilla.mozilla.org/show_bug.cgi?id=758258 |
|
5 --> |
|
6 <head> |
|
7 <meta charset="utf-8"> |
|
8 <title>Test for nsIPrincipal jarPrefix, origin, appStatus and appId</title> |
|
9 <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> |
|
10 <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> |
|
11 </head> |
|
12 <body> |
|
13 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=758258">Mozilla Bug 758258</a> |
|
14 <p id="display"></p> |
|
15 <div id="content"> |
|
16 |
|
17 </div> |
|
18 <pre id="test"> |
|
19 <script type="application/javascript;version=1.7"> |
|
20 |
|
21 /** Test for Bug 758258 **/ |
|
22 |
|
23 var Ci = Components.interfaces; |
|
24 SimpleTest.waitForExplicitFinish(); |
|
25 |
|
26 /* |
|
27 * gData is an array of objects. Each object represents a test case. |
|
28 * - app: gives the app manifest URL, will set mozapp to it on the iframe; |
|
29 * - origin: gives the origin of the iframe. This is the URL thas is going to |
|
30 * to be passed as iframe.src but also the expected principal's |
|
31 * origin. |
|
32 * - isapp: tells if the iframe is really a mozapp. If the manifest url isn't |
|
33 * valid, the iframe will not be considered as a mozapp. |
|
34 * - browser: say if the iframe should be a mozbrowser. This is implicit when |
|
35 * app is set. |
|
36 * - test: an array of tests to run for this test case: |
|
37 * - eo-unique: the extendedOrigin of the prinicpal must be unique in the |
|
38 * current list. |
|
39 * - eo-as-last: the extendedOrigin of the principal must be the same as the |
|
40 * last added to the list. |
|
41 */ |
|
42 var gData = [ |
|
43 { |
|
44 app: "http://example.org/manifest.webapp", |
|
45 src: "http://example.org/", |
|
46 isapp: true, |
|
47 test: [ "eo-unique" ], |
|
48 }, |
|
49 { |
|
50 app: "https://example.com/manifest.webapp", |
|
51 src: "https://example.com/", |
|
52 isapp: true, |
|
53 test: [ "eo-unique" ], |
|
54 }, |
|
55 { |
|
56 app: "http://test1.example.org/manifest.webapp", |
|
57 src: "http://test1.example.org/", |
|
58 isapp: true, |
|
59 test: [ "eo-unique" ], |
|
60 }, |
|
61 { |
|
62 app: "http://test1.example.org:8000/manifest.webapp", |
|
63 src: "http://test1.example.org:8000/", |
|
64 isapp: true, |
|
65 test: [ "eo-unique" ], |
|
66 }, |
|
67 { |
|
68 app: "http://sub1.test1.example.org/manifest.webapp", |
|
69 src: "http://sub1.test1.example.org/", |
|
70 isapp: true, |
|
71 test: [ "eo-unique" ], |
|
72 }, |
|
73 // WebApps implementation doesn't allow apps with the same origin. Sad... |
|
74 // { |
|
75 // app: "http://example.org/foo/manifest.webapp", |
|
76 // src: "http://example.org/", |
|
77 // isapp: true, |
|
78 // test: [ "eo-unique" ], |
|
79 // }, |
|
80 // { |
|
81 // app: "http://example.org/bar/manifest.webapp", |
|
82 // src: "http://example.org/", |
|
83 // isapp: true, |
|
84 // test: [ "eo-unique" ], |
|
85 // }, |
|
86 { |
|
87 src: "http://example.org/", |
|
88 isapp: false, |
|
89 test: [ "eo-unique" ], |
|
90 }, |
|
91 { |
|
92 browser: true, |
|
93 src: "http://example.org/", |
|
94 isapp: false, |
|
95 test: [ "eo-unique" ], |
|
96 }, |
|
97 { |
|
98 app: "http://example.org/wedonthaveanyappinthatdirectory/manifest.webapp", |
|
99 src: "http://example.org/", |
|
100 isapp: false, |
|
101 // TODO: this is a browser because we need apps to be browser and it's not |
|
102 // an app because the manifest is invalid. Ideally, it should not be a |
|
103 // browser. |
|
104 browser: true, |
|
105 test: [ "eo-as-last" ], |
|
106 }, |
|
107 // { |
|
108 // app: "http://example.org/manifest.webapp", |
|
109 // src: "data:text/html,foobar", |
|
110 // test: [ "todo-src" ], |
|
111 // }, |
|
112 // { |
|
113 // app: "http://example.org/manifest.webapp", |
|
114 // src: "data:text/html,foobar2", |
|
115 // test: [ "todo-src" ], |
|
116 // }, |
|
117 { |
|
118 src: "file:///", |
|
119 isapp: false, |
|
120 test: [ "eo-unique" ], |
|
121 }, |
|
122 { |
|
123 src: "file:///tmp/", |
|
124 isapp: false, |
|
125 test: [ "eo-unique" ], |
|
126 }, |
|
127 { |
|
128 app: "http://example.org/manifest.webapp", |
|
129 src: "file:///", |
|
130 isapp: true, |
|
131 test: [ "eo-unique", "in-app-not-installed" ], |
|
132 }, |
|
133 { |
|
134 app: "http://example.org/manifest.webapp", |
|
135 src: "file:///tmp/", |
|
136 isapp: true, |
|
137 test: [ "eo-unique", "in-app-not-installed" ], |
|
138 }, |
|
139 // iframe inside an app is part of the app. |
|
140 { |
|
141 app: "http://example.org/manifest.webapp", |
|
142 src: "http://example.org/", |
|
143 isapp: true, |
|
144 child: { |
|
145 src: "http://example.org/chrome/", |
|
146 isapp: true |
|
147 }, |
|
148 test: [ "child-has-same-eo" ], |
|
149 }, |
|
150 // app A inside app B aren't the same app. |
|
151 { |
|
152 app: "http://example.org/manifest.webapp", |
|
153 src: "http://example.org/", |
|
154 isapp: true, |
|
155 child: { |
|
156 app: "https://example.com/manifest.webapp", |
|
157 src: "https://example.com/chrome/", |
|
158 isapp: true |
|
159 }, |
|
160 test: [ "child-has-different-eo", "child-has-same-appstatus", "child-has-different-appid" ], |
|
161 }, |
|
162 // app A inside app A are the same app. |
|
163 { |
|
164 app: "http://example.org/manifest.webapp", |
|
165 src: "http://example.org/", |
|
166 isapp: true, |
|
167 child: { |
|
168 app: "http://example.org/manifest.webapp", |
|
169 src: "http://example.org/chrome/", |
|
170 isapp: true |
|
171 }, |
|
172 test: [ "child-has-same-eo" ], |
|
173 }, |
|
174 // app inside a regular iframe is an app. |
|
175 { |
|
176 src: "http://example.org/", |
|
177 isapp: false, |
|
178 child: { |
|
179 app: "http://example.org/manifest.webapp", |
|
180 src: "http://example.org/chrome/", |
|
181 isapp: true |
|
182 }, |
|
183 test: [ "child-has-different-eo", "child-has-different-appstatus", "child-has-different-appid" ], |
|
184 }, |
|
185 // browser inside app is a browser, has appid but isn't installed. |
|
186 { |
|
187 src: "http://example.org/", |
|
188 app: "http://example.org/manifest.webapp", |
|
189 isapp: true, |
|
190 child: { |
|
191 src: "http://example.org/chrome/", |
|
192 isapp: false, |
|
193 browser: true, |
|
194 }, |
|
195 test: [ "child-has-different-eo", "child-has-different-appstatus", "child-has-same-appid" ], |
|
196 }, |
|
197 // app inside a browser is an app. |
|
198 { |
|
199 src: "http://example.org/", |
|
200 isapp: false, |
|
201 browser: true, |
|
202 child: { |
|
203 app: "http://example.org/manifest.webapp", |
|
204 src: "http://example.org/chrome/", |
|
205 isapp: true, |
|
206 }, |
|
207 test: [ "child-has-different-eo", "child-has-different-appstatus", "child-has-different-appid" ], |
|
208 }, |
|
209 // browser inside a browser are two browsers |
|
210 { |
|
211 src: "http://example.org/", |
|
212 isapp: false, |
|
213 browser: true, |
|
214 child: { |
|
215 src: "http://example.org/chrome/", |
|
216 isapp: false, |
|
217 browser: true, |
|
218 }, |
|
219 test: [ "child-has-same-eo" ], |
|
220 }, |
|
221 // browser inside a browser are two browsers |
|
222 { |
|
223 src: "http://example.org/", |
|
224 isapp: false, |
|
225 browser: true, |
|
226 child: { |
|
227 src: "https://example.com/chrome/", |
|
228 isapp: false, |
|
229 browser: true, |
|
230 }, |
|
231 test: [ "child-has-different-eo", "child-has-same-appstatus", "child-has-same-appid" ], |
|
232 }, |
|
233 // iframe containing a browser |
|
234 { |
|
235 src: "http://example.org/", |
|
236 isapp: false, |
|
237 browser: false, |
|
238 child: { |
|
239 src: "http://example.org/chrome/", |
|
240 isapp: false, |
|
241 browser: true, |
|
242 }, |
|
243 test: [ "child-has-different-eo", "child-has-same-appstatus", "child-has-same-appid" ], |
|
244 }, |
|
245 // browser containing an iframe is part of the browser |
|
246 { |
|
247 src: "http://example.org/", |
|
248 isapp: false, |
|
249 browser: true, |
|
250 child: { |
|
251 src: "http://example.org/chrome/", |
|
252 isapp: false, |
|
253 inBrowser: true, |
|
254 }, |
|
255 test: [ "child-has-same-eo" ], |
|
256 }, |
|
257 ]; |
|
258 |
|
259 // The list of all data ids generated by this test. |
|
260 var eoList = []; |
|
261 |
|
262 var content = document.getElementById('content'); |
|
263 var checkedCount = 0; |
|
264 var checksTodo = gData.length; |
|
265 |
|
266 function checkIFrame(aFrame, data) { |
|
267 var principal = aFrame.contentDocument.nodePrincipal; |
|
268 |
|
269 if (!data.test) { |
|
270 data.test = []; |
|
271 } |
|
272 |
|
273 if (navigator.platform.indexOf("Mac") != -1) { |
|
274 is(principal.URI.spec, |
|
275 data.src.replace('file:///tmp/', 'file:///private/tmp/'), |
|
276 'the correct URL should have been loaded'); |
|
277 } else { |
|
278 is(principal.URI.spec, data.src, |
|
279 'the correct URL should have been loaded'); |
|
280 } |
|
281 |
|
282 if (data.isapp) { |
|
283 if (data.test.indexOf("in-app-not-installed") != -1) { |
|
284 is(principal.appStatus, Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED, 'this should not be an installed app'); |
|
285 } else { |
|
286 is(principal.appStatus, Ci.nsIPrincipal.APP_STATUS_INSTALLED, 'this should be an installed app'); |
|
287 } |
|
288 } else { |
|
289 is(principal.appStatus, Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED, |
|
290 'this should not be an installed app'); |
|
291 is(principal.appId, Ci.nsIScriptSecurityManager.NO_APP_ID, |
|
292 "principals from non-installed app should have NO_APP_ID"); |
|
293 } |
|
294 |
|
295 if (!data.isapp && !data.browser) { |
|
296 is(principal.jarPrefix, "", |
|
297 'jarPrefix should return an empty string for non-app and non-browsers principals'); |
|
298 } else { |
|
299 isnot(principal.jarPrefix, "", |
|
300 'jarPrefix should not return an empty string for apps or mozbrowsers'); |
|
301 } |
|
302 |
|
303 if (data.test.indexOf("eo-unique") != -1) { |
|
304 is(eoList.indexOf(principal.jarPrefix + principal.origin), -1, |
|
305 "extended origin should be unique"); |
|
306 } |
|
307 if (data.test.indexOf("eo-as-last") != -1) { |
|
308 is(principal.jarPrefix + principal.origin, eoList[eoList.length-1], |
|
309 "extended origin should be the same as the last inserted one"); |
|
310 } |
|
311 |
|
312 is(principal.isInBrowserElement, !!data.browser, |
|
313 "check principal.isInBrowserElement"); |
|
314 |
|
315 if (data.child) { |
|
316 let childPrincipal = aFrame.contentWindow.frames[0].document.nodePrincipal; |
|
317 |
|
318 if (data.child.isapp) { |
|
319 is(childPrincipal.appStatus, Ci.nsIPrincipal.APP_STATUS_INSTALLED, |
|
320 "child should be an installed app"); |
|
321 } |
|
322 |
|
323 is(childPrincipal.isInBrowserElement, !!data.child.browser || !!data.child.inBrowser, |
|
324 "check childPrincipal.isInBrowserElement"); |
|
325 |
|
326 if (data.test.indexOf("child-has-same-eo") != -1) { |
|
327 is(childPrincipal.jarPrefix + childPrincipal.origin, |
|
328 principal.jarPrefix + principal.origin, |
|
329 "child should have the same extended origin as parent"); |
|
330 is(childPrincipal.appStatus, principal.appStatus, |
|
331 "child should have the same appStatus if it has the same extended origin"); |
|
332 is(childPrincipal.appId, principal.appId, |
|
333 "child should have the same appId if it has the same extended origin"); |
|
334 } |
|
335 |
|
336 if (data.test.indexOf("child-has-different-eo") != -1) { |
|
337 isnot(childPrincipal.jarPrefix + childPrincipal.origin, |
|
338 principal.jarPrefix + principal.origin, |
|
339 "child should not have the same extended origin as parent"); |
|
340 } |
|
341 |
|
342 if (data.test.indexOf("child-has-same-appstatus") != -1) { |
|
343 is(childPrincipal.appStatus, principal.appStatus, |
|
344 "childPrincipal and parent principal should have the same appStatus"); |
|
345 } |
|
346 |
|
347 if (data.test.indexOf("child-has-different-appstatus") != -1) { |
|
348 isnot(childPrincipal.appStatus, principal.appStatus, |
|
349 "childPrincipal and parent principal should not have the same appStatus"); |
|
350 } |
|
351 |
|
352 if (data.test.indexOf("child-has-same-appid") != -1) { |
|
353 is(childPrincipal.appId, principal.appId, |
|
354 "childPrincipal and parent principal should have the same appId"); |
|
355 } |
|
356 |
|
357 if (data.test.indexOf("child-has-different-appid") != -1) { |
|
358 isnot(childPrincipal.appId, principal.appId, |
|
359 "childPrincipal and parent principal should have different appId"); |
|
360 } |
|
361 } |
|
362 |
|
363 eoList.push(principal.jarPrefix + principal.origin); |
|
364 |
|
365 checkedCount++; |
|
366 if (checkedCount == checksTodo) { |
|
367 SpecialPowers.removePermission("browser", "http://example.org"); |
|
368 SpecialPowers.removePermission("embed-apps", "http://example.org"); |
|
369 SimpleTest.finish(); |
|
370 } else { |
|
371 gTestRunner.next(); |
|
372 } |
|
373 } |
|
374 |
|
375 is('appStatus' in document.nodePrincipal, true, |
|
376 'appStatus should be present in nsIPrincipal'); |
|
377 is('jarPrefix' in document.nodePrincipal, true, |
|
378 'jarPrefix should be present in nsIPrincipal'); |
|
379 is('origin' in document.nodePrincipal, true, |
|
380 'origin should be present in nsIPrincipal'); |
|
381 is('appId' in document.nodePrincipal, true, |
|
382 'appId should be present in nsIPrincipal'); |
|
383 |
|
384 function runTest() { |
|
385 // We want to use a generator. Those only work in a one level stack so we |
|
386 // can't use .forEach() here. |
|
387 for (var i=0; i<gData.length; ++i) { |
|
388 let data = gData[i]; |
|
389 |
|
390 var iframe = document.createElement('iframe'); |
|
391 iframe.check = function() { |
|
392 checkIFrame(this, data); |
|
393 }; |
|
394 iframe.addChild = function() { |
|
395 SpecialPowers.addPermission("browser", true, iframe.contentDocument); |
|
396 SpecialPowers.addPermission("embed-apps", true, iframe.contentDocument); |
|
397 |
|
398 var childFrame = document.createElement('iframe'); |
|
399 |
|
400 if (data.child.app) { |
|
401 childFrame.setAttribute('mozapp', data.child.app) |
|
402 childFrame.setAttribute('mozbrowser', ''); |
|
403 } else if (data.child.browser) { |
|
404 childFrame.setAttribute('mozbrowser', ''); |
|
405 } |
|
406 |
|
407 childFrame.src = data.child.src; |
|
408 |
|
409 this.removeEventListener('load', this.addChild.bind(this)); |
|
410 childFrame.addEventListener('load', this.check.bind(this)); |
|
411 |
|
412 this.contentDocument.body.appendChild(childFrame); |
|
413 }; |
|
414 |
|
415 if (data.app) { |
|
416 iframe.setAttribute('mozapp', data.app); |
|
417 iframe.setAttribute('mozbrowser', ''); |
|
418 } else if (data.browser) { |
|
419 iframe.setAttribute('mozbrowser', ''); |
|
420 } |
|
421 |
|
422 iframe.src = data.src; |
|
423 |
|
424 if (data.child) { |
|
425 iframe.addEventListener('load', iframe.addChild.bind(iframe)); |
|
426 } else { |
|
427 iframe.addEventListener('load', iframe.check.bind(iframe)); |
|
428 } |
|
429 |
|
430 content.appendChild(iframe); |
|
431 |
|
432 yield; |
|
433 } |
|
434 } |
|
435 |
|
436 var gTestRunner = runTest(); |
|
437 |
|
438 SpecialPowers.pushPrefEnv({'set':[["dom.mozBrowserFramesEnabled", true]]}, |
|
439 function() { gTestRunner.next(); }); |
|
440 |
|
441 </script> |
|
442 </pre> |
|
443 </body> |
|
444 </html> |