<!DOCTYPE html>
<html>
<head>
  <script src="/resources/testharness.js"></script>
  <script src="/resources/testharnessreport.js"></script>
</head>
<body>
<script>
  function assert_deep_equals(obj1, obj2) {
    assert_equals(typeof obj1, typeof obj2);
    if (typeof obj1 == "string") {
      assert_equals(obj1, obj2);
    } else if (typeof obj1 == "boolean") {
      assert_true(obj1 == obj2);
    } else if (Array.isArray(obj1)) {
      assert_equals(obj1.length, obj2.length);
      assert_array_equals(obj1.sort(), obj2.sort());
    } else if (typeof obj1 == "object") {
      assert_array_equals(Object.keys(obj1).sort(), Object.keys(obj2).sort());
      for (const k of Object.keys(obj1))
        assert_deep_equals(obj1[k], obj2[k]);
    }
  }

  test(t => {
    // Quick sanity test: Test a few default values.
    assert_in_array("div", Sanitizer.getDefaultConfiguration().allowElements);
    assert_false(Sanitizer.getDefaultConfiguration().allowElements.includes("script"));
    assert_false(Sanitizer.getDefaultConfiguration().allowElements.includes("noscript"));

    assert_true("span" in Sanitizer.getDefaultConfiguration().allowAttributes);
    assert_false("onclick" in Sanitizer.getDefaultConfiguration().allowAttributes);

    assert_false("dropElements" in Sanitizer.getDefaultConfiguration());
    assert_false("blockElements" in Sanitizer.getDefaultConfiguration());
    assert_false("dropAttributes" in Sanitizer.getDefaultConfiguration());
    assert_false(Sanitizer.getDefaultConfiguration().allowCustomElements);
    assert_false(Sanitizer.getDefaultConfiguration().allowUnknownMarkup);
  }, "SanitizerAPI getDefaultConfiguration()");

  test(t => {
    assert_deep_equals(Sanitizer.getDefaultConfiguration(),
                       new Sanitizer().getConfiguration());
  }, "SanitizerAPI getConfiguration() on default created Sanitizer");

  test(t => {
    const configs = [{
      allowElements: ["div", "span", "helloworld"],
      dropElements: ["xxx"],
      allowAttributes: { "class": ["*"], "color": ["span", "div"],
                         "onclick": ["*"] },
      allowCustomElements: true,
      allowUnknownMarkup: true,
    },{
      blockElements: ["table", "tbody", "th", "td"],
    }, {
      allowCustomElements: false,
    }, {
      allowUnknownMarkup: false,
    }];
    for (const config of configs)
      assert_deep_equals(config, new Sanitizer(config).getConfiguration());

    // Also test a mixed case variant:
    const config_0_mixed = {
      allowElements: ["div", "sPAn", "HelloWorld"],
      dropElements: ["XXX"],
      allowAttributes: { "class": ["*"], "color": ["sPAn", "div"],
                         "onclick": ["*"] },
      allowCustomElements: true,
      allowUnknownMarkup: true,
    };
    assert_deep_equals(config_0_mixed,
                       new Sanitizer(config_0_mixed).getConfiguration());
  }, "SanitizerAPI getConfiguration() reflects creation config.");

</script>
</body>
</html>
