package render import ( "context" "strings" "testing" ) func TestAutolinkText_PlainTextPassthrough(t *testing.T) { got := autolinkText("just some prose with no link") want := "just some prose with no link" if got != want { t.Errorf("got %q, want %q", got, want) } } func TestAutolinkText_HTMLMetacharactersEscaped(t *testing.T) { got := autolinkText("a < b && c > d") if !strings.Contains(got, "<") || !strings.Contains(got, ">") || !strings.Contains(got, "&") { t.Errorf("expected escaped metacharacters, got %q", got) } if strings.Contains(got, " tag in plain prose: %q", got) } } func TestAutolinkText_SingleHTTPSURL(t *testing.T) { got := autolinkText("see https://example.com for more") want := `see https://example.com for more` if got != want { t.Errorf("got %q, want %q", got, want) } } func TestAutolinkText_HTTPNotLinked(t *testing.T) { got := autolinkText("see http://example.com for more") if strings.Contains(got, "https://example.com.` if got != want { t.Errorf("got %q, want %q", got, want) } } func TestAutolinkText_TrailingPunctuationStripped(t *testing.T) { cases := []struct { input string wantTail string }{ {"check https://example.com,", ","}, {"is it https://example.com?", "?"}, {"wow https://example.com!", "!"}, {"so https://example.com;", ";"}, {"foo https://example.com:", ":"}, {`he said "https://example.com"`, `"`}, {"foo https://example.com'", "'"}, } for _, tc := range cases { got := autolinkText(tc.input) if !strings.Contains(got, `https://example.com`) { t.Errorf("input %q: expected URL link without trailing punctuation, got %q", tc.input, got) } if !strings.HasSuffix(got, tc.wantTail) { t.Errorf("input %q: expected suffix %q, got %q", tc.input, tc.wantTail, got) } } } func TestAutolinkText_ClosingParenOutsideAnchorWhenUnbalanced(t *testing.T) { got := autolinkText("(see https://example.com)") want := `(see https://example.com)` if got != want { t.Errorf("got %q, want %q", got, want) } } func TestAutolinkText_ClosingParenKeptWhenBalanced(t *testing.T) { got := autolinkText("see https://en.wikipedia.org/wiki/Foo_(bar) page") if !strings.Contains(got, `https://en.wikipedia.org/wiki/Foo_(bar)`) { t.Errorf("expected paren kept inside anchor when balanced, got %q", got) } } func TestAutolinkText_MultipleURLs(t *testing.T) { got := autolinkText("first https://a.com then https://b.com end") if strings.Count(got, "https://example.com`) { t.Errorf("expected anchor at start, got %q", got) } } func TestAutolinkText_URLAtStringEnd(t *testing.T) { got := autolinkText("checkout https://example.com") want := `checkout https://example.com` if got != want { t.Errorf("got %q, want %q", got, want) } } // Integration tests: confirm autolinking flows through the public renderer func TestBlockNoteToHTML_AutolinksURLInParagraph(t *testing.T) { doc := map[string]any{ "blocks": []any{ map[string]any{ "type": "paragraph", "content": []any{ map[string]any{"type": "text", "text": "visit https://example.com today"}, }, }, }, } html := BlockNoteToHTML(context.Background(), doc) if !strings.Contains(html, `https://example.com`) { t.Errorf("expected autolinked URL in paragraph, got %s", html) } } func TestBlockNoteToHTML_NoNestedAnchorInsideExplicitLink(t *testing.T) { doc := map[string]any{ "blocks": []any{ map[string]any{ "type": "paragraph", "content": []any{ map[string]any{ "type": "link", "href": "https://short.url/", "content": []any{ map[string]any{"type": "text", "text": "see https://full-url-text.com"}, }, }, }, }, }, } html := BlockNoteToHTML(context.Background(), doc) // Outer link should exist if !strings.Contains(html, ``) { t.Errorf("expected outer explicit link, got %s", html) } // Inner text must NOT become a nested anchor if strings.Contains(html, `") || !strings.Contains(html, "https://example.com") { t.Errorf("expected code-wrapped literal URL, got %s", html) } } func TestBlockNoteToHTML_BoldWrapsAutolink(t *testing.T) { doc := map[string]any{ "blocks": []any{ map[string]any{ "type": "paragraph", "content": []any{ map[string]any{ "type": "text", "text": "https://example.com", "styles": map[string]any{"bold": true}, }, }, }, }, } html := BlockNoteToHTML(context.Background(), doc) if !strings.Contains(html, `https://example.com`) { t.Errorf("expected bold-wrapped autolink, got %s", html) } }