<!DOCTYPE html>
<title>Service Worker: Registration update()</title>
<meta name="timeout" content="long">
<script src="/common/utils.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
'use strict';

const SCOPE = 'resources/simple.txt';

// Create a service worker (update-worker.py). The response to update() will be
// different based on the mode.
async function prepare_ready_registration_with_mode(t, mode) {
  const key = token();
  const worker_url = `resources/update-worker.py?Key=${key}&Mode=${mode}`;
  const expected_url = normalizeURL(worker_url);
  const registration = await service_worker_unregister_and_register(
      t, worker_url, SCOPE);
  await wait_for_state(t, registration.installing, 'activated');
  assert_equals(registration.installing, null,
                'prepare_ready: installing');
  assert_equals(registration.waiting, null,
                'prepare_ready: waiting');
  assert_equals(registration.active.scriptURL, expected_url,
                'prepare_ready: active');
  return [registration, expected_url];
}

// Create a service worker (update-worker-from-file.py), which is initially
// |initial_worker| and |updated_worker| later.
async function prepare_ready_registration_with_file(
    t, initial_worker, updated_worker) {
  const key = token();
  const worker_url = `resources/update-worker-from-file.py?` +
      `First=${initial_worker}&Second=${updated_worker}&Key=${key}`;
  const expected_url = normalizeURL(worker_url);

  const registration = await service_worker_unregister_and_register(
      t, worker_url, SCOPE);
  await wait_for_state(t, registration.installing, 'activated');
  assert_equals(registration.installing, null,
                'prepare_ready: installing');
  assert_equals(registration.waiting, null,
                'prepare_ready: waiting');
  assert_equals(registration.active.scriptURL, expected_url,
                'prepare_ready: active');
  return [registration, expected_url];
}

function assert_installing_and_active(registration, expected_url) {
  assert_equals(registration.installing.scriptURL, expected_url,
                'assert_installing_and_active: installing');
  assert_equals(registration.waiting, null,
                'assert_installing_and_active: waiting');
  assert_equals(registration.active.scriptURL, expected_url,
                'assert_installing_and_active: active');
}

function assert_waiting_and_active(registration, expected_url) {
  assert_equals(registration.installing, null,
                'assert_waiting_and_active: installing');
  assert_equals(registration.waiting.scriptURL, expected_url,
                'assert_waiting_and_active: waiting');
  assert_equals(registration.active.scriptURL, expected_url,
                'assert_waiting_and_active: active');
}

function assert_active_only(registration, expected_url) {
  assert_equals(registration.installing, null,
                'assert_active_only: installing');
  assert_equals(registration.waiting, null,
                'assert_active_only: waiting');
  assert_equals(registration.active.scriptURL, expected_url,
                'assert_active_only: active');
}

promise_test(async t => {
  const [registration, expected_url] =
      await prepare_ready_registration_with_mode(t, 'normal');
  t.add_cleanup(() => registration.unregister());

  await Promise.all([registration.update(), wait_for_update(t, registration)]);
  assert_installing_and_active(registration, expected_url);

  await wait_for_state(t, registration.installing, 'installed');
  assert_waiting_and_active(registration, expected_url);

  await wait_for_state(t, registration.waiting, 'activated');
  assert_active_only(registration, expected_url);
}, 'update() should succeed when new script is available.');

promise_test(async t => {
  const [registration, expected_url] =
      await prepare_ready_registration_with_mode(t, 'bad_mime_type');
  t.add_cleanup(() => registration.unregister());

  await promise_rejects(t, 'SecurityError', registration.update());
  assert_active_only(registration, expected_url);
}, 'update() should fail when mime type is invalid.');

promise_test(async t => {
  const [registration, expected_url] =
      await prepare_ready_registration_with_mode(t, 'redirect');
  t.add_cleanup(() => registration.unregister());

  await promise_rejects(t, new TypeError(), registration.update());
  assert_active_only(registration, expected_url);
}, 'update() should fail when a response for the main script is redirect.');

promise_test(async t => {
  const [registration, expected_url] =
      await prepare_ready_registration_with_mode(t, 'syntax_error');
  t.add_cleanup(() => registration.unregister());

  await promise_rejects(t, new TypeError(), registration.update());
  assert_active_only(registration, expected_url);
}, 'update() should fail when a new script contains a syntax error.');

promise_test(async t => {
  const [registration, expected_url] =
      await prepare_ready_registration_with_mode(t, 'throw_install');
  t.add_cleanup(() => registration.unregister());

  await Promise.all([registration.update(), wait_for_update(t, registration)]);
  assert_installing_and_active(registration, expected_url);
}, 'update() should resolve when the install event throws.');

promise_test(async t => {
  const [registration, expected_url] =
      await prepare_ready_registration_with_mode(t, 'normal');
  t.add_cleanup(() => registration.unregister());

  // We need to hold a client alive so that unregister() below doesn't remove
  // the registration before update() has had a chance to look at the pending
  // uninstall flag.
  const frame = await with_iframe(SCOPE);
  t.add_cleanup(() => frame.remove());

  await promise_rejects(
      t, new TypeError(),
      Promise.all([registration.unregister(), registration.update()]));
}, 'update() should fail when the pending uninstall flag is set.');

promise_test(async t => {
  const [registration, expected_url] =
      await prepare_ready_registration_with_file(
        t,
        'update-smaller-body-before-update-worker.js',
        'update-smaller-body-after-update-worker.js');
  t.add_cleanup(() => registration.unregister());

  await Promise.all([registration.update(), wait_for_update(t, registration)]);
  assert_installing_and_active(registration, expected_url);

  await wait_for_state(t, registration.installing, 'installed');
  assert_waiting_and_active(registration, expected_url);

  await wait_for_state(t, registration.waiting, 'activated');
  assert_active_only(registration, expected_url);
}, 'update() should succeed when the script shrinks.');
</script>
