1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/permission/tests/file_framework.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,226 @@ 1.4 +/** Test for Bug 815105 **/ 1.5 +/* 1.6 + * gData is an array of object that tests using this framework must pass in 1.7 + * The current tests only pass in a single element array. Each test in 1.8 + * gData is executed by the framework for a given file 1.9 + * 1.10 + * Fields in gData object 1.11 + * perms (required) Array of Strings 1.12 + * list of permissions that this test will need. See 1.13 + * http://mxr.mozilla.org/mozilla-central/source/dom/apps/src/PermissionsTable.jsm 1.14 + * These permissions are added after a sanity check and removed at 1.15 + * test conclusion 1.16 + * 1.17 + * obj (required for default verifier) String 1.18 + * The name of the window.navigator object used for accessing the 1.19 + * WebAPI during the tests 1.20 + * 1.21 + * webidl (required for default verifier) String 1.22 + * idl (required for default verifier) String 1.23 + * Only one of webidl / idl is required 1.24 + * The IDL describing the navigator object. The returned object 1.25 + * during tests /must/ be an instanceof this 1.26 + * 1.27 + * skip (optional) Array of Strings 1.28 + * A list of navigator.userAgent's to skip the second part of tests 1.29 + * on. The tests still verify that you can't get obj on those 1.30 + * platforms without permissions, however it is expected that adding 1.31 + * the permission still won't allow access to those objects 1.32 + * 1.33 + * settings (optional) Array of preference tuples 1.34 + * A list of settings that need to be set before this API is 1.35 + * enabled. Note the settings are set before the sanity check is 1.36 + * performed. If an API gates access only by preferences, then it 1.37 + * will fail the initial test 1.38 + * 1.39 + * verifier (optional) Function 1.40 + * A function used to test whether a WebAPI is accessible or not. 1.41 + * The function takes a success and failure callback which both 1.42 + * accept a msg argument. msg is surfaced up to the top level tests 1.43 + * A default verifier is provided which only attempts to access 1.44 + * the navigator object. 1.45 + * 1.46 + * needParentPerm (optional) Boolean 1.47 + * Whether or not the parent frame requires these permissions as 1.48 + * well. Otherwise the test process may be killed. 1.49 + */ 1.50 + 1.51 +SimpleTest.waitForExplicitFinish(); 1.52 +var expand = SpecialPowers.Cu.import("resource://gre/modules/PermissionsTable.jsm").expandPermissions; 1.53 +const permTable = SpecialPowers.Cu.import("resource://gre/modules/PermissionsTable.jsm").PermissionsTable; 1.54 + 1.55 +const TEST_DOMAIN = "http://example.org"; 1.56 +const SHIM_PATH = "/tests/dom/permission/tests/file_shim.html" 1.57 +var gContent = document.getElementById('content'); 1.58 + 1.59 +//var gData; defined in external files 1.60 +var gCurrentTest = 0; 1.61 +var gRemainingTests; 1.62 +var pendingTests = {}; 1.63 + 1.64 +function PermTest(aData) { 1.65 + var self = this; 1.66 + var skip = aData.skip || false; 1.67 + this.step = 0; 1.68 + this.data = aData; 1.69 + this.isSkip = skip && 1.70 + skip.some(function (el) { 1.71 + return navigator. 1.72 + userAgent.toLowerCase(). 1.73 + indexOf(el.toLowerCase()) != -1; 1.74 + }); 1.75 + 1.76 + this.setupParent = false; 1.77 + this.perms = expandPermissions(aData.perm); 1.78 + this.id = gCurrentTest++; 1.79 + this.iframe = null; 1.80 + 1.81 + // keep a reference to this for eventhandler 1.82 + pendingTests[this.id] = this; 1.83 + 1.84 + this.createFrame = function() { 1.85 + if (self.iframe) { 1.86 + gContent.removeChild(self.iframe); 1.87 + } 1.88 + var iframe = document.createElement('iframe'); 1.89 + iframe.setAttribute('id', 'testframe' + self.step + self.perms) 1.90 + iframe.setAttribute('remote', true); 1.91 + iframe.src = TEST_DOMAIN + SHIM_PATH; 1.92 + iframe.addEventListener('load', function _iframeLoad() { 1.93 + iframe.removeEventListener('load', _iframeLoad); 1.94 + 1.95 + // check permissions are correct 1.96 + var allow = (self.step == 0 ? false : true); 1.97 + self.perms.forEach(function (el) { 1.98 + try { 1.99 + var res = SpecialPowers.hasPermission(el, SpecialPowers.wrap(iframe) 1.100 + .contentDocument); 1.101 + is(res, allow, (allow ? "Has " : "Doesn't have ") + el); 1.102 + } catch(e) { 1.103 + ok(false, "failed " + e); 1.104 + } 1.105 + }); 1.106 + 1.107 + var msg = { 1.108 + id: self.id, 1.109 + step: self.step++, 1.110 + testdata: self.data, 1.111 + } 1.112 + // start the tests 1.113 + iframe.contentWindow.postMessage(msg, "*"); 1.114 + }); 1.115 + 1.116 + self.iframe = iframe; 1.117 + gContent.appendChild(iframe); 1.118 + } 1.119 + 1.120 + this.next = function () { 1.121 + switch(self.step) { 1.122 + case 0: 1.123 + self.createFrame(); 1.124 + break; 1.125 + case 1: 1.126 + // add permissions 1.127 + addPermissions(self.perms, SpecialPowers. 1.128 + wrap(self.iframe). 1.129 + contentDocument, 1.130 + self.createFrame.bind(self)); 1.131 + break; 1.132 + case 2: 1.133 + if (self.iframe) { 1.134 + gContent.removeChild(self.iframe); 1.135 + } 1.136 + checkFinish(); 1.137 + break; 1.138 + default: 1.139 + ok(false, "Should not be reached"); 1.140 + break 1.141 + } 1.142 + } 1.143 + 1.144 + this.start = function() { 1.145 + // some permissions need parent to have permission as well 1.146 + if (!self.setupParent && self.data.needParentPerm && 1.147 + !SpecialPowers.isMainProcess()) { 1.148 + self.setupParent = true; 1.149 + addPermissions(self.perms, window.document, self.start.bind(self)); 1.150 + } else if (self.data.settings && self.data.settings.length) { 1.151 + SpecialPowers.pushPrefEnv({'set': self.data.settings.slice(0)}, 1.152 + self.next.bind(self)); 1.153 + } else { 1.154 + self.next(); 1.155 + } 1.156 + } 1.157 +} 1.158 + 1.159 +function addPermissions(aPerms, aDoc, aCallback) { 1.160 + var permList = []; 1.161 + aPerms.forEach(function (el) { 1.162 + var obj = {'type': el, 1.163 + 'allow': 1, 1.164 + 'context': aDoc}; 1.165 + permList.push(obj); 1.166 + }); 1.167 + SpecialPowers.pushPermissions(permList, aCallback); 1.168 +} 1.169 + 1.170 +function expandPermissions(aPerms) { 1.171 + var perms = []; 1.172 + aPerms.forEach(function(el) { 1.173 + var access = permTable[el].access ? "readwrite" : null; 1.174 + var expanded = SpecialPowers.unwrap(expand(el, access)); 1.175 + // COW arrays don't behave array-like enough, to allow 1.176 + // using expanded.slice(0) here. 1.177 + for (let i = 0; i < expanded.length; i++) { 1.178 + perms.push(expanded[i]); 1.179 + } 1.180 + }); 1.181 + 1.182 + return perms; 1.183 +} 1.184 + 1.185 +function msgHandler(evt) { 1.186 + var data = evt.data; 1.187 + var test = pendingTests[data.id]; 1.188 + 1.189 + /* 1.190 + * step 2 of tests should fail on 1.191 + * platforms which are skipped 1.192 + */ 1.193 + if (test.isSkip && test.step == 2) { 1.194 + todo(data.result, data.msg); 1.195 + } else { 1.196 + ok(data.result, data.msg); 1.197 + } 1.198 + 1.199 + if (test) { 1.200 + test.next(); 1.201 + } else { 1.202 + ok(false, "Received unknown id " + data.id); 1.203 + checkFinish(); 1.204 + } 1.205 +} 1.206 + 1.207 +function checkFinish() { 1.208 + if (--gRemainingTests) { 1.209 + gTestRunner.next(); 1.210 + } else { 1.211 + window.removeEventListener('message', msgHandler); 1.212 + SimpleTest.finish(); 1.213 + } 1.214 +} 1.215 + 1.216 +function runTest() { 1.217 + gRemainingTests = Object.keys(gData).length; 1.218 + 1.219 + for (var test in gData) { 1.220 + var test = new PermTest(gData[test]); 1.221 + test.start(); 1.222 + yield undefined; 1.223 + } 1.224 +} 1.225 + 1.226 +var gTestRunner = runTest(); 1.227 + 1.228 +window.addEventListener('load', function() { gTestRunner.next(); }, false); 1.229 +window.addEventListener('message', msgHandler, false);