<!DOCTYPE html>
<meta charset="utf-8">
<title>Credentials for service worker scripts</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="/common/utils.js"></script>
<script src="/cookies/resources/cookie-helper.sub.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<body>
<script>
// Check if the service worker's script has appropriate credentials for a new
// worker and byte-for-byte checking.

const SCOPE = 'resources/in-scope';
const COOKIE_NAME = `service-worker-credentials-${Math.random()}`;

promise_test(async t => {
  // Set-Cookies for path=/.
  await fetch(
      `/cookies/resources/set-cookie.py?name=${COOKIE_NAME}&path=%2F`);
}, 'Set cookies as initialization');

async function get_cookies(worker) {
  worker.postMessage('get cookie');
  const message = await new Promise(resolve =>
      navigator.serviceWorker.addEventListener('message', resolve));
  return message.data;
}

promise_test(async t => {
  const key = token();
  const registration = await service_worker_unregister_and_register(
      t, `resources/echo-cookie-worker.py?key=${key}`, SCOPE);
  t.add_cleanup(() => registration.unregister());
  const worker = registration.installing;

  const cookies = await get_cookies(worker);
  assert_equals(cookies[COOKIE_NAME], '1', 'new worker has credentials');

  await registration.update();
  const updated_worker = registration.installing;
  const updated_cookies = await get_cookies(updated_worker);
  assert_equals(updated_cookies[COOKIE_NAME], '1',
                'updated worker has credentials');
}, 'Main script should have credentials');

promise_test(async t => {
  const key = token();
  const registration = await service_worker_unregister_and_register(
      t, `resources/import-echo-cookie-worker.js?key=${key}`, SCOPE);
  t.add_cleanup(() => registration.unregister());
  const worker = registration.installing;

  const cookies = await get_cookies(worker);
  assert_equals(cookies[COOKIE_NAME], '1', 'new worker has credentials');

  await registration.update();
  const updated_worker = registration.installing;
  const updated_cookies = await get_cookies(updated_worker);
  assert_equals(updated_cookies[COOKIE_NAME], '1',
                'updated worker has credentials');
}, 'Imported script should have credentials');

promise_test(async t => {
  const key = token();
  const registration = await service_worker_unregister_and_register(
      t, `resources/import-echo-cookie-worker-module.py?key=${key}`, SCOPE, {type: 'module'});
  t.add_cleanup(() => registration.unregister());
  const worker = registration.installing;

  const cookies = await get_cookies(worker);
  assert_equals(cookies[COOKIE_NAME], undefined, 'new module worker should not have credentials');

  await registration.update();
  const updated_worker = registration.installing;
  const updated_cookies = await get_cookies(updated_worker);
  assert_equals(updated_cookies[COOKIE_NAME], undefined,
                'updated worker should not have credentials');
}, 'Module with an imported statement should not have credentials');

promise_test(async t => {
  const key = token();
  const registration = await service_worker_unregister_and_register(
t, `resources/echo-cookie-worker.py?key=${key}`, SCOPE, {type: 'module'});
  t.add_cleanup(() => registration.unregister());
  const worker = registration.installing;

  const cookies = await get_cookies(worker);
  assert_equals(cookies[COOKIE_NAME], undefined, 'new module worker should not have credentials');

  await registration.update();
  const updated_worker = registration.installing;
  const updated_cookies = await get_cookies(updated_worker);
  assert_equals(updated_cookies[COOKIE_NAME], undefined,
                'updated worker should not have credentials');
}, 'Script with service worker served as modules should not have credentials');

</script>
</body>
