Add more referrer policy WPTs for Early Hints

Bug: 1302851
Change-Id: Ia3b68877f2aa77faa1cf85e425ae8ac21b539f2b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3511630
Reviewed-by: Yutaka Hirano <yhirano@chromium.org>
Commit-Queue: Kenichi Ishibashi <bashi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#979642}
diff --git a/loading/early-hints/preload-initiator-type.h2.window.js b/loading/early-hints/preload-initiator-type.h2.window.js
index 33f2c81..959aace 100644
--- a/loading/early-hints/preload-initiator-type.h2.window.js
+++ b/loading/early-hints/preload-initiator-type.h2.window.js
@@ -1,4 +1,4 @@
-// META: script=resources/early-hints-helpers.js
+// META: script=resources/early-hints-helpers.sub.js
 
 test(() => {
     const preloads = [{
diff --git a/loading/early-hints/referrer-policy-no-referrer.h2.window.js b/loading/early-hints/referrer-policy-no-referrer.h2.window.js
new file mode 100644
index 0000000..10f2c2c
--- /dev/null
+++ b/loading/early-hints/referrer-policy-no-referrer.h2.window.js
@@ -0,0 +1,4 @@
+// META: script=/common/utils.js
+// META: script=resources/early-hints-helpers.sub.js
+
+test(() => testReferrerPolicy("no-referrer"));
diff --git a/loading/early-hints/referrer-policy-origin-when-cross-origin.h2.window.js b/loading/early-hints/referrer-policy-origin-when-cross-origin.h2.window.js
new file mode 100644
index 0000000..250f350
--- /dev/null
+++ b/loading/early-hints/referrer-policy-origin-when-cross-origin.h2.window.js
@@ -0,0 +1,4 @@
+// META: script=/common/utils.js
+// META: script=resources/early-hints-helpers.sub.js
+
+test(() => testReferrerPolicy("origin-when-cross-origin"));
diff --git a/loading/early-hints/referrer-policy-origin.h2.window.js b/loading/early-hints/referrer-policy-origin.h2.window.js
new file mode 100644
index 0000000..3fbe9df
--- /dev/null
+++ b/loading/early-hints/referrer-policy-origin.h2.window.js
@@ -0,0 +1,4 @@
+// META: script=/common/utils.js
+// META: script=resources/early-hints-helpers.sub.js
+
+test(() => testReferrerPolicy("origin"));
diff --git a/loading/early-hints/referrer-policy-same-origin.h2.window.js b/loading/early-hints/referrer-policy-same-origin.h2.window.js
new file mode 100644
index 0000000..4d24e1b
--- /dev/null
+++ b/loading/early-hints/referrer-policy-same-origin.h2.window.js
@@ -0,0 +1,4 @@
+// META: script=/common/utils.js
+// META: script=resources/early-hints-helpers.sub.js
+
+test(() => testReferrerPolicy("same-origin"));
diff --git a/loading/early-hints/referrer-policy-unsafe-url.h2.window.js b/loading/early-hints/referrer-policy-unsafe-url.h2.window.js
new file mode 100644
index 0000000..a0c304c
--- /dev/null
+++ b/loading/early-hints/referrer-policy-unsafe-url.h2.window.js
@@ -0,0 +1,4 @@
+// META: script=/common/utils.js
+// META: script=resources/early-hints-helpers.sub.js
+
+test(() => testReferrerPolicy("unsafe-url"));
diff --git a/loading/early-hints/referrer-policy.h2.window.js b/loading/early-hints/referrer-policy.h2.window.js
deleted file mode 100644
index 28756c9..0000000
--- a/loading/early-hints/referrer-policy.h2.window.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// META: script=/common/utils.js
-
-function test_referrer_policy(referrer_policy) {
-    const params = new URLSearchParams();
-    const preload_url = "fetch-and-record-js.h2.py?id=" + token();
-    params.set("preload-url", preload_url);
-    params.set("referrer-policy", referrer_policy);
-    const path = "resources/referrer-policy-test-loader.h2.py?" + params.toString();
-    const url = new URL(path, window.location);
-    window.location.replace(url);
-}
-
-// TODO(https://crbug.com/1302851): Add more test cases.
-test(() => test_referrer_policy("no-referrer"));
diff --git a/loading/early-hints/resources/early-hints-helpers.js b/loading/early-hints/resources/early-hints-helpers.sub.js
similarity index 60%
rename from loading/early-hints/resources/early-hints-helpers.js
rename to loading/early-hints/resources/early-hints-helpers.sub.js
index e2fc1e7..72cebf9 100644
--- a/loading/early-hints/resources/early-hints-helpers.js
+++ b/loading/early-hints/resources/early-hints-helpers.sub.js
@@ -35,4 +35,22 @@
         preloads.push(JSON.parse(encoded));
     }
     return preloads;
-}
\ No newline at end of file
+}
+
+/**
+ * Navigate to the referrer policy test page.
+ *
+ * @param {string} referrer_policy - A value of Referrer-Policy to test.
+ */
+function testReferrerPolicy(referrer_policy) {
+    const params = new URLSearchParams();
+    params.set("referrer-policy", referrer_policy);
+    const same_origin_preload_url = "https://{{host}}:{{ports[h2][0]}}/loading/early-hints/resources/fetch-and-record-js.h2.py?id=" + token();
+    params.set("same-origin-preload-url", same_origin_preload_url);
+    const cross_origin_preload_url = "https://{{hosts[alt][www]}}:{{ports[h2][0]}}/loading/early-hints/resources/fetch-and-record-js.h2.py?id=" + token();
+    params.set("cross-origin-preload-url", cross_origin_preload_url);
+
+    const path = "resources/referrer-policy-test-loader.h2.py?" + params.toString();
+    const url = new URL(path, window.location);
+    window.location.replace(url);
+}
diff --git a/loading/early-hints/resources/early-hints-test-loader.h2.py b/loading/early-hints/resources/early-hints-test-loader.h2.py
index 92ce586..aa9188c 100644
--- a/loading/early-hints/resources/early-hints-test-loader.h2.py
+++ b/loading/early-hints/resources/early-hints-test-loader.h2.py
@@ -1,6 +1,6 @@
 # An HTTP/2 handler for testing Early Hints. Used as an entry point of Early
 # Hints related tests to inject Early Hints response. See comments in
-# `early-hints-helpers.js`.
+# `early-hints-helpers.sub.js`.
 
 import json
 import os
diff --git a/loading/early-hints/resources/get-fetch-timing-and-headers.h2.py b/loading/early-hints/resources/get-fetch-timing-and-headers.h2.py
index ff4f8be..59f67be 100644
--- a/loading/early-hints/resources/get-fetch-timing-and-headers.h2.py
+++ b/loading/early-hints/resources/get-fetch-timing-and-headers.h2.py
@@ -4,6 +4,9 @@
 
 
 def main(request, response):
-    headers = [("Content-Type", "application/json")]
+    headers = [
+        ("Content-Type", "application/json"),
+        ("Access-Control-Allow-Origin", "*"),
+    ]
     body = utils.get_request_timing_and_headers(request)
     return (200, "OK"), headers, body
diff --git a/loading/early-hints/resources/preload-initiator-type.html b/loading/early-hints/resources/preload-initiator-type.html
index 34188df..39b0db0 100644
--- a/loading/early-hints/resources/preload-initiator-type.html
+++ b/loading/early-hints/resources/preload-initiator-type.html
@@ -2,7 +2,7 @@
 <meta charset=utf-8>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="early-hints-helpers.js"></script>
+<script src="early-hints-helpers.sub.js"></script>
 <body>
 <script>
 async_test((t) => {
diff --git a/loading/early-hints/resources/referrer-policy-test-loader.h2.py b/loading/early-hints/resources/referrer-policy-test-loader.h2.py
index ad48cbb..901d64a 100644
--- a/loading/early-hints/resources/referrer-policy-test-loader.h2.py
+++ b/loading/early-hints/resources/referrer-policy-test-loader.h2.py
@@ -6,7 +6,11 @@
     headers = []
     referrer_policy = request.GET.first(b"referrer-policy")
     headers.append((b"referrer-policy", referrer_policy))
-    preload_url = request.GET.first(b"preload-url").decode()
+
+    preload_url = request.GET.first(b"same-origin-preload-url").decode()
+    link_header_value = "<{}>; rel=preload; as=script".format(preload_url)
+    headers.append((b"link", link_header_value))
+    preload_url = request.GET.first(b"cross-origin-preload-url").decode()
     link_header_value = "<{}>; rel=preload; as=script".format(preload_url)
     headers.append((b"link", link_header_value))
 
diff --git a/loading/early-hints/resources/referrer-policy-test.html b/loading/early-hints/resources/referrer-policy-test.html
index 514e6c6..af4f393 100644
--- a/loading/early-hints/resources/referrer-policy-test.html
+++ b/loading/early-hints/resources/referrer-policy-test.html
@@ -2,7 +2,7 @@
 <meta charset=utf-8>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
-<script src="early-hints-helpers.js"></script>
+<script src="early-hints-helpers.sub.js"></script>
 <body>
 <script>
 const SEARCH_PARAMS = new URLSearchParams(window.location.search);
@@ -17,37 +17,58 @@
     });
 }
 
-async function get_fetch_timing_and_headers(url) {
-    const index = url.lastIndexOf("?");
-    const params = new URLSearchParams(url.substring(index));
-    const id = params.get("id");
+async function get_fetch_timing_and_headers(url_string) {
+    const url = new URL(url_string);
+    const id = url.searchParams.get("id");
     if (id === null) {
-        throw new Error(`"${url}" does not contain id parameter`);
+        throw new Error(`"${url.href}" does not contain id parameter`);
     }
-    const response = await fetch("get-fetch-timing-and-headers.h2.py?id=" + id);
+    const response = await fetch(`${url.origin}/loading/early-hints/resources/get-fetch-timing-and-headers.h2.py?id=${id}`);
     const json = await response.json();
     return json;
 }
 
-function get_expected_referrer() {
+function get_expected_referrer(is_same_origin) {
+    const full = window.location.href;
+    const origin = self.origin + "/";
+    // There is no support for security level related policies such as
+    // "no-referrer-when-downgrade" since the test is available only on HTTP/2.
     switch (REFERRER_POLICY) {
-        case "no-referrer": return undefined;
-        default: new Error(`Unknown referrer policy: ${REFERRER_POLICY}`);
+        case "no-referrer":
+            return undefined;
+        case "origin":
+            return origin;
+        case "origin-when-cross-origin":
+            return is_same_origin ? full : origin;
+        case "same-origin":
+            return is_same_origin ? full : undefined;
+        case "unsafe-url":
+            return full;
+        default:
+            throw new Error(`Unsupported referrer policy: ${REFERRER_POLICY}`);
     }
 }
 
-promise_test(async (t) => {
-    const preload_url = SEARCH_PARAMS.get("preload-url");
-    await fetch_script(preload_url);
+async function check_referrer(url, expected_referrer) {
+    await fetch_script(url);
 
-    const { headers } = await get_fetch_timing_and_headers(preload_url);
-    const expected_referrer = get_expected_referrer();
-    assert_equals(headers["referrer"], expected_referrer);
+    const { headers } = await get_fetch_timing_and_headers(url);
+    assert_equals(headers["referer"], expected_referrer);
 
-    const name = new URL(preload_url, window.location);
+    const name = new URL(url, window.location);
     const entries = performance.getEntriesByName(name);
     assert_equals(entries.length, 1);
     assert_equals(entries[0].initiatorType, "early-hints");
+}
+
+promise_test(async (t) => {
+    const same_origin_preload_url = SEARCH_PARAMS.get("same-origin-preload-url");
+    const same_origin_expected = get_expected_referrer(true);
+    await check_referrer(same_origin_preload_url, same_origin_expected);
+
+    const cross_origin_preload_url = SEARCH_PARAMS.get("cross-origin-preload-url");
+    const cross_origin_expected = get_expected_referrer(false);
+    await check_referrer(cross_origin_preload_url, cross_origin_expected);
 }, `Referrer policy: ${REFERRER_POLICY}`);
 </script>
 </body>