chore: baseline snapshot before moderation-strictness feature

Repo .git was damaged (refs/ missing, index truncated, object store near-empty).
Repaired via git init (rebuilt refs), stale index preserved as .git/index.corrupt-20260910.bak,
then full worktree committed as a rollback baseline.
This commit is contained in:
tamakyi
2026-09-10 10:56:27 +08:00
commit e3e59e7c69
296 changed files with 67458 additions and 0 deletions
+341
View File
@@ -0,0 +1,341 @@
// Copyright 2026 tamakyi. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package db
import (
"testing"
"time"
)
// TestFeatureControlEvaluate 覆盖开关 / 定时 / 定量三类控制的组合与优先级。
// 纯逻辑测试,不依赖外部数据库。
func TestFeatureControlEvaluate(t *testing.T) {
now := time.Date(2026, 8, 31, 12, 0, 0, 0, time.UTC)
past := now.Add(-time.Hour)
future := now.Add(time.Hour)
tests := []struct {
name string
fc FeatureControl
wantOk bool
want string
}{
{
name: "开启且无限制",
fc: FeatureControl{Enabled: true},
wantOk: true, want: "",
},
{
name: "手动关闭优先于其它条件",
fc: FeatureControl{Enabled: false, OpenAt: &past, CloseAt: &future, QuotaLimit: 1},
wantOk: false, want: FeatureReasonDisabled,
},
{
name: "未到开放时间",
fc: FeatureControl{Enabled: true, OpenAt: &future},
wantOk: false, want: FeatureReasonNotStarted,
},
{
name: "开放时间已过但功能仍开启",
fc: FeatureControl{Enabled: true, OpenAt: &past},
wantOk: true, want: "",
},
{
name: "已过关闭时间",
fc: FeatureControl{Enabled: true, OpenAt: &past, CloseAt: &past},
wantOk: false, want: FeatureReasonEnded,
},
{
name: "刚好到达关闭时间即关闭",
fc: FeatureControl{Enabled: true, CloseAt: &now},
wantOk: false, want: FeatureReasonEnded,
},
{
name: "未到收集上限",
fc: FeatureControl{Enabled: true, QuotaLimit: 10, QuotaCount: 9},
wantOk: true, want: "",
},
{
name: "恰好达到收集上限",
fc: FeatureControl{Enabled: true, QuotaLimit: 10, QuotaCount: 10},
wantOk: false, want: FeatureReasonQuotaReached,
},
{
name: "超过收集上限",
fc: FeatureControl{Enabled: true, QuotaLimit: 10, QuotaCount: 12},
wantOk: false, want: FeatureReasonQuotaReached,
},
{
name: "上限为 0 表示不限制",
fc: FeatureControl{Enabled: true, QuotaLimit: 0, QuotaCount: 9999},
wantOk: true, want: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
st := tt.fc.Evaluate(now)
if st.Open != tt.wantOk || st.Reason != tt.want {
t.Fatalf("Evaluate() = (open=%v, reason=%q), want (open=%v, reason=%q)",
st.Open, st.Reason, tt.wantOk, tt.want)
}
})
}
}
// TestDefaultFeatureControl 私聊默认关闭(沿用 users.allow_chat 的历史默认),
// 提问与投票默认开启,保证功能上线不改变既有行为。
func TestDefaultFeatureControl(t *testing.T) {
cases := map[string]bool{
FeatureQuestion: true,
FeatureChat: false,
FeatureVote: true,
}
for feature, want := range cases {
if got := DefaultFeatureControl(1, feature).Enabled; got != want {
t.Fatalf("DefaultFeatureControl(%q).Enabled = %v, want %v", feature, got, want)
}
}
}
func TestIsValidFeature(t *testing.T) {
for _, k := range FeatureKeys {
if !IsValidFeature(k) {
t.Fatalf("IsValidFeature(%q) = false, want true", k)
}
}
for _, k := range []string{"", "chat ", "CHAT", "poll", "messages"} {
if IsValidFeature(k) {
t.Fatalf("IsValidFeature(%q) = true, want false", k)
}
}
}
// TestFeatureControlSchedule 覆盖循环定时(每周开放日 + 每日时间段)的 Evaluate 判定。
func TestFeatureControlSchedule(t *testing.T) {
// 固定在一个周四 12:00(time.Weekday: 0=周日…4=周四…6=周六)
now := time.Date(2026, 9, 3, 12, 0, 0, 0, time.UTC) // 2026-09-03 是周四
thursday := int(now.Weekday())
if thursday != 4 {
t.Fatalf("test precondition: 2026-09-03 should be Thursday, got %d", thursday)
}
tests := []struct {
name string
fc FeatureControl
wantOk bool
want string
}{
{
name: "无循环定时不影响判定",
fc: FeatureControl{Enabled: true},
wantOk: true, want: "",
},
{
name: "每日时间段内开放",
fc: FeatureControl{Enabled: true, ScheduleStart: "09:00", ScheduleEnd: "18:00"},
wantOk: true, want: "",
},
{
name: "每日时间段开始前关闭",
fc: FeatureControl{Enabled: true, ScheduleStart: "13:00", ScheduleEnd: "18:00"},
wantOk: false, want: FeatureReasonNotStarted,
},
{
name: "每日时间段结束后关闭(次日会再开)",
fc: FeatureControl{Enabled: true, ScheduleStart: "09:00", ScheduleEnd: "11:00"},
wantOk: false, want: FeatureReasonNotStarted,
},
{
name: "当天不在开放日关闭(未来还会再开)",
fc: FeatureControl{Enabled: true, ScheduleDays: "0", ScheduleStart: "09:00", ScheduleEnd: "18:00"},
wantOk: false, want: FeatureReasonNotStarted,
},
{
name: "只设开放日(不设时间)表示全天",
fc: FeatureControl{Enabled: true, ScheduleDays: "4"},
wantOk: true, want: "",
},
{
name: "只设时间(不设开放日)表示每天该时段",
fc: FeatureControl{Enabled: true, ScheduleStart: "09:00", ScheduleEnd: "18:00"},
wantOk: true, want: "",
},
{
name: "开放日与时间段组合:非开放日关闭",
fc: FeatureControl{Enabled: true, ScheduleDays: "1,3,5", ScheduleStart: "09:00", ScheduleEnd: "18:00"},
wantOk: false, want: FeatureReasonNotStarted, // 周四不在 1,3,5 中
},
{
name: "开放日与时间段组合:开放日+时段内开放",
fc: FeatureControl{Enabled: true, ScheduleDays: "2,4", ScheduleStart: "09:00", ScheduleEnd: "18:00"},
wantOk: true, want: "",
},
{
name: "循环定时达到收集上限",
fc: FeatureControl{Enabled: true, ScheduleDays: "4", ScheduleStart: "09:00", ScheduleEnd: "18:00", QuotaLimit: 5, QuotaCount: 5},
wantOk: false, want: FeatureReasonQuotaReached,
},
{
name: "手动关闭优先于循环定时",
fc: FeatureControl{Enabled: false, ScheduleDays: "4", ScheduleStart: "09:00", ScheduleEnd: "18:00"},
wantOk: false, want: FeatureReasonDisabled,
},
{
name: "一次性窗口与循环定时叠加:窗口内+时段内开放",
fc: FeatureControl{Enabled: true, OpenAt: &[]time.Time{now.Add(-time.Hour)}[0], CloseAt: &[]time.Time{now.Add(24 * time.Hour)}[0], ScheduleStart: "09:00", ScheduleEnd: "18:00"},
wantOk: true, want: "",
},
{
name: "一次性窗口已关闭后循环定时不再生效(硬边界)",
fc: FeatureControl{Enabled: true, OpenAt: &[]time.Time{now.Add(-48 * time.Hour)}[0], CloseAt: &[]time.Time{now.Add(-24 * time.Hour)}[0], ScheduleDays: "4", ScheduleStart: "09:00", ScheduleEnd: "18:00"},
wantOk: false, want: FeatureReasonEnded,
},
{
name: "一次性窗口已关闭且无循环定时",
fc: FeatureControl{Enabled: true, OpenAt: &[]time.Time{now.Add(-48 * time.Hour)}[0], CloseAt: &[]time.Time{now.Add(-24 * time.Hour)}[0]},
wantOk: false, want: FeatureReasonEnded,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
st := tt.fc.Evaluate(now)
if st.Open != tt.wantOk || st.Reason != tt.want {
t.Fatalf("Evaluate() = (open=%v, reason=%q), want (open=%v, reason=%q)",
st.Open, st.Reason, tt.wantOk, tt.want)
}
})
}
}
// TestFeatureControlNextOpenAtLastCloseAt 覆盖「下次开放时间 / 上次关闭时间」的计算。
func TestFeatureControlNextOpenAtLastCloseAt(t *testing.T) {
// 2026-09-03 12:00 UTC(周四)
now := time.Date(2026, 9, 3, 12, 0, 0, 0, time.UTC)
t.Run("循环定时与一次性窗口交集:当天时段内更晚开放", func(t *testing.T) {
// now=周四 12:00,循环每天 09:00-18:00;一次性开放时间 = 今天 14:00 → 今天 14:00 开放
openAt := time.Date(2026, 9, 3, 14, 0, 0, 0, time.UTC)
closeAt := time.Date(2026, 9, 3, 20, 0, 0, 0, time.UTC)
fc := FeatureControl{Enabled: true, OpenAt: &openAt, CloseAt: &closeAt,
ScheduleStart: "09:00", ScheduleEnd: "18:00"}
st := fc.Evaluate(now)
if st.Reason != FeatureReasonNotStarted {
t.Fatalf("reason = %q, want not_started", st.Reason)
}
if st.NextOpenAt == nil || !st.NextOpenAt.Equal(openAt) {
t.Fatalf("NextOpenAt = %v, want %v(今天 14:00)", st.NextOpenAt, openAt)
}
})
t.Run("一次性窗口在循环时段结束后才开放则当天不开放", func(t *testing.T) {
// 一次性开放时间 20:00 晚于循环时段结束 18:00 → 今天无有效窗口,下次开放 = 明天 09:00
openAt := time.Date(2026, 9, 3, 20, 0, 0, 0, time.UTC)
closeAt := time.Date(2026, 9, 5, 20, 0, 0, 0, time.UTC)
fc := FeatureControl{Enabled: true, OpenAt: &openAt, CloseAt: &closeAt,
ScheduleStart: "09:00", ScheduleEnd: "18:00"}
st := fc.Evaluate(now)
if st.Reason != FeatureReasonNotStarted {
t.Fatalf("reason = %q, want not_started", st.Reason)
}
wantNext := time.Date(2026, 9, 4, 9, 0, 0, 0, time.UTC)
if st.NextOpenAt == nil || !st.NextOpenAt.Equal(wantNext) {
t.Fatalf("NextOpenAt = %v, want %v(明天 09:00)", st.NextOpenAt, wantNext)
}
})
t.Run("手动关闭与定量上限不展示时间信息", func(t *testing.T) {
disabled := FeatureControl{Enabled: false, ScheduleStart: "09:00", ScheduleEnd: "18:00"}
st := disabled.Evaluate(now)
if st.Reason != FeatureReasonDisabled || st.NextOpenAt != nil || st.LastCloseAt != nil {
t.Fatalf("disabled state = (reason=%q, next=%v, last=%v), want nil times",
st.Reason, st.NextOpenAt, st.LastCloseAt)
}
quota := FeatureControl{Enabled: true, ScheduleStart: "09:00", ScheduleEnd: "18:00", QuotaLimit: 1, QuotaCount: 1}
st = quota.Evaluate(now)
if st.Reason != FeatureReasonQuotaReached || st.NextOpenAt != nil || st.LastCloseAt != nil {
t.Fatalf("quota state = (reason=%q, next=%v, last=%v), want nil times",
st.Reason, st.NextOpenAt, st.LastCloseAt)
}
})
t.Run("一次性窗口未到开放时间", func(t *testing.T) {
openAt := now.Add(2 * time.Hour)
closeAt := now.Add(24 * time.Hour)
fc := FeatureControl{Enabled: true, OpenAt: &openAt, CloseAt: &closeAt}
st := fc.Evaluate(now)
if st.NextOpenAt == nil || !st.NextOpenAt.Equal(openAt) {
t.Fatalf("NextOpenAt = %v, want %v", st.NextOpenAt, openAt)
}
if st.LastCloseAt != nil {
t.Fatalf("LastCloseAt = %v, want nil(从未开放过)", st.LastCloseAt)
}
})
t.Run("一次性窗口已结束", func(t *testing.T) {
openAt := now.Add(-48 * time.Hour)
closeAt := now.Add(-24 * time.Hour)
fc := FeatureControl{Enabled: true, OpenAt: &openAt, CloseAt: &closeAt}
st := fc.Evaluate(now)
if st.NextOpenAt != nil {
t.Fatalf("NextOpenAt = %v, want nil(无循环定时,永久关闭)", st.NextOpenAt)
}
if st.LastCloseAt == nil || !st.LastCloseAt.Equal(closeAt) {
t.Fatalf("LastCloseAt = %v, want %v", st.LastCloseAt, closeAt)
}
})
t.Run("循环定时:每天 09:00-18:00", func(t *testing.T) {
fc := FeatureControl{Enabled: true, ScheduleStart: "09:00", ScheduleEnd: "18:00"}
// 12:00 在窗口内:下次开放 = 明天 09:00;上次关闭 = 今天 18:00 尚未结束 → 昨天 18:00
st := fc.Evaluate(now)
if st.Open != true {
t.Fatalf("should be open, got reason=%q", st.Reason)
}
wantNext := time.Date(2026, 9, 4, 9, 0, 0, 0, time.UTC)
if st.NextOpenAt == nil || !st.NextOpenAt.Equal(wantNext) {
t.Fatalf("NextOpenAt = %v, want %v", st.NextOpenAt, wantNext)
}
wantLast := time.Date(2026, 9, 2, 18, 0, 0, 0, time.UTC)
if st.LastCloseAt == nil || !st.LastCloseAt.Equal(wantLast) {
t.Fatalf("LastCloseAt = %v, want %v", st.LastCloseAt, wantLast)
}
})
t.Run("循环定时:18:00 已过", func(t *testing.T) {
evening := time.Date(2026, 9, 3, 20, 0, 0, 0, time.UTC)
fc := FeatureControl{Enabled: true, ScheduleStart: "09:00", ScheduleEnd: "18:00"}
st := fc.Evaluate(evening)
if st.Open {
t.Fatal("should be closed after daily end")
}
wantNext := time.Date(2026, 9, 4, 9, 0, 0, 0, time.UTC)
if st.NextOpenAt == nil || !st.NextOpenAt.Equal(wantNext) {
t.Fatalf("NextOpenAt = %v, want %v", st.NextOpenAt, wantNext)
}
wantLast := time.Date(2026, 9, 3, 18, 0, 0, 0, time.UTC)
if st.LastCloseAt == nil || !st.LastCloseAt.Equal(wantLast) {
t.Fatalf("LastCloseAt = %v, want %v", st.LastCloseAt, wantLast)
}
})
t.Run("循环定时:仅周五开放(今天周四)", func(t *testing.T) {
fc := FeatureControl{Enabled: true, ScheduleDays: "5"} // 周五全天
st := fc.Evaluate(now)
if st.Open {
t.Fatal("should be closed on non-scheduled day")
}
wantNext := time.Date(2026, 9, 4, 0, 0, 0, 0, time.UTC) // 周五零点
if st.NextOpenAt == nil || !st.NextOpenAt.Equal(wantNext) {
t.Fatalf("NextOpenAt = %v, want %v", st.NextOpenAt, wantNext)
}
// 全天窗口 [周五 00:00, 周六 00:00),最近一次关闭 = 上周六零点
wantLast := time.Date(2026, 8, 29, 0, 0, 0, 0, time.UTC)
if st.LastCloseAt == nil || !st.LastCloseAt.Equal(wantLast) {
t.Fatalf("LastCloseAt = %v, want %v", st.LastCloseAt, wantLast)
}
})
}