Bug 1174913 - anchor and area mochitests. r=bz
authorFranziskus Kiefer <franziskuskiefer@gmail.com>
Thu, 18 Jun 2015 09:01:27 -0700
changeset 253863 339a34e9a135
parent 253862 c55086289922
child 253864 8b4de2466c80
push id29081
push usercbook@mozilla.com
push dateTue, 21 Jul 2015 14:57:20 +0000
treeherdermozilla-central@512c7e8f0030 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1174913
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1174913 - anchor and area mochitests. r=bz
dom/base/test/mochitest.ini
dom/base/test/referrer_helper.js
dom/base/test/referrer_testserver.sjs
dom/base/test/test_anchor_area_referrer.html
dom/base/test/test_anchor_area_referrer_changing.html
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -235,16 +235,18 @@ support-files =
   wholeTexty-helper.xml
   file_nonascii_blob_url.html
   referrerHelper.js
   test_performance_user_timing.js
   img_referrer_testserver.sjs
   file_audioLoop.html
   file_webaudioLoop.html
   file_webaudioLoop2.html
+  referrer_helper.js
+  referrer_testserver.sjs
 
 [test_anonymousContent_api.html]
 [test_anonymousContent_append_after_reflow.html]
 [test_anonymousContent_insert.html]
 [test_anonymousContent_manipulate_content.html]
 [test_appname_override.html]
 [test_audioWindowUtils.html]
 [test_audioNotification.html]
@@ -667,16 +669,18 @@ skip-if = buildapp == 'mulet' || buildap
 [test_bug1070015.html]
 [test_bug1101364.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android'
 [test_bug1163743.html]
 support-files = referrerHelper.js
 [test_bug1165501.html]
 support-files = referrerHelper.js
 [test_img_referrer.html]
+[test_anchor_area_referrer.html]
+[test_anchor_area_referrer_changing.html]
 [test_caretPositionFromPoint.html]
 [test_classList.html]
 # This test fails on the Mac for some reason
 [test_copyimage.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || toolkit != 'gtk2' && toolkit != 'gtk3' && toolkit != 'windows' || e10s #b2g-desktop(Bug 931116, b2g desktop specific, initial triage)
 [test_copypaste.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s #bug 904183 # b2g(clipboard undefined) b2g-debug(clipboard undefined) b2g-desktop(clipboard undefined)
 [test_copypaste.xhtml]
new file mode 100644
--- /dev/null
+++ b/dom/base/test/referrer_helper.js
@@ -0,0 +1,98 @@
+/*
+ * common functionality for iframe, anchor, and area referrer attribute tests
+ */
+const GET_RESULT = sjs + 'action=get-test-results';
+const RESET_STATE = sjs + 'action=resetState';
+
+SimpleTest.waitForExplicitFinish();
+var advance = function() { tests.next(); };
+
+/**
+ * Listen for notifications from the child.
+ * These are sent in case of error, or when the loads we await have completed.
+ */
+window.addEventListener("message", function(event) {
+  if (event.data == "childLoadComplete") {
+    // all loads happen, continue the test.
+    advance();
+  }
+});
+
+/**
+ * helper to perform an XHR
+ * to do checkIndividualResults and resetState
+ */
+function doXHR(aUrl, onSuccess, onFail) {
+  var xhr = new XMLHttpRequest();
+  xhr.responseType = "json";
+  xhr.onload = function () {
+    onSuccess(xhr);
+  };
+  xhr.onerror = function () {
+    onFail(xhr);
+  };
+  xhr.open('GET', aUrl, true);
+  xhr.send(null);
+}
+
+/**
+ * Grabs the results via XHR and passes to checker.
+ */
+function checkIndividualResults(aTestname, aExpectedReferrer, aName) {
+  var onload = xhr => {
+    var results = xhr.response;
+    info(JSON.stringify(xhr.response));
+    ok(aName in results, aName + " tests have to be performed.");
+    is(results[aName].policy, aExpectedReferrer, aTestname + ' --- ' + results[aName].policy + ' (' + results[aName].referrer + ')');
+    advance();
+  };
+  var onerror = xhr => {
+    ok(false, "Can't get results from the counter server.");
+    SimpleTest.finish();
+  };
+  doXHR(GET_RESULT, onload, onerror);
+}
+
+function resetState() {
+  doXHR(RESET_STATE,
+    advance,
+    function(xhr) {
+      ok(false, "error in reset state");
+      SimpleTest.finish();
+    });
+}
+
+/**
+ * testing if anchor and area referrer attributes are honoured (1174913)
+ */
+var tests = (function() {
+
+  // enable referrer attribute
+  yield SpecialPowers.pushPrefEnv({"set": [['network.http.enablePerElementReferrer', true]]}, advance);
+
+  var iframe = document.getElementById("testframe");
+
+  for (var j = 0; j < testCases.length; j++) {
+    var actions = testCases[j].ACTION;
+    var tests = testCases[j].TESTS;
+    for (var k = 0; k < actions.length; k++) {
+      var actionString = actions[k];
+      for (var i = 0; i < tests.length; i++) {
+        yield resetState();
+        var searchParams = new URLSearchParams();
+        searchParams.append(ACTION, actionString);
+        searchParams.append(NAME, tests[i].NAME);
+        for (var l of PARAMS) {
+          if (tests[i][l]) {
+            searchParams.append(window[l], tests[i][l]);
+          }
+        }
+        yield iframe.src = sjs + searchParams.toString();
+        yield checkIndividualResults(tests[i].DESC, tests[i].RESULT, tests[i].NAME);
+      };
+    };
+  };
+
+  // complete.  Be sure to yield so we don't call this twice.
+  yield SimpleTest.finish();
+})();
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/base/test/referrer_testserver.sjs
@@ -0,0 +1,180 @@
+/*
+* Test server for iframe, anchor, and area referrer attributes.
+* https://bugzilla.mozilla.org/show_bug.cgi?id=1175736
+*/
+
+Components.utils.importGlobalProperties(["URLSearchParams"]);
+const BASE_URL = 'example.com/tests/dom/base/test/referrer_testserver.sjs';
+const SHARED_KEY = 'referrer_testserver.sjs';
+const ATTRIBUTE_POLICY = 'attributePolicy';
+const NEW_ATTRIBUTE_POLICY = 'newAttributePolicy';
+const NAME = 'name';
+const META_POLICY = 'metaPolicy';
+const REL = 'rel';
+
+function createTestUrl(aPolicy, aAction, aName, aType) {
+  return 'http://' + BASE_URL + '?' +
+         'action=' + aAction + '&' +
+         'policy=' + aPolicy + '&' +
+         'name=' + aName + '&' +
+         'type=' + aType;
+}
+
+function buildAnchorString(aMetaPolicy, aReferrerPolicy, aName, aRelString){
+  if (aReferrerPolicy) {
+    return `<a href="${createTestUrl(aReferrerPolicy, 'test', aName, 'link')}" referrer="${aReferrerPolicy}" id="link" ${aRelString}>${aReferrerPolicy}</a>`;
+  }
+  return `<a href="${createTestUrl(aMetaPolicy, 'test', aName, 'link')}" id="link" ${aRelString}>link</a>`;
+}
+
+function buildAreaString(aMetaPolicy, aReferrerPolicy, aName, aRelString){
+  var result = `<img src="file_mozfiledataurl_img.jpg" alt="image" usemap="#imageMap">`;
+  result += `<map name="imageMap">`;
+  if (aReferrerPolicy) {
+    result += `<area shape="circle" coords="1,1,1" href="${createTestUrl(aReferrerPolicy, 'test', aName, 'link')}" alt="theArea" referrer="${aReferrerPolicy}" id="link" ${aRelString}>`;
+  } else {
+    result += `<area shape="circle" coords="1,1,1" href="${createTestUrl(aMetaPolicy, 'test', aName, 'link')}" alt="theArea" id="link" ${aRelString}>`;
+  }
+  result += `</map>`;
+
+  return result;
+}
+
+// test page using anchor or area referrer attribute
+function createAETestPageUsingRefferer(aMetaPolicy, aAttributePolicy, aNewAttributePolicy, aName, aRel, aStringBuilder, aChangingMethod) {
+  var metaString = '';
+  if (aMetaPolicy) {
+    metaString = '<head><meta name="referrer" content="' + aMetaPolicy + '"></head>';
+  }
+  var changeString = '';
+  if (aChangingMethod === 'setAttribute') {
+    changeString = `document.getElementById("link").setAttribute("referrer", "${aNewAttributePolicy}")`;
+  } else if (aChangingMethod === 'property') {
+    changeString = `document.getElementById("link").referrer = "${aNewAttributePolicy}"`;
+  }
+  var relString = '';
+  if (aRel) {
+    relString = `rel="noreferrer"`;
+  }
+  var elementString = aStringBuilder(aMetaPolicy, aAttributePolicy, aName, relString);
+
+  return `<!DOCTYPE HTML>
+           <html>
+             ${metaString}
+             <body>
+               ${elementString}
+               <script>
+                 window.addEventListener("load", function() {
+                   ${changeString}
+                   document.getElementById("link").click();
+                 }.bind(window), false);
+               </script>
+             </body>
+           </html>`;
+}
+
+function handleRequest(request, response) {
+  var params = new URLSearchParams(request.queryString);
+  var action = params.get('action');
+
+  response.setHeader('Cache-Control', 'no-cache', false);
+  response.setHeader('Content-Type', 'text/html; charset=utf-8', false);
+
+  if (action === 'resetState') {
+    setSharedState(SHARED_KEY, "{}");
+    response.write("");
+    return;
+  }
+  if (action === 'get-test-results') {
+    // ?action=get-result
+    response.setHeader('Cache-Control', 'no-cache', false);
+    response.setHeader('Content-Type', 'text/plain', false);
+    response.write(getSharedState(SHARED_KEY));
+    return;
+  }
+  if (action === 'redirect') {
+    response.write('<script>parent.postMessage("childLoadComplete", "http://mochi.test:8888");</script>');
+    return;
+  }
+  if (action === 'test') {
+    // ?action=test&policy=origin&name=name
+    var policy = params.get('policy');
+    var name = params.get('name');
+    var type = params.get('type');
+    var result = getSharedState(SHARED_KEY);
+
+    result = result ? JSON.parse(result) : {};
+
+    var referrerLevel = "none";
+    var test = {}
+    if (request.hasHeader('Referer')) {
+      var referrer = request.getHeader("Referer");
+      if (referrer.indexOf("referrer_testserver") > 0) {
+        referrerLevel = "full";
+      } else if (referrer.indexOf("http://mochi.test:8888") == 0) {
+        referrerLevel = "origin";
+      } else {
+        // this is never supposed to happen
+        referrerLevel = "other-origin";
+      }
+      test.referrer = referrer;
+    } else {
+      test.referrer = '';
+    }
+    test.policy = referrerLevel;
+    test.expected = policy;
+
+    result[name] = test;
+
+    setSharedState(SHARED_KEY, JSON.stringify(result));
+
+    if (type === "link") {
+      // forward link click to redirect URL to finish test
+      var loc = "http://" + BASE_URL + "?action=redirect";
+      response.setStatusLine('1.1', 302, 'Found');
+      response.setHeader('Location', loc, false);
+    }
+    return;
+  }
+
+  // parse test arguments and start test
+  var attributePolicy = params.get(ATTRIBUTE_POLICY) || '';
+  var newAttributePolicy = params.get(NEW_ATTRIBUTE_POLICY) || '';
+  var metaPolicy = params.get(META_POLICY) || '';
+  var rel = params.get(REL) || '';
+  var name = params.get(NAME);
+
+  // anchor & area
+  var _getPage = createAETestPageUsingRefferer.bind(null, metaPolicy, attributePolicy, newAttributePolicy, name, rel);
+  var _getAnchorPage = _getPage.bind(null, buildAnchorString);
+  var _getAreaPage = _getPage.bind(null, buildAreaString);
+
+  // aMetaPolicy, aAttributePolicy, aNewAttributePolicy, aName, aChangingMethod, aStringBuilder
+  if (action === 'generate-anchor-policy-test') {
+    response.write(_getAnchorPage());
+    return;
+  }
+  if (action === 'generate-anchor-changing-policy-test-set-attribute') {
+    response.write(_getAnchorPage('setAttribute'));
+    return;
+  }
+  if (action === 'generate-anchor-changing-policy-test-property') {
+    response.write(_getAnchorPage('property'));
+    return;
+  }
+  if (action === 'generate-area-policy-test') {
+    response.write(_getAreaPage());
+    return;
+  }
+  if (action === 'generate-area-changing-policy-test-set-attribute') {
+    response.write(_getAreaPage('setAttribute'));
+    return;
+  }
+  if (action === 'generate-area-changing-policy-test-property') {
+    response.write(_getAreaPage('property'));
+    return;
+  }
+
+  response.write("I don't know action " + action);
+  return;
+}
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_anchor_area_referrer.html
@@ -0,0 +1,116 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test anchor and area policy attribute for Bug 1174913</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+  <!--
+  Testing that anchor and area referrer attributes are honoured correctly
+  * anchor tag with referrer attribute (generate-anchor-policy-test)
+  * regression tests that meta referrer is still working even if attribute referrers are enabled (generate-anchor-policy-test)
+  https://bugzilla.mozilla.org/show_bug.cgi?id=1174913
+  -->
+
+  <script type="application/javascript;version=1.8">
+
+  const sjs = "/tests/dom/base/test/referrer_testserver.sjs?";
+  const ATTRIBUTE_POLICY = 'attributePolicy';
+  const NEW_ATTRIBUTE_POLICY = 'newAttributePolicy';
+  const NAME = 'name';
+  const META_POLICY = 'metaPolicy';
+  const DESC = 'description';
+  const RESULT = 'result';
+  const ACTION = 'action';
+  const TESTS = 'tests';
+  const REL = 'rel';
+  const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY", "REL"];
+
+  const testCases = [
+    {ACTION: ["generate-anchor-policy-test", "generate-area-policy-test"],
+      TESTS: [
+        {ATTRIBUTE_POLICY: 'unsafe-url',
+         NAME: 'unsafe-url-with-origin-in-meta',
+         META_POLICY: 'origin',
+         DESC: "unsafe-url (anchor) with origin in meta",
+         RESULT: 'full'},
+        {ATTRIBUTE_POLICY: 'origin',
+         NAME: 'origin-with-unsafe-url-in-meta',
+         META_POLICY: 'unsafe-url',
+         DESC: "origin (anchor) with unsafe-url in meta",
+         RESULT: 'origin'},
+        {ATTRIBUTE_POLICY: 'no-referrer',
+         NAME: 'no-referrer-with-origin-in-meta',
+         META_POLICY: 'origin',
+         DESC: "no-referrer (anchor) with origin in meta",
+         RESULT: 'none'},
+        {NAME: 'no-referrer-in-meta',
+         META_POLICY: 'no-referrer',
+         DESC: "no-referrer in meta",
+         RESULT: 'none'},
+        {ATTRIBUTE_POLICY: 'origin',
+         NAME: 'origin-with-no-meta',
+         META_POLICY: '',
+         DESC: "origin (anchor) with no meta",
+         RESULT: 'origin'},
+        // setting rel=noreferrer -> we expect no referrer
+        {ATTRIBUTE_POLICY: 'unsafe-url',
+         NAME: 'unsafe-url-with-origin-in-meta-rel',
+         META_POLICY: 'origin',
+         DESC: "unsafe-url (anchor) with origin in meta and rel=noreferrer",
+         RESULT: 'none',
+         REL: 'noreferrer'},
+        {ATTRIBUTE_POLICY: 'origin',
+         NAME: 'origin-with-unsafe-url-in-meta-rel',
+         META_POLICY: 'unsafe-url',
+         DESC: "origin (anchor) with unsafe-url in meta and rel=noreferrer",
+         RESULT: 'none',
+         REL: 'noreferrer'},
+        {ATTRIBUTE_POLICY: 'origin',
+         NAME: 'origin-with-no-meta-rel',
+         META_POLICY: '',
+         DESC: "origin (anchor) with no meta and rel=noreferrer",
+         RESULT: 'none',
+         REL: 'noreferrer'},
+        // setting invalid refer values -> we expect either full referrer (default)
+        // or whatever is specified in the meta referrer policy
+        {ATTRIBUTE_POLICY: 'origin-when-cross-origin',
+         NAME: 'origin-when-cross-origin-with-no-meta',
+         META_POLICY: '',
+         DESC: "origin-when-cross-origin (anchor) with no meta",
+         RESULT: 'full'},
+        {ATTRIBUTE_POLICY: 'default',
+         NAME: 'default-with-no-meta',
+         META_POLICY: '',
+         DESC: "default (anchor) with no meta",
+         RESULT: 'full'},
+        {ATTRIBUTE_POLICY: 'something',
+         NAME: 'something-with-no-meta',
+         META_POLICY: '',
+         DESC: "something (anchor) with no meta",
+         RESULT: 'full'},
+        {ATTRIBUTE_POLICY: 'origin-when-cross-origin',
+         NAME: 'origin-when-cross-origin-with-no-referrer-in-meta',
+         META_POLICY: 'no-referrer',
+         DESC: "origin-when-cross-origin (anchor) with no-referrer in meta",
+         RESULT: 'none'},
+        {ATTRIBUTE_POLICY: 'origin-when-cross-origin',
+         NAME: 'origin-when-cross-origin-with-unsafe-url-in-meta',
+         META_POLICY: 'unsafe-url',
+         DESC: "origin-when-cross-origin (anchor) with unsafe-url in meta",
+         RESULT: 'full'},
+        {ATTRIBUTE_POLICY: 'origin-when-cross-origin',
+         NAME: 'origin-when-cross-origin-with-origin-in-meta',
+         META_POLICY: 'origin',
+         DESC: "origin-when-cross-origin (anchor) with origin in meta",
+         RESULT: 'origin'}]}
+  ];
+  </script>
+  <script type="application/javascript;version=1.7" src="/tests/dom/base/test/referrer_helper.js"></script>
+</head>
+<body onload="tests.next();">
+  <iframe id="testframe"></iframe>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_anchor_area_referrer_changing.html
@@ -0,0 +1,75 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test anchor and area policy attribute for Bug 1174913</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+  <!--
+  Testing that anchor and area referrer attributes are honoured correctly
+  This test is split due to errors on b2g
+  * testing setAttribute and .referrer (generate-anchor-changing-test)
+  https://bugzilla.mozilla.org/show_bug.cgi?id=1174913
+  -->
+
+  <script type="application/javascript;version=1.8">
+
+  const sjs = "/tests/dom/base/test/referrer_testserver.sjs?";
+  const ATTRIBUTE_POLICY = 'attributePolicy';
+  const NEW_ATTRIBUTE_POLICY = 'newAttributePolicy';
+  const NAME = 'name';
+  const META_POLICY = 'metaPolicy';
+  const DESC = 'description';
+  const RESULT = 'result';
+  const ACTION = 'action';
+  const TESTS = 'tests';
+  const REL = 'rel';
+  const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY", "REL"];
+
+  const testCases = [
+    {ACTION: ["generate-anchor-changing-policy-test-set-attribute", "generate-area-changing-policy-test-set-attribute"],
+      TESTS: [
+        {ATTRIBUTE_POLICY: 'unsafe-url',
+         NEW_ATTRIBUTE_POLICY: 'no-referrer',
+         NAME: 'no-referrer-unsafe-url-with-origin-in-meta',
+         META_POLICY: 'origin',
+         DESC: "no-referrer (anchor, orginally unsafe-url) with origin in meta",
+         RESULT: 'none'},
+        {ATTRIBUTE_POLICY: 'origin',
+         NEW_ATTRIBUTE_POLICY: 'unsafe-url',
+         NAME: 'unsafe-url-origin-with-no-referrer-in-meta',
+         META_POLICY: 'no-referrer',
+         DESC: "unsafe-url (anchor, orginally origin) with no-referrer in meta",
+         RESULT: 'full'},
+        {ATTRIBUTE_POLICY: 'origin',
+         NEW_ATTRIBUTE_POLICY: 'unsafe-url',
+         NAME: 'unsafe-url-origin-with-no-referrer-in-meta-rel',
+         META_POLICY: 'no-referrer',
+         DESC: "unsafe-url (anchor, orginally origin) with no-referrer in meta and rel=noreferrer",
+         RESULT: 'none',
+         REL: 'noreferrer'}]},
+    {ACTION: ["generate-anchor-changing-policy-test-property", "generate-area-changing-policy-test-property"],
+      TESTS: [
+        {ATTRIBUTE_POLICY: 'no-referrer',
+         NEW_ATTRIBUTE_POLICY: 'unsafe-url',
+         NAME: 'unsafe-url-no-referrer-with-origin-in-meta',
+         META_POLICY: 'origin',
+         DESC: "unsafe-url (anchor, orginally no-referrer) with origin in meta",
+         RESULT: 'full'},
+        {ATTRIBUTE_POLICY: 'no-referrer',
+         NEW_ATTRIBUTE_POLICY: 'unsafe-url',
+         NAME: 'unsafe-url-no-referrer-with-origin-in-meta-rel',
+         META_POLICY: 'origin',
+         DESC: "unsafe-url (anchor, orginally no-referrer) with origin in meta and rel=noreferrer",
+         RESULT: 'none',
+         REL: 'noreferrer'}]}
+  ];
+  </script>
+  <script type="application/javascript;version=1.7" src="/tests/dom/base/test/referrer_helper.js"></script>
+</head>
+<body onload="tests.next();">
+  <iframe id="testframe"></iframe>
+</body>
+</html>
+