package markup
import (
"strings"
"testing"
)
// A rendered diagram keeps Pikchr's own paint and type. The sanitizer
// dropped every style it had no value rule for, so every shape drew as
// a solid black block with no outline, every line vanished, and bold,
// italic and small labels all came out one weight and size.
func TestPikchrKeepsItsPaintAndType(t *testing.T) {
svg, err := RenderPikchr([]byte(`box "title" bold "detail" small
arrow dashed
circle "slanted" italic
line from last circle.s down 1 right 1 "aligned" aligned above`))
if err != nil {
t.Fatal(err)
}
// The sanitizer rewrites a style with a space after each colon.
out := strings.ReplaceAll(string(svg), ": ", ":")
for _, want := range []string{
`stroke:currentColor`, // an outline, in the page's ink
`fill:none`, // an unfilled shape stays unfilled
`stroke-width:`,
`stroke-dasharray:`,
`font-weight="bold"`,
`font-style="italic"`,
`font-size="`,
`transform="rotate(`,
} {
if !strings.Contains(out, want) {
t.Errorf("FAIL: the rendered diagram lost %s", want)
}
}
if !t.Failed() {
t.Log("ok: paint and type survive sanitizing")
}
}
// The value rules still refuse what is not paint.
func TestPikchrPaintRefusesAURL(t *testing.T) {
out := strings.ReplaceAll(svgPolicy.Sanitize(`<svg><path d="M0,0L1,1" style="fill:url(https://example.com/x);stroke:currentColor"/></svg>`), ": ", ":")
if strings.Contains(out, "url(") {
t.Errorf("FAIL: a url() paint survived: %s", out)
}
if !strings.Contains(out, "stroke:currentColor") {
t.Errorf("FAIL: the legitimate stroke beside it was dropped: %s", out)
}
if !t.Failed() {
t.Log("ok: a url() paint is refused and the rest kept")
}
}