<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>This test validates the values in resource timing for cross-origin
redirects.</title>
<link rel="author" title="Intel" href="http://www.intel.com/" />
<link rel="help" href="https://www.w3.org/TR/resource-timing-2/#sec-performanceresourcetiming"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/custom-cors-response.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="resources/entry-invariants.js"></script>
<script src="resources/resource-loaders.js"></script>
<script src="resources/tao-response.js"></script>
</head>
<body>
<script>
const {ORIGIN, REMOTE_ORIGIN} = get_host_info();

const HTTP_SO_to_XO_redirect_url = url => {
  // Make an initial request to a same-domain resource that will return a 302
  // redirect to the given (possibly cross-origin) url.
  return `/resource-timing/resources/redirect-cors.py?location=${url}`;
};

const HTTP_SO_resource = () => {
  if (location.protocol != "http:") {
    throw new Error("Can only make an HTTP SO request if this page was " +
      "served over HTTP.");
  }
  return tao_response("*", ORIGIN);
};

const HTTP_XO_redirect = (url, tao) => {
  const ret = new URL(
    `${REMOTE_ORIGIN}/resource-timing/resources/redirect-cors.py`);
  ret.searchParams.append("location", url);
  ret.searchParams.append("allow_origin", "*");
  ret.searchParams.append("timing_allow_origin", tao);
  return ret.href;
};

attribute_test(
  load.iframe, HTTP_SO_to_XO_redirect_url(custom_cors_response({},
    REMOTE_ORIGIN)),
  invariants.assert_http_to_cross_origin_redirected_resource,
  "Verify that cross-origin resources' timings aren't exposed through HTTP " +
  "redirects.");

attribute_test(
  load.iframe, HTTP_SO_to_XO_redirect_url(remote_tao_response("no-match")),
  invariants.assert_cross_origin_redirected_resource,
  "Verify that a redirected cross-origin resources' timings aren't exposed " +
  "when the TAO check fails.");

attribute_test(
  load.iframe, HTTP_SO_to_XO_redirect_url(remote_tao_response("*")),
  invariants.assert_http_to_tao_enabled_cross_origin_https_redirected_resource,
  "Verify that cross-origin resources' timings are exposed when the TAO " +
  "check succeeds. Also verify that secureConnectionStart is 0 since the " +
  "original request was over HTTP.");

attribute_test(
  load.iframe, HTTP_XO_redirect(HTTP_XO_redirect(HTTP_SO_resource(), "*"), "*"),
  invariants.assert_http_to_tao_enabled_cross_origin_https_redirected_resource,
  "Verify that a redirect chain through cross-origin resources have their " +
  "timings exposed when all TAO checks succeed. Also verify that " +
  "secureConnectionStart is 0 since the original request was over HTTP.");

const failure_permutations = [
  ["fail", "fail", "fail"],
  ["fail", "fail", "*"   ],
  ["fail", "*",    "fail"],
  ["fail", "*",    "*"   ],
  ["*",    "fail", "fail"],
  ["*",    "fail", "*"   ],
  ["*",    "*",    "fail"],
];
const test_case = (so_tao, xo1_tao, xo2_tao) => {
  return HTTP_XO_redirect(HTTP_XO_redirect(HTTP_SO_resource(
    so_tao), xo2_tao), xo1_tao);
};
const test_label = perm => {
  return perm.map(x => {
    if (x == "*" ) return "PASS";
    if (x == "fail" ) return "FAIL";
    throw new Error(`unexpected element ${x}`);
  }).join(" -> ");
};
for (const permutation of failure_permutations) {
  attribute_test(
    load.iframe, test_case.apply(permutation),
    invariants.assert_tao_failure_resource,
    `Verify that a redirect chain through cross-origin resources do not have ` +
    `their timings exposed when any of the TAO checks fail. ` +
    `(${test_label(permutation)})`);
}

</script>
</body>
</html>
