<!DOCTYPE html>
<title>Sec-Purpose header on prerendered page</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="/common/utils.js"></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js"></script>
<script src="../resources/utils.js"></script>
<script src="resources/utils.js"></script>

<body>
<script>
setup(() => assertSpeculationRulesIsSupported());

promise_test(async () => {
  const rcHelper = new PrerenderingRemoteContextHelper();
  const referrerRC = await rcHelper.addWindow(undefined, { features: 'noopener' });
  const prerenderedRC = await referrerRC.addPrerender();

  const prerenderedHeaders = await prerenderedRC.getRequestHeaders();
  assertHeaders(prerenderedHeaders, true, true, 'prerendered page');

  const iframeRC = await prerenderedRC.addIframe();
  const iframeHeaders = await iframeRC.getRequestHeaders();
  assertHeaders(iframeHeaders, true, false, 'iframe');

  // No test for cross-origin iframe, since those requests are delayed until
  // after activation. See below.

  const imageHeaders = await insertImageAndGetRequestHeaders(prerenderedRC);
  assertHeaders(imageHeaders, true, false, 'image');

  const crossOriginImageHeaders = await insertImageAndGetRequestHeaders(
    prerenderedRC,
    get_host_info().HTTPS_REMOTE_ORIGIN
  );
  assertHeaders(crossOriginImageHeaders, true, false, 'cross-origin image');

  const fetchHeaders = await doFetchAndGetRequestHeaders(prerenderedRC);
  assertHeaders(fetchHeaders, true, false, 'fetch');

  const crossOriginFetchHeaders = await doFetchAndGetRequestHeaders(
    prerenderedRC,
    get_host_info().HTTPS_REMOTE_ORIGIN
  );
  assertHeaders(crossOriginFetchHeaders, true, false, 'cross-origin fetch');

  const navigatedToRC = await prerenderedRC.navigateToNew();
  const navigatedToHeaders = await navigatedToRC.getRequestHeaders();
  assertHeaders(navigatedToHeaders, true, false, 'navigated-to page');
}, 'Headers before activation, including prerendered page navigation');

promise_test(async () => {
  const rcHelper = new PrerenderingRemoteContextHelper();
  const referrerRC = await rcHelper.addWindow(undefined, { features: 'noopener' });
  const prerenderedRC = await referrerRC.addPrerender();

  // Add the iframe now, but only check its headers after activation.
  const crossOriginIframeBeforeActivationRC = await prerenderedRC.addIframe({ origin: 'HTTPS_REMOTE_ORIGIN' });

  await referrerRC.navigateExpectingPrerenderingActivation(prerenderedRC);

  const crossOriginIframeBeforeActivationHeaders = await crossOriginIframeBeforeActivationRC.getRequestHeaders();
  assertHeaders(crossOriginIframeBeforeActivationHeaders, true, false, 'cross-origin iframe before activation');

  const iframeRC = await prerenderedRC.addIframe();
  const iframeHeaders = await iframeRC.getRequestHeaders();
  assertHeaders(iframeHeaders, false, false, 'post-activation iframe');

  const imageHeaders = await insertImageAndGetRequestHeaders(prerenderedRC);
  assertHeaders(imageHeaders, false, false, 'post-activation image');

  const crossOriginImageHeaders = await insertImageAndGetRequestHeaders(
    prerenderedRC,
    get_host_info().HTTPS_REMOTE_ORIGIN
  );
  assertHeaders(crossOriginImageHeaders, false, false, 'cross-origin image');

  const fetchHeaders = await doFetchAndGetRequestHeaders(prerenderedRC);
  assertHeaders(fetchHeaders, false, false, 'post-activation fetch');

  const crossOriginFetchHeaders = await doFetchAndGetRequestHeaders(
    prerenderedRC,
    get_host_info().HTTPS_REMOTE_ORIGIN
  );
  assertHeaders(crossOriginFetchHeaders, false, false, 'cross-origin fetch');
}, 'Headers after activation (plus cross-origin iframe before activation)');

async function insertImageAndGetRequestHeaders(rc, hostname) {
  const uuid = token();
  const url = (new URL(`resources/image-with-headers-stash.py?image=${uuid}`, location.href));
  const headersURL = (new URL(`resources/image-with-headers-stash.py?read=${uuid}`, location.href));

  if (hostname !== undefined) {
    url.hostname = hostname;
    headersURL.hostname = hostname;
  }

  await rc.executeScript(async (url) => {
    const img = new Image();
    img.src = url;
    const promise = new Promise(resolve => img.onload = resolve);
    document.body.append(img);
    return promise;
  }, [url]);

  const headersJSON = await (await fetch(headersURL)).json();
  assert_not_equals(headersJSON, null, 'image headers should not be null');
  return new Headers(headersJSON);
}

async function doFetchAndGetRequestHeaders(rc, hostname) {
  const uuid = token();
  const url = (new URL(`resources/image-with-headers-stash.py?image=${uuid}`, location.href));
  const headersURL = (new URL(`resources/image-with-headers-stash.py?read=${uuid}`, location.href));

  if (hostname !== undefined) {
    url.hostname = hostname;
    headersURL.hostname = hostname;
  }

  await rc.executeScript(async (url) => {
    return fetch(url, { mode: "cors" });
  }, [url]);

  const headersJSON = await (await fetch(headersURL)).json();
  assert_not_equals(headersJSON, null, 'fetch headers should not be null');
  return new Headers(headersJSON);
}

function assertHeaders(headers, secPurposeIsPrefetchPrerender, secSpeculationTagsIsPresent, label) {
  if (secPurposeIsPrefetchPrerender) {
    assert_equals(
      headers.get('Sec-Purpose'),
      'prefetch;prerender',
      `${label} Sec-Purpose`
    );
  } else {
    assert_false(
      headers.has('Sec-Purpose'),
      `${label} Sec-Purpose should not be present`
    );
  }
  if (secSpeculationTagsIsPresent) {
    assert_equals(
      headers.get('Sec-Speculation-Tags'),
      'null',
      `${label} Sec-Speculation-Tags`
    );
  } else {
    assert_false(
      headers.has('Sec-Speculation-Tags'),
      `${label} Sec-Speculation-Tags should not be present`
    );
  }
}
</script>
