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=805322
5 -->
6 <head>
7 <meta charset="utf-8">
8 <title>Permission test for Device Storage</title>
9 <script type="application/javascript"
10 src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
11 <link rel="stylesheet" type="text/css"
12 href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
13 </head>
14 <body>
15 <a target="_blank"
16 href="https://bugzilla.mozilla.org/show_bug.cgi?id=805322">Mozilla Bug 805322</a>
17 <p id="display"></p>
18 <div id="content">
20 </div>
21 <pre id="test">
22 <script type="application/javascript;version=1.7">
24 function randomFilename(l) {
25 var set = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ";
26 var result = "";
27 for (var i=0; i<l; i++) {
28 var r = Math.floor(set.length * Math.random());
29 result += set.substring(r, r + 1);
30 }
31 return result;
32 }
34 var MockPermissionPrompt = SpecialPowers.MockPermissionPrompt;
35 MockPermissionPrompt.init();
37 SimpleTest.waitForExplicitFinish();
39 function TestAdd(iframe, data) {
41 var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
42 isnot(storage, null, "Should be able to get storage object for " + data.type);
44 var blob = new Blob(["Kyle Huey is not a helicopter."], {type: data.mimeType});
46 request = storage.addNamed(blob, randomFilename(100) + "hi" + data.fileExtension);
47 isnot(request, null, "Should be able to get request");
49 request.onsuccess = function() {
50 is(data.shouldPass, true, "onsuccess was called for type " + data.type);
51 testComplete(iframe, data);
52 };
54 request.onerror = function(e) {
55 isnot(data.shouldPass, true, "onfailure was called for type " + data.type + " Error: " + e.target.error.name);
56 is(e.target.error.name, "SecurityError", "onerror should fire a SecurityError");
57 testComplete(iframe, data);
58 };
59 }
61 function TestGet(iframe, data) {
63 createTestFile(data.fileExtension);
65 var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
66 isnot(storage, null, "Should be able to get storage object for " + data.type);
68 request = storage.get("testfile" + data.fileExtension);
69 isnot(request, null, "Should be able to get request");
71 request.onsuccess = function() {
72 is(data.shouldPass, true, "onsuccess was called for type " + data.type);
73 testComplete(iframe, data);
74 };
76 request.onerror = function(e) {
77 isnot(data.shouldPass, true, "onfailure was called for type " + data.type + " Error: " + e.target.error.name);
78 testComplete(iframe, data);
79 };
80 }
82 function TestDelete(iframe, data) {
84 createTestFile(data.fileExtension);
86 var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
87 isnot(storage, null, "Should be able to get storage object for " + data.type);
89 request = storage.delete("testfile" + data.fileExtension);
90 isnot(request, null, "Should be able to get request");
92 request.onsuccess = function() {
93 is(data.shouldPass, true, "onsuccess was called for type " + data.type);
94 testComplete(iframe, data);
95 };
97 request.onerror = function(e) {
98 isnot(data.shouldPass, true, "onfailure was called for type " + data.type + " Error: " + e.target.error.name);
99 is(e.target.error.name, "SecurityError", "onerror should fire a SecurityError");
100 testComplete(iframe, data);
101 };
102 }
104 function TestEnumerate(iframe, data) {
106 createTestFile(data.fileExtension);
108 var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type);
109 isnot(storage, null, "Should be able to get storage object for " + data.type);
111 request = storage.enumerate();
112 isnot(request, null, "Should be able to get request");
114 request.onsuccess = function(e) {
115 is(data.shouldPass, true, "onsuccess was called for type " + data.type);
117 if (e.target.result == null) {
118 testComplete(iframe, data);
119 return;
120 }
121 e.target.continue();
122 };
124 request.onerror = function(e) {
125 isnot(data.shouldPass, true, "onfailure was called for type " + data.type + " Error: " + e.target.error.name);
126 is(e.target.error.name, "SecurityError", "onerror should fire a SecurityError");
127 testComplete(iframe, data);
128 };
129 }
131 var gTestUri = "https://example.com/tests/dom/devicestorage/test/test_app_permissions.html"
133 var gData = [
135 // Get
136 // Web applications with no permissions
137 {
138 type: 'pictures',
139 shouldPass: false,
140 fileExtension: '.png',
141 test: TestGet
142 },
143 {
144 type: 'videos',
145 shouldPass: false,
146 fileExtension: '.ogv',
147 test: TestGet
148 },
149 {
150 type: 'music',
151 shouldPass: false,
152 fileExtension: '.ogg',
153 test: TestGet
154 },
155 {
156 type: 'sdcard',
157 shouldPass: false,
158 fileExtension: '.txt',
159 test: TestGet
160 },
162 // Web applications with permission granted
163 {
164 type: 'pictures',
165 shouldPass: true,
166 fileExtension: '.png',
168 permissions: ["device-storage:pictures"],
170 test: TestGet
171 },
172 {
173 type: 'videos',
174 shouldPass: true,
175 fileExtension: '.ogv',
177 permissions: ["device-storage:videos"],
179 test: TestGet
180 },
181 {
182 type: 'music',
183 shouldPass: true,
184 fileExtension: '.ogg',
186 permissions: ["device-storage:music"],
188 test: TestGet
189 },
190 {
191 type: 'sdcard',
192 shouldPass: true,
193 fileExtension: '.txt',
195 permissions: ["device-storage:sdcard"],
197 test: TestGet
198 },
200 // Certified application with permision granted
201 {
202 type: 'pictures',
203 shouldPass: true,
204 fileExtension: '.png',
206 app: "https://example.com/manifest_cert.webapp",
207 permissions: ["device-storage:pictures"],
209 test: TestGet
210 },
211 {
212 type: 'videos',
213 shouldPass: true,
214 fileExtension: '.ogv',
216 app: "https://example.com/manifest_cert.webapp",
217 permissions: ["device-storage:videos"],
219 test: TestGet
220 },
221 {
222 type: 'music',
223 shouldPass: true,
224 fileExtension: '.ogg',
226 app: "https://example.com/manifest_cert.webapp",
227 permissions: ["device-storage:music"],
229 test: TestGet
230 },
231 {
232 type: 'sdcard',
233 shouldPass: true,
234 fileExtension: '.txt',
236 app: "https://example.com/manifest_cert.webapp",
237 permissions: ["device-storage:sdcard"],
239 test: TestGet
240 },
243 // Add
246 // Web applications with no permissions
247 {
248 type: 'pictures',
249 mimeType: 'image/png',
250 fileExtension: '.png',
251 shouldPass: false,
252 test: TestAdd
253 },
254 {
255 type: 'videos',
256 mimeType: 'video/ogv',
257 fileExtension: '.ogv',
258 shouldPass: false,
259 test: TestAdd
260 },
261 {
262 type: 'music',
263 mimeType: 'audio/ogg',
264 fileExtension: '.ogg',
265 shouldPass: false,
266 test: TestAdd
267 },
268 {
269 type: 'sdcard',
270 mimeType: 'text/plain',
271 fileExtension: '.txt',
272 shouldPass: false,
273 test: TestAdd
274 },
276 // Web applications with permission granted
277 {
278 type: 'pictures',
279 mimeType: 'image/png',
280 fileExtension: '.png',
281 shouldPass: true,
283 permissions: ["device-storage:pictures"],
285 test: TestAdd
286 },
287 {
288 type: 'videos',
289 mimeType: 'video/ogv',
290 fileExtension: '.ogv',
291 shouldPass: true,
293 permissions: ["device-storage:videos"],
295 test: TestAdd
296 },
297 {
298 type: 'music',
299 mimeType: 'audio/ogg',
300 fileExtension: '.ogg',
301 shouldPass: true,
303 permissions: ["device-storage:music"],
305 test: TestAdd
306 },
307 {
308 type: 'sdcard',
309 mimeType: 'text/plain',
310 fileExtension: '.txt',
311 shouldPass: true,
313 permissions: ["device-storage:sdcard"],
315 test: TestAdd
316 },
318 // Certified application with permision granted
319 {
320 type: 'pictures',
321 mimeType: 'image/png',
322 fileExtension: '.png',
323 shouldPass: true,
325 app: "https://example.com/manifest_cert.webapp",
326 permissions: ["device-storage:pictures"],
328 test: TestAdd
329 },
330 {
331 type: 'videos',
332 mimeType: 'video/ogv',
333 fileExtension: '.ogv',
334 shouldPass: true,
336 app: "https://example.com/manifest_cert.webapp",
337 permissions: ["device-storage:videos"],
339 test: TestAdd
340 },
341 {
342 type: 'music',
343 mimeType: 'audio/ogg',
344 fileExtension: '.ogg',
345 shouldPass: true,
347 app: "https://example.com/manifest_cert.webapp",
348 permissions: ["device-storage:music"],
350 test: TestAdd
351 },
352 {
353 type: 'sdcard',
354 mimeType: 'text/plain',
355 fileExtension: '.txt',
356 shouldPass: true,
358 app: "https://example.com/manifest_cert.webapp",
359 permissions: ["device-storage:sdcard"],
361 test: TestAdd
362 },
365 // Delete
367 // Web applications with no permissions
368 {
369 type: 'pictures',
370 shouldPass: false,
371 fileExtension: '.png',
372 test: TestDelete
373 },
374 {
375 type: 'videos',
376 shouldPass: false,
377 fileExtension: '.ogv',
378 test: TestDelete
379 },
380 {
381 type: 'music',
382 shouldPass: false,
383 fileExtension: '.ogg',
384 test: TestDelete
385 },
386 {
387 type: 'sdcard',
388 shouldPass: false,
389 fileExtension: '.txt',
390 test: TestDelete
391 },
393 // Web applications with permission granted
394 {
395 type: 'pictures',
396 shouldPass: true,
397 fileExtension: '.png',
399 permissions: ["device-storage:pictures"],
401 test: TestDelete
402 },
403 {
404 type: 'videos',
405 shouldPass: true,
406 fileExtension: '.ogv',
408 permissions: ["device-storage:videos"],
410 test: TestDelete
411 },
412 {
413 type: 'music',
414 shouldPass: true,
415 fileExtension: '.ogg',
417 permissions: ["device-storage:music"],
419 test: TestDelete
420 },
421 {
422 type: 'sdcard',
423 shouldPass: true,
424 fileExtension: '.txt',
426 permissions: ["device-storage:sdcard"],
428 test: TestDelete
429 },
431 // Certified application with permision granted
432 {
433 type: 'pictures',
434 shouldPass: true,
435 fileExtension: '.png',
437 app: "https://example.com/manifest_cert.webapp",
438 permissions: ["device-storage:pictures"],
440 test: TestDelete
441 },
442 {
443 type: 'videos',
444 shouldPass: true,
445 fileExtension: '.ogv',
447 app: "https://example.com/manifest_cert.webapp",
448 permissions: ["device-storage:videos"],
450 test: TestDelete
451 },
452 {
453 type: 'music',
454 shouldPass: true,
455 fileExtension: '.ogg',
457 app: "https://example.com/manifest_cert.webapp",
458 permissions: ["device-storage:music"],
460 test: TestDelete
461 },
462 {
463 type: 'sdcard',
464 shouldPass: true,
465 fileExtension: '.txt',
467 app: "https://example.com/manifest_cert.webapp",
468 permissions: ["device-storage:sdcard"],
470 test: TestDelete
471 },
473 // Enumeration
475 // Web applications with no permissions
476 {
477 type: 'pictures',
478 shouldPass: false,
479 fileExtension: '.png',
480 test: TestEnumerate
481 },
482 {
483 type: 'videos',
484 shouldPass: false,
485 fileExtension: '.ogv',
486 test: TestEnumerate
487 },
488 {
489 type: 'music',
490 shouldPass: false,
491 fileExtension: '.ogg',
492 test: TestEnumerate
493 },
494 {
495 type: 'sdcard',
496 shouldPass: false,
497 fileExtension: '.txt',
498 test: TestEnumerate
499 },
501 // Web applications with permission granted
502 {
503 type: 'pictures',
504 shouldPass: true,
505 fileExtension: '.png',
507 permissions: ["device-storage:pictures"],
509 test: TestEnumerate
510 },
511 {
512 type: 'videos',
513 shouldPass: true,
514 fileExtension: '.ogv',
516 permissions: ["device-storage:videos"],
518 test: TestEnumerate
519 },
520 {
521 type: 'music',
522 shouldPass: true,
523 fileExtension: '.ogg',
525 permissions: ["device-storage:music"],
527 test: TestEnumerate
528 },
529 {
530 type: 'sdcard',
531 shouldPass: true,
532 fileExtension: '.txt',
534 permissions: ["device-storage:sdcard"],
536 test: TestEnumerate
537 },
539 // Certified application with permision granted
540 {
541 type: 'pictures',
542 shouldPass: true,
543 fileExtension: '.png',
545 app: "https://example.com/manifest_cert.webapp",
546 permissions: ["device-storage:pictures"],
548 test: TestEnumerate
549 },
550 {
551 type: 'videos',
552 shouldPass: true,
553 fileExtension: '.ogv',
555 app: "https://example.com/manifest_cert.webapp",
556 permissions: ["device-storage:videos"],
558 test: TestEnumerate
559 },
560 {
561 type: 'music',
562 shouldPass: true,
563 fileExtension: '.ogg',
565 app: "https://example.com/manifest_cert.webapp",
566 permissions: ["device-storage:music"],
568 test: TestEnumerate
569 },
570 {
571 type: 'sdcard',
572 shouldPass: true,
573 fileExtension: '.txt',
575 app: "https://example.com/manifest_cert.webapp",
576 permissions: ["device-storage:sdcard"],
578 test: TestEnumerate
579 },
581 ];
583 function setupTest(iframe,data) {
584 if (data.permissions) {
585 for (var j in data.permissions) {
586 SpecialPowers.addPermission(data.permissions[j], true, iframe.contentDocument);
587 }
588 }
589 }
591 function testComplete(iframe, data) {
592 if (data.permissions) {
593 for (var j in data.permissions) {
594 SpecialPowers.removePermission(data.permissions[j], iframe.contentDocument);
595 }
596 }
598 document.getElementById('content').removeChild(iframe);
600 if (gData.length == 0) {
601 SimpleTest.finish();
602 } else {
603 gTestRunner.next();
604 }
605 }
607 function runTest() {
608 while (gData.length > 0) {
609 var iframe = document.createElement('iframe');
610 var data = gData.pop();
612 iframe.setAttribute('mozbrowser', '');
613 if (data.app) {
614 iframe.setAttribute('mozapp', data.app);
615 }
617 iframe.src = gTestUri;
619 iframe.addEventListener('load', function(e) {
620 setupTest(iframe, data)
621 data.test(iframe, data);
622 });
624 document.getElementById('content').appendChild(iframe);
625 yield undefined;
626 }
627 }
629 function createTestFile(extension) {
630 try {
631 const Cc = SpecialPowers.Cc;
632 const Ci = SpecialPowers.Ci;
633 var directoryService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
634 var f = directoryService.get("TmpD", Ci.nsIFile);
635 f.appendRelativePath("device-storage-testing");
636 f.remove(true);
637 f.appendRelativePath("testfile" + extension);
638 f.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
639 } catch(e) {}
640 }
642 createTestFile('.txt');
643 var gTestRunner = runTest();
644 SpecialPowers.addPermission("browser", true, gTestUri);
646 // We are more permissive with CSP in our testing environment....
647 const DEFAULT_CSP_PRIV = "default-src *; script-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'none'";
648 const DEFAULT_CSP_CERT = "default-src *; script-src 'self'; style-src 'self'; object-src 'none'";
650 SpecialPowers.pushPrefEnv({'set': [["dom.mozBrowserFramesEnabled", true],
651 ["device.storage.enabled", true],
652 ["device.storage.testing", true],
653 ["device.storage.prompt.testing", false],
654 ["security.apps.privileged.CSP.default", DEFAULT_CSP_PRIV],
655 ["security.apps.certified.CSP.default", DEFAULT_CSP_CERT]]},
656 function() { gTestRunner.next(); });
658 </script>
659 </pre>
660 </body>
661 </html>