93 lines
2.8 KiB
Go
93 lines
2.8 KiB
Go
|
|
package tg
|
||
|
|
|
||
|
|
import (
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"github.com/gotd/td/tg"
|
||
|
|
|
||
|
|
"github.com/tegwick/fluid-telegram/internal/spec"
|
||
|
|
)
|
||
|
|
|
||
|
|
// The token is the one secret that passes through this process's memory. If the
|
||
|
|
// pattern stops matching, RegisterBot reports "no token found" after a bot has
|
||
|
|
// already been created -- which is the expensive failure, since retrying makes a
|
||
|
|
// second bot.
|
||
|
|
func TestTokenPattern(t *testing.T) {
|
||
|
|
replies := []struct {
|
||
|
|
name string
|
||
|
|
text string
|
||
|
|
want string
|
||
|
|
}{
|
||
|
|
{"typical", "Done! Congratulations on your new bot.\n\nUse this token to access the HTTP API:\n123456789:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw\n\nKeep your token secure.", "123456789:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw"},
|
||
|
|
{"long id", "Token: 7123456789:AAF-abcDEFghiJKLmnoPQRstuVWXyz012345", "7123456789:AAF-abcDEFghiJKLmnoPQRstuVWXyz012345"},
|
||
|
|
{"underscores and dashes", "8000000001:AA_this-has_all-the_chars012345678", "8000000001:AA_this-has_all-the_chars012345678"},
|
||
|
|
}
|
||
|
|
for _, r := range replies {
|
||
|
|
t.Run(r.name, func(t *testing.T) {
|
||
|
|
m := tokenRe.FindStringSubmatch(r.text)
|
||
|
|
if m == nil {
|
||
|
|
t.Fatalf("no token matched in %q", r.text)
|
||
|
|
}
|
||
|
|
if m[1] != r.want {
|
||
|
|
t.Fatalf("got %q, want %q", m[1], r.want)
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// It must not match things that merely look like tokens, or a failure reply
|
||
|
|
// could be mistaken for success and a bogus token written to OpenBao.
|
||
|
|
func TestTokenPatternRejects(t *testing.T) {
|
||
|
|
for _, s := range []string{
|
||
|
|
"Sorry, this username is already taken.",
|
||
|
|
"12:34",
|
||
|
|
"Please choose a name for your bot.",
|
||
|
|
} {
|
||
|
|
if tokenRe.MatchString(s) {
|
||
|
|
t.Errorf("matched a token in %q", s)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestFirstLineTruncates(t *testing.T) {
|
||
|
|
if got := firstLine("one\ntwo"); got != "one" {
|
||
|
|
t.Errorf("got %q", got)
|
||
|
|
}
|
||
|
|
long := make([]byte, 200)
|
||
|
|
for i := range long {
|
||
|
|
long[i] = 'x'
|
||
|
|
}
|
||
|
|
if got := firstLine(string(long)); len(got) > 95 {
|
||
|
|
t.Errorf("length %d, expected truncation", len(got))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Rights reported back must use the spec's vocabulary, so a plan can compare
|
||
|
|
// them to the spec without translating between two naming schemes -- and must
|
||
|
|
// report a wider right rather than dropping it, since dropping one would make
|
||
|
|
// drift invisible exactly where it matters.
|
||
|
|
func TestRightsNames(t *testing.T) {
|
||
|
|
got := rightsNames(tg.ChatAdminRights{PostMessages: true})
|
||
|
|
if len(got) != 1 || got[0] != spec.PostMessages {
|
||
|
|
t.Fatalf("got %v, want [%s]", got, spec.PostMessages)
|
||
|
|
}
|
||
|
|
|
||
|
|
got = rightsNames(tg.ChatAdminRights{PostMessages: true, DeleteMessages: true})
|
||
|
|
if len(got) != 2 {
|
||
|
|
t.Fatalf("a wider right must be reported, got %v", got)
|
||
|
|
}
|
||
|
|
var sawDelete bool
|
||
|
|
for _, r := range got {
|
||
|
|
if r == "delete_messages" {
|
||
|
|
sawDelete = true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if !sawDelete {
|
||
|
|
t.Errorf("delete_messages was dropped: %v", got)
|
||
|
|
}
|
||
|
|
|
||
|
|
if got := rightsNames(tg.ChatAdminRights{}); len(got) != 0 {
|
||
|
|
t.Errorf("a bot with no rights should report none, got %v", got)
|
||
|
|
}
|
||
|
|
}
|