@Test
 public void testMediaTypeUnion() throws ParseException, TokeniserException {
   Policy p;
   p = parse("plugin-types a/b");
   Policy q;
   q = parse("plugin-types c/d");
   PluginTypesDirective d1 = p.getDirectiveByType(PluginTypesDirective.class);
   PluginTypesDirective d2 = q.getDirectiveByType(PluginTypesDirective.class);
   d1.union(d2);
   assertEquals("directive-name, directive-value", "plugin-types a/b c/d", d1.show());
 }
 @Test
 public void testNonceSource() throws ParseException, TokeniserException {
   assertEquals(
       "script-src 'self' https://example.com 'nonce-MTIzNDU2Nw=='",
       parse("script-src 'self' https://example.com 'nonce-MTIzNDU2Nw=='")
           .getDirectiveByType(ScriptSrcDirective.class)
           .show());
   Policy p = parse("script-src 'nonce-MTIzNDU2Nw=='");
   Policy q = parse("script-src 'nonce-MTIzNDU2Nw=='");
   ScriptSrcDirective d = p.getDirectiveByType(ScriptSrcDirective.class);
   assertEquals("hash code matches", p.hashCode(), q.hashCode());
   assertTrue("nonce-source equals", d.equals(q.getDirectiveByType(ScriptSrcDirective.class)));
   q = parse("script-src 'nonce-aGVsbG8gd29ybGQ='");
   assertFalse("sandbox !equals", d.equals(q.getDirectiveByType(ScriptSrcDirective.class)));
 }
  @Test
  public void testAncestorSource() throws ParseException, TokeniserException {
    assertEquals(
        "directive-name, no directive-value",
        "frame-ancestors",
        parse("frame-ancestors").getDirectiveByType(FrameAncestorsDirective.class).show());
    assertEquals(
        "directive-name, directive-value",
        "frame-ancestors 'none'",
        parse("frame-ancestors 'none'").getDirectiveByType(FrameAncestorsDirective.class).show());

    Policy p;
    p = parse("frame-ancestors 'self' https://example.com");
    Policy q;
    q = parse("script-src abc; frame-ancestors http://example.com");
    FrameAncestorsDirective d1 = p.getDirectiveByType(FrameAncestorsDirective.class);
    FrameAncestorsDirective d2 = q.getDirectiveByType(FrameAncestorsDirective.class);

    d1.union(d2);
    assertEquals(
        "ancestor-source union",
        "frame-ancestors 'self' https://example.com http://example.com",
        d1.show());
    assertFalse("ancestor-source inequality", d1.equals(d2));

    p = parse("frame-ancestors http://example.com");
    q = parse("frame-ancestors http://example.com");
    d1 = p.getDirectiveByType(FrameAncestorsDirective.class);
    d2 = q.getDirectiveByType(FrameAncestorsDirective.class);
    assertTrue("ancestor-source equality", d1.equals(d2));
    assertEquals("ancestor-source hashcode equality", d1.hashCode(), d2.hashCode());
    p = parse("frame-ancestors http:");
    q = parse("frame-ancestors http:");
    assertTrue("ancestor-source scheme-source equality", p.equals(q));
    assertEquals("ancestor-source scheme-source equality", p.hashCode(), q.hashCode());

    failsToParse("frame-ancestors scheme::");
    failsToParse("frame-ancestors 'none' 'self'");

    p = parse("frame-ancestors *");
    q = parse("frame-ancestors http://example.com");
    p.union(q);
    assertEquals("frame-ancestors *", p.show());
  }
 @Test
 public void testDuplicates() throws ParseException, TokeniserException {
   Policy p;
   p = parse("img-src a ;;; img-src b");
   assertNotNull("policy should not be null", p);
   assertEquals("", 1, p.getDirectives().size());
   Directive<?> firstDirective = p.getDirectives().iterator().next();
   ImgSrcDirective imgSrcDirective = p.getDirectiveByType(ImgSrcDirective.class);
   assertNotNull(imgSrcDirective);
   assertTrue(firstDirective instanceof ImgSrcDirective);
   assertEquals("", imgSrcDirective, (ImgSrcDirective) firstDirective);
   assertEquals("", "img-src", ImgSrcDirective.name);
   assertEquals("", "img-src a", imgSrcDirective.show());
 }
 @Test
 public void testSandboxParsing() throws ParseException, TokeniserException {
   failsToParse("sandbox a!*\n");
   failsToParse("sandbox a!*^:");
   assertEquals(
       "sandbox is valid",
       "sandbox abc",
       parse("sandbox abc").getDirectiveByType(SandboxDirective.class).show());
   Policy p;
   p = parse("sandbox a");
   Policy q;
   q = parse("sandbox a");
   SandboxDirective d1 = p.getDirectiveByType(SandboxDirective.class);
   assertTrue("sandbox equals", d1.equals(q.getDirectiveByType(SandboxDirective.class)));
   assertEquals("sandbox hashcode equality", p.hashCode(), q.hashCode());
   q = parse("sandbox b; script-src a");
   assertFalse(
       "sandbox directives equality", d1.equals(q.getDirectiveByType(SandboxDirective.class)));
   d1.union(q.getDirectiveByType(SandboxDirective.class));
   assertEquals("sandbox union", "sandbox a b", d1.show());
   assertNotEquals("sandbox hashcode inequality", p.hashCode(), q.hashCode());
   ScriptSrcDirective d2 = q.getDirectiveByType(ScriptSrcDirective.class);
 }
  @Test
  public void testReportUri() throws ParseException, TokeniserException {
    failsToParse("report-uri ");
    failsToParse("report-uri #");
    failsToParse("report-uri a");
    Policy p, q;
    p = parse("report-uri http://a");
    q = parse("report-uri http://b");
    ReportUriDirective d1 = p.getDirectiveByType(ReportUriDirective.class);
    assertFalse("report-uri inequality", d1.equals(q.getDirectiveByType(ReportUriDirective.class)));
    d1.union(q.getDirectiveByType(ReportUriDirective.class));
    assertEquals("report-uri union", "report-uri http://a http://b", d1.show());
    assertNotEquals("report-uri hashcode shouldn't match", p.hashCode(), q.hashCode());

    p = parse("report-uri  https://a");
    q = parse("report-uri https://a; ");
    assertEquals("report-uri hashcode match", p.hashCode(), q.hashCode());
    assertTrue("report-uri equals", p.equals(q));
    q = parse("report-uri http://a; sandbox 4");
    d1 = q.getDirectiveByType(ReportUriDirective.class);
    SandboxDirective d2 = q.getDirectiveByType(SandboxDirective.class);
    assertEquals("report-uri http://a", d1.show());
    assertEquals("sandbox 4", d2.show());
  }
 @Test
 public void sourceListTest() throws ParseException, TokeniserException {
   Policy p = parse("script-src http://a https://b; style-src http://e");
   Policy q = parse("script-src c d");
   ScriptSrcDirective d1 = p.getDirectiveByType(ScriptSrcDirective.class);
   assertFalse(
       "source-list inequality", d1.equals(q.getDirectiveByType(ScriptSrcDirective.class)));
   d1.union(q.getDirectiveByType(ScriptSrcDirective.class));
   assertEquals("source-list union", "script-src http://a https://b c d", d1.show());
   ScriptSrcDirective d2 = q.getDirectiveByType(ScriptSrcDirective.class);
   p = parse("script-src http://a https://b");
   q = parse("script-src http://a https://b");
   d1 = p.getDirectiveByType(ScriptSrcDirective.class);
   assertTrue("source-list equality", d1.equals(q.getDirectiveByType(ScriptSrcDirective.class)));
   assertEquals("source-list hashcode equality", p.hashCode(), q.hashCode());
 }
  @Test()
  public void testPluginTypesParsing() throws ParseException, TokeniserException {
    failsToParse("plugin-types");
    // XXX: technically allowed via ietf-token if an RFC introduces a type/subtype that is empty
    failsToParse("plugin-types /");
    assertEquals(
        "directive-name, directive-value",
        "plugin-types a/b",
        parse("plugin-types a/b").getDirectiveByType(PluginTypesDirective.class).show());
    assertEquals(
        "directive-name, directive-value",
        "plugin-types a/b c/d",
        parse("plugin-types a/b c/d").getDirectiveByType(PluginTypesDirective.class).show());
    assertEquals(
        "directive-name, directive-value",
        "plugin-types x-a/x-b",
        parse("plugin-types x-a/x-b").getDirectiveByType(PluginTypesDirective.class).show());
    assertEquals(
        "directive-name, directive-value",
        "plugin-types X-A/X-B",
        parse("plugin-types X-A/X-B").getDirectiveByType(PluginTypesDirective.class).show());

    Policy p, q;
    p = parse("plugin-types a/b");
    q = parse("plugin-types c/d; script-src *");

    PluginTypesDirective d1 = p.getDirectiveByType(PluginTypesDirective.class);
    PluginTypesDirective d2 = q.getDirectiveByType(PluginTypesDirective.class);

    d1.union(d2);
    assertEquals("plugin-types union", "plugin-types a/b c/d", d1.show());
    p = parse("plugin-types a/b");
    q = parse("plugin-types a/c;");
    d1 = p.getDirectiveByType(PluginTypesDirective.class);
    d2 = q.getDirectiveByType(PluginTypesDirective.class);
    assertFalse("plugin-type subtype inequality", d1.equals(d2));
    p = parse("plugin-types a/b");
    q = parse("plugin-types a/b;");
    d1 = p.getDirectiveByType(PluginTypesDirective.class);
    d2 = q.getDirectiveByType(PluginTypesDirective.class);
    assertEquals("plugin-types hashcode equality", d1.hashCode(), d2.hashCode());
  }
  @Test
  public void testHashSource() throws ParseException, TokeniserException {
    failsToParse(
        "script-src 'self' https://example.com 'sha255-K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols'");
    failsToParse(
        "script-src 'self' https://example.com 'sha256-K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols'");
    assertEquals(
        "directive-name, directive-value",
        "script-src 'self' https://example.com 'sha256-K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols='",
        parse(
                "script-src 'self' https://example.com 'sha256-K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols='")
            .getDirectiveByType(ScriptSrcDirective.class)
            .show());
    assertEquals(
        "directive-name, directive-value",
        "script-src 'self' https://example.com 'sha384-QXIS/RyLxYlv79jbWK+CRUXoWw0FRkCTZqMK73Jp+uJYFzvRhfsmLIbzu4b7oENo'",
        parse(
                "script-src 'self' https://example.com 'sha384-QXIS/RyLxYlv79jbWK+CRUXoWw0FRkCTZqMK73Jp+uJYFzvRhfsmLIbzu4b7oENo'")
            .getDirectiveByType(ScriptSrcDirective.class)
            .show());
    assertEquals(
        "directive-name, directive-value",
        "script-src 'self' https://example.com 'sha512-vSsar3708Jvp9Szi2NWZZ02Bqp1qRCFpbcTZPdBhnWgs5WtNZKnvCXdhztmeD2cmW192CF5bDufKRpayrW/isg=='",
        parse(
                "script-src 'self' https://example.com 'sha512-vSsar3708Jvp9Szi2NWZZ02Bqp1qRCFpbcTZPdBhnWgs5WtNZKnvCXdhztmeD2cmW192CF5bDufKRpayrW/isg=='")
            .getDirectiveByType(ScriptSrcDirective.class)
            .show());
    Policy p =
        parse(
            "script-src 'sha512-vSsar3708Jvp9Szi2NWZZ02Bqp1qRCFpbcTZPdBhnWgs5WtNZKnvCXdhztmeD2cmW192CF5bDufKRpayrW/isg=='");
    Policy q =
        parse(
            "script-src 'sha512-vSsar3708Jvp9Szi2NWZZ02Bqp1qRCFpbcTZPdBhnWgs5WtNZKnvCXdhztmeD2cmW192CF5bDufKRpayrW/isg=='");
    assertEquals("hash-source hashcode equality", p.hashCode(), q.hashCode());
    ScriptSrcDirective d = p.getDirectiveByType(ScriptSrcDirective.class);
    assertTrue("hash-source equals", d.equals(q.getDirectiveByType(ScriptSrcDirective.class)));
    q =
        parse(
            "script-src 'sha512-HD6Xh+Y6oIZnXv4XqbKxrb6t3RkoPYv+NkqOBE8MwkssuATRE2aFBp8Nm9kp/Xn5a4l2Ki8QkX5qIUlbXQgO4Q=='");
    assertFalse("hash-source inequality", d.equals(q.getDirectiveByType(ScriptSrcDirective.class)));

    try {
      parse("script-src 'sha256-gpw4BEAbByf3D3PUQV4WJADL5Xs='");
      fail();
    } catch (ParseException e) {
      assertEquals("Invalid SHA-256 value (wrong length): 20", e.getMessage());
    }

    try {
      parse("script-src 'sha384-gpw4BEAbByf3D3PUQV4WJADL5Xs='");
      fail();
    } catch (ParseException e) {
      assertEquals("Invalid SHA-384 value (wrong length): 20", e.getMessage());
    }

    try {
      parse("script-src 'sha512-gpw4BEAbByf3D3PUQV4WJADL5Xs='");
      fail();
    } catch (ParseException e) {
      assertEquals("Invalid SHA-512 value (wrong length): 20", e.getMessage());
    }
  }