Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
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">
17 </div>
18 <pre id="test">
19 <script type="application/javascript;version=1.7">
21 /** Test for Bug 758258 **/
23 var Ci = Components.interfaces;
24 SimpleTest.waitForExplicitFinish();
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 ];
259 // The list of all data ids generated by this test.
260 var eoList = [];
262 var content = document.getElementById('content');
263 var checkedCount = 0;
264 var checksTodo = gData.length;
266 function checkIFrame(aFrame, data) {
267 var principal = aFrame.contentDocument.nodePrincipal;
269 if (!data.test) {
270 data.test = [];
271 }
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 }
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 }
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 }
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 }
312 is(principal.isInBrowserElement, !!data.browser,
313 "check principal.isInBrowserElement");
315 if (data.child) {
316 let childPrincipal = aFrame.contentWindow.frames[0].document.nodePrincipal;
318 if (data.child.isapp) {
319 is(childPrincipal.appStatus, Ci.nsIPrincipal.APP_STATUS_INSTALLED,
320 "child should be an installed app");
321 }
323 is(childPrincipal.isInBrowserElement, !!data.child.browser || !!data.child.inBrowser,
324 "check childPrincipal.isInBrowserElement");
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 }
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 }
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 }
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 }
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 }
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 }
363 eoList.push(principal.jarPrefix + principal.origin);
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 }
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');
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];
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);
398 var childFrame = document.createElement('iframe');
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 }
407 childFrame.src = data.child.src;
409 this.removeEventListener('load', this.addChild.bind(this));
410 childFrame.addEventListener('load', this.check.bind(this));
412 this.contentDocument.body.appendChild(childFrame);
413 };
415 if (data.app) {
416 iframe.setAttribute('mozapp', data.app);
417 iframe.setAttribute('mozbrowser', '');
418 } else if (data.browser) {
419 iframe.setAttribute('mozbrowser', '');
420 }
422 iframe.src = data.src;
424 if (data.child) {
425 iframe.addEventListener('load', iframe.addChild.bind(iframe));
426 } else {
427 iframe.addEventListener('load', iframe.check.bind(iframe));
428 }
430 content.appendChild(iframe);
432 yield;
433 }
434 }
436 var gTestRunner = runTest();
438 SpecialPowers.pushPrefEnv({'set':[["dom.mozBrowserFramesEnabled", true]]},
439 function() { gTestRunner.next(); });
441 </script>
442 </pre>
443 </body>
444 </html>