package html
import (
"fmt"
"strings"
"testing"
"github.com/stretchr/testify/require"
"golang.org/x/net/html"
"go.mau.fi/mautrix-telegram/pkg/gotd/telegram/message/entity"
"go.mau.fi/mautrix-telegram/pkg/gotd/tg"
)
type htmlTestCase struct {
html string
msg string
entities func(msg string) []tg.MessageEntityClass
wantErr bool
skipReason string
}
func getEntities(formats ...entity.Formatter) func(msg string) []tg.MessageEntityClass {
return func(msg string) []tg.MessageEntityClass {
length := entity.ComputeLength(msg)
r := make([]tg.MessageEntityClass, len(formats))
for i := range formats {
r[i] = formats[i](0, length)
}
return r
}
}
func TestHTML(t *testing.T) {
runTests := func(tests []htmlTestCase, numericName bool) func(t *testing.T) {
return func(t *testing.T) {
for i, test := range tests {
testName := test.msg
if numericName || testName == "" {
testName = fmt.Sprintf("Test%d", i+1)
}
t.Run(strings.Title(testName), func(t *testing.T) {
t.Cleanup(func() {
if t.Failed() {
t.Logf("Input: %q", test.html)
}
})
if test.skipReason != "" {
t.Skip(test.skipReason)
}
a := require.New(t)
b := entity.Builder{}
err := HTML(strings.NewReader(test.html), &b, Options{})
if test.wantErr {
a.Error(err)
return
}
a.NoError(err)
var (
msg string
entities []tg.MessageEntityClass
)
if strings.TrimSpace(test.msg) != test.msg {
// Complete cuts spaces and fixes entities, but TDLib test expects
// that it happens after parsing.
msg, entities = b.Raw()
entity.SortEntities(entities)
} else {
msg, entities = b.Complete()
}
a.Equal(test.msg, msg)
if test.entities != nil {
expect := test.entities(test.msg)
a.Len(entities, len(expect))
a.ElementsMatch(expect, entities)
} else {
a.Empty(entities)
}
})
}
}
}
{
tests := []htmlTestCase{
{html: "bold", msg: "bold", entities: getEntities(entity.Bold())},
{html: "bold", msg: "bold", entities: getEntities(entity.Bold())},
{html: "italic", msg: "italic", entities: getEntities(entity.Italic())},
{html: "italic", msg: "italic", entities: getEntities(entity.Italic())},
{html: "underline", msg: "underline", entities: getEntities(entity.Underline())},
{html: "underline", msg: "underline", entities: getEntities(entity.Underline())},
{html: "strikethrough", msg: "strikethrough", entities: getEntities(entity.Strike())},
{html: "strikethrough", msg: "strikethrough", entities: getEntities(entity.Strike())},
{html: "strikethrough", msg: "strikethrough", entities: getEntities(entity.Strike())},
{html: "code", msg: "code", entities: getEntities(entity.Code())},
{html: "
abc", msg: "abc", entities: getEntities(entity.Pre(""))}, {html: `inline URL`, msg: "inline URL", entities: getEntities(entity.TextURL("http://www.example.com/"))}, {html: `inline mention of a user`, msg: "inline mention of a user", entities: getEntities(entity.MentionName(&tg.InputUser{ UserID: 123456789, }))}, {html: `
python code`, msg: "python code",
entities: getEntities(entity.Pre("python"))},
{html: "<", msg: "<", entities: getEntities(entity.Bold())},
{html: `spoiler`, msg: "spoiler", entities: getEntities(entity.Spoiler())},
{html: "quote", msg: "quote", entities: getEntities(entity.Blockquote(true))}, {html: "
quote", msg: "quote", entities: getEntities(entity.Blockquote(false))}, } t.Run("Common", runTests(tests, false)) } { negativeTests := []htmlTestCase{ {html: "", wantErr: true}, {html: "", wantErr: true}, {html: "", wantErr: true}, {html: "๐ ๐<