<!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 scope3 = 'resources/scope/getregistrations/scope12';

  const script = 'resources/empty-worker.js';
  t.add_cleanup(() => service_worker_unregister(t, scope1));
  t.add_cleanup(() => service_worker_unregister(t, scope2));
  t.add_cleanup(() => service_worker_unregister(t, scope3));

  const registrations = [
      await service_worker_unregister_and_register(t, script, scope1),
      await service_worker_unregister_and_register(t, script, scope2),
      await service_worker_unregister_and_register(t, script, scope3),
  ];

  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>
