file_framework.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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://dxr.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. */
  47. SimpleTest.waitForExplicitFinish();
  48. var expand = SpecialPowers.Cu.import("resource://gre/modules/PermissionsTable.jsm").expandPermissions;
  49. const permTable = SpecialPowers.Cu.import("resource://gre/modules/PermissionsTable.jsm").PermissionsTable;
  50. const TEST_DOMAIN = "http://example.org";
  51. const SHIM_PATH = "/tests/dom/permission/tests/file_shim.html"
  52. var gContent = document.getElementById('content');
  53. //var gData; defined in external files
  54. var gCurrentTest = 0;
  55. var gRemainingTests;
  56. var pendingTests = {};
  57. function PermTest(aData) {
  58. var self = this;
  59. var skip = aData.skip || false;
  60. this.step = 0;
  61. this.data = aData;
  62. this.isSkip = skip &&
  63. skip.some(function (el) {
  64. return navigator.
  65. userAgent.toLowerCase().
  66. indexOf(el.toLowerCase()) != -1;
  67. });
  68. this.setupParent = false;
  69. this.perms = expandPermissions(aData.perm);
  70. this.id = gCurrentTest++;
  71. this.iframe = null;
  72. // keep a reference to this for eventhandler
  73. pendingTests[this.id] = this;
  74. this.createFrame = function() {
  75. if (self.iframe) {
  76. gContent.removeChild(self.iframe);
  77. }
  78. var iframe = document.createElement('iframe');
  79. iframe.setAttribute('id', 'testframe' + self.step + self.perms)
  80. iframe.setAttribute('remote', true);
  81. iframe.src = TEST_DOMAIN + SHIM_PATH;
  82. iframe.addEventListener('load', function _iframeLoad() {
  83. iframe.removeEventListener('load', _iframeLoad);
  84. // check permissions are correct
  85. var allow = (self.step == 0 ? false : true);
  86. self.perms.forEach(function (el) {
  87. try {
  88. var res = SpecialPowers.hasPermission(el, SpecialPowers.wrap(iframe)
  89. .contentDocument);
  90. is(res, allow, (allow ? "Has " : "Doesn't have ") + el);
  91. } catch(e) {
  92. ok(false, "failed " + e);
  93. }
  94. });
  95. var msg = {
  96. id: self.id,
  97. step: self.step++,
  98. testdata: self.data,
  99. }
  100. // start the tests
  101. iframe.contentWindow.postMessage(msg, "*");
  102. });
  103. self.iframe = iframe;
  104. gContent.appendChild(iframe);
  105. }
  106. this.next = function () {
  107. switch(self.step) {
  108. case 0:
  109. self.createFrame();
  110. break;
  111. case 1:
  112. // add permissions
  113. addPermissions(self.perms, SpecialPowers.
  114. wrap(self.iframe).
  115. contentDocument,
  116. self.createFrame.bind(self));
  117. break;
  118. case 2:
  119. if (self.iframe) {
  120. gContent.removeChild(self.iframe);
  121. }
  122. checkFinish();
  123. break;
  124. default:
  125. ok(false, "Should not be reached");
  126. break
  127. }
  128. }
  129. this.start = function() {
  130. // some permissions need parent to have permission as well
  131. if (!self.setupParent && self.data.needParentPerm &&
  132. !SpecialPowers.isMainProcess()) {
  133. self.setupParent = true;
  134. addPermissions(self.perms, window.document, self.start.bind(self));
  135. } else if (self.data.settings && self.data.settings.length) {
  136. SpecialPowers.pushPrefEnv({'set': self.data.settings.slice(0)},
  137. self.next.bind(self));
  138. } else {
  139. self.next();
  140. }
  141. }
  142. }
  143. function addPermissions(aPerms, aDoc, aCallback) {
  144. var permList = [];
  145. aPerms.forEach(function (el) {
  146. var obj = {'type': el,
  147. 'allow': 1,
  148. 'context': aDoc};
  149. permList.push(obj);
  150. });
  151. SpecialPowers.pushPermissions(permList, aCallback);
  152. }
  153. function expandPermissions(aPerms) {
  154. var perms = [];
  155. aPerms.forEach(function(el) {
  156. var access = permTable[el].access ? "readwrite" : null;
  157. var expanded = expand(el, access);
  158. for (let i = 0; i < expanded.length; i++) {
  159. perms.push(SpecialPowers.unwrap(expanded[i]));
  160. }
  161. });
  162. return perms;
  163. }
  164. function msgHandler(evt) {
  165. var data = evt.data;
  166. var test = pendingTests[data.id];
  167. /*
  168. * step 2 of tests should fail on
  169. * platforms which are skipped
  170. */
  171. if (test.isSkip && test.step == 2) {
  172. todo(data.result, data.msg);
  173. } else {
  174. ok(data.result, data.msg);
  175. }
  176. if (test) {
  177. test.next();
  178. } else {
  179. ok(false, "Received unknown id " + data.id);
  180. checkFinish();
  181. }
  182. }
  183. function checkFinish() {
  184. if (--gRemainingTests) {
  185. gTestRunner.next();
  186. } else {
  187. window.removeEventListener('message', msgHandler);
  188. SimpleTest.finish();
  189. }
  190. }
  191. function runTest() {
  192. gRemainingTests = Object.keys(gData).length;
  193. for (var test in gData) {
  194. var test = new PermTest(gData[test]);
  195. test.start();
  196. yield undefined;
  197. }
  198. }
  199. var gTestRunner = runTest();
  200. window.addEventListener('load', function() { gTestRunner.next(); }, false);
  201. window.addEventListener('message', msgHandler, false);