<!DOCTYPE html>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/common/utils.js"></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="../resources/utils.js"></script>
<script src="resources/utils.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>

<script>

function getNextWindowMessageFromFrame(frame) {
  return new Promise(resolve => {
    window.addEventListener('message', event => {
      if (event.source === frame.contentWindow) {
        resolve(event.data);
      }
    });
  });
}

function getNextMessageFromServiceWorker(serviceWorker) {
  return new Promise(resolve => {
    serviceWorker.addEventListener('message', event => {
      resolve(event.data);
    }, {once: true});
  });
}

promise_setup(async () => {
  assertSpeculationRulesIsSupported()
  await test_driver.set_rph_registration_mode('autoAccept');
  await test_driver.bless('handler registration');
});

// The overall idea for this test is:
// 1. Register a protocol handler for a custom URI scheme.
// 2. Create a prerendered page that unregisters the protocol handler.
// 3. Navigate an iframe to the custom URI scheme. It should navigate
// successfully.
// 4. Activate the prerendered page. This should run the deferred unregistration
// work.
// 5. Navigate the iframe to the custom URI scheme again. It should fail to
// navigate.
// To detect the navigation failure, we use a service worker to perform the
// navigation via client.navigate and report the result back to
// the test. This is because the service worker's client.navigate method
// actually reports if the navigation failed, unlike other mechanisms which
// tell us nothing in this case.
promise_test(async t => {
  const customUrlScheme = 'web+wptrphtest';
  function getProtocolHandlerUrlTemplate(id) {
    return new URL(
        `resources/protocol-handler.html?id=${id}&s=%s`, location.href).href;
  }

  const urlTemplate = getProtocolHandlerUrlTemplate('unregister');

  t.add_cleanup(() => {
    navigator.unregisterProtocolHandler(
        customUrlScheme, urlTemplate);
  });
  navigator.registerProtocolHandler(customUrlScheme, urlTemplate);

  const {exec, activate} = await create_prerendered_page(t);

  const result = await exec(
      (customUrlScheme, urlTemplate) => {
        try {
          navigator.unregisterProtocolHandler(
              customUrlScheme, urlTemplate);
        } catch (registerProtocolHandlerException) {
          return 'registerProtocolHandler failed with \'' +
              registerProtocolHandlerException.name + '\'';
        }
        return 'success';
  }, [customUrlScheme, urlTemplate]);
  assert_equals(result, 'success', 'unregisterProtocolHandler should succeed.');

  const frame1 = await with_iframe('about:blank');

  const frame1MessagePromise = getNextWindowMessageFromFrame(frame1);
  frame1.src = `${customUrlScheme}:1`;
  assert_equals((await frame1MessagePromise).id, 'unregister',
    'Until activation, the initial handler should be registered.');

  frame1.remove();

  // Activate the prerendered page.
  await activate();

  // At this point the deferred unregistration work has run during activation
  // and the protocol handler is no longer registered.
  // We use Service Worker client.navigate to detect the failed navigation since
  // it is well supported and reliably reports error for unknown URL schemes.
  const serviceWorkerScope =
      'resources/protocol-handler.html?service_worker_client';
  const frame2Url = serviceWorkerScope + '&id=communication';
  const frame3Url = serviceWorkerScope + '&id=nav_target';
  const serviceWorkerUrl = 'resources/protocol-handler-service-worker.js';
  const serviceWorkerRegistration =
      await service_worker_unregister_and_register(
          t, serviceWorkerUrl, serviceWorkerScope);

  t.add_cleanup(async () => {
    await serviceWorkerRegistration.unregister();
  });

  await wait_for_state(t, serviceWorkerRegistration.installing, 'activated');

  // We use frame2 to communicate with the service worker.
  const frame2 = await with_iframe(frame2Url);

  // Frame3 is used by the service worker to attempt navigation.
  const frame3 = await with_iframe(frame3Url);

  const serviceWorkerMessagePromise = getNextMessageFromServiceWorker(
      frame2.contentWindow.navigator.serviceWorker);

  // Post message via frame2 to the service worker to tell it to navigate frame3
  // to the custom URI.
  frame2.contentWindow.navigator.serviceWorker.controller.postMessage(
      {clientUrlMatch: new URL(frame3Url, location.href).href,
       navigationUrl: `${customUrlScheme}:3`});

  // The service worker will post message back the result of the navigation.
  const navigationResult = await serviceWorkerMessagePromise;

  frame2.remove();
  frame3.remove();

  assert_false(navigationResult.success, 'Navigation to unregistered URI should fail');
  assert_equals(navigationResult.message, 'navigate failure: TypeError',
      'unregisterProtocolHandler should have completed.');
}, 'prerendering page unregisterProtocolHandler call defers registration until activation.');

</script>