<!doctype html>
<html>
<title> Retrieve resources from CacheStorage with Cross-Origin-Embedder-Policy: require-corp</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
<script>

/*
  This document does NOT define the Cross-Origin-Embedder-Policy header.
  Cross-Origin Embedder Policy Editor's draft: https://mikewest.github.io/corpp/

  This test is retrieving same-origin and cross-origin resources from the
  CacheStorage. The resources are generated from the ServiceWorker or from the
  network with the header Cross-Origin-Resource-Policy being one of:
    - 'same-origin'
    - 'cross-origin'
    - <undefined>
*/

promise_test(async (t) => {
  const SCOPE = new URL(location.href).pathname;
  const SCRIPT =
    'resources/sw-store-to-cache-storage.js?' +
    `pipe=header(service-worker-allowed,${SCOPE})`;

  const reg = await service_worker_unregister_and_register(t, SCRIPT, SCOPE);
  add_completion_callback(() => reg.unregister());
  await new Promise(resolve => {
    navigator.serviceWorker.addEventListener('controllerchange', resolve);
  });
}, 'setting up');

function remote(path) {
  const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN;
  return new URL(path, REMOTE_ORIGIN);
}

function local(path) {
  return new URL(path, location.origin);
}

// Send a message to the currently active ServiceWorker and wait for its
// response.
function executeCommandInServiceWorker(command) {
  return new Promise(resolve => {
    navigator.serviceWorker.addEventListener('message', e => resolve(e.data));
    navigator.serviceWorker.controller.postMessage(command);
  });
}

// Try loading an image from a |response|. Return a Promise resolving or
// rejecting depending on the image loading result.
const loadFailure = {name: "Image.onerror"};
function readImageFromResponse(response) {
  return new Promise((resolve, reject) => {
    const img = document.createElement("img");
    img.onload = resolve.bind(this, "");
    img.onerror = reject.bind(this, loadFailure);
    response.blob().then(blob => {
      img.src = URL.createObjectURL(blob);
      document.body.appendChild(img);
    })
  })
}

const image_path = "/images/blue.png?pipe=";

const corp_header = {
  "":"",
  "corp-undefined": "",
  "corp-same-origin": "|header(Cross-Origin-Resource-Policy,same-origin)",
  "corp-cross-origin": "|header(Cross-Origin-Resource-Policy,cross-origin)",
}

const cors_header = {
  "":"",
  "cors-disabled": "",
  "cors-enabled": "|header(Access-Control-Allow-Origin,*)",
}

function test(
  // Test parameters:
  request_source, request_origin, request_mode, response_cors, response_corp,
  // Test expectations:
  response_stored, response_type) {
  promise_test(async (t) => {
    // 0. Start from an empty CacheStorage.
    await caches.delete("v1");

    // 1. Make the ServiceWorker to request the ressource and store it into the
    //    CacheStorage.
    const path = image_path +
      corp_header[response_corp] +
      cors_header[response_cors];
    const url = (request_origin === "same-origin" ? local : remote)(path);
    const command = {
      url: url.href,
      mode: request_mode,
      source: request_source,
    };

    assert_equals(await executeCommandInServiceWorker(command), response_stored);
    if (response_stored === "not-stored") {
      return;
    }

    // 2. Make this document to retrieve it from the CacheStorage.
    const cache = await caches.open('v1');
    const response = await cache.match(url);

    assert_equals(response.type, response_type);

    if (request_source === "service-worker") {
      assert_equals("foo", await response.text());
      return;
    }

    // Opaque response are not readable.
    if (response_type === "opaque") {
      await promise_rejects_exactly(t, loadFailure, readImageFromResponse(response));
      return;
    }

    await readImageFromResponse(response);
  }, `Fetch ${request_origin} ${request_mode} ${response_cors} ${response_corp} from ${request_source} and CacheStorage.`)
}

// Responses generated from the ServiceWorker.
{
  test("service-worker", "cross-origin", "cors", "", "", "stored", "default");
  test("service-worker", "cross-origin", "no-cors", "", "", "stored", "default");
  test("service-worker", "same-origin", "cors", "", "", "stored", "default");
  test("service-worker", "same-origin", "no-cors", "", "", "stored", "default");
}

// Responses generated from a same-origin server.
{
  const t = test.bind(this, "network", "same-origin");
  t("cors", "cors-disabled", "corp-cross-origin", "stored", "basic");
  t("cors", "cors-disabled", "corp-same-origin", "stored", "basic");
  t("cors", "cors-disabled", "corp-undefined", "stored", "basic");
  t("cors", "cors-enabled", "corp-cross-origin", "stored", "basic");
  t("cors", "cors-enabled", "corp-same-origin", "stored", "basic");
  t("cors", "cors-enabled", "corp-undefined", "stored", "basic");
  t("no-cors", "cors-disabled", "corp-cross-origin", "stored", "basic");
  t("no-cors", "cors-disabled", "corp-same-origin", "stored", "basic");
  t("no-cors", "cors-disabled", "corp-undefined", "stored", "basic");
  t("no-cors", "cors-enabled", "corp-cross-origin", "stored", "basic");
  t("no-cors", "cors-enabled", "corp-same-origin", "stored", "basic");
  t("no-cors", "cors-enabled", "corp-undefined", "stored", "basic");
}

// Responses generated from a cross-origin server.
{
  const t = test.bind(this, "network", "cross-origin");
  t("cors", "cors-disabled", "corp-cross-origin", "not-stored");
  t("cors", "cors-disabled", "corp-same-origin", "not-stored");
  t("cors", "cors-disabled", "corp-undefined", "not-stored");
  t("cors", "cors-enabled", "corp-cross-origin", "stored", "cors");
  t("cors", "cors-enabled", "corp-same-origin", "stored", "cors");
  t("cors", "cors-enabled", "corp-undefined", "stored", "cors");
  t("no-cors", "cors-disabled", "corp-cross-origin", "stored", "opaque");
  t("no-cors", "cors-disabled", "corp-same-origin", "not-stored");
  t("no-cors", "cors-disabled", "corp-undefined", "stored", "opaque");
  t("no-cors", "cors-enabled", "corp-cross-origin", "stored", "opaque");
  t("no-cors", "cors-enabled", "corp-same-origin", "not-stored");
  t("no-cors", "cors-enabled", "corp-undefined", "stored", "opaque");
}

</script>
</html>
