mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 03:26:37 +08:00
193 lines
6.9 KiB
Go
193 lines
6.9 KiB
Go
package service
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/ShukeBta/MediaStationGo/internal/model"
|
|
)
|
|
|
|
func TestRegisterTelegramBotCommands(t *testing.T) {
|
|
var gotPath string
|
|
var payloads []struct {
|
|
Commands []telegramBotCommand `json:"commands"`
|
|
Scope map[string]any `json:"scope"`
|
|
}
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
gotPath = r.URL.Path
|
|
var payload struct {
|
|
Commands []telegramBotCommand `json:"commands"`
|
|
Scope map[string]any `json:"scope"`
|
|
}
|
|
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
|
t.Fatalf("decode payload: %v", err)
|
|
}
|
|
payloads = append(payloads, payload)
|
|
_, _ = w.Write([]byte(`{"ok":true}`))
|
|
}))
|
|
defer server.Close()
|
|
|
|
err := registerTelegramBotCommands(t.Context(), map[string]string{
|
|
"bot_token": "123456:ABC",
|
|
"api_base_url": server.URL,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if gotPath != "/bot123456:ABC/setMyCommands" {
|
|
t.Fatalf("path = %q", gotPath)
|
|
}
|
|
if len(payloads) < 3 {
|
|
t.Fatalf("expected default/private/group command registrations, got %d", len(payloads))
|
|
}
|
|
if len(payloads[0].Commands) == 0 || payloads[0].Commands[0].Command != "start" {
|
|
t.Fatalf("commands not registered: %#v", payloads[0].Commands)
|
|
}
|
|
var groupCommands []telegramBotCommand
|
|
for _, payload := range payloads {
|
|
if payload.Scope["type"] == "all_group_chats" {
|
|
groupCommands = payload.Commands
|
|
break
|
|
}
|
|
}
|
|
if len(groupCommands) == 0 {
|
|
t.Fatal("group command scope was not registered")
|
|
}
|
|
for _, command := range groupCommands {
|
|
if command.Command == "users" || command.Command == "status" || command.Command == "cleanup" || command.Command == "register" || command.Command == "redeem" {
|
|
t.Fatalf("group commands must not expose private/admin command %q", command.Command)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDeleteTelegramWebhookBeforePolling(t *testing.T) {
|
|
var gotPath string
|
|
var payload map[string]any
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
gotPath = r.URL.Path
|
|
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
|
t.Fatalf("decode payload: %v", err)
|
|
}
|
|
_, _ = w.Write([]byte(`{"ok":true}`))
|
|
}))
|
|
defer server.Close()
|
|
|
|
err := deleteTelegramWebhook(t.Context(), map[string]string{
|
|
"bot_token": "123456:ABC",
|
|
"api_base_url": server.URL,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if gotPath != "/bot123456:ABC/deleteWebhook" {
|
|
t.Fatalf("path = %q", gotPath)
|
|
}
|
|
if got := payload["drop_pending_updates"]; got != false {
|
|
t.Fatalf("drop_pending_updates = %#v, want false", got)
|
|
}
|
|
}
|
|
|
|
func TestTelegramCommandMenusSeparateGroupAndAdminCommands(t *testing.T) {
|
|
privateNames := telegramCommandNames(telegramPrivateBotCommandMenu())
|
|
for _, required := range []string{"setname", "setpass"} {
|
|
if !privateNames[required] {
|
|
t.Fatalf("private menu should include %s", required)
|
|
}
|
|
}
|
|
for _, hiddenAlias := range []string{"myinfo", "count"} {
|
|
if privateNames[hiddenAlias] {
|
|
t.Fatalf("private menu should hide compatibility alias %s", hiddenAlias)
|
|
}
|
|
if !telegramSupportedCommand("/" + hiddenAlias) {
|
|
t.Fatalf("compatibility alias /%s should remain executable", hiddenAlias)
|
|
}
|
|
}
|
|
|
|
groupNames := telegramCommandNames(telegramGroupBotCommandMenu())
|
|
for _, forbidden := range []string{"status", "search", "downloads", "stats", "users", "cleanup", "cleanup_rule", "register", "redeem"} {
|
|
if groupNames[forbidden] {
|
|
t.Fatalf("group menu should not expose %s", forbidden)
|
|
}
|
|
}
|
|
for _, required := range []string{"start", "menu", "help", "account", "signin", "devices", "kick", "hideadult"} {
|
|
if !groupNames[required] {
|
|
t.Fatalf("group menu should include %s", required)
|
|
}
|
|
}
|
|
adminCommands := telegramAdminBotCommandMenu()
|
|
adminNames := telegramCommandNames(adminCommands)
|
|
for _, required := range []string{"users", "status", "cleanup_mode", "cleanup_rule", "ucr", "uinfo", "rmemby", "only_rm_record", "renewall", "userip", "auditip", "auditdevice", "auditclient", "udeviceid", "syncunbound", "syncgroupm", "check_ex", "deleted", "embyadmin", "banall", "unbanall", "prouser", "revuser", "embylibs_blockall", "embylibs_unblockall", "proadmin", "revadmin", "backup_db", "restore_from_db"} {
|
|
if !adminNames[required] {
|
|
t.Fatalf("admin menu should include %s", required)
|
|
}
|
|
}
|
|
for _, hiddenAlias := range []string{"myinfo", "count", "low_activity", "urm", "only_rm_emby", "extraembylibs_blockall", "extraembylibs_unblockall"} {
|
|
if adminNames[hiddenAlias] {
|
|
t.Fatalf("admin menu should hide compatibility alias %s", hiddenAlias)
|
|
}
|
|
}
|
|
for _, command := range adminCommands {
|
|
if strings.Contains(command.Description, "Mgo 兼容") {
|
|
t.Fatalf("admin menu command %s should use native Mgo wording: %q", command.Command, command.Description)
|
|
}
|
|
}
|
|
help := telegramMgoAdminCommandHelp()
|
|
for _, want := range []string{"用户:", "审计:", "清理:", "权限:", "运维:"} {
|
|
if !strings.Contains(help, want) {
|
|
t.Fatalf("mgo admin help should include category %q in %q", want, help)
|
|
}
|
|
}
|
|
if strings.Contains(help, "/setpass") {
|
|
t.Fatalf("mgo admin help should not include user self-service command /setpass")
|
|
}
|
|
}
|
|
|
|
func telegramCommandNames(commands []telegramBotCommand) map[string]bool {
|
|
names := make(map[string]bool, len(commands))
|
|
for _, command := range commands {
|
|
names[command.Command] = true
|
|
}
|
|
return names
|
|
}
|
|
|
|
func TestTelegramCommandFiltering(t *testing.T) {
|
|
if telegramIsCommandText("今天看什么") {
|
|
t.Fatal("plain chat message should not be treated as command")
|
|
}
|
|
if !telegramIsCommandText("/start user pass") {
|
|
t.Fatal("/start should be treated as command")
|
|
}
|
|
if got := telegramCommandName("/hideadult@MediaStationGoBot on"); got != "/hideadult" {
|
|
t.Fatalf("telegramCommandName = %q, want /hideadult", got)
|
|
}
|
|
if telegramSupportedCommand("/签到") {
|
|
t.Fatal("unrelated group bot command should not be handled")
|
|
}
|
|
for _, cmd := range []string{"/signin", "/redeem", "/gencode", "/users", "/renew_user", "/delete_user", "/cleanup_rule"} {
|
|
if !telegramSupportedCommand(cmd) {
|
|
t.Fatalf("%s should be supported so group slash commands get feedback", cmd)
|
|
}
|
|
}
|
|
for _, cmd := range []string{"/restart", "/update_bot", "/coins", "/red", "/white_channel", "/config"} {
|
|
if telegramSupportedCommand(cmd) {
|
|
t.Fatalf("%s should not be treated as supported until it has a real Mgo implementation", cmd)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTelegramSupportedCommandSetMatchesRegistry(t *testing.T) {
|
|
_, bot := newBotTestService(t)
|
|
channel := &model.NotifyChannel{Name: "Telegram", Type: "telegram", Enabled: true, Config: `{"admin_user_ids":"9001"}`}
|
|
msg := &TelegramMessage{From: TelegramUser{ID: 9001, Username: "admin"}, Chat: TelegramChat{ID: 9001, Type: "private"}}
|
|
for _, def := range bot.telegramCommandDefinitions(t.Context(), channel, msg) {
|
|
for _, alias := range def.Aliases {
|
|
if !telegramSupportedCommand(alias) {
|
|
t.Fatalf("registered command %s must be in telegramSupportedCommandSet", alias)
|
|
}
|
|
}
|
|
}
|
|
}
|