spark-server/internal/module/moderation/logic/moderation_test.go
2026-09-29 16:37:36 +08:00

121 lines
3.6 KiB
Go

package logic
import (
"context"
"errors"
"testing"
"time"
modentity "spark-server/internal/module/moderation/entity"
"spark-server/internal/pkg/errs"
"spark-server/internal/pkg/sensitive"
)
type fakeUsers struct {
mutedUntil time.Time
disabled bool
}
func (f *fakeUsers) AssertCanSend(_ context.Context, _ int64) error { return nil }
func (f *fakeUsers) DisableAccount(_ context.Context, _ int64) error {
f.disabled = true
return nil
}
func (f *fakeUsers) ExtendSendMutedUntil(_ context.Context, _ int64, until time.Time) error {
if until.After(f.mutedUntil) {
f.mutedUntil = until
}
return nil
}
type fakeIDs struct{ n int64 }
func (f *fakeIDs) NextID() (int64, error) {
f.n++
return f.n, nil
}
func TestScanReplace(t *testing.T) {
word := sensitive.FoldWord("赌博")
repo := NewMemoryRepo(&modentity.Word{
ID: 1, WordRaw: "赌博", Word: word, Category: modentity.CategoryGambling,
Action: modentity.ActionReplace, Enabled: true,
})
svc := NewService(repo, nil, &fakeIDs{})
res, err := svc.Scan(context.Background(), "今晚赌博")
if err != nil || res == nil || res.Action != modentity.ActionReplace || res.ReplacedBody != "今晚***" {
t.Fatalf("scan %+v %v", res, err)
}
}
func TestCreateWordAndReload(t *testing.T) {
repo := NewMemoryRepo()
svc := NewService(repo, nil, &fakeIDs{})
w, err := svc.CreateWord(context.Background(), &CreateWordInput{
WordRaw: "广告词", Category: int8(modentity.CategoryAd), Action: int8(modentity.ActionLog),
})
if err != nil || w == nil || w.Word == "" {
t.Fatalf("create %+v %v", w, err)
}
list, total, err := svc.ListWords(context.Background(), "", 0, nil, 0, 10)
if err != nil || total != 1 || len(list) != 1 {
t.Fatalf("list %d %+v %v", total, list, err)
}
}
func TestEnforceReject(t *testing.T) {
repo := NewMemoryRepo(&modentity.Word{
ID: 2, Word: sensitive.FoldWord("毒品"), WordRaw: "毒品",
Category: modentity.CategoryDrug, Action: modentity.ActionReject, Enabled: true,
})
ids := &fakeIDs{}
svc := NewService(repo, &fakeUsers{}, ids)
res, _ := svc.Scan(context.Background(), "涉毒品")
if err := svc.Apply(context.Background(), 9, 1, &modentity.ApplyInput{Hits: res.Hits}); err != nil {
t.Fatal(err)
}
if err := svc.Enforce(context.Background(), 9, res); !errors.Is(err, errs.ErrContentBlocked) {
t.Fatalf("enforce %v", err)
}
if len(repo.hits) != 1 {
t.Fatalf("hits %d", len(repo.hits))
}
}
func TestEnforceMute(t *testing.T) {
repo := NewMemoryRepo(&modentity.Word{
ID: 3, Word: sensitive.FoldWord("骂人"), WordRaw: "骂人",
Category: modentity.CategoryAbuse, Action: modentity.ActionMute, MuteSeconds: 60, Enabled: true,
})
fu := &fakeUsers{}
svc := NewService(repo, fu, &fakeIDs{})
res, _ := svc.Scan(context.Background(), "骂人啊")
if err := svc.Apply(context.Background(), 1, 2, &modentity.ApplyInput{Hits: res.Hits}); err != nil {
t.Fatal(err)
}
if err := svc.Enforce(context.Background(), 1, res); !errors.Is(err, errs.ErrContentBlocked) {
t.Fatalf("%v", err)
}
if fu.mutedUntil.IsZero() {
t.Fatal("expected mute")
}
}
func TestPatchAndDeleteWord(t *testing.T) {
repo := NewMemoryRepo()
svc := NewService(repo, nil, &fakeIDs{})
w, err := svc.CreateWord(context.Background(), &CreateWordInput{
WordRaw: "临时", Category: int8(modentity.CategoryOther), Action: int8(modentity.ActionReject),
})
if err != nil {
t.Fatal(err)
}
act := int8(modentity.ActionLog)
if err := svc.PatchWord(context.Background(), w.ID, &PatchWordInput{Action: &act}); err != nil {
t.Fatal(err)
}
if err := svc.DeleteWord(context.Background(), w.ID); err != nil {
t.Fatal(err)
}
}