<!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_dom(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_js(t, 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_js(t, 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_js(
      t, 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>
