gecko-dev/dom/permission/tests/file_framework.js

227 lines
6.9 KiB
JavaScript
Raw Normal View History

/** Test for Bug 815105 **/
/*
* gData is an array of object that tests using this framework must pass in
* The current tests only pass in a single element array. Each test in
* gData is executed by the framework for a given file
*
* Fields in gData object
* perms (required) Array of Strings
* list of permissions that this test will need. See
* http://mxr.mozilla.org/mozilla-central/source/dom/apps/src/PermissionsTable.jsm
* These permissions are added after a sanity check and removed at
* test conclusion
*
* obj (required for default verifier) String
* The name of the window.navigator object used for accessing the
* WebAPI during the tests
*
* webidl (required for default verifier) String
* idl (required for default verifier) String
* Only one of webidl / idl is required
* The IDL describing the navigator object. The returned object
* during tests /must/ be an instanceof this
*
* skip (optional) Array of Strings
* A list of navigator.userAgent's to skip the second part of tests
* on. The tests still verify that you can't get obj on those
* platforms without permissions, however it is expected that adding
* the permission still won't allow access to those objects
*
* settings (optional) Array of preference tuples
* A list of settings that need to be set before this API is
* enabled. Note the settings are set before the sanity check is
* performed. If an API gates access only by preferences, then it
* will fail the initial test
*
* verifier (optional) Function
* A function used to test whether a WebAPI is accessible or not.
* The function takes a success and failure callback which both
* accept a msg argument. msg is surfaced up to the top level tests
* A default verifier is provided which only attempts to access
* the navigator object.
*
* needParentPerm (optional) Boolean
* Whether or not the parent frame requires these permissions as
* well. Otherwise the test process may be killed.
*/
SimpleTest.waitForExplicitFinish();
var expand = SpecialPowers.Cu.import("resource://gre/modules/PermissionsTable.jsm").expandPermissions;
const permTable = SpecialPowers.Cu.import("resource://gre/modules/PermissionsTable.jsm").PermissionsTable;
const TEST_DOMAIN = "http://example.org";
const SHIM_PATH = "/tests/dom/permission/tests/file_shim.html"
var gContent = document.getElementById('content');
//var gData; defined in external files
var gCurrentTest = 0;
var gRemainingTests;
var pendingTests = {};
function PermTest(aData) {
var self = this;
var skip = aData.skip || false;
this.step = 0;
this.data = aData;
this.isSkip = skip &&
skip.some(function (el) {
return navigator.
userAgent.toLowerCase().
indexOf(el.toLowerCase()) != -1;
});
this.setupParent = false;
this.perms = expandPermissions(aData.perm);
this.id = gCurrentTest++;
this.iframe = null;
// keep a reference to this for eventhandler
pendingTests[this.id] = this;
this.createFrame = function() {
if (self.iframe) {
gContent.removeChild(self.iframe);
}
var iframe = document.createElement('iframe');
iframe.setAttribute('id', 'testframe' + self.step + self.perms)
iframe.setAttribute('remote', true);
iframe.src = TEST_DOMAIN + SHIM_PATH;
iframe.addEventListener('load', function _iframeLoad() {
iframe.removeEventListener('load', _iframeLoad);
// check permissions are correct
var allow = (self.step == 0 ? false : true);
self.perms.forEach(function (el) {
try {
var res = SpecialPowers.hasPermission(el, SpecialPowers.wrap(iframe)
.contentDocument);
is(res, allow, (allow ? "Has " : "Doesn't have ") + el);
} catch(e) {
ok(false, "failed " + e);
}
});
var msg = {
id: self.id,
step: self.step++,
testdata: self.data,
}
// start the tests
iframe.contentWindow.postMessage(msg, "*");
});
self.iframe = iframe;
gContent.appendChild(iframe);
}
this.next = function () {
switch(self.step) {
case 0:
self.createFrame();
break;
case 1:
// add permissions
addPermissions(self.perms, SpecialPowers.
wrap(self.iframe).
contentDocument,
self.createFrame.bind(self));
break;
case 2:
if (self.iframe) {
gContent.removeChild(self.iframe);
}
checkFinish();
break;
default:
ok(false, "Should not be reached");
break
}
}
this.start = function() {
// some permissions need parent to have permission as well
if (!self.setupParent && self.data.needParentPerm &&
!SpecialPowers.isMainProcess()) {
self.setupParent = true;
addPermissions(self.perms, window.document, self.start.bind(self));
} else if (self.data.settings && self.data.settings.length) {
SpecialPowers.pushPrefEnv({'set': self.data.settings.slice(0)},
self.next.bind(self));
} else {
self.next();
}
}
}
function addPermissions(aPerms, aDoc, aCallback) {
var permList = [];
aPerms.forEach(function (el) {
var obj = {'type': el,
'allow': 1,
'context': aDoc};
permList.push(obj);
});
SpecialPowers.pushPermissions(permList, aCallback);
}
function expandPermissions(aPerms) {
var perms = [];
aPerms.forEach(function(el) {
var access = permTable[el].access ? "readwrite" : null;
var expanded = SpecialPowers.unwrap(expand(el, access));
// COW arrays don't behave array-like enough, to allow
// using expanded.slice(0) here.
for (let i = 0; i < expanded.length; i++) {
perms.push(expanded[i]);
}
});
return perms;
}
function msgHandler(evt) {
var data = evt.data;
var test = pendingTests[data.id];
/*
* step 2 of tests should fail on
* platforms which are skipped
*/
if (test.isSkip && test.step == 2) {
todo(data.result, data.msg);
} else {
ok(data.result, data.msg);
}
if (test) {
test.next();
} else {
ok(false, "Received unknown id " + data.id);
checkFinish();
}
}
function checkFinish() {
if (--gRemainingTests) {
gTestRunner.next();
} else {
window.removeEventListener('message', msgHandler);
SimpleTest.finish();
}
}
function runTest() {
gRemainingTests = Object.keys(gData).length;
for (var test in gData) {
var test = new PermTest(gData[test]);
test.start();
yield undefined;
}
}
var gTestRunner = runTest();
window.addEventListener('load', function() { gTestRunner.next(); }, false);
window.addEventListener('message', msgHandler, false);