<!DOCTYPE html>
<title>Service Worker: getRegistrations()</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script>
// Purge the existing registrations for the origin.
// getRegistrations() is used in order to avoid adding additional complexity
// e.g. adding an internal function.
promise_test(async () => {
  const registrations = await navigator.serviceWorker.getRegistrations();
  await Promise.all(registrations.map(r => r.unregister()));
  const value = await navigator.serviceWorker.getRegistrations();
  assert_array_equals(
      value, [],
      'getRegistrations should resolve with an empty array.');
}, 'registrations are not returned following unregister');

promise_test(async t => {
  const scope = 'resources/scope/getregistrations/normal';
  const script = 'resources/empty-worker.js';
  const registrations = [
      await service_worker_unregister_and_register(t, script, scope)];
  t.add_cleanup(() => registrations[0].unregister());
  const value = await navigator.serviceWorker.getRegistrations();
  assert_array_equals(value, registrations,
      'getRegistrations should resolve with an array of registrations');
}, 'Register then getRegistrations');

promise_test(async t => {
  const scope1 = 'resources/scope/getregistrations/scope1';
  const scope2 = 'resources/scope/getregistrations/scope2';
  const script = 'resources/empty-worker.js';
  t.add_cleanup(() => service_worker_unregister(t, scope1));
  t.add_cleanup(() => service_worker_unregister(t, scope2));

  const registrations = [
      await service_worker_unregister_and_register(t, script, scope1),
      await service_worker_unregister_and_register(t, script, scope2)
  ];
  const value = await navigator.serviceWorker.getRegistrations();
  assert_array_equals(value, registrations);
}, 'Register multiple times then getRegistrations');

promise_test(async t => {
  const scope = 'resources/scope/getregistrations/register-unregister';
  const script = 'resources/empty-worker.js';
  const registration = await service_worker_unregister_and_register(t, script, scope);
  await registration.unregister();
  const value = await navigator.serviceWorker.getRegistrations();
  assert_array_equals(
      value, [], 'getRegistrations should resolve with an empty array.');
}, 'Register then Unregister then getRegistrations');

promise_test(async t => {
  const scope = 'resources/scope/getregistrations/register-unregister-controlled';
  const script = 'resources/empty-worker.js';
  const registration = await service_worker_unregister_and_register(t, script, scope);
  await wait_for_state(t, registration.installing, 'activated');

  // Create a frame controlled by the service worker and unregister the
  // worker.
  const frame = await with_iframe(scope);
  t.add_cleanup(() => frame.remove());
  await registration.unregister();

  const value = await navigator.serviceWorker.getRegistrations();
  assert_array_equals(
      value, [],
      'getRegistrations should resolve with an empty array.');
  assert_equals(registration.installing, null);
  assert_equals(registration.waiting, null);
  assert_equals(registration.active.state, 'activated');
}, 'Register then Unregister with controlled frame then getRegistrations');

promise_test(async t => {
  const host_info = get_host_info();
  // Rewrite the url to point to remote origin.
  const frame_same_origin_url = new URL("resources/frame-for-getregistrations.html", window.location);
  const frame_url = host_info['HTTPS_REMOTE_ORIGIN'] + frame_same_origin_url.pathname;
  const scope = 'resources/scope-for-getregistrations';
  const script = 'resources/empty-worker.js';

  // Loads an iframe and waits for 'ready' message from it to resolve promise.
  // Caller is responsible for removing frame.
  function with_iframe_ready(url) {
      return new Promise(resolve => {
          const frame = document.createElement('iframe');
          frame.src = url;
          window.addEventListener('message', function onMessage(e) {
            window.removeEventListener('message', onMessage);
            if (e.data == 'ready') {
              resolve(frame);
            }
          });
          document.body.appendChild(frame);
      });
  }

  // We need this special frame loading function because the frame is going
  // to register it's own service worker and there is the possibility that that
  // register() finishes after the register() for the same domain later in the
  // test. So we have to wait until the cross origin register() is done, and not
  // just until the frame loads.
  const frame = await with_iframe_ready(frame_url);
  t.add_cleanup(async () => {
    // Wait until the cross-origin worker is unregistered.
    let resolve;
    const channel = new MessageChannel();
    channel.port1.onmessage = e => {
      if (e.data == 'unregistered')
        resolve();
    };
    frame.contentWindow.postMessage('unregister', '*', [channel.port2]);
    await new Promise(r => { resolve = r; });

    frame.remove();
  });

  const registrations = [
    await service_worker_unregister_and_register(t, script, scope)];
  t.add_cleanup(() => registrations[0].unregister());
  const value = await navigator.serviceWorker.getRegistrations();
  assert_array_equals(
      value, registrations,
      'getRegistrations should only return same origin registrations.');
}, 'getRegistrations promise resolves only with same origin registrations.');
</script>
