package markup
import (
"strings"
"testing"
)
// ticketResolver knows two tickets, one of them local, and one check-in.
type ticketResolver struct{ fakeResolver }
func (ticketResolver) ResolveHash(p string) string {
if strings.HasPrefix("c0ffee0000c0ffee", p) {
return "/r/q/checkin/c0ffee0000c0ffee"
}
return ""
}
func (ticketResolver) DescribeTicket(t RefToken) (TicketRef, bool) {
switch {
case strings.HasPrefix("54dc6a414800aa", t.ID):
return TicketRef{URL: "/r/q/ticket/54dc6a414800aa", Number: 231, State: "closed", Status: "Fixed", Local: true}, true
case strings.HasPrefix("508fd44ab000bb", t.ID):
return TicketRef{URL: "/r/q/ticket/508fd44ab000bb", Number: 232, State: "open", Status: "Open"}, true
}
return TicketRef{}, false
}
func renderT(t *testing.T, src string) string {
t.Helper()
out, err := Render([]byte(src), ticketResolver{})
if err != nil {
t.Fatal(err)
}
return string(out)
}
// A ticket named in prose reads as its number with its state beside it,
// whether the author typed the bare id or linked the ticket's page.
func TestATicketReferenceShowsItsNumberAndState(t *testing.T) {
for _, src := range []string{
"see 54dc6a4148 for the crash",
"see [54dc6a4148](/r/dmestas/q/ticket/54dc6a4148) for the crash",
"see [54dc6a4148](https://zeitforge.app/r/q/ticket/54dc6a4148) for the crash",
} {
html := renderT(t, src)
if !strings.Contains(html, `/ticket/54dc6a414800aa"`) && !strings.Contains(html, `/ticket/54dc6a4148"`) {
t.Errorf("FAIL: %q: no link to the ticket: %s", src, html)
}
if !strings.Contains(html, `class="tref`) || !strings.Contains(html, ">#231</a>") {
t.Errorf("FAIL: %q: the reference does not read as #231: %s", src, html)
}
if !strings.Contains(html, `class="tref-state tref-closed"`) {
t.Errorf("FAIL: %q: no closed state beside it: %s", src, html)
}
if !strings.Contains(html, `class="tref-local"`) {
t.Errorf("FAIL: %q: a local ticket is not marked local: %s", src, html)
}
}
if !t.Failed() {
t.Log("ok: bare ids and links both read #231 with state and local mark")
}
}
// An author's own link text is theirs; only a bare id is relabelled.
func TestALinkWithItsOwnWordsKeepsThem(t *testing.T) {
html := renderT(t, "[the goroutine leak](/r/q/ticket/508fd44ab0)")
if !strings.Contains(html, ">the goroutine leak</a>") || !strings.Contains(html, `tref-open`) {
t.Errorf("FAIL: the author's words or the state are lost: %s", html)
}
if strings.Contains(html, "tref-local") {
t.Errorf("FAIL: an ordinary ticket is marked local: %s", html)
}
}
// A hash that names a check-in is not described as a ticket.
func TestACheckinHashIsNotATicket(t *testing.T) {
html := renderT(t, "landed in c0ffee0000")
if strings.Contains(html, "tref") || !strings.Contains(html, "/checkin/") {
t.Errorf("FAIL: a check-in reference changed: %s", html)
}
}