114 lines
4.0 KiB
Go
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 ©, 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 = ©
|
|
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("阈值上限未校验")
|
|
}
|
|
}
|