<!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.
function readImageFromResponse(response) {
  return new Promise((resolve, reject) => {
    const img = document.createElement("img");
    img.onload = resolve.bind(this, "");
    img.onerror = reject.bind(this, {name: "Image.onerror"});
    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(t, {name: "Image.onerror"}, 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>
