<!DOCTYPE html>
<meta charset=utf-8>
<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>
<!-- Pull in executor_path needed by newPopup / newIframe -->
<script src="/html/cross-origin-embedder-policy/credentialless/resources/common.js"></script>
<!-- Pull in importScript / newPopup / newIframe -->
<script src="/html/anonymous-iframe/resources/common.js"></script>
<body>
<script>

const fetch_unsuccessful_response = "Fetch failed";
const fetch_successful_response = "Fetch succeeded";
const js_finished = "revoking blob_url js finished";

// Fetches a previously revoked blob_url to see if the revoking was successful.
async function fetch_contents_check(blob_url) {
  try {
    const blob = await fetch(blob_url).then(response => response.blob());
    await blob.text();
  } catch(e) {
    return fetch_unsuccessful_response;
  }
  return fetch_successful_response;
}

const can_blob_url_be_revoked_js = (blob_url, response_queue_name) => `
  async function test() {
    if (!('revokeObjectURL' in URL)) {
      return send("${response_queue_name}", "URL.revokeObjectURL is not exposed");
    }
    try {
      URL.revokeObjectURL("${blob_url}");
    } catch(e) {
      return send("${response_queue_name}", e.toString());
    }

    // Create, fetch, and revoke a separate blob URL to better ensure that the
    // revoke call above has had time to take effect before we return.
    const blob_1 = new Blob(["blob data"], {type : "text/plain"});
    const blob_url_1 = URL.createObjectURL(blob_1);
    await fetch(blob_url_1).then(response => response.blob());
    URL.revokeObjectURL(blob_url_1);

    return send("${response_queue_name}", "${js_finished}");
  }
  await test();
`;

const can_blob_url_be_fetched_js = (blob_url, response_queue_name) => `
  async function test() {
    try {
      const blob = await fetch("${blob_url}").then(response => response.blob());
      await blob.text();
    } catch(e) {
      return send("${response_queue_name}", "${fetch_unsuccessful_response}");
    }

    return send("${response_queue_name}", "${fetch_successful_response}");
  }
  await test();
`;

const add_iframe_js = (iframe_origin, response_queue_uuid) => `
  const importScript = ${importScript};
  await importScript("/html/cross-origin-embedder-policy/credentialless" +
                   "/resources/common.js");
  await importScript("/html/anonymous-iframe/resources/common.js");
  await importScript("/common/utils.js");

  // dispatcher.js has already been loaded by the popup this is running in.
  await send("${response_queue_uuid}", newIframe("${iframe_origin}"));
`;

const same_site_origin = get_host_info().HTTPS_ORIGIN;
const cross_site_origin = get_host_info().HTTPS_NOTSAMESITE_ORIGIN;

async function create_test_iframes(t, response_queue_uuid) {
  assert_equals("https://" + window.location.host, same_site_origin,
  "this test assumes that the page's window.location.host corresponds to " +
  "get_host_info().HTTPS_ORIGIN");

  // Create a same-origin iframe in a cross-site popup.
  const not_same_site_popup_uuid = newPopup(t, cross_site_origin);
  await send(not_same_site_popup_uuid,
       add_iframe_js(same_site_origin, response_queue_uuid));
  const cross_site_iframe_uuid = await receive(response_queue_uuid);

  // Create a same-origin iframe in a same-site popup.
  const same_origin_popup_uuid = newPopup(t, same_site_origin);
  await send(same_origin_popup_uuid,
       add_iframe_js(same_site_origin, response_queue_uuid));
  const same_site_iframe_uuid = await receive(response_queue_uuid);

  return [cross_site_iframe_uuid, same_site_iframe_uuid];
}

// Tests revoking blob URL for same and cross partition iframes.
promise_test(t => {
  return new Promise(async (resolve, reject) => {
    try {
      // Creates blob URL.
      const blob = new Blob(["blob data"], {type : "text/plain"});
      const blob_url = window.URL.createObjectURL(blob);

      // Fetches blob URL to ensure that it's valid.
      const blob_fetch = await fetch_contents_check(blob_url);
      if (blob_fetch !== fetch_successful_response) {
        reject("Blob URL invalid");
      }

      // Creates same and cross partition iframes.
      const response_queue_uuid = token();

      const [cross_site_iframe_uuid, same_site_iframe_uuid] =
        await create_test_iframes(t, response_queue_uuid);

      // Attempt to revoke blob URL in cross partition iframe.
      await send(cross_site_iframe_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid));
      var response_1 = await receive(response_queue_uuid);
      if (response_1 !== js_finished) {
        reject(response_1);
      }
      response_1 = await fetch_contents_check(blob_url);
      if (response_1 !== fetch_successful_response) {
        reject(`Blob URL was revoked in not-same-top-level-site iframe: ${response_1}`);
      }

      // Attempt to revoke blob URL in same partition iframe.
      await send(same_site_iframe_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid));
      var response_2 = await receive(response_queue_uuid);
      if (response_2 !== js_finished) {
        reject(response_2);
      }
      response_2 = await fetch_contents_check(blob_url);
      if (response_2 !== fetch_unsuccessful_response) {
        t.add_cleanup(() => window.URL.revokeObjectURL(blob_url));
        reject(`Blob URL wasn't revoked in same-top-level-site iframe: ${response_2}`);
      }

      resolve();
    } catch (e) {
      reject(e);
    }
  });
}, "Blob URL shouldn't be revocable from a cross-partition iframe");

const newWorker = (origin) => {
  const worker_token = token();
  const worker_url = origin + executor_worker_path + `&uuid=${worker_token}`;
  const worker = new Worker(worker_url);
  return worker_token;
}

const create_dedicated_worker_js = (origin, response_queue_uuid) => `
  const importScript = ${importScript};
  await importScript("/html/cross-origin-embedder-policy/credentialless" +
                    "/resources/common.js");
  await importScript("/html/anonymous-iframe/resources/common.js");
  await importScript("/common/utils.js");

  // dispatcher.js has already been loaded by the popup this is running in.
  const newWorker = ${newWorker};
  await send("${response_queue_uuid}", newWorker("${origin}"));
`;

// Tests revoking blob URL from same and cross partition dedicated worker.
promise_test(t => {
  return new Promise(async (resolve, reject) => {
    try {
      const response_queue_uuid = token();

      const [cross_site_iframe_uuid, same_site_iframe_uuid] =
        await create_test_iframes(t, response_queue_uuid);

      await send(cross_site_iframe_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid));
      const worker_1_uuid = await receive(response_queue_uuid);

      await send(same_site_iframe_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid));
      const worker_2_uuid = await receive(response_queue_uuid);

      const blob = new Blob(["blob data"], {type : "text/plain"});
      const blob_url = window.URL.createObjectURL(blob);

      await send(worker_1_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid));
      var response_1 = await receive(response_queue_uuid);
      if (response_1 !== js_finished) {
        reject(response_1);
      }
      response_1 = await fetch_contents_check(blob_url);
      if (response_1 !== fetch_successful_response) {
        reject(`Blob URL was revoked in not-same-top-level-site dedicated worker: ${response_1}`);
      }

      await send(worker_2_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid));
      var response_2 = await receive(response_queue_uuid);
      if (response_2 !== js_finished) {
        reject(response_2);
      }
      response_2 = await fetch_contents_check(blob_url);
      if (response_2 !== fetch_unsuccessful_response) {
        t.add_cleanup(() => window.URL.revokeObjectURL(blob_url));
        reject(`Blob URL wasn't revoked in same-top-level-site dedicated worker: ${response_2}`);
      }

      resolve();
    } catch (e) {
      reject(e);
    }
  });
}, "Blob URL shouldn't be revocable from a cross-partition dedicated worker");

const newSharedWorker = (origin) => {
  const worker_token = token();
  const worker_url = origin + executor_worker_path + `&uuid=${worker_token}`;
  const worker = new SharedWorker(worker_url, worker_token);
  return worker_token;
}

const create_shared_worker_js = (origin, response_queue_uuid) => `
  const importScript = ${importScript};
  await importScript("/html/cross-origin-embedder-policy/credentialless" +
                    "/resources/common.js");
  await importScript("/html/anonymous-iframe/resources/common.js");
  await importScript("/common/utils.js");

  // dispatcher.js has already been loaded by the popup this is running in.
  const newSharedWorker = ${newSharedWorker};
  await send("${response_queue_uuid}", newSharedWorker("${origin}"));
`;

// Tests revoking blob URL from same and cross partition shared worker.
promise_test(t => {
  return new Promise(async (resolve, reject) => {
    try {
      const response_queue_uuid = token();

      const [cross_site_iframe_uuid, same_site_iframe_uuid] =
        await create_test_iframes(t, response_queue_uuid);

      // Create a shared worker in the cross-top-level-site iframe.
      await send(cross_site_iframe_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid));
      const worker_1_uuid = await receive(response_queue_uuid);

      // Create a shared worker in the same-top-level-site iframe.
      await send(same_site_iframe_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid));
      const worker_2_uuid = await receive(response_queue_uuid);

      const blob = new Blob(["blob data"], {type : "text/plain"});
      const blob_url = window.URL.createObjectURL(blob);

      await send(worker_1_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid));
      var response_1 = await receive(response_queue_uuid);
      if (response_1 !== js_finished) {
        reject(response_1);
      }
      response_1 = await fetch_contents_check(blob_url);
      if (response_1 !== fetch_successful_response) {
        reject(`Blob URL was revoked in not-same-top-level-site shared worker: ${response_1}`);
      }

      await send(worker_2_uuid, can_blob_url_be_revoked_js(blob_url, response_queue_uuid));
      var response_2 = await receive(response_queue_uuid);
      if (response_2 !== js_finished) {
        reject(response_2);
      }
      response_2 = await fetch_contents_check(blob_url);
      if (response_2 !== fetch_unsuccessful_response) {
        t.add_cleanup(() => window.URL.revokeObjectURL(blob_url));
        reject(`Blob URL wasn't revoked in same-top-level-site shared worker: ${response_2}`);
      }

      resolve();
    } catch (e) {
      reject(e);
    }
  });
}, "Blob URL shouldn't be revocable from a cross-partition shared worker");

const newServiceWorker = async (origin) => {
  const worker_token = token();
  const worker_url = origin + executor_service_worker_path +
                     `&uuid=${worker_token}`;
  const worker_url_path = executor_service_worker_path.substring(0,
                              executor_service_worker_path.lastIndexOf('/'));
  const scope = worker_url_path + "/not-used/";
  const reg = await navigator.serviceWorker.register(worker_url,
                                                     {'scope': scope});
  return worker_token;
}

const create_service_worker_js = (origin, response_queue_uuid) => `
  const importScript = ${importScript};
  await importScript("/html/cross-origin-embedder-policy/credentialless" +
                    "/resources/common.js");
  await importScript("/html/anonymous-iframe/resources/common.js");
  await importScript("/common/utils.js");

  // dispatcher.js has already been loaded by the popup this is running in.
  const newServiceWorker = ${newServiceWorker};
  await send("${response_queue_uuid}", await newServiceWorker("${origin}"));
`;

// Tests revoking blob URL from a service worker.
promise_test(t => {
  return new Promise(async (resolve, reject) => {
    try {
      const response_queue_uuid = token();

      const [cross_site_iframe_uuid, same_site_iframe_uuid] =
        await create_test_iframes(t, response_queue_uuid);

      // Create a service worker in either iframe.
      await send(cross_site_iframe_uuid, create_service_worker_js(same_site_origin, response_queue_uuid));
      var worker_1_uuid = await receive(response_queue_uuid);
      t.add_cleanup(() =>
        send(worker_1_uuid, "self.registration.unregister();"));

      const blob = new Blob(["blob data"], {type : "text/plain"});
      const blob_url = window.URL.createObjectURL(blob);
      t.add_cleanup(() => window.URL.revokeObjectURL(blob_url));

      await send(worker_1_uuid,
           can_blob_url_be_revoked_js(blob_url, response_queue_uuid));
      const response = await receive(response_queue_uuid);
      if (response !== "URL.revokeObjectURL is not exposed") {
        reject(`URL.revokeObjectURL is exposed in a Service Worker context: ${response}`);
      }
      resolve();
    } catch (e) {
      reject(e);
    }
  });
}, "Blob URL shouldn't be revocable from a service worker");

// Tests fetching blob URL for same and cross partition iframes.
promise_test(t => {
  return new Promise(async (resolve, reject) => {
    try {
      // Creates blob URL.
      const blob = new Blob(["blob data"], {type : "text/plain"});
      const blob_url = window.URL.createObjectURL(blob);
      t.add_cleanup(() => window.URL.revokeObjectURL(blob_url));

      // Fetches blob URL to ensure that it's valid.
      const blob_fetch = await fetch_contents_check(blob_url);
      if (blob_fetch !== fetch_successful_response) {
        reject("Blob URL invalid");
      }

      // Creates same and cross partition iframes.
      const response_queue_uuid = token();

      const [cross_site_iframe_uuid, same_site_iframe_uuid] =
        await create_test_iframes(t, response_queue_uuid);

      // Attempt to fetch blob URL in cross partition iframe.
      await send(cross_site_iframe_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid));
      var response_1 = await receive(response_queue_uuid);
      if (response_1 !== fetch_unsuccessful_response) {
        reject(`Blob URL was fetched in not-same-top-level-site iframe: ${response_1}`);
      }

      // Attempt to fetch blob URL in same partition iframe.
      await send(same_site_iframe_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid));
      var response_2 = await receive(response_queue_uuid);
      if (response_2 !== fetch_successful_response) {
        reject(`Blob URL wasn't fetched in same-top-level-site iframe: ${response_2}`);
      }

      resolve();
    } catch (e) {
      reject(e);
    }
  });
}, "Blob URL shouldn't be fetched from a cross-partition iframe");

// Tests fetching blob URL from same and cross partition dedicated worker.
promise_test(t => {
  return new Promise(async (resolve, reject) => {
    try {
      const response_queue_uuid = token();

      // Creates same and cross partition iframes.
      const [cross_site_iframe_uuid, same_site_iframe_uuid] =
        await create_test_iframes(t, response_queue_uuid);

      // Creates a dedicated worker in the cross-top-level-site iframe.
      await send(cross_site_iframe_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid));
      const worker_1_uuid = await receive(response_queue_uuid);

      // Creates a dedicated worker in the same-top-level-site iframe.
      await send(same_site_iframe_uuid, create_dedicated_worker_js(same_site_origin, response_queue_uuid));
      const worker_2_uuid = await receive(response_queue_uuid);

      const blob = new Blob(["blob data"], {type : "text/plain"});
      const blob_url = window.URL.createObjectURL(blob);
      t.add_cleanup(() => window.URL.revokeObjectURL(blob_url));

      // Attempts to fetch in the cross-top-level-site dedicated worker.
      await send(worker_1_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid));
      var response_1 = await receive(response_queue_uuid);
      if (response_1 !== fetch_unsuccessful_response) {
        reject(`Blob URL was fetched in not-same-top-level-site dedicated worker: ${response_1}`);
      }

      // Attempts to fetch in the same-top-level-site dedicated worker.
      await send(worker_2_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid));
      var response_2 = await receive(response_queue_uuid);
      if (response_2 !== fetch_successful_response) {
        reject(`Blob URL wasn't fetched in same-top-level-site dedicated worker: ${response_2}`);
      }

      resolve();
    } catch (e) {
      reject(e);
    }
  });
}, "Blob URL shouldn't be fetched from a cross-partition dedicated worker");

// Tests fetching blob URL from same and cross partition shared worker.
promise_test(t => {
  return new Promise(async (resolve, reject) => {
    try {
      const response_queue_uuid = token();

      const [cross_site_iframe_uuid, same_site_iframe_uuid] =
        await create_test_iframes(t, response_queue_uuid);

      // Create a shared worker in the cross-top-level-site iframe.
      await send(cross_site_iframe_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid));
      const worker_1_uuid = await receive(response_queue_uuid);

      // Create a shared worker in the same-top-level-site iframe.
      await send(same_site_iframe_uuid, create_shared_worker_js(same_site_origin, response_queue_uuid));
      const worker_2_uuid = await receive(response_queue_uuid);

      const blob = new Blob(["blob data"], {type : "text/plain"});
      const blob_url = window.URL.createObjectURL(blob);
      t.add_cleanup(() => window.URL.revokeObjectURL(blob_url));

      // Attempts to fetch in the cross-top-level-site shared worker.
      await send(worker_1_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid));
      var response_1 = await receive(response_queue_uuid);
      if (response_1 !== fetch_unsuccessful_response) {
        reject(`Blob URL was fetched in not-same-top-level-site shared worker: ${response_1}`);
      }

      // Attempts to fetch in the same-top-level-site shared worker.
      await send(worker_2_uuid, can_blob_url_be_fetched_js(blob_url, response_queue_uuid));
      var response_2 = await receive(response_queue_uuid);
      if (response_2 !== fetch_successful_response) {
        reject(`Blob URL wasn't fetched in same-top-level-site shared worker: ${response_2}`);
      }

      resolve();
    } catch (e) {
      reject(e);
    }
  });
}, "Blob URL shouldn't be fetched from a cross-partition shared worker");

// Tests fetching blob URL from a cross partition service worker.
promise_test(t => {
  return new Promise(async (resolve, reject) => {
    try {
      const response_queue_uuid = token();

      const [cross_site_iframe_uuid, same_site_iframe_uuid] =
        await create_test_iframes(t, response_queue_uuid);

      const blob = new Blob(["blob data"], {type : "text/plain"});
      const blob_url = window.URL.createObjectURL(blob);
      t.add_cleanup(() => window.URL.revokeObjectURL(blob_url));

      // Create a service worker in cross-top-level-site iframe.
      await send(cross_site_iframe_uuid, create_service_worker_js(same_site_origin, response_queue_uuid));
      var worker_1_uuid = await receive(response_queue_uuid);
      t.add_cleanup(() =>
        send(worker_1_uuid, "self.registration.unregister();"));

      await send(worker_1_uuid,
           can_blob_url_be_fetched_js(blob_url, response_queue_uuid));
      const response_1 = await receive(response_queue_uuid);
      if (response_1 !== fetch_unsuccessful_response) {
        reject(`Blob URL was fetched in not-same-top-level-site service worker: ${response_1}`);
      }

      // Create a service worker in same-top-level-site iframe.
      await send(same_site_iframe_uuid, create_service_worker_js(same_site_origin, response_queue_uuid));
      var worker_2_uuid = await receive(response_queue_uuid);
      t.add_cleanup(() =>
        send(worker_2_uuid, "self.registration.unregister();"));

      await send(worker_2_uuid,
           can_blob_url_be_fetched_js(blob_url, response_queue_uuid));
      const response_2 = await receive(response_queue_uuid);
      if (response_2 !== fetch_successful_response) {
        reject(`Blob URL wasn't fetched in same-top-level-site service worker: ${response_2}`);
      }
      resolve();
    } catch (e) {
      reject(e);
    }
  });
}, "Blob URL shouldn't be fetched from a cross-partition service worker");

</script>
</body>
