小程序一些功能更新
This commit is contained in:
78
internal/logic/admin_level_test.go
Normal file
78
internal/logic/admin_level_test.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
|
||||
"tool-api/internal/consts"
|
||||
"tool-api/internal/model/entity"
|
||||
)
|
||||
|
||||
// TestCountActiveMembers_PermanentCounted 看板「有效会员」必须计入永久会员
|
||||
// (level_expire_at = NULL,管理员手动分配)。这是本次修复(#24)的核心回归点:
|
||||
// 旧 SQL 用 `level_expire_at IS NOT NULL` 把永久会员全部漏掉了。
|
||||
func TestCountActiveMembers_PermanentCounted(t *testing.T) {
|
||||
future := gtime.New(time.Now().Add(24 * time.Hour))
|
||||
past := gtime.New(time.Now().Add(-24 * time.Hour))
|
||||
users := []*entity.Users{
|
||||
{LevelKey: "v2", LevelExpireAt: nil}, // ① 永久(NULL)→ 应计入
|
||||
{LevelKey: "v2", LevelExpireAt: future}, // ② 未过期 → 应计入
|
||||
{LevelKey: "v2", LevelExpireAt: past}, // ③ 已过期 → 回落默认等级,不计入
|
||||
}
|
||||
if got := countActiveMembers(users); got != 2 {
|
||||
t.Fatalf("countActiveMembers=%d want 2", got)
|
||||
}
|
||||
}
|
||||
|
||||
// TestLevelDistribution_EffectiveKey 等级分布按「生效等级」分组:
|
||||
// 已过期用户必须落入默认等级桶,而不是其原始 level_key。
|
||||
func TestLevelDistribution_EffectiveKey(t *testing.T) {
|
||||
future := gtime.New(time.Now().Add(24 * time.Hour))
|
||||
past := gtime.New(time.Now().Add(-24 * time.Hour))
|
||||
users := []*entity.Users{
|
||||
{LevelKey: "v2", LevelExpireAt: nil},
|
||||
{LevelKey: "v2", LevelExpireAt: future},
|
||||
{LevelKey: "v2", LevelExpireAt: past},
|
||||
}
|
||||
dist := levelDistribution(users)
|
||||
if dist["v2"] != 2 {
|
||||
t.Fatalf("v2 桶=%d want 2 (%v)", dist["v2"], dist)
|
||||
}
|
||||
if dist[consts.DefaultLevelKey] != 1 {
|
||||
t.Fatalf("默认等级桶=%d want 1 (%v)", dist[consts.DefaultLevelKey], dist)
|
||||
}
|
||||
}
|
||||
|
||||
// TestCountActiveMembers_DefaultExcluded 默认等级(含空 key)不算有效会员。
|
||||
func TestCountActiveMembers_DefaultExcluded(t *testing.T) {
|
||||
users := []*entity.Users{
|
||||
{LevelKey: consts.DefaultLevelKey, LevelExpireAt: nil},
|
||||
{LevelKey: "", LevelExpireAt: nil},
|
||||
}
|
||||
if got := countActiveMembers(users); got != 0 {
|
||||
t.Fatalf("countActiveMembers=%d want 0", got)
|
||||
}
|
||||
if n := countActiveMembers(nil); n != 0 {
|
||||
t.Fatalf("nil 应返回 0,got %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
// TestValidateLevelKeyUnchanged 编辑等级时 level_key 是跨端契约字段,不允许变更(T01.6)。
|
||||
// 服务端闸门:前端把输入框 disabled 只是体验层,这里固化「变更即报错」的行为,
|
||||
// 取消失败回归(例如未来有人误把 level_key 写进编辑 data map)。
|
||||
func TestValidateLevelKeyUnchanged(t *testing.T) {
|
||||
// 未变更 → 放行
|
||||
if err := validateLevelKeyUnchanged("v2", "v2"); err != nil {
|
||||
t.Fatalf("相同 level_key 应放行,got err=%v", err)
|
||||
}
|
||||
// 变更 → 报错
|
||||
if err := validateLevelKeyUnchanged("v2", "v3"); err == nil {
|
||||
t.Fatalf("变更 level_key 应报错,got nil")
|
||||
}
|
||||
// 清空(旧展开式回填的典型故障)→ 报错
|
||||
if err := validateLevelKeyUnchanged("v2", ""); err == nil {
|
||||
t.Fatalf("清空 level_key 应报错,got nil")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user