123 lines
5.1 KiB
Go
123 lines
5.1 KiB
Go
package business
|
|
|
|
import (
|
|
"context"
|
|
"gorm.io/gorm"
|
|
"kra/internal/biz/business"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestAlertWritesRecheckCurrentChannelOwnerAndRejectConflictingBindings(t *testing.T) {
|
|
exerciseAlertOwnerRecheck(t, openTestDB(t))
|
|
}
|
|
func TestMySQLAlertWritesRecheckCurrentChannelOwner(t *testing.T) {
|
|
exerciseAlertOwnerRecheck(t, openRehearsalMySQL(t))
|
|
}
|
|
func exerciseAlertOwnerRecheck(t *testing.T, db *gorm.DB) {
|
|
t.Helper()
|
|
now := prepareAlertV2(t, db)
|
|
if err := db.AutoMigrate(&accountPO{}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, sql := range []string{
|
|
"INSERT INTO sys_users(id,username,level,id_path) VALUES(7,'原商务',1,'0'),(8,'新商务',1,'0')",
|
|
"INSERT INTO sys_user_bind_platform(user_id,source_db,platform_busier_id,status) VALUES(7,'lx',7,'0')",
|
|
} {
|
|
if err := db.Exec(sql).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
ctx := context.Background()
|
|
scope := business.UserScope{SelfID: 7, IncludeSelf: true, DescendantPath: "0,7"}
|
|
hit := &business.AlertRecord{OwnerScope: &scope, PlatformCode: "lx", TargetPromoteID: 1, BusinessID: 7, RuleID: 1, RuleType: "充值", Status: 1, AlertContent: "换绑前", CreatedAt: now, UpdatedAt: now}
|
|
trigger := NewAlertTriggerRepo(testData{db})
|
|
write := func(want bool) {
|
|
t.Helper()
|
|
got, err := trigger.StoreHit(ctx, hit, []int{1, 2, 3, 4}, func(*business.AlertRecord) bool { return true })
|
|
if err != nil || got != want {
|
|
t.Fatalf("written=%v want=%v err=%v", got, want, err)
|
|
}
|
|
}
|
|
write(true)
|
|
oldExemption := &business.AlertExemption{ChannelKey: business.ChannelKey{SourceDB: "lx", ID: 1}, OwnerID: 7, AddedBy: 7, AddedName: "原商务", Reason: "原商务的豁免", AddedAt: now}
|
|
if err := NewAlertGovernanceRepo(testData{db}).AddExemption(ctx, scope, oldExemption.ChannelKey, func(*business.AlertExemptionTarget) (*business.AlertExemption, error) { return oldExemption, nil }); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := db.Exec("UPDATE sys_user_bind_platform SET user_id=8 WHERE source_db='lx'").Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
hit.AlertContent = "换绑后的私有数据"
|
|
write(false)
|
|
var old alertRecordPO
|
|
if err := db.First(&old).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if old.AlertContent != "换绑前" {
|
|
t.Fatal("旧商务预警被新归属数据刷新")
|
|
}
|
|
newHit := *hit
|
|
newScope := business.UserScope{SelfID: 8, IncludeSelf: true, DescendantPath: "0,8"}
|
|
newHit.OwnerScope = &newScope
|
|
newHit.BusinessID = 8
|
|
newHit.RuleID = 2
|
|
if ok, err := trigger.StoreHit(ctx, &newHit, []int{1, 2, 3, 4}, func(*business.AlertRecord) bool { return true }); err != nil || !ok {
|
|
t.Fatalf("新商务应产生独立预警: %v %v", ok, err)
|
|
}
|
|
var histories []alertRecordPO
|
|
if err := db.Order("id").Find(&histories).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(histories) != 2 || histories[0].BusinessID != 7 || histories[0].AlertContent != "换绑前" || histories[1].BusinessID != 8 {
|
|
t.Fatalf("旧商务预警不应被转移给新商务: %+v", histories)
|
|
}
|
|
governance := NewAlertGovernanceRepo(testData{db})
|
|
called := false
|
|
build := func(*business.AlertExemptionTarget) (*business.AlertExemption, error) {
|
|
called = true
|
|
return nil, business.ErrAlertRecordInput
|
|
}
|
|
if err := governance.AddExemption(ctx, scope, business.ChannelKey{SourceDB: "lx", ID: 1}, build); err != business.ErrAlertRecordScope || called {
|
|
t.Fatalf("换绑后仍允许免预警: %v called=%v", err, called)
|
|
}
|
|
if err := db.Exec("INSERT INTO sys_user_bind_platform(user_id,source_db,platform_busier_id,status) VALUES(7,'lx',7,'0')").Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := governance.AddExemption(ctx, scope, business.ChannelKey{SourceDB: "lx", ID: 1}, build); err != business.ErrAlertRecordScope || called {
|
|
t.Fatal("不能忽略范围外的冲突绑定")
|
|
}
|
|
}
|
|
|
|
func TestAlertLossMissingChannelRemainsUnknown(t *testing.T) {
|
|
db := openTestDB(t)
|
|
now := prepareAlertV2(t, db)
|
|
if err := db.Create(&alertRecordPO{ID: 1, PlatformCode: "lx", TargetPromoteID: 999, Status: 1, CreatedAt: now}).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
scope := business.AlertRecordScope{Owner: business.LevelOneScope{All: true}, Viewer: business.UserScope{All: true}}
|
|
r := NewAlertRecordRepo(testData{db})
|
|
page, err := r.List(context.Background(), scope, business.AlertRecordFilter{})
|
|
if err != nil || page.Total != 1 || page.Rows[0].Lost != nil {
|
|
t.Fatalf("缺失渠道不应被展示为未流失: %+v %v", page, err)
|
|
}
|
|
lost := false
|
|
page, err = r.List(context.Background(), scope, business.AlertRecordFilter{Lost: &lost})
|
|
if err != nil || page.Total != 0 {
|
|
t.Fatalf("未流失筛选应排除未知渠道: %+v %v", page, err)
|
|
}
|
|
}
|
|
|
|
func TestAlertComparisonIgnoresInvalidHistoricalTimestamps(t *testing.T) {
|
|
db := openTestDB(t)
|
|
now := prepareAlertV2(t, db)
|
|
if err := db.Exec("INSERT INTO tab_user VALUES(99,'lx',1,0,'','unknown')").Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
key := business.ChannelKey{SourceDB: "lx", ID: 1}
|
|
values, err := NewAlertTriggerRepo(testData{db}).Comparison(context.Background(), 1, []business.ChannelKey{key}, now, 1)
|
|
if err != nil || values[key].FirstUnix != now.Add(-48*time.Hour).Unix() {
|
|
t.Fatalf("无效时间不应阻止正常渠道触发: %+v %v", values, err)
|
|
}
|
|
}
|