mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 19:36:36 +08:00
176 lines
6.0 KiB
Go
176 lines
6.0 KiB
Go
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)
|
|
}
|
|
}
|