<!DOCTYPE html>
<meta charset="utf-8"/>
<title>Service Worker: Partitioned Service Workers</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 src="resources/partitioned-utils.js"></script>

<body>
This test loads a SW in a first-party context and gets the SW's (randomly)
generated ID. It does the same thing for the SW but in a third-party context
and then confirms that the IDs are different.

<script>
promise_test(async t => {
  const script = './resources/partitioned-storage-sw.js'
  const scope = './resources/partitioned-'
  const absoluteScope = new URL(scope, window.location).href;

  // Add service worker to this 1P context.
  const reg = await service_worker_unregister_and_register(t, script, scope);
  t.add_cleanup(() => reg.unregister());
  await wait_for_state(t, reg.installing, 'activated');

  // Register the message listener.
  self.addEventListener('message', messageEventHandler);

  // Open an iframe that will create a promise within the SW.
  // The query param is there to track which request the service worker is
  // handling.
  //
  // This promise is necessary to prevent the service worker from being
  // shutdown during the test which would cause a new ID to be generated
  // and thus invalidate the test.
  const wait_frame_url = new URL(
    './resources/partitioned-waitUntilResolved.fakehtml?From1pFrame',
    self.location);

  // We don't really need the data the SW sent us from this request
  // but we can use the ID to confirm the SW wasn't shut down during the
  // test.
  const wait_frame_1p_data = await loadAndReturnSwData(t, wait_frame_url,
                                                       'iframe');

  // Now we need to create a third-party iframe that will send us its SW's
  // ID.
  const third_party_iframe_url = new URL(
    './resources/partitioned-service-worker-third-party-iframe-getRegistrations.html',
    get_host_info().HTTPS_ORIGIN + self.location.pathname);

  // Create the 3p window (which will in turn create the iframe with the SW)
  // and await on its data.
  const frame_3p_ID = await loadAndReturnSwData(t, third_party_iframe_url,
    'window');

  // Now get this frame's SW's ID.
  const frame_1p_ID_promise = makeMessagePromise();

  const retrieved_registrations =
        await navigator.serviceWorker.getRegistrations();
  // It's possible that other tests have left behind other service workers.
  // This steps filters those other SWs out.
  const filtered_registrations =
    retrieved_registrations.filter(reg => reg.scope == absoluteScope);

  // Register a listener on the service worker container and then forward to
  // the self event listener so we can reuse the existing message promise
  // function.
  navigator.serviceWorker.addEventListener('message', evt => {
    self.postMessage(evt.data, '*');
  });

  filtered_registrations[0].active.postMessage({type: "get-id"});

  const  frame_1p_ID = await frame_1p_ID_promise;

  // First check that the SW didn't shutdown during the run of the test.
  // (Note: We're not using assert_equals because random values make it
  // difficult to use a test expectations file.)
  assert_true(wait_frame_1p_data.ID === frame_1p_ID.ID,
    "1p SW didn't shutdown");
  // Now check that the 1p and 3p IDs differ.
  assert_false(frame_1p_ID.ID === frame_3p_ID.ID,
    "1p SW ID matches 3p SW ID");

  // Finally, for clean up, resolve the SW's promise so it stops waiting.
  const resolve_frame_url = new URL(
    './resources/partitioned-resolve.fakehtml?From1pFrame', self.location);

  // We don't care about the data.
  await loadAndReturnSwData(t, resolve_frame_url, 'iframe');

}, "ServiceWorker's getRegistrations() is partitioned");


</script>

</body>