<!DOCTYPE html>
<title>Service Worker: navigator.serviceWorker.ready</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<body>
<script>
test(function() {
    var promise = navigator.serviceWorker.ready;
    assert_equals(promise, navigator.serviceWorker.ready,
                  'repeated access to ready without intervening ' +
                  'registrations should return the same Promise object');
  }, 'ready returns the same Promise object');

promise_test(function(t) {
    return with_iframe('resources/blank.html?uncontrolled')
      .then(t.step_func(function(frame) {
          var promise = frame.contentWindow.navigator.serviceWorker.ready;
          t.add_cleanup(function() {
              frame.remove();
            });

          assert_equals(Object.getPrototypeOf(promise),
                        frame.contentWindow.Promise.prototype,
                        'the Promise should be in the context of the ' +
                        'related document');
        }));
  }, 'ready returns a Promise object in the context of the related document');

promise_test(function(t) {
    var url = 'resources/empty-worker.js';
    var scope = 'resources/blank.html?ready-controlled';
    var expected_url = normalizeURL(url);
    var frame;

    return service_worker_unregister_and_register(t, url, scope)
      .then(function(registration) {
          add_completion_callback(function() {
              registration.unregister();
            });
          return wait_for_state(t, registration.installing, 'activated');
        })
      .then(function() { return with_iframe(scope); })
      .then(function(f) {
          t.add_cleanup(function() {
              f.remove();
            });
          frame = f;
          return frame.contentWindow.navigator.serviceWorker.ready;
        })
      .then(function(registration) {
          assert_equals(registration.installing, null,
                        'installing should be null');
          assert_equals(registration.waiting, null,
                        'waiting should be null');
          assert_equals(registration.active.scriptURL, expected_url,
                        'active after ready should not be null');
          assert_equals(frame.contentWindow.navigator.serviceWorker.controller,
                        registration.active,
                        'the controller should be the active worker');
          assert_in_array(registration.active.state,
                          ['activating', 'activated'],
                          '.ready should be resolved when the registration ' +
                          'has an active worker');
        });
  }, 'ready on a controlled document');

promise_test(function(t) {
    var url = 'resources/empty-worker.js';
    var scope = 'resources/blank.html?ready-potential-controlled';
    var expected_url = normalizeURL(url);
    var frame;

    return with_iframe(scope)
      .then(function(f) {
          t.add_cleanup(function() {
              f.remove();
            });
          frame = f;
          return navigator.serviceWorker.register(url, {scope:scope});
        })
      .then(function(r) {
          add_completion_callback(function() {
              r.unregister();
            });
          return frame.contentWindow.navigator.serviceWorker.ready;
        })
      .then(function(registration) {
          assert_equals(registration.installing, null,
                        'installing should be null');
          assert_equals(registration.waiting, null,
                        'waiting should be null.')
          assert_equals(registration.active.scriptURL, expected_url,
                        'active after ready should not be null');
          assert_in_array(registration.active.state,
                          ['activating', 'activated'],
                          '.ready should be resolved when the registration ' +
                          'has an active worker');
          assert_equals(frame.contentWindow.navigator.serviceWorker.controller,
                        null,
                        'uncontrolled document should not have a controller');
        });
  }, 'ready on a potential controlled document');

promise_test(function(t) {
    var url = 'resources/empty-worker.js';
    var scope = 'resources/blank.html?ready-installing';

    return service_worker_unregister(t, scope)
      .then(function() {
          return with_iframe(scope);
        })
      .then(function(f) {
          var promise = f.contentWindow.navigator.serviceWorker.ready;
          t.add_cleanup(function() {
              f.remove();
            });
          navigator.serviceWorker.register(url, {scope: scope});
          return promise;
        })
      .then(function(registration) {
          add_completion_callback(function() {
              registration.unregister();
            });

          assert_equals(registration.installing, null,
                        'installing should be null');
          assert_equals(registration.waiting, null, 'waiting should be null');
          assert_not_equals(registration.active, null,
                            'active after ready should not be null');
          assert_in_array(registration.active.state,
                          ['activating', 'activated'],
                          '.ready should be resolved when the registration ' +
                          'has an active worker');
       });
 }, 'ready on an iframe whose parent registers a new service worker');

promise_test(function(t) {
    var url = 'resources/empty-worker.js';
    var scope = 'resources/register-iframe.html';
    var expected_url = normalizeURL(url);

    return with_iframe(scope)
      .then(function(f) {
          t.add_cleanup(function() {
              f.remove();
            });
          return f.contentWindow.navigator.serviceWorker.ready;
        })
      .then(function(registration) {
          add_completion_callback(function() {
              registration.unregister();
            });

          assert_equals(registration.installing, null,
                        'installing should be null');
          assert_equals(registration.waiting, null, 'waiting should be null');
          assert_not_equals(registration.active, null,
                            'active after ready should not be null');
          assert_in_array(registration.active.state,
                          ['activating', 'activated'],
                          '.ready should be resolved with "active worker"');
       });
 }, 'ready on an iframe that installs a new service worker');

promise_test(function(t) {
    var url = 'resources/empty-worker.js';
    var matched_scope = 'resources/blank.html?ready-after-match';
    var longer_matched_scope = 'resources/blank.html?ready-after-match-longer';
    var frame, registration;

    return Promise.all([service_worker_unregister(t, matched_scope),
                        service_worker_unregister(t, longer_matched_scope)])
      .then(function() {
          return with_iframe(longer_matched_scope);
        })
      .then(function(f) {
          t.add_cleanup(function() {
              f.remove();
            });
          frame = f;
          return navigator.serviceWorker.register(url, {scope: matched_scope});
        })
      .then(function(r) {
          add_completion_callback(function() {
              r.unregister();
            });
          registration = r;
          return wait_for_state(t, r.installing, 'activated');
        })
      .then(function() {
          return navigator.serviceWorker.register(
              url, {scope: longer_matched_scope});
        })
      .then(function(r) {
          add_completion_callback(function() {
              r.unregister();
            });
          return frame.contentWindow.navigator.serviceWorker.ready;
        })
      .then(function(r) {
          assert_equals(r.scope, normalizeURL(longer_matched_scope),
                        'longer matched registration should be returned');
          assert_equals(frame.contentWindow.navigator.serviceWorker.controller,
                        null, 'controller should be null');
        });
  }, 'ready after a longer matched registration registered');

promise_test(function(t) {
    var url = 'resources/empty-worker.js';
    var matched_scope = 'resources/blank.html?ready-after-resolve';
    var longer_matched_scope =
        'resources/blank.html?ready-after-resolve-longer';
    var frame, registration;

    return service_worker_unregister_and_register(t, url, matched_scope)
      .then(function(r) {
          add_completion_callback(function() {
              r.unregister();
            });
          registration = r;
          return wait_for_state(t, r.installing, 'activated');
        })
      .then(function() {
          return with_iframe(longer_matched_scope);
        })
      .then(function(f) {
          t.add_cleanup(function() {
              f.remove();
            });
          frame = f;
          return f.contentWindow.navigator.serviceWorker.ready;
        })
      .then(function(r) {
          assert_equals(r.scope, normalizeURL(matched_scope),
                        'matched registration should be returned');
          return navigator.serviceWorker.register(
              url, {scope: longer_matched_scope});
        })
      .then(function(r) {
          add_completion_callback(function() {
              r.unregister();
            });
          return frame.contentWindow.navigator.serviceWorker.ready;
        })
      .then(function(r) {
          assert_equals(r.scope, normalizeURL(matched_scope),
                        'ready should only be resolved once');
        });
  }, 'access ready after it has been resolved');

promise_test(async function(t) {
  const url1 = 'resources/empty-worker.js';
  const url2 = url1 + '?2';
  const matched_scope = 'resources/blank.html?ready-after-unregister';

  const reg1 = await service_worker_unregister_and_register(t, url1, matched_scope);
  t.add_cleanup(() => reg1.unregister());

  await wait_for_state(t, reg1.installing, 'activating');
  // This registration will resolve all ready promises in clients that match the scope.
  // But there are no clients.

  const frame = await with_iframe(matched_scope);
  t.add_cleanup(() => frame.remove());

  await reg1.unregister();

  // Access the ready promise while the registration is unregistering.
  const readyPromise = frame.contentWindow.navigator.serviceWorker.ready;

  // Create a new registration.
  const reg2 = await navigator.serviceWorker.register(url2, { scope: matched_scope });
  t.add_cleanup(() => reg2.unregister());
  // This registration will resolve all ready promises in clients that match the scope.
  // That includes frame's client.

  const readyReg = await readyPromise;

  assert_equals(readyReg.active.scriptURL, reg2.active.scriptURL, 'Resolves with the second registration');
  assert_not_equals(reg1, reg2, 'Registrations should be different');
}, 'resolve ready after unregistering and reregistering');

promise_test(async function(t) {
  const url1 = 'resources/empty-worker.js';
  const url2 = url1 + '?2';
  const matched_scope = 'resources/blank.html?ready-after-unregister';

  const frame = await with_iframe(matched_scope);
  t.add_cleanup(() => frame.remove());

  const reg1 = await service_worker_unregister_and_register(t, url1, matched_scope);
  t.add_cleanup(() => reg1.unregister());

  await wait_for_state(t, reg1.installing, 'activated');
  // This registration will resolve all ready promises in clients that match the scope.
  // That includes frame's client.

  const reg1Active = reg1.active;

  await reg1.unregister();

  // Access the ready promise while the registration is unregistering.
  const readyPromise = frame.contentWindow.navigator.serviceWorker.ready;

  // Create a new registration.
  const reg2 = await navigator.serviceWorker.register(url2, { scope: matched_scope });
  t.add_cleanup(() => reg2.unregister());
  // This registration will resolve all ready promises in clients that match the scope.
  // That includes frame's client, but its ready promise has already resolved.

  const readyReg = await readyPromise;

  assert_equals(readyReg.active.scriptURL, reg1Active.scriptURL, 'Resolves with the first registration');
  assert_not_equals(reg1, reg2, 'Registrations should be different');
}, 'resolve ready before unregistering and reregistering');
</script>
