<!doctype html>
<html>
  <head>
    <meta charset=utf-8>
    <title>Test WorkerGlobalScope.isSecureContext for HTTP creator</title>
    <meta name="help" href="https://w3c.github.io/webappsec-secure-contexts/#monkey-patching-global-object">
    <script src=/resources/testharness.js></script>
    <script src=/resources/testharnessreport.js></script>
    <script src="server-locations.sub.js"></script>
  </head>
  <body>
    <script>
      var t1 = async_test("HTTP worker");
      var t2 = async_test("HTTPS worker");
      var t3 = async_test("HTTP nested worker");
      var t4 = async_test("HTTPS nested worker");
      var t5 = async_test("HTTP worker from HTTPS subframe");
      var t6 = async_test("HTTPS worker from HTTPS subframe");

      var w1 = new Worker(http_dir + "support/dedicated-worker-script.js");
      w1.onmessage = t1.step_func_done(function(e) {
        assert_false(e.data);
      });
      w1.onerror = t1.step_func_done(function(e) {
        assert_unreached("isSecureContext should be supported");
      });

      try {
        var w2 = new Worker(https_dir + "support/dedicated-worker-script.js");
        w2.onmessage = t2.step_func_done(function(e) {
          assert_unreached("cross-origin workers should not be loaded");
        });
        w2.onerror = t2.step_func_done(function(e) {
          e.preventDefault();
        });
      } catch (e) {
        // Some browsers throw for cross-origin URLs. This violates the Worker spec,
        // but isn't actually relevant to what we're testing here.
        t2.done();
      }

      var w3 = new Worker(http_dir + "support/parent-dedicated-worker-script.js");
      w3.onmessage = t3.step_func_done(function(e) {
        assert_false(e.data);
      });
      w3.onerror = t3.step_func_done(function(e) {
        assert_unreached("isSecureContext should be supported");
      });

      try {
        var w4 = new Worker(https_dir + "support/parent-dedicated-worker-script.js");
        w4.onmessage = t4.step_func_done(function(e) {
          assert_unreached("cross-origin workers should not be loaded");
        });
        w4.onerror = t4.step_func_done(function(e) {
          e.preventDefault();
        });
      } catch (e) {
        // Some browsers throw for cross-origin URLs. This violates the Worker spec,
        // but isn't actually relevant to what we're testing here.
        t4.done();
      }

      onmessage = function(e) {
        var data = e.data;
        if (data.type == "http") {
          t5.step(function() {
            assert_true(data.error);
          });
          t5.done();
        } else if (data.type == "https") {
          t6.step(function() {
            assert_false(data.error);
            assert_false(data.isSecureContext);
          });
          t6.done();
        } else {
          t5.step(function() {
            assert_unreached("Unknown message");
          });
          t5.done();
          t6.step(function() {
            assert_unreached("Unknown message");
          });
          t6.done();
        }
      }

      var ifr = document.createElement("iframe");
      ifr.src = https_dir + "support/https-subframe-dedicated.html";
      document.body.appendChild(ifr);
    </script>
  </body>
</html>

