|
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"> |
|
19 |
|
20 </div> |
|
21 <pre id="test"> |
|
22 <script type="application/javascript;version=1.7"> |
|
23 |
|
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 } |
|
33 |
|
34 var MockPermissionPrompt = SpecialPowers.MockPermissionPrompt; |
|
35 MockPermissionPrompt.init(); |
|
36 |
|
37 SimpleTest.waitForExplicitFinish(); |
|
38 |
|
39 function TestAdd(iframe, data) { |
|
40 |
|
41 var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type); |
|
42 isnot(storage, null, "Should be able to get storage object for " + data.type); |
|
43 |
|
44 var blob = new Blob(["Kyle Huey is not a helicopter."], {type: data.mimeType}); |
|
45 |
|
46 request = storage.addNamed(blob, randomFilename(100) + "hi" + data.fileExtension); |
|
47 isnot(request, null, "Should be able to get request"); |
|
48 |
|
49 request.onsuccess = function() { |
|
50 is(data.shouldPass, true, "onsuccess was called for type " + data.type); |
|
51 testComplete(iframe, data); |
|
52 }; |
|
53 |
|
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 } |
|
60 |
|
61 function TestGet(iframe, data) { |
|
62 |
|
63 createTestFile(data.fileExtension); |
|
64 |
|
65 var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type); |
|
66 isnot(storage, null, "Should be able to get storage object for " + data.type); |
|
67 |
|
68 request = storage.get("testfile" + data.fileExtension); |
|
69 isnot(request, null, "Should be able to get request"); |
|
70 |
|
71 request.onsuccess = function() { |
|
72 is(data.shouldPass, true, "onsuccess was called for type " + data.type); |
|
73 testComplete(iframe, data); |
|
74 }; |
|
75 |
|
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 } |
|
81 |
|
82 function TestDelete(iframe, data) { |
|
83 |
|
84 createTestFile(data.fileExtension); |
|
85 |
|
86 var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type); |
|
87 isnot(storage, null, "Should be able to get storage object for " + data.type); |
|
88 |
|
89 request = storage.delete("testfile" + data.fileExtension); |
|
90 isnot(request, null, "Should be able to get request"); |
|
91 |
|
92 request.onsuccess = function() { |
|
93 is(data.shouldPass, true, "onsuccess was called for type " + data.type); |
|
94 testComplete(iframe, data); |
|
95 }; |
|
96 |
|
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 } |
|
103 |
|
104 function TestEnumerate(iframe, data) { |
|
105 |
|
106 createTestFile(data.fileExtension); |
|
107 |
|
108 var storage = iframe.contentDocument.defaultView.navigator.getDeviceStorage(data.type); |
|
109 isnot(storage, null, "Should be able to get storage object for " + data.type); |
|
110 |
|
111 request = storage.enumerate(); |
|
112 isnot(request, null, "Should be able to get request"); |
|
113 |
|
114 request.onsuccess = function(e) { |
|
115 is(data.shouldPass, true, "onsuccess was called for type " + data.type); |
|
116 |
|
117 if (e.target.result == null) { |
|
118 testComplete(iframe, data); |
|
119 return; |
|
120 } |
|
121 e.target.continue(); |
|
122 }; |
|
123 |
|
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 } |
|
130 |
|
131 var gTestUri = "https://example.com/tests/dom/devicestorage/test/test_app_permissions.html" |
|
132 |
|
133 var gData = [ |
|
134 |
|
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 }, |
|
161 |
|
162 // Web applications with permission granted |
|
163 { |
|
164 type: 'pictures', |
|
165 shouldPass: true, |
|
166 fileExtension: '.png', |
|
167 |
|
168 permissions: ["device-storage:pictures"], |
|
169 |
|
170 test: TestGet |
|
171 }, |
|
172 { |
|
173 type: 'videos', |
|
174 shouldPass: true, |
|
175 fileExtension: '.ogv', |
|
176 |
|
177 permissions: ["device-storage:videos"], |
|
178 |
|
179 test: TestGet |
|
180 }, |
|
181 { |
|
182 type: 'music', |
|
183 shouldPass: true, |
|
184 fileExtension: '.ogg', |
|
185 |
|
186 permissions: ["device-storage:music"], |
|
187 |
|
188 test: TestGet |
|
189 }, |
|
190 { |
|
191 type: 'sdcard', |
|
192 shouldPass: true, |
|
193 fileExtension: '.txt', |
|
194 |
|
195 permissions: ["device-storage:sdcard"], |
|
196 |
|
197 test: TestGet |
|
198 }, |
|
199 |
|
200 // Certified application with permision granted |
|
201 { |
|
202 type: 'pictures', |
|
203 shouldPass: true, |
|
204 fileExtension: '.png', |
|
205 |
|
206 app: "https://example.com/manifest_cert.webapp", |
|
207 permissions: ["device-storage:pictures"], |
|
208 |
|
209 test: TestGet |
|
210 }, |
|
211 { |
|
212 type: 'videos', |
|
213 shouldPass: true, |
|
214 fileExtension: '.ogv', |
|
215 |
|
216 app: "https://example.com/manifest_cert.webapp", |
|
217 permissions: ["device-storage:videos"], |
|
218 |
|
219 test: TestGet |
|
220 }, |
|
221 { |
|
222 type: 'music', |
|
223 shouldPass: true, |
|
224 fileExtension: '.ogg', |
|
225 |
|
226 app: "https://example.com/manifest_cert.webapp", |
|
227 permissions: ["device-storage:music"], |
|
228 |
|
229 test: TestGet |
|
230 }, |
|
231 { |
|
232 type: 'sdcard', |
|
233 shouldPass: true, |
|
234 fileExtension: '.txt', |
|
235 |
|
236 app: "https://example.com/manifest_cert.webapp", |
|
237 permissions: ["device-storage:sdcard"], |
|
238 |
|
239 test: TestGet |
|
240 }, |
|
241 |
|
242 |
|
243 // Add |
|
244 |
|
245 |
|
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 }, |
|
275 |
|
276 // Web applications with permission granted |
|
277 { |
|
278 type: 'pictures', |
|
279 mimeType: 'image/png', |
|
280 fileExtension: '.png', |
|
281 shouldPass: true, |
|
282 |
|
283 permissions: ["device-storage:pictures"], |
|
284 |
|
285 test: TestAdd |
|
286 }, |
|
287 { |
|
288 type: 'videos', |
|
289 mimeType: 'video/ogv', |
|
290 fileExtension: '.ogv', |
|
291 shouldPass: true, |
|
292 |
|
293 permissions: ["device-storage:videos"], |
|
294 |
|
295 test: TestAdd |
|
296 }, |
|
297 { |
|
298 type: 'music', |
|
299 mimeType: 'audio/ogg', |
|
300 fileExtension: '.ogg', |
|
301 shouldPass: true, |
|
302 |
|
303 permissions: ["device-storage:music"], |
|
304 |
|
305 test: TestAdd |
|
306 }, |
|
307 { |
|
308 type: 'sdcard', |
|
309 mimeType: 'text/plain', |
|
310 fileExtension: '.txt', |
|
311 shouldPass: true, |
|
312 |
|
313 permissions: ["device-storage:sdcard"], |
|
314 |
|
315 test: TestAdd |
|
316 }, |
|
317 |
|
318 // Certified application with permision granted |
|
319 { |
|
320 type: 'pictures', |
|
321 mimeType: 'image/png', |
|
322 fileExtension: '.png', |
|
323 shouldPass: true, |
|
324 |
|
325 app: "https://example.com/manifest_cert.webapp", |
|
326 permissions: ["device-storage:pictures"], |
|
327 |
|
328 test: TestAdd |
|
329 }, |
|
330 { |
|
331 type: 'videos', |
|
332 mimeType: 'video/ogv', |
|
333 fileExtension: '.ogv', |
|
334 shouldPass: true, |
|
335 |
|
336 app: "https://example.com/manifest_cert.webapp", |
|
337 permissions: ["device-storage:videos"], |
|
338 |
|
339 test: TestAdd |
|
340 }, |
|
341 { |
|
342 type: 'music', |
|
343 mimeType: 'audio/ogg', |
|
344 fileExtension: '.ogg', |
|
345 shouldPass: true, |
|
346 |
|
347 app: "https://example.com/manifest_cert.webapp", |
|
348 permissions: ["device-storage:music"], |
|
349 |
|
350 test: TestAdd |
|
351 }, |
|
352 { |
|
353 type: 'sdcard', |
|
354 mimeType: 'text/plain', |
|
355 fileExtension: '.txt', |
|
356 shouldPass: true, |
|
357 |
|
358 app: "https://example.com/manifest_cert.webapp", |
|
359 permissions: ["device-storage:sdcard"], |
|
360 |
|
361 test: TestAdd |
|
362 }, |
|
363 |
|
364 |
|
365 // Delete |
|
366 |
|
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 }, |
|
392 |
|
393 // Web applications with permission granted |
|
394 { |
|
395 type: 'pictures', |
|
396 shouldPass: true, |
|
397 fileExtension: '.png', |
|
398 |
|
399 permissions: ["device-storage:pictures"], |
|
400 |
|
401 test: TestDelete |
|
402 }, |
|
403 { |
|
404 type: 'videos', |
|
405 shouldPass: true, |
|
406 fileExtension: '.ogv', |
|
407 |
|
408 permissions: ["device-storage:videos"], |
|
409 |
|
410 test: TestDelete |
|
411 }, |
|
412 { |
|
413 type: 'music', |
|
414 shouldPass: true, |
|
415 fileExtension: '.ogg', |
|
416 |
|
417 permissions: ["device-storage:music"], |
|
418 |
|
419 test: TestDelete |
|
420 }, |
|
421 { |
|
422 type: 'sdcard', |
|
423 shouldPass: true, |
|
424 fileExtension: '.txt', |
|
425 |
|
426 permissions: ["device-storage:sdcard"], |
|
427 |
|
428 test: TestDelete |
|
429 }, |
|
430 |
|
431 // Certified application with permision granted |
|
432 { |
|
433 type: 'pictures', |
|
434 shouldPass: true, |
|
435 fileExtension: '.png', |
|
436 |
|
437 app: "https://example.com/manifest_cert.webapp", |
|
438 permissions: ["device-storage:pictures"], |
|
439 |
|
440 test: TestDelete |
|
441 }, |
|
442 { |
|
443 type: 'videos', |
|
444 shouldPass: true, |
|
445 fileExtension: '.ogv', |
|
446 |
|
447 app: "https://example.com/manifest_cert.webapp", |
|
448 permissions: ["device-storage:videos"], |
|
449 |
|
450 test: TestDelete |
|
451 }, |
|
452 { |
|
453 type: 'music', |
|
454 shouldPass: true, |
|
455 fileExtension: '.ogg', |
|
456 |
|
457 app: "https://example.com/manifest_cert.webapp", |
|
458 permissions: ["device-storage:music"], |
|
459 |
|
460 test: TestDelete |
|
461 }, |
|
462 { |
|
463 type: 'sdcard', |
|
464 shouldPass: true, |
|
465 fileExtension: '.txt', |
|
466 |
|
467 app: "https://example.com/manifest_cert.webapp", |
|
468 permissions: ["device-storage:sdcard"], |
|
469 |
|
470 test: TestDelete |
|
471 }, |
|
472 |
|
473 // Enumeration |
|
474 |
|
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 }, |
|
500 |
|
501 // Web applications with permission granted |
|
502 { |
|
503 type: 'pictures', |
|
504 shouldPass: true, |
|
505 fileExtension: '.png', |
|
506 |
|
507 permissions: ["device-storage:pictures"], |
|
508 |
|
509 test: TestEnumerate |
|
510 }, |
|
511 { |
|
512 type: 'videos', |
|
513 shouldPass: true, |
|
514 fileExtension: '.ogv', |
|
515 |
|
516 permissions: ["device-storage:videos"], |
|
517 |
|
518 test: TestEnumerate |
|
519 }, |
|
520 { |
|
521 type: 'music', |
|
522 shouldPass: true, |
|
523 fileExtension: '.ogg', |
|
524 |
|
525 permissions: ["device-storage:music"], |
|
526 |
|
527 test: TestEnumerate |
|
528 }, |
|
529 { |
|
530 type: 'sdcard', |
|
531 shouldPass: true, |
|
532 fileExtension: '.txt', |
|
533 |
|
534 permissions: ["device-storage:sdcard"], |
|
535 |
|
536 test: TestEnumerate |
|
537 }, |
|
538 |
|
539 // Certified application with permision granted |
|
540 { |
|
541 type: 'pictures', |
|
542 shouldPass: true, |
|
543 fileExtension: '.png', |
|
544 |
|
545 app: "https://example.com/manifest_cert.webapp", |
|
546 permissions: ["device-storage:pictures"], |
|
547 |
|
548 test: TestEnumerate |
|
549 }, |
|
550 { |
|
551 type: 'videos', |
|
552 shouldPass: true, |
|
553 fileExtension: '.ogv', |
|
554 |
|
555 app: "https://example.com/manifest_cert.webapp", |
|
556 permissions: ["device-storage:videos"], |
|
557 |
|
558 test: TestEnumerate |
|
559 }, |
|
560 { |
|
561 type: 'music', |
|
562 shouldPass: true, |
|
563 fileExtension: '.ogg', |
|
564 |
|
565 app: "https://example.com/manifest_cert.webapp", |
|
566 permissions: ["device-storage:music"], |
|
567 |
|
568 test: TestEnumerate |
|
569 }, |
|
570 { |
|
571 type: 'sdcard', |
|
572 shouldPass: true, |
|
573 fileExtension: '.txt', |
|
574 |
|
575 app: "https://example.com/manifest_cert.webapp", |
|
576 permissions: ["device-storage:sdcard"], |
|
577 |
|
578 test: TestEnumerate |
|
579 }, |
|
580 |
|
581 ]; |
|
582 |
|
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 } |
|
590 |
|
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 } |
|
597 |
|
598 document.getElementById('content').removeChild(iframe); |
|
599 |
|
600 if (gData.length == 0) { |
|
601 SimpleTest.finish(); |
|
602 } else { |
|
603 gTestRunner.next(); |
|
604 } |
|
605 } |
|
606 |
|
607 function runTest() { |
|
608 while (gData.length > 0) { |
|
609 var iframe = document.createElement('iframe'); |
|
610 var data = gData.pop(); |
|
611 |
|
612 iframe.setAttribute('mozbrowser', ''); |
|
613 if (data.app) { |
|
614 iframe.setAttribute('mozapp', data.app); |
|
615 } |
|
616 |
|
617 iframe.src = gTestUri; |
|
618 |
|
619 iframe.addEventListener('load', function(e) { |
|
620 setupTest(iframe, data) |
|
621 data.test(iframe, data); |
|
622 }); |
|
623 |
|
624 document.getElementById('content').appendChild(iframe); |
|
625 yield undefined; |
|
626 } |
|
627 } |
|
628 |
|
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 } |
|
641 |
|
642 createTestFile('.txt'); |
|
643 var gTestRunner = runTest(); |
|
644 SpecialPowers.addPermission("browser", true, gTestUri); |
|
645 |
|
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'"; |
|
649 |
|
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(); }); |
|
657 |
|
658 </script> |
|
659 </pre> |
|
660 </body> |
|
661 </html> |