// META: script=/common/get-host-info.sub.js
// META: script=/common/utils.js
// META: script=/common/dispatcher/dispatcher.js
// META: script=./resources/common.js
// META: script=/service-workers/service-worker/resources/test-helpers.sub.js

const same_origin = get_host_info().HTTPS_ORIGIN;
const cross_origin = get_host_info().HTTPS_REMOTE_ORIGIN;

promise_test(async test => {
  const this_token_1 = token();
  const this_token_2 = token();

  // Register a COEP:none ServiceWorker.
  const sw_token = token();
  const sw_url = executor_service_worker_path + coep_none + `&uuid=${sw_token}`;
  // Executors should be controlled by the service worker.
  const scope = executor_path;
  const sw_registration =
    await service_worker_unregister_and_register(test, sw_url, scope);
  test.add_cleanup(() => sw_registration.unregister());
  await wait_for_state(test, sw_registration.installing, 'activated');

  // Configure the ServiceWorker to proxy the fetch requests. Wait for the
  // worker to be installed and activated.
  send(sw_token, `
    fetchHandler = event => {
      if (!event.request.url.includes("/proxied"))
        return;

      send("${this_token_1}", "ServiceWorker: Proxying");

      // Response with a cross-origin no-cors resource.
      const url = "${cross_origin}" + "/common/blank.html}";

      event.respondWith(new Promise(async resolve => {
        try {
          let response = await fetch(url, {
            mode: "no-cors",
            credentials: "include"
          });
          send("${this_token_1}", "ServiceWorker: Fetch success");
          resolve(response);
        } catch (error) {
          send("${this_token_1}", "ServiceWorker: Fetch failure");
          resolve(new Response("", {status: 400}));
        }
      }));
    }

    await clients.claim();

    send("${this_token_1}", serviceWorker.state);
  `)
  assert_equals(await receive(this_token_1), "activated");

  // Create a COEP:credentialless document.
  const document_token = environments["document"](coep_credentialless)[0];

  // The document fetches a same-origin no-cors resource. The requests needs to
  // be same-origin to be handled by the ServiceWorker.
  send(document_token, `
    try {
      const response = await fetch("/proxied", {
        mode: "no-cors",
        credentials: "include"
      });

      send("${this_token_2}", "Document: Fetch success");
    } catch (error) {
      send("${this_token_2}", "Document: Fetch error");
    }
  `);

  // The COEP:unsafe-none ServiceWorker is able to handle the cross-origin
  // no-cors request, requested with credentials.
  assert_equals(await receive(this_token_1), "ServiceWorker: Proxying");
  assert_equals(await receive(this_token_1), "ServiceWorker: Fetch success");

  // However, the COEP:credentialless Document is disallowed by CORP to get it.
  assert_equals(await receive(this_token_2), "Document: Fetch error");

  // test.add_cleanup doesn't allow waiting for a promise. Unregistering a
  // ServiceWorker is an asynchronous operation. It might not be completed on
  // time for the next test. Do it here for extra flakiness safety.
  await sw_registration.unregister()
}, "COEP:unsafe-none ServiceWorker");
