mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-10 15:26:38 +08:00
refactor: split bot feature tests
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/ShukeBta/MediaStationGo/internal/model"
|
||||
)
|
||||
|
||||
func TestBotRegistrationCommandUsesOpenRegQuota(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
repos, bot := newBotTestService(t)
|
||||
admin := &model.User{Username: "root", PasswordHash: "x", Role: "admin", IsActive: true}
|
||||
if err := repos.User.Create(ctx, admin); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := repos.Setting.Set(ctx, SettingOpenRegEnabled, "false"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := repos.DB.Create(&model.TelegramBinding{
|
||||
TelegramUserID: 9051,
|
||||
TelegramName: "@root",
|
||||
ChatID: 9051,
|
||||
UserID: admin.ID,
|
||||
}).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
channel := &model.NotifyChannel{Name: "Telegram", Type: "telegram", Enabled: true, Config: `{"admin_user_ids":"9051"}`}
|
||||
msg := &TelegramMessage{From: TelegramUser{ID: 9051, Username: "root"}, Chat: TelegramChat{ID: 9051, Type: "private"}}
|
||||
|
||||
reply, err := bot.executeCommand(ctx, channel, msg, "/registration on 2")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(reply.Text, "2 个名额") {
|
||||
t.Fatalf("expected quota feedback, got %q", reply.Text)
|
||||
}
|
||||
capacity := bot.loadCapacity(ctx)
|
||||
if !capacity.OpenRegOn || capacity.OpenRegLimit != 2 || capacity.OpenRegUsed != 0 {
|
||||
t.Fatalf("registration command should open quota-aware registration, got %+v", capacity)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBotUserCommandsAndAdminGate(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
repos, bot := newBotTestService(t)
|
||||
user := &model.User{Username: "viewer", PasswordHash: "x", Role: "user", IsActive: true}
|
||||
if err := repos.User.Create(ctx, user); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := repos.DB.Create(&model.TelegramBinding{
|
||||
TelegramUserID: 9101,
|
||||
TelegramName: "@viewer",
|
||||
ChatID: 9101,
|
||||
UserID: user.ID,
|
||||
}).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
now := time.Now()
|
||||
if err := repos.UserDevice.Create(ctx, &model.UserDevice{
|
||||
UserID: user.ID, DeviceID: "dev-1", DeviceName: "iPhone", Client: "Infuse", FirstSeenAt: now, LastSeenAt: now,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
channel := &model.NotifyChannel{Name: "Telegram", Type: "telegram", Enabled: true, Config: `{"admin_user_ids":"9001"}`}
|
||||
msg := &TelegramMessage{From: TelegramUser{ID: 9101, Username: "viewer"}, Chat: TelegramChat{ID: 9101, Type: "private"}}
|
||||
|
||||
reply, err := bot.executeCommand(ctx, channel, msg, "/antishare on")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(reply.Text, "仅管理员") {
|
||||
t.Fatalf("regular user should not manage policy, got %q", reply.Text)
|
||||
}
|
||||
|
||||
reply, err = bot.executeCommand(ctx, channel, msg, "/devices")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(reply.Text, "我的登录设备") {
|
||||
t.Fatalf("expected device list, got %q", reply.Text)
|
||||
}
|
||||
|
||||
reply, err = bot.executeCommand(ctx, channel, msg, "/kick 1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(reply.Text, "已踢下线") {
|
||||
t.Fatalf("expected kick feedback, got %q", reply.Text)
|
||||
}
|
||||
if kicked := bot.device; kicked != nil {
|
||||
t.Fatal("test should not require wired device service")
|
||||
}
|
||||
if ok := NewDeviceService(zap.NewNop(), repos).IsDeviceKicked(ctx, user.ID, "dev-1"); !ok {
|
||||
t.Fatal("device should be marked kicked")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBotAdminCodeAndUserCommands(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
repos, bot := newBotTestService(t)
|
||||
admin := &model.User{Username: "root", PasswordHash: "x", Role: "admin", IsActive: true}
|
||||
user := &model.User{Username: "viewer", PasswordHash: "x", Role: "user", IsActive: true}
|
||||
if err := repos.User.Create(ctx, admin); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := repos.User.Create(ctx, user); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := repos.DB.Create(&model.TelegramBinding{
|
||||
TelegramUserID: 9301,
|
||||
TelegramName: "@root",
|
||||
ChatID: 9301,
|
||||
UserID: admin.ID,
|
||||
}).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
channel := &model.NotifyChannel{Name: "Telegram", Type: "telegram", Enabled: true, Config: `{"admin_user_ids":"9301"}`}
|
||||
msg := &TelegramMessage{From: TelegramUser{ID: 9301, Username: "root"}, Chat: TelegramChat{ID: 9301, Type: "private"}}
|
||||
|
||||
reply, err := bot.executeCommand(ctx, channel, msg, "/gencode renew 90 7")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(reply.Text, "已生成续期码") {
|
||||
t.Fatalf("expected generated renew code, got %q", reply.Text)
|
||||
}
|
||||
|
||||
reply, err = bot.executeCommand(ctx, channel, msg, "/renew_user viewer 30")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(reply.Text, "viewer") {
|
||||
t.Fatalf("renew command should return user actions, got %q", reply.Text)
|
||||
}
|
||||
updated, _ := repos.User.FindByID(ctx, user.ID)
|
||||
if updated.ExpiredAt == nil || updated.ExpiredAt.Before(time.Now()) {
|
||||
t.Fatalf("renew_user should set future expiry, got %v", updated.ExpiredAt)
|
||||
}
|
||||
|
||||
reply, err = bot.executeCommand(ctx, channel, msg, "/delete_user viewer")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(reply.Text, "需要确认") {
|
||||
t.Fatalf("delete without confirm should be rejected, got %q", reply.Text)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBotGroupMenuShowsAdminActionsOnlyForAdmins(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
_, bot := newBotTestService(t)
|
||||
channel := &model.NotifyChannel{Name: "Telegram", Type: "telegram", Enabled: true, Config: `{"admin_user_ids":"9301","group_chat_id":"-1001"}`}
|
||||
adminMsg := &TelegramMessage{From: TelegramUser{ID: 9301, Username: "admin"}, Chat: TelegramChat{ID: -1001, Type: "group"}}
|
||||
reply, err := bot.executeCommand(ctx, channel, adminMsg, "/menu")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(reply.Text, "管理员入口") || len(reply.Buttons) == 0 {
|
||||
t.Fatalf("admin group menu should expose management actions, got %#v", reply)
|
||||
}
|
||||
|
||||
userMsg := &TelegramMessage{From: TelegramUser{ID: 9302, Username: "user"}, Chat: TelegramChat{ID: -1001, Type: "group"}}
|
||||
reply, err = bot.executeCommand(ctx, channel, userMsg, "/menu")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Contains(reply.Text, "管理员入口") {
|
||||
t.Fatalf("non-admin group menu must not expose management actions, got %#v", reply)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user