Files
spsays-bff/pkg/richtext/richtext_test.go
T
2026-10-09 06:40:13 +05:30

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)
}
}
}