Files
kra-new/internal/biz/business/alert_rule_test.go
T

114 lines
4.0 KiB
Go

package business
import (
"context"
"testing"
)
type alertRuleRepoFake struct {
AlertRuleRepo
rule *AlertRule
created *AlertRule
updated *AlertRule
scope LevelOneScope
}
func (r *alertRuleRepoFake) Find(context.Context, uint64) (*AlertRule, error) {
if r.rule == nil {
return nil, ErrAlertRuleNotFound
}
copy := *r.rule
return &copy, nil
}
func (r *alertRuleRepoFake) List(_ context.Context, s LevelOneScope, _ AlertRuleFilter, _ ...ListOption) ([]*AlertRule, int64, error) {
r.scope = s
return []*AlertRule{}, 0, nil
}
func (r *alertRuleRepoFake) Create(_ context.Context, rule *AlertRule) error {
copy := *rule
r.created = &copy
rule.ID = 5
return nil
}
func (r *alertRuleRepoFake) Update(_ context.Context, rule *AlertRule) error {
r.updated = rule
return nil
}
func intPointer(n int) *int { return &n }
func textPointer(s string) *string { return &s }
func alertRuleFixture() (*AlertRuleUsecase, *alertRuleRepoFake) {
a := &accountRepoFake{accounts: map[uint]*Account{1: {ID: 1, Level: 0, IDPath: "0"}, 7: {ID: 7, Level: 1, IDPath: "0"}, 8: {ID: 8, Level: 2, IDPath: "0,7"}, 9: {ID: 9, Level: 3, IDPath: "0,7,8"}, 10: {ID: 10, Level: 2, IDPath: "broken"}}}
r := &alertRuleRepoFake{}
return NewAlertRuleUsecase(r, NewAccountUsecase(a)), r
}
func validAlertRule() *AlertRule {
return &AlertRule{Name: "注册异常", Type: " 自定义标签 ", Metric: 1, StatPeriodDays: intPointer(7), MomDirection: intPointer(2), MomThreshold: textPointer("20.50"), WarningColor: "#f56c6c"}
}
func TestAlertRuleReadScopeUsesLevelOneAncestor(t *testing.T) {
uc, r := alertRuleFixture()
for _, id := range []uint{7, 8, 9} {
if _, _, err := uc.List(accountContext(id, 901), AlertRuleFilter{}); err != nil || r.scope.UserID != 7 || r.scope.All || r.scope.Empty {
t.Fatalf("所属一级范围错误: %+v %v", r.scope, err)
}
}
uc.List(accountContext(10, 901), AlertRuleFilter{})
if !r.scope.Empty {
t.Fatal("损坏祖先链不应放行规则")
}
uc.List(accountContext(1, 888), AlertRuleFilter{})
if !r.scope.All {
t.Fatal("超管读取应不限创建人")
}
}
func TestAlertRuleOwnershipDefaultsAndInactiveFields(t *testing.T) {
uc, r := alertRuleFixture()
input := validAlertRule()
input.CreatorID = 99
input.MonitorScope = 99
input.Enabled = 0
if _, err := uc.Save(accountContext(7, 901), input); err != nil {
t.Fatal(err)
}
if r.created.CreatorID != 7 || r.created.MonitorScope != 1 || r.created.Enabled != 1 || r.created.Type != "自定义标签" {
t.Fatalf("服务器归属或默认值错误: %+v", r.created)
}
if _, err := uc.Save(accountContext(8, 902), validAlertRule()); err != ErrAlertRuleLevel {
t.Fatal("二级不能创建规则")
}
r.rule = &AlertRule{ID: 5, CreatorID: 99}
input.ID = 5
if _, err := uc.Save(accountContext(7, 901), input); err != ErrAlertRuleScope {
t.Fatal("不能编辑其他一级商务的规则")
}
r.rule = &AlertRule{ID: 5, CreatorID: 7, StatPeriodDays: intPointer(7), MomThreshold: textPointer("20.50"), MomDirection: intPointer(2)}
if _, err := uc.Save(accountContext(7, 901), &AlertRule{ID: 5, Name: "登录", Type: "登录异常", Metric: 3, UnloginDays: intPointer(10), WarningColor: "red"}); err != nil {
t.Fatal(err)
}
if r.updated.StatPeriodDays == nil || *r.updated.StatPeriodDays != 7 || r.updated.MomThreshold == nil {
t.Fatal("切换指标丢失了未传入的历史配置")
}
}
func TestAlertRuleValidationAndLegacyDescription(t *testing.T) {
r := validAlertRule()
if err := validateAlertRule(r); err != nil {
t.Fatal(err)
}
if r.Description() != "渠道近 7 天注册量较上一同期环比下降 20.50% 时触发" {
t.Fatal(r.Description())
}
r.MomDirection = intPointer(99)
if err := validateAlertRule(r); err != ErrAlertRuleDirection {
t.Fatal("无效方向被接受")
}
r = validAlertRule()
r.MomThreshold = textPointer("9999")
if err := validateAlertRule(r); err != nil {
t.Fatal("原页面上限应可保存")
}
r.MomThreshold = textPointer("10000")
if err := validateAlertRule(r); err != ErrAlertRuleThreshold {
t.Fatal("阈值上限未校验")
}
}