<!DOCTYPE HTML>
<html>
<!--
Tests for Mixed Content Blocker
https://bugzilla.mozilla.org/show_bug.cgi?id=62178
-->
<head>
  <meta charset="utf-8">
  <title>Tests for Bug 62178</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>

  <script>
  let counter = 0;
  // blockDisplay blockActive upgradeDisplay
  const settings = [
    [true, true, true],
    [true, false, true],
    [false, true, true],
    [false, false, true],
    [true, true, false],
    [true, false, false],
    [false, true, false],
    [false, false, false],
  ];

  let blockActive;
  let blockDisplay;
  let upgradeDisplay;

  //Cycle through 8 different preference settings.
  function changePrefs(otherPrefs, callback) {
    let basePrefs = [["security.mixed_content.block_display_content", settings[counter][0]],
                     ["security.mixed_content.block_active_content", settings[counter][1]],
                     ["security.mixed_content.upgrade_display_content", settings[counter][2]]];
    let newPrefs = basePrefs.concat(otherPrefs);

    SpecialPowers.pushPrefEnv({"set": newPrefs}, function () {
      blockDisplay = SpecialPowers.getBoolPref("security.mixed_content.block_display_content");
      blockActive = SpecialPowers.getBoolPref("security.mixed_content.block_active_content");
      upgradeDisplay = SpecialPowers.getBoolPref("security.mixed_content.upgrade_display_content");
      counter++;
      callback();
    });
  }

  let testsToRun = {
    iframe: false,
    image: false,
    imageSrcset: false,
    imageSrcsetFallback: false,
    imagePicture: false,
    imageJoinPicture: false,
    imageLeavePicture: false,
    script: false,
    stylesheet: false,
    object: false,
    media: false,
    xhr: false,
  };

  function log(msg) {
    document.getElementById("log").textContent += "\n" + msg;
  }

  function reloadFrame() {
    document.getElementById('framediv').innerHTML = '<iframe id="testHarness" src="https://example.com/tests/dom/security/test/mixedcontentblocker/file_main.html"></iframe>';
  }

  function checkTestsCompleted() {
    for (var prop in testsToRun) {
      // some test hasn't run yet so we're not done
      if (!testsToRun[prop])
        return;
    }
    //if the testsToRun are all completed, chnage the pref and run the tests again until we have cycled through all the prefs.
    if(counter < 8) {
       for (var prop in testsToRun) {
         testsToRun[prop] = false;
       }
      //call to change the preferences
      changePrefs([], function() {
        log(`\nblockDisplay set to ${blockDisplay}, blockActive set to ${blockActive}, upgradeDisplay set to ${upgradeDisplay}`);
        reloadFrame();
      });
    }
    else {
      SimpleTest.finish();
    }
  }

  var firstTest = true;

  function receiveMessage(event) {
    if(firstTest) {
      log(`blockActive set to ${blockActive}, blockDisplay set to ${blockDisplay}, upgradeDisplay set to ${upgradeDisplay}.`);
      firstTest = false;
    }

    // Simple check from the iframe.
    if (event.data.check) {
      ok(event.data.status, event.data.msg);
      return;
    }

    log("test: "+event.data.test+", msg: "+event.data.msg + " logging message.");
    // test that the load type matches the pref for this type of content
    // (i.e. active vs. display)

    switch(event.data.test) {

      /* Mixed Script tests */
      case "iframe":
        ok(blockActive == (event.data.msg == "insecure iframe blocked"), "iframe did not follow block_active_content pref");
        testsToRun.iframe = true;
        break;

      case "object":
        ok(blockActive == (event.data.msg == "insecure object blocked"), "object did not follow block_active_content pref");
        testsToRun.object = true;
        break;

      case "script":
        ok(blockActive == (event.data.msg == "insecure script blocked"), "script did not follow block_active_content pref");
        testsToRun.script = true;
        break;

      case "stylesheet":
        ok(blockActive == (event.data.msg == "insecure stylesheet blocked"), "stylesheet did not follow block_active_content pref");
        testsToRun.stylesheet = true;
        break;

      case "xhr":
        ok(blockActive == (event.data.msg == "insecure xhr blocked"), "xhr did not follow block_active_content pref");
        testsToRun.xhr = true;
        break;

      /* Mixed Display tests */
      case "image":
        //test that the image load matches the pref for display content
        if (upgradeDisplay) {
          ok(event.data.msg == "secure image loaded after upgrade", "image did not follow upgrade_display_content pref");
        } else {
          ok(blockDisplay == (event.data.msg == "insecure image blocked"), "image did not follow block_display_content pref");
        }
        testsToRun.image = true;
        break;

      case "media":
        if (upgradeDisplay) {
          ok(event.data.msg == "secure media loaded after upgrade", "media did not follow upgrade_display_content pref");
        } else {
          ok(blockDisplay == (event.data.msg == "insecure media blocked"), "media did not follow block_display_content pref");
        }
        testsToRun.media = true;
        break;

      /* Images using the "imageset" policy, from <img srcset> and <picture>, do not get the mixed display exception */
      case "imageSrcset":
        // When blockDisplay && blockActive && upgradeDisplay are all true the request is blocked
        // This appears to be a side effect of blockDisplay taking precedence here.
        if (event.data.msg == "secure image loaded after upgrade") {
          ok(upgradeDisplay, "imageSrcset did not follow upgrade_display_content pref");
        } else {
          ok(blockActive == (event.data.msg == "insecure image blocked"), "imageSrcset did not follow block_active_content pref");
        }
        testsToRun.imageSrcset = true;
        break;

      case "imageSrcsetFallback":
        if (event.data.msg == "secure image loaded after upgrade") {
          ok(upgradeDisplay, "imageSrcsetFallback did not follow upgrade_display_content pref");
        } else {
          ok(blockActive == (event.data.msg == "insecure image blocked"), "imageSrcsetFallback did not follow block_active_content pref");
        }
        testsToRun.imageSrcsetFallback = true;
        break;

      case "imagePicture":
        if (event.data.msg == "secure image loaded after upgrade") {
          ok(upgradeDisplay, "imagePicture did not follow upgrade_display_content pref");
        } else {
          ok(blockActive == (event.data.msg == "insecure image blocked"), "imagePicture did not follow block_active_content pref");
        }
        testsToRun.imagePicture = true;
        break;

      case "imageJoinPicture":
        if (event.data.msg == "secure image loaded after upgrade") {
          ok(upgradeDisplay, "imageJoinPicture did not follow upgrade_display_content pref");
        } else {
          ok(blockActive == (event.data.msg == "insecure image blocked"), "imageJoinPicture did not follow block_active_content pref");
        }
        testsToRun.imageJoinPicture = true;
        break;

      // Should return to mixed display mode
      case "imageLeavePicture":
        if (event.data.msg == "secure image loaded after upgrade") {
          ok(upgradeDisplay, "imageLeavePicture did not follow upgrade_display_content pref");
        } else {
          ok(blockDisplay == (event.data.msg == "insecure image blocked"), "imageLeavePicture did not follow block_display_content pref");
        }
        testsToRun.imageLeavePicture = true;
        break;

    }
    checkTestsCompleted();
  }

  function startTest() {
    //Set the first set of mixed content settings and increment the counter.
    changePrefs([], function() {
      //listen for a messages from the mixed content test harness
      window.addEventListener("message", receiveMessage);

      //Kick off test
      reloadFrame();
    });
  }

  SimpleTest.waitForExplicitFinish();

  </script>
</head>

<body onload='startTest()'>
  <div id="framediv"></div>
  <pre id="log"></pre>
</body>
</html>
