topfans/backend/services/moderationService/service/auto_hide_service_test.go
2026-06-22 17:19:48 +08:00

116 lines
3.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"context"
"errors"
"testing"
"github.com/redis/go-redis/v9"
"github.com/topfans/backend/services/moderationService/config"
)
// auto_hide_service_test.go - Lua 脚本逻辑测试spec §7.2
// TestLuaScript 嵌入的 Lua 脚本存在且非空
func TestLuaScript(t *testing.T) {
if autoHideLuaScript == "" {
t.Fatal("autoHideLuaScript must be embedded")
}
// 验证 Lua 包含关键逻辑SETNX, INCR, EXPIRE, threshold
requiredKeywords := []string{"SET", "INCR", "EXPIRE"}
for _, kw := range requiredKeywords {
if !contains(autoHideLuaScript, kw) {
t.Errorf("Lua script missing keyword: %s", kw)
}
}
}
// TestTryTrigger_LockFailure 测试锁抢占失败场景
// 应用层短锁覆盖整个 auto-hide 流程spec §6.4
func TestTryTrigger_LockFailure(t *testing.T) {
rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379"})
defer rdb.Close()
ctx := context.Background()
svc := &AutoHideService{redis: rdb, cfg: config.Default}
// 用 miniredis 或真实 Redis先 acquire lock
lockKey := "test:mod:report:lock:asset:999"
rdb.SetNX(ctx, lockKey, "1", config.Default.LockTTL)
// 再调用应该返回 (false, 0, nil) — 锁失败不触发
triggered, _, err := svc.TryTrigger(ctx, "asset", 999, 100)
if err != nil {
t.Skipf("redis not available: %v", err)
}
if triggered {
t.Errorf("expected triggered=false when lock held")
}
rdb.Del(ctx, lockKey)
}
// TestResetCounter_EmptyKeys 测试重置计数器在空 keys 场景
func TestResetCounter_EmptyKeys(t *testing.T) {
rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379"})
defer rdb.Close()
ctx := context.Background()
svc := &AutoHideService{redis: rdb, cfg: config.Default}
err := svc.ResetCounter(ctx, "asset", 888)
if err != nil && !errors.Is(err, redis.Nil) {
t.Logf("ResetCounter err (acceptable for empty): %v", err)
}
}
// TestResetCounter_WithExistingKeys 测试有 keys 时的清理
func TestResetCounter_WithExistingKeys(t *testing.T) {
rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379"})
defer rdb.Close()
ctx := context.Background()
svc := &AutoHideService{redis: rdb, cfg: config.Default}
// pre-populate
prefix := config.Default.RedisKeyPrefix + ":user:asset:777:"
for _, uid := range []int64{101, 102, 103} {
key := prefix + itoa(uid)
rdb.Set(ctx, key, "1", config.Default.UserMarkerTTL)
}
counterKey := config.Default.RedisKeyPrefix + ":counter:asset:777"
rdb.Set(ctx, counterKey, "3", config.Default.CounterTTL)
err := svc.ResetCounter(ctx, "asset", 777)
if err != nil && !errors.Is(err, redis.Nil) {
t.Logf("ResetCounter err: %v", err)
}
// verify counter + user markers cleared
if exists, _ := rdb.Exists(ctx, counterKey).Result(); exists != 0 {
t.Errorf("counter key not cleared")
}
for _, uid := range []int64{101, 102, 103} {
key := prefix + itoa(uid)
if exists, _ := rdb.Exists(ctx, key).Result(); exists != 0 {
t.Errorf("user marker %d not cleared", uid)
}
}
}
func itoa(i int64) string {
if i == 0 {
return "0"
}
negative := i < 0
if negative {
i = -i
}
digits := []byte{}
for i > 0 {
digits = append([]byte{byte('0' + i%10)}, digits...)
i /= 10
}
if negative {
digits = append([]byte{'-'}, digits...)
}
return string(digits)
}