Add more Cross-Origin-Opener-Policy tests

Differential Revision: https://phabricator.services.mozilla.com/D33330

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1527314
gecko-commit: d833fd94e8e3749f159a4d67f9d1ac9a269123d3
gecko-integration-branch: autoland
gecko-reviewers: annevk
diff --git a/html/cross-origin-opener/common.sub.js b/html/cross-origin-opener/common.sub.js
new file mode 100644
index 0000000..a73a95a
--- /dev/null
+++ b/html/cross-origin-opener/common.sub.js
@@ -0,0 +1,28 @@
+const SAME_ORIGIN = {origin: get_host_info().HTTP_ORIGIN, name: "SAME_ORIGIN"};
+const SAME_SITE = {origin: get_host_info().HTTP_REMOTE_ORIGIN, name: "SAME_SITE"};
+const CROSS_ORIGIN = {origin: get_host_info().HTTP_NOTSAMESITE_ORIGIN, name: "CROSS_ORIGIN"}
+
+function coop_test(t, host, coop, channelName, hasOpener) {
+  let bc = new BroadcastChannel(channelName);
+  bc.onmessage = t.step_func_done((event) => {
+    let payload = event.data;
+    assert_equals(payload.name, hasOpener ? channelName : "");
+    assert_equals(payload.opener, hasOpener);
+  });
+
+  let w = window.open(`${host.origin}/html/cross-origin-opener/resources/coop_window.py?path=window.sub.html&coop=${escape(coop)}&channel=${channelName}`, channelName);
+
+  // w will be closed by its postback iframe. When out of process,
+  // window.close() does not work.
+  t.add_cleanup(() => w.close());
+}
+
+function run_coop_tests(mainTest, testArray) {
+  for (let test of tests) {
+   async_test(t => {
+    coop_test(t, test[0], test[1],
+              `${mainTest}_to_${test[0].name}_${test[1].replace(/ /g,"-")}`,
+              test[2]);
+  }, `${mainTest} document opening popup to ${test[0].origin} with COOP: "${test[1]}"`);
+ }
+}
diff --git a/html/cross-origin-opener/new_window_null.tentative.html b/html/cross-origin-opener/new_window_null.tentative.html
new file mode 100644
index 0000000..35a42fd
--- /dev/null
+++ b/html/cross-origin-opener/new_window_null.tentative.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="/common/get-host-info.sub.js"></script>
+
+<script src="common.sub.js"></script>
+
+<div id=log></div>
+<script>
+
+let tests = [
+  // popup Origin, popup COOP, expect opener
+  [SAME_ORIGIN, "", true],
+  [SAME_ORIGIN, "jibberish", true],
+  [SAME_ORIGIN, "same-site", false],
+  [SAME_ORIGIN, "same-site unsafe-allow-outgoing", false],
+  [SAME_ORIGIN, "same-origin", false],
+  [SAME_ORIGIN, "same-origin unsafe-allow-outgoing", false],
+
+  [SAME_SITE, "", true],
+  [SAME_SITE, "jibberish", true],
+  [SAME_SITE, "same-site", false],
+  [SAME_SITE, "same-site unsafe-allow-outgoing", false],
+  [SAME_SITE, "same-origin", false],
+  [SAME_SITE, "same-origin unsafe-allow-outgoing", false],
+
+  [CROSS_ORIGIN, "", true],
+  [CROSS_ORIGIN, "jibberish", true],
+  [CROSS_ORIGIN, "same-site", false],
+  [CROSS_ORIGIN, "same-site unsafe-allow-outgoing", false],
+  [CROSS_ORIGIN, "same-origin", false],
+  [CROSS_ORIGIN, "same-origin unsafe-allow-outgoing", false],
+];
+
+run_coop_tests("null", tests);
+
+</script>
diff --git a/html/cross-origin-opener/new_window_same_origin.tentative.html b/html/cross-origin-opener/new_window_same_origin.tentative.html
new file mode 100644
index 0000000..6bbb37c
--- /dev/null
+++ b/html/cross-origin-opener/new_window_same_origin.tentative.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="/common/get-host-info.sub.js"></script>
+
+<script src="common.sub.js"></script>
+
+<div id=log></div>
+<script>
+
+let tests = [
+  // popup Origin, popup COOP, expect opener
+  [SAME_ORIGIN, "", false],
+  [SAME_ORIGIN, "jibberish", false],
+  [SAME_ORIGIN, "same-site", false],
+  [SAME_ORIGIN, "same-site unsafe-allow-outgoing", false],
+  [SAME_ORIGIN, "same-origin", true],
+  [SAME_ORIGIN, "same-origin unsafe-allow-outgoing", false],
+
+  [SAME_SITE, "", false],
+  [SAME_SITE, "jibberish", false],
+  [SAME_SITE, "same-site", false],
+  [SAME_SITE, "same-site unsafe-allow-outgoing", false],
+  [SAME_SITE, "same-origin", false],
+  [SAME_SITE, "same-origin unsafe-allow-outgoing", false],
+
+  [CROSS_ORIGIN, "", false],
+  [CROSS_ORIGIN, "jibberish", false],
+  [CROSS_ORIGIN, "same-site", false],
+  [CROSS_ORIGIN, "same-site unsafe-allow-outgoing", false],
+  [CROSS_ORIGIN, "same-origin", false],
+  [CROSS_ORIGIN, "same-origin unsafe-allow-outgoing", false],
+];
+
+run_coop_tests("same-origin", tests);
+
+</script>
diff --git a/html/cross-origin-opener/new_window_same_origin.tentative.html.headers b/html/cross-origin-opener/new_window_same_origin.tentative.html.headers
new file mode 100644
index 0000000..46ad58d
--- /dev/null
+++ b/html/cross-origin-opener/new_window_same_origin.tentative.html.headers
@@ -0,0 +1 @@
+Cross-Origin-Opener-Policy: same-origin
diff --git a/html/cross-origin-opener/new_window_same_origin_unsafe_allow_outgoing.tentative.html b/html/cross-origin-opener/new_window_same_origin_unsafe_allow_outgoing.tentative.html
new file mode 100644
index 0000000..bbd5513
--- /dev/null
+++ b/html/cross-origin-opener/new_window_same_origin_unsafe_allow_outgoing.tentative.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="/common/get-host-info.sub.js"></script>
+
+<script src="common.sub.js"></script>
+
+<div id=log></div>
+<script>
+
+let tests = [
+  // popup Origin, popup COOP, expect opener
+  [SAME_ORIGIN, "", true],
+  [SAME_ORIGIN, "jibberish", true],
+  [SAME_ORIGIN, "same-site", false],
+  [SAME_ORIGIN, "same-site unsafe-allow-outgoing", false],
+  [SAME_ORIGIN, "same-origin", false],
+  [SAME_ORIGIN, "same-origin unsafe-allow-outgoing", true],
+
+  [SAME_SITE, "", true],
+  [SAME_SITE, "jibberish", true],
+  [SAME_SITE, "same-site", false],
+  [SAME_SITE, "same-site unsafe-allow-outgoing", false],
+  [SAME_SITE, "same-origin", false],
+  [SAME_SITE, "same-origin unsafe-allow-outgoing", false],
+
+  [CROSS_ORIGIN, "", true],
+  [CROSS_ORIGIN, "jibberish", true],
+  [CROSS_ORIGIN, "same-site", false],
+  [CROSS_ORIGIN, "same-site unsafe-allow-outgoing", false],
+  [CROSS_ORIGIN, "same-origin", false],
+  [CROSS_ORIGIN, "same-origin unsafe-allow-outgoing", false],
+];
+
+run_coop_tests("same-origin_unsafe-allow-outgoing", tests);
+
+</script>
diff --git a/html/cross-origin-opener/new_window_same_origin_unsafe_allow_outgoing.tentative.html.headers b/html/cross-origin-opener/new_window_same_origin_unsafe_allow_outgoing.tentative.html.headers
new file mode 100644
index 0000000..a19f440
--- /dev/null
+++ b/html/cross-origin-opener/new_window_same_origin_unsafe_allow_outgoing.tentative.html.headers
@@ -0,0 +1 @@
+Cross-Origin-Opener-Policy: same-origin unsafe-allow-outgoing
diff --git a/html/cross-origin-opener/new_window_same_site.tentative.html b/html/cross-origin-opener/new_window_same_site.tentative.html
index b75f7ff..e1efac1 100644
--- a/html/cross-origin-opener/new_window_same_site.tentative.html
+++ b/html/cross-origin-opener/new_window_same_site.tentative.html
@@ -4,23 +4,35 @@
 <script src=/resources/testharnessreport.js></script>
 <script src="/common/get-host-info.sub.js"></script>
 
+<script src="common.sub.js"></script>
+
+<div id=log></div>
 <script>
 
-const CHANNEL_NAME = "new_window_same_site";
+let tests = [
+  // popup Origin, popup COOP, expect opener
+  [SAME_ORIGIN, "", false],
+  [SAME_ORIGIN, "jibberish", false],
+  [SAME_ORIGIN, "same-site", true],
+  [SAME_ORIGIN, "same-site unsafe-allow-outgoing", false],
+  [SAME_ORIGIN, "same-origin", false],
+  [SAME_ORIGIN, "same-origin unsafe-allow-outgoing", false],
 
-async_test(t => {
-  let w = window.open(`${get_host_info().HTTP_REMOTE_ORIGIN}/html/cross-origin-opener/resources/window.sub.html?channel=${CHANNEL_NAME}`, "window_name", "height=200,width=250");
+  [SAME_SITE, "", false],
+  [SAME_SITE, "jibberish", false],
+  [SAME_SITE, "same-site", true],
+  [SAME_SITE, "same-site unsafe-allow-outgoing", false],
+  [SAME_SITE, "same-origin", false],
+  [SAME_SITE, "same-origin unsafe-allow-outgoing", false],
 
-  // w will be closed by its postback iframe. When out of process,
-  // window.close() does not work.
-  t.add_cleanup(() => w.close());
+  [CROSS_ORIGIN, "", false],
+  [CROSS_ORIGIN, "jibberish", false],
+  [CROSS_ORIGIN, "same-site", false],
+  [CROSS_ORIGIN, "same-site unsafe-allow-outgoing", false],
+  [CROSS_ORIGIN, "same-origin", false],
+  [CROSS_ORIGIN, "same-origin unsafe-allow-outgoing", false],
+];
 
-  let bc = new BroadcastChannel(CHANNEL_NAME);
-  bc.onmessage = t.step_func_done((event) => {
-    let payload = event.data;
-    assert_equals(payload.name, "window_name");
-    assert_equals(payload.opener, true);
-  });
-}, "same-site policy works");
+run_coop_tests("same-site", tests);
 
 </script>
diff --git a/html/cross-origin-opener/new_window_same_site_unsafe_allow_outgoing.tentative.html b/html/cross-origin-opener/new_window_same_site_unsafe_allow_outgoing.tentative.html
new file mode 100644
index 0000000..d81506f
--- /dev/null
+++ b/html/cross-origin-opener/new_window_same_site_unsafe_allow_outgoing.tentative.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="/common/get-host-info.sub.js"></script>
+
+<script src="common.sub.js"></script>
+
+<div id=log></div>
+<script>
+
+let tests = [
+  // popup Origin, popup COOP, expect opener
+  [SAME_ORIGIN, "", true],
+  [SAME_ORIGIN, "jibberish", true],
+  [SAME_ORIGIN, "same-site", false],
+  [SAME_ORIGIN, "same-site unsafe-allow-outgoing", true],
+  [SAME_ORIGIN, "same-origin", false],
+  [SAME_ORIGIN, "same-origin unsafe-allow-outgoing", false],
+
+  [SAME_SITE, "", true],
+  [SAME_SITE, "jibberish", true],
+  [SAME_SITE, "same-site", false],
+  [SAME_SITE, "same-site unsafe-allow-outgoing", true],
+  [SAME_SITE, "same-origin", false],
+  [SAME_SITE, "same-origin unsafe-allow-outgoing", false],
+
+  [CROSS_ORIGIN, "", true],
+  [CROSS_ORIGIN, "jibberish", true],
+  [CROSS_ORIGIN, "same-site", false],
+  [CROSS_ORIGIN, "same-site unsafe-allow-outgoing", false],
+  [CROSS_ORIGIN, "same-origin", false],
+  [CROSS_ORIGIN, "same-origin unsafe-allow-outgoing", false],
+];
+
+run_coop_tests("same-site_unsafe-allow-outgoing", tests);
+
+</script>
diff --git a/html/cross-origin-opener/new_window_same_site_unsafe_allow_outgoing.tentative.html.headers b/html/cross-origin-opener/new_window_same_site_unsafe_allow_outgoing.tentative.html.headers
new file mode 100644
index 0000000..ab7b289
--- /dev/null
+++ b/html/cross-origin-opener/new_window_same_site_unsafe_allow_outgoing.tentative.html.headers
@@ -0,0 +1 @@
+Cross-Origin-Opener-Policy: same-site unsafe-allow-outgoing
diff --git a/html/cross-origin-opener/resources/coop_window.py b/html/cross-origin-opener/resources/coop_window.py
new file mode 100644
index 0000000..b24d6d5
--- /dev/null
+++ b/html/cross-origin-opener/resources/coop_window.py
@@ -0,0 +1,10 @@
+import urllib
+import os.path
+
+def main(request, response):
+    coop = request.GET.first('coop')
+    if coop:
+        response.headers.set('Cross-Origin-Opener-Policy', urllib.unquote(coop))
+
+    path = os.path.join(os.path.dirname(__file__), request.GET.first('path'))
+    response.content = open(path, mode='rb').read()
diff --git a/html/cross-origin-opener/resources/window.sub.html b/html/cross-origin-opener/resources/window.sub.html
index 7c72f87..524efe2 100644
--- a/html/cross-origin-opener/resources/window.sub.html
+++ b/html/cross-origin-opener/resources/window.sub.html
@@ -2,17 +2,17 @@
 <meta charset=utf-8>
 
 <script src="/common/get-host-info.sub.js"></script>
-<div id="status"> </div>
 
 <script type="text/javascript">
 
-  let iframe = document.createElement("iframe");
-  iframe.onload = () => {
-    let payload = { name: self.name, opener: !!self.opener };
-    iframe.contentWindow.postMessage(payload, "*");
-  };
-  let channelName = new URL(location).searchParams.get("channel");
-  iframe.src = `${get_host_info().HTTP_ORIGIN}/html/cross-origin-opener/resources/postback.sub.html?channel=${channelName}`;
-  document.body.appendChild(iframe);
-
+  window.addEventListener('load', function() {
+    let iframe = document.createElement("iframe");
+    iframe.onload = () => {
+      let payload = { name: self.name, opener: !!self.opener };
+      iframe.contentWindow.postMessage(payload, "*");
+    };
+    let channelName = new URL(location).searchParams.get("channel");
+    iframe.src = `${get_host_info().HTTP_ORIGIN}/html/cross-origin-opener/resources/postback.sub.html?channel=${channelName}`;
+    document.body.appendChild(iframe);
+  });
 </script>