mirror of
https://github.com/BEARlogin/max-telegram-bridge-bot.git
synced 2026-04-28 03:39:46 +00:00
Replace go-telegram-bot-api/v5 (2021, no forum topics) with go-telegram/bot v1.20.0 (Bot API 9.5) via TGSender adapter pattern. - New TGSender interface + tgBotSender implementation isolating library - Native message_thread_id support: saved at /bridge, used in MAX→TG sends, echoed in all command responses, looked up in queue retries - All 16 files migrated, zero old library references remain - Proper error wrapping: MigrateError, Forbidden, BadRequest, NotFound, TooManyRequests → TGError with codes - ForwardFromChat → ForwardOriginChat (Bot API MessageOrigin pattern) - Repository: GetTgThreadID/SetTgThreadID (migration 000012 already applied) - Tests for convertMsg, convertCallback, wrapErr, toInputFile, toLibInputMedia, tgEntitiesToMarkdown, maxMarkupsToHTML Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
255 lines
5.2 KiB
Go
255 lines
5.2 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
|
|
maxschemes "github.com/max-messenger/max-bot-api-client-go/schemes"
|
|
)
|
|
|
|
func TestTgName(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
msg *TGMessage
|
|
expected string
|
|
}{
|
|
{
|
|
name: "first name only",
|
|
msg: &TGMessage{
|
|
From: &UserInfo{FirstName: "Ivan"},
|
|
},
|
|
expected: "Ivan",
|
|
},
|
|
{
|
|
name: "first and last name",
|
|
msg: &TGMessage{
|
|
From: &UserInfo{FirstName: "Ivan", LastName: "Petrov"},
|
|
},
|
|
expected: "Ivan Petrov",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := tgName(tt.msg)
|
|
if got != tt.expected {
|
|
t.Errorf("tgName() = %q, want %q", got, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFormatTgCaption(t *testing.T) {
|
|
msg := &TGMessage{
|
|
Text: "hello world",
|
|
From: &UserInfo{FirstName: "Anna"},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
prefix bool
|
|
expected string
|
|
}{
|
|
{"with prefix", true, "[TG] Anna: hello world"},
|
|
{"without prefix", false, "Anna: hello world"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := formatTgCaption(msg, tt.prefix, false)
|
|
if got != tt.expected {
|
|
t.Errorf("formatTgCaption() = %q, want %q", got, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFormatTgCaption_UsesCaption(t *testing.T) {
|
|
msg := &TGMessage{
|
|
Text: "",
|
|
Caption: "photo caption",
|
|
From: &UserInfo{FirstName: "Bob"},
|
|
}
|
|
|
|
got := formatTgCaption(msg, false, false)
|
|
expected := "Bob: photo caption"
|
|
if got != expected {
|
|
t.Errorf("formatTgCaption() = %q, want %q", got, expected)
|
|
}
|
|
}
|
|
|
|
func TestFormatTgMessage(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
msg *TGMessage
|
|
prefix bool
|
|
expected string
|
|
}{
|
|
{
|
|
name: "text with prefix",
|
|
msg: &TGMessage{
|
|
Text: "edited text",
|
|
From: &UserInfo{FirstName: "Ivan"},
|
|
},
|
|
prefix: true,
|
|
expected: "[TG] Ivan: edited text",
|
|
},
|
|
{
|
|
name: "text without prefix",
|
|
msg: &TGMessage{
|
|
Text: "edited text",
|
|
From: &UserInfo{FirstName: "Ivan"},
|
|
},
|
|
prefix: false,
|
|
expected: "Ivan: edited text",
|
|
},
|
|
{
|
|
name: "empty text returns empty",
|
|
msg: &TGMessage{
|
|
Text: "",
|
|
From: &UserInfo{FirstName: "Ivan"},
|
|
},
|
|
prefix: true,
|
|
expected: "",
|
|
},
|
|
{
|
|
name: "caption fallback",
|
|
msg: &TGMessage{
|
|
Text: "",
|
|
Caption: "cap",
|
|
From: &UserInfo{FirstName: "Ivan"},
|
|
},
|
|
prefix: false,
|
|
expected: "Ivan: cap",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := formatTgMessage(tt.msg, tt.prefix, false)
|
|
if got != tt.expected {
|
|
t.Errorf("formatTgMessage() = %q, want %q", got, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMaxName(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
upd *maxschemes.MessageCreatedUpdate
|
|
expected string
|
|
}{
|
|
{
|
|
name: "has name",
|
|
upd: &maxschemes.MessageCreatedUpdate{
|
|
Message: maxschemes.Message{
|
|
Sender: maxschemes.User{Name: "Алексей"},
|
|
},
|
|
},
|
|
expected: "Алексей",
|
|
},
|
|
{
|
|
name: "fallback to username",
|
|
upd: &maxschemes.MessageCreatedUpdate{
|
|
Message: maxschemes.Message{
|
|
Sender: maxschemes.User{Name: "", Username: "alex42"},
|
|
},
|
|
},
|
|
expected: "alex42",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := maxName(tt.upd)
|
|
if got != tt.expected {
|
|
t.Errorf("maxName() = %q, want %q", got, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFormatMaxCaption(t *testing.T) {
|
|
upd := &maxschemes.MessageCreatedUpdate{
|
|
Message: maxschemes.Message{
|
|
Sender: maxschemes.User{Name: "Вася"},
|
|
Body: maxschemes.MessageBody{Text: "привет"},
|
|
},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
prefix bool
|
|
expected string
|
|
}{
|
|
{"with prefix", true, "[MAX] Вася: привет"},
|
|
{"without prefix", false, "Вася: привет"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := formatMaxCaption(upd, tt.prefix, false)
|
|
if got != tt.expected {
|
|
t.Errorf("formatMaxCaption() = %q, want %q", got, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFormatTgCrosspostCaption(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
msg *TGMessage
|
|
expected string
|
|
}{
|
|
{
|
|
name: "text",
|
|
msg: &TGMessage{Text: "Новый пост"},
|
|
expected: "Новый пост",
|
|
},
|
|
{
|
|
name: "caption fallback",
|
|
msg: &TGMessage{Text: "", Caption: "фото"},
|
|
expected: "фото",
|
|
},
|
|
{
|
|
name: "empty",
|
|
msg: &TGMessage{Text: ""},
|
|
expected: "",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := formatTgCrosspostCaption(tt.msg)
|
|
if got != tt.expected {
|
|
t.Errorf("formatTgCrosspostCaption() = %q, want %q", got, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFormatMaxCrosspostCaption(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
text string
|
|
expected string
|
|
}{
|
|
{"with text", "Новость дня", "Новость дня"},
|
|
{"empty text", "", ""},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
upd := &maxschemes.MessageCreatedUpdate{
|
|
Message: maxschemes.Message{
|
|
Body: maxschemes.MessageBody{Text: tt.text},
|
|
},
|
|
}
|
|
got := formatMaxCrosspostCaption(upd)
|
|
if got != tt.expected {
|
|
t.Errorf("formatMaxCrosspostCaption() = %q, want %q", got, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|