dom/permission/tests/file_framework.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /** Test for Bug 815105 **/
     2 /*
     3  * gData is an array of object that tests using this framework must pass in
     4  * The current tests only pass in a single element array. Each test in
     5  * gData is executed by the framework for a given file
     6  *
     7  * Fields in gData object
     8  * perms   (required) Array of Strings
     9  *         list of permissions that this test will need. See
    10  *         http://mxr.mozilla.org/mozilla-central/source/dom/apps/src/PermissionsTable.jsm
    11  *         These permissions are added after a sanity check and removed at
    12  *         test conclusion
    13  *
    14  * obj     (required for default verifier) String
    15  *         The name of the window.navigator object used for accessing the
    16  *         WebAPI during the tests
    17  *
    18  * webidl  (required for default verifier) String
    19  * idl     (required for default verifier) String
    20  *         Only one of webidl / idl is required
    21  *         The IDL describing the navigator object. The returned object
    22  *         during tests /must/ be an instanceof this
    23  *
    24  * skip    (optional) Array of Strings
    25  *         A list of navigator.userAgent's to skip the second part of tests
    26  *         on. The tests still verify that you can't get obj on those
    27  *         platforms without permissions, however it is expected that adding
    28  *         the permission still won't allow access to those objects
    29  *
    30  * settings (optional) Array of preference tuples
    31  *         A list of settings that need to be set before this API is
    32  *         enabled. Note the settings are set before the sanity check is
    33  *         performed. If an API gates access only by preferences, then it
    34  *         will fail the initial test
    35  *
    36  * verifier (optional) Function
    37  *         A function used to test whether a WebAPI is accessible or not.
    38  *         The function takes a success and failure callback which both
    39  *         accept a msg argument. msg is surfaced up to the top level tests
    40  *         A default verifier is provided which only attempts to access
    41  *         the navigator object.
    42  *
    43  * needParentPerm (optional) Boolean
    44  *         Whether or not the parent frame requires these permissions as
    45  *         well. Otherwise the test process may be killed.
    46  */
    48 SimpleTest.waitForExplicitFinish();
    49 var expand = SpecialPowers.Cu.import("resource://gre/modules/PermissionsTable.jsm").expandPermissions;
    50 const permTable = SpecialPowers.Cu.import("resource://gre/modules/PermissionsTable.jsm").PermissionsTable;
    52 const TEST_DOMAIN = "http://example.org";
    53 const SHIM_PATH = "/tests/dom/permission/tests/file_shim.html"
    54 var gContent = document.getElementById('content');
    56 //var gData; defined in external files
    57 var gCurrentTest = 0;
    58 var gRemainingTests;
    59 var pendingTests = {};
    61 function PermTest(aData) {
    62   var self = this;
    63   var skip = aData.skip || false;
    64   this.step = 0;
    65   this.data = aData;
    66   this.isSkip = skip &&
    67                 skip.some(function (el) {
    68                           return navigator.
    69                                  userAgent.toLowerCase().
    70                                  indexOf(el.toLowerCase()) != -1;
    71                         });
    73   this.setupParent = false;
    74   this.perms = expandPermissions(aData.perm);
    75   this.id = gCurrentTest++;
    76   this.iframe = null;
    78   // keep a reference to this for eventhandler
    79   pendingTests[this.id] = this;
    81   this.createFrame = function() {
    82     if (self.iframe) {
    83       gContent.removeChild(self.iframe);
    84     }
    85     var iframe = document.createElement('iframe');
    86     iframe.setAttribute('id', 'testframe' + self.step + self.perms)
    87     iframe.setAttribute('remote', true);
    88     iframe.src = TEST_DOMAIN + SHIM_PATH;
    89     iframe.addEventListener('load', function _iframeLoad() {
    90       iframe.removeEventListener('load', _iframeLoad);
    92       // check permissions are correct
    93       var allow = (self.step == 0 ? false : true);
    94       self.perms.forEach(function (el) {
    95         try {
    96         var res = SpecialPowers.hasPermission(el, SpecialPowers.wrap(iframe)
    97                                                   .contentDocument);
    98         is(res, allow, (allow ? "Has " : "Doesn't have ") + el);
    99         } catch(e) {
   100           ok(false, "failed " + e);
   101         }
   102       });
   104       var msg = {
   105         id: self.id,
   106         step: self.step++,
   107         testdata: self.data,
   108       }
   109       // start the tests
   110       iframe.contentWindow.postMessage(msg, "*");
   111     });
   113     self.iframe = iframe;
   114     gContent.appendChild(iframe);
   115   }
   117   this.next = function () {
   118     switch(self.step) {
   119     case 0:
   120       self.createFrame();
   121     break;
   122     case 1:
   123       // add permissions
   124       addPermissions(self.perms, SpecialPowers.
   125                                  wrap(self.iframe).
   126                                  contentDocument,
   127                      self.createFrame.bind(self));
   128     break;
   129     case 2:
   130       if (self.iframe) {
   131         gContent.removeChild(self.iframe);
   132       }
   133       checkFinish();
   134     break;
   135     default:
   136       ok(false, "Should not be reached");
   137     break
   138     }
   139   }
   141   this.start = function() {
   142     // some permissions need parent to have permission as well
   143     if (!self.setupParent && self.data.needParentPerm &&
   144         !SpecialPowers.isMainProcess()) {
   145       self.setupParent = true;
   146       addPermissions(self.perms, window.document, self.start.bind(self));
   147     } else if (self.data.settings && self.data.settings.length) {
   148       SpecialPowers.pushPrefEnv({'set': self.data.settings.slice(0)},
   149                                 self.next.bind(self));
   150     } else {
   151       self.next();
   152     }
   153   }
   154 }
   156 function addPermissions(aPerms, aDoc, aCallback) {
   157   var permList = [];
   158   aPerms.forEach(function (el) {
   159     var obj = {'type': el,
   160                'allow': 1,
   161                'context': aDoc};
   162     permList.push(obj);
   163   });
   164   SpecialPowers.pushPermissions(permList, aCallback);
   165 }
   167 function expandPermissions(aPerms) {
   168   var perms = [];
   169   aPerms.forEach(function(el) {
   170     var access = permTable[el].access ? "readwrite" : null;
   171     var expanded = SpecialPowers.unwrap(expand(el, access));
   172     // COW arrays don't behave array-like enough, to allow
   173     // using expanded.slice(0) here.
   174     for (let i = 0; i < expanded.length; i++) {
   175       perms.push(expanded[i]);
   176     }
   177   });
   179   return perms;
   180 }
   182 function msgHandler(evt) {
   183   var data = evt.data;
   184   var test = pendingTests[data.id];
   186   /*
   187    * step 2 of tests should fail on
   188    * platforms which are skipped
   189    */
   190   if (test.isSkip && test.step == 2) {
   191     todo(data.result, data.msg);
   192   } else {
   193     ok(data.result, data.msg);
   194   }
   196   if (test) {
   197     test.next();
   198   } else {
   199     ok(false, "Received unknown id " + data.id);
   200     checkFinish();
   201   }
   202 }
   204 function checkFinish() {
   205   if (--gRemainingTests) {
   206     gTestRunner.next();
   207   } else {
   208     window.removeEventListener('message', msgHandler);
   209     SimpleTest.finish();
   210   }
   211 }
   213 function runTest() {
   214   gRemainingTests = Object.keys(gData).length;
   216   for (var test in gData) {
   217     var test = new PermTest(gData[test]);
   218     test.start();
   219     yield undefined;
   220   }
   221 }
   223 var gTestRunner = runTest();
   225 window.addEventListener('load', function() { gTestRunner.next(); }, false);
   226 window.addEventListener('message', msgHandler, false);

mercurial