86 lines
2.8 KiB
Go
86 lines
2.8 KiB
Go
package richtext
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestToHTML_Markers(t *testing.T) {
|
|
cases := []struct{ in, want string }{
|
|
{"*bold*", "<strong>bold</strong>"},
|
|
{"_italic_", "<em>italic</em>"},
|
|
{"__under__", "<u>under</u>"},
|
|
{"~gone~", "<s>gone</s>"},
|
|
{"a *b* and _c_", "a <strong>b</strong> and <em>c</em>"},
|
|
{"line one\nline two", "line one<br>line two"},
|
|
// Underscores inside words are not italics.
|
|
{"snake_case_name", "snake_case_name"},
|
|
{"@some_handle here", "@some_handle here"},
|
|
}
|
|
for _, c := range cases {
|
|
if got := string(ToHTML(c.in)); got != c.want {
|
|
t.Errorf("ToHTML(%q) = %q, want %q", c.in, got, c.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestToHTML_Links(t *testing.T) {
|
|
got := string(ToHTML("see [the gītā](https://prabhupadasays.org/books/bg)"))
|
|
if !strings.Contains(got, `href="https://prabhupadasays.org/books/bg"`) ||
|
|
!strings.Contains(got, ">the gītā</a>") {
|
|
t.Errorf("labelled link: %q", got)
|
|
}
|
|
|
|
// A bare URL becomes a link, but sentence punctuation stays outside it.
|
|
got = string(ToHTML("Visit https://prabhupadasays.org."))
|
|
if !strings.Contains(got, `href="https://prabhupadasays.org"`) ||
|
|
!strings.HasSuffix(got, "</a>.") {
|
|
t.Errorf("bare link with trailing period: %q", got)
|
|
}
|
|
|
|
// Underscores and tildes inside a URL are not formatting.
|
|
got = string(ToHTML("https://example.com/a_b_c~d"))
|
|
if strings.Contains(got, "<em>") || strings.Contains(got, "<s>") {
|
|
t.Errorf("markers applied inside a URL: %q", got)
|
|
}
|
|
}
|
|
|
|
// The security property: nothing typed can become markup of its own.
|
|
func TestToHTML_EscapesAuthorInput(t *testing.T) {
|
|
cases := []string{
|
|
`<script>alert(1)</script>`,
|
|
`<img src=x onerror=alert(1)>`,
|
|
`*<b>bold</b>*`,
|
|
`[click](javascript:alert(1))`,
|
|
`[x](https://ok.example/" onmouseover="alert(1))`,
|
|
}
|
|
for _, in := range cases {
|
|
got := string(ToHTML(in))
|
|
if strings.Contains(got, "<script") || strings.Contains(got, "<img") ||
|
|
strings.Contains(got, "<b>") || strings.Contains(got, "javascript:alert") && strings.Contains(got, "href=\"javascript") {
|
|
t.Errorf("ToHTML(%q) produced author markup: %q", in, got)
|
|
}
|
|
if strings.Contains(got, `" onmouseover=`) {
|
|
t.Errorf("ToHTML(%q) let a quote break out of an attribute: %q", in, got)
|
|
}
|
|
}
|
|
// A javascript: URL is never made a link at all.
|
|
if got := string(ToHTML(`[click](javascript:alert(1))`)); strings.Contains(got, "<a ") {
|
|
t.Errorf("javascript: URL was linked: %q", got)
|
|
}
|
|
}
|
|
|
|
func TestPlain(t *testing.T) {
|
|
cases := []struct{ in, want string }{
|
|
{"*New:* _chat_ is __here__ ~soon~", "New: chat is here soon"},
|
|
{"read [the gītā](https://x.example)", "read the gītā"},
|
|
{"see https://prabhupadasays.org", "see https://prabhupadasays.org"},
|
|
{"snake_case stays", "snake_case stays"},
|
|
}
|
|
for _, c := range cases {
|
|
if got := Plain(c.in); got != c.want {
|
|
t.Errorf("Plain(%q) = %q, want %q", c.in, got, c.want)
|
|
}
|
|
}
|
|
}
|