<!doctype html>
<meta charset=utf-8>
<title>Service Worker: WindowClient.navigate</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
  function wait_for_message(msg) {
    return new Promise(function(resolve, reject) {
      var get_message_data = function get_message_data(e) {
        window.removeEventListener("message", get_message_data);
        resolve(e.data);
      }
      window.addEventListener("message", get_message_data, false);
    });
  }

  function run_test(controller, clientId, test) {
    return new Promise(function(resolve, reject) {
      var channel = new MessageChannel();
      channel.port1.onmessage = function(e) {
        resolve(e.data);
      };
      var message = {
        port: channel.port2,
        test: test,
        clientId: clientId,
      };
      controller.postMessage(
        message, [channel.port2]);
    });
  }

  promise_test(function(t) {
    var worker = "resources/client-navigate-worker.js";
    var scope = "resources/client-navigate-frame.html";
    var controller, frame, clientId;

    return service_worker_unregister_and_register(t, worker, scope)
      .then(reg => wait_for_state(t, reg.installing, "activated"))
      .then(___ => with_iframe(scope))
      .then(f => {
        frame = f;
        controller = frame.contentWindow.navigator.serviceWorker.controller;
        fetch_tests_from_worker(controller);
        return wait_for_message()
      })
      .then(({id}) => clientId = id)
      .then(___ => run_test(controller, clientId, "test_client_navigate_success"))
      .then(({result, url}) => {
        assert_equals(result, "test_client_navigate_success");
        assert_equals(
          url, new URL("resources/client-navigated-frame.html",
                       location).toString());
        assert_equals(
          frame.contentWindow.location.href,
          new URL("resources/client-navigated-frame.html",
                  location).toString());
        frame.remove();
      })
      .catch(unreached_rejection(t))
      .then(___ => service_worker_unregister(t, scope));
  }, "Frame location should update on successful navigation");

  promise_test(function(t) {
    var worker = "resources/client-navigate-worker.js";
    var scope = "resources/client-navigate-frame.html";
    var controller, frame, clientId;

    return service_worker_unregister_and_register(t, worker, scope)
      .then(reg => wait_for_state(t, reg.installing, "activated"))
      .then(___ => with_iframe(scope))
      .then(f => {
        frame = f;
        controller = frame.contentWindow.navigator.serviceWorker.controller;
        fetch_tests_from_worker(controller);
        return wait_for_message()
      })
      .then(({id}) => clientId = id)
      .then(___ => run_test(controller, clientId, "test_client_navigate_redirect"))
      .then(({result, url}) => {
        assert_equals(result, "test_client_navigate_redirect");
        assert_equals(url, "");
        assert_throws("SecurityError", function() { return frame.contentWindow.location.href });
        frame.remove();
      })
      .catch(unreached_rejection(t))
      .then(___ => service_worker_unregister(t, scope));
  }, "Frame location should not be accessible after redirect");

  promise_test(function(t) {
    var worker = "resources/client-navigate-worker.js";
    var scope = "resources/client-navigate-frame.html";
    var controller, frame, clientId;

    return service_worker_unregister_and_register(t, worker, scope)
      .then(reg => wait_for_state(t, reg.installing, "activated"))
      .then(___ => with_iframe(scope))
      .then(f => {
        frame = f;
        controller = frame.contentWindow.navigator.serviceWorker.controller;
        fetch_tests_from_worker(controller);
        return wait_for_message()
      })
      .then(({id}) => clientId = id)
      .then(___ => run_test(controller, clientId, "test_client_navigate_cross_origin"))
      .then(({result, url}) => {
        assert_equals(result, "test_client_navigate_cross_origin");
        assert_equals(url, "");
        assert_throws("SecurityError", function() { return frame.contentWindow.location.href });
        frame.remove();
      })
      .catch(unreached_rejection(t))
      .then(___ => service_worker_unregister(t, scope));
  }, "Frame location should not be accessible after cross-origin navigation");

  promise_test(function(t) {
    var worker = "resources/client-navigate-worker.js";
    var scope = "resources/client-navigate-frame.html";
    var controller, frame, clientId;

    return service_worker_unregister_and_register(t, worker, scope)
      .then(reg => wait_for_state(t, reg.installing, "activated"))
      .then(___ => with_iframe(scope))
      .then(f => {
        frame = f;
        controller = frame.contentWindow.navigator.serviceWorker.controller;
        fetch_tests_from_worker(controller);
        return wait_for_message()
      })
      .then(({id}) => clientId = id)
      .then(___ => run_test(controller, clientId, "test_client_navigate_about_blank"))
      .then(({result, url}) => {
        assert_equals(result, "test_client_navigate_about_blank");
        assert_equals(
          frame.contentWindow.location.href,
          new URL("resources/client-navigate-frame.html",
                  location).toString());
        frame.contentWindow.document.body.style = "background-color: green"
        frame.remove();
      })
      .catch(unreached_rejection(t))
      .then(___ => service_worker_unregister(t, scope));
  }, "Frame location should not update on failed about:blank navigation");

  promise_test(function(t) {
    var worker = "resources/client-navigate-worker.js";
    var scope = "resources/client-navigate-frame.html";
    var controller, frame, clientId;

    return service_worker_unregister_and_register(t, worker, scope)
      .then(reg => {
        return wait_for_state(t, reg.installing, "activated");
      })
      .then(___ => with_iframe(scope))
      .then(f => {
        frame = f;
        controller = frame.contentWindow.navigator.serviceWorker.controller;
        fetch_tests_from_worker(controller);
        return wait_for_message()
      })
      .then(({id}) => clientId = id)
      .then(___ => run_test(controller, clientId, "test_client_navigate_mixed_content"))
      .then(({result, url}) => {
        assert_equals(result, "test_client_navigate_mixed_content");
        assert_equals(
          frame.contentWindow.location.href,
          new URL("resources/client-navigate-frame.html",
                  location).toString());
        frame.contentWindow.document.body.style = "background-color: green"
        frame.remove();
      })
      .catch(unreached_rejection(t))
      .then(___ => service_worker_unregister(t, scope));
  }, "Frame location should not update on failed mixed-content navigation");
</script>
