package warningnotify import ( "context" "testing" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/do" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/frame/g" ) type batchRecordingSender struct{ batches []Batch } func (sender *batchRecordingSender) Send(ctx context.Context, batch Batch) error { sender.batches = append(sender.batches, batch) return nil } func TestCollectorSkipsWechatEvenForEligibleEnterpriseCreators(t *testing.T) { ctx := context.Background() previous := gdb.GetConfig("default") if err := gdb.SetConfigGroup("default", gdb.ConfigGroup{{Type: "sqlite", Link: "sqlite::@file(:memory:)", MaxOpenConnCount: 1}}); err != nil { t.Fatal(err) } db := g.DB() t.Cleanup(func() { _ = db.GetCore().ClearCacheAll(ctx) _ = db.Close(ctx) _ = gdb.SetConfigGroup("default", previous) }) for _, statement := range []string{ "CREATE TABLE sys_dept (dept_id INTEGER PRIMARY KEY, tenant_id TEXT, ancestors TEXT, deleted_at DATETIME)", "CREATE TABLE sys_user (user_id INTEGER PRIMARY KEY, tenant_id TEXT, user_type TEXT, dept_id INTEGER, status TEXT, deleted_at DATETIME)", "CREATE TABLE t_sim_card_info (id INTEGER PRIMARY KEY, tenant_id TEXT, dept_id INTEGER)", "CREATE TABLE t_sim_terminal (terminal_id INTEGER, tenant_id TEXT, iccid TEXT, msisdn TEXT)", "CREATE TABLE t_terminal (terminal_id INTEGER, tenant_id TEXT, leader INTEGER, deleted_at DATETIME)", } { if _, err := db.Exec(ctx, statement); err != nil { t.Fatal(err) } } for _, dept := range []do.SysDept{ {DeptId: 175, TenantId: "tenant", Ancestors: "0,100,"}, {DeptId: 176, TenantId: "tenant", Ancestors: "0,100,"}, {DeptId: 185, TenantId: "tenant", Ancestors: "0,100,175,"}, {DeptId: 195, TenantId: "tenant", Ancestors: "0,100,175,185"}, {DeptId: 100, TenantId: "tenant", Ancestors: "0"}, } { if _, err := db.Model("sys_dept").Data(dept).Insert(); err != nil { t.Fatal(err) } } for _, user := range []do.SysUser{ {UserId: 133, TenantId: "tenant", UserType: "sys_user", DeptId: 175, Status: "0"}, {UserId: 134, TenantId: "tenant", UserType: "sys_user", DeptId: 175, Status: "0"}, {UserId: 135, TenantId: "other", UserType: "sys_user", DeptId: 175, Status: "0"}, {UserId: 136, TenantId: "tenant", UserType: "sys_user", DeptId: 175, Status: "1"}, {UserId: 137, TenantId: "tenant", UserType: "sys_user", DeptId: 175, Status: "0"}, } { if _, err := db.Model("sys_user").Data(user).Insert(); err != nil { t.Fatal(err) } } if _, err := db.Model("sys_user").Where("user_id", 137).Delete(); err != nil { t.Fatal(err) } for _, card := range []do.TSimCardInfo{ {Id: 84189, TenantId: "tenant", DeptId: 175}, {Id: 84190, TenantId: "tenant", DeptId: 176}, {Id: 84191, TenantId: "other", DeptId: 175}, {Id: 84199, TenantId: "tenant", DeptId: 185}, {Id: 84200, TenantId: "tenant", DeptId: 195}, {Id: 84201, TenantId: "tenant", DeptId: 100}, {Id: 84202, TenantId: "tenant", DeptId: 999}, } { if _, err := db.Model("t_sim_card_info").Data(card).Insert(); err != nil { t.Fatal(err) } } base := Event{Business: BusinessSimWarning, TenantID: "tenant", DeptID: 175, CreatedBy: 133, ItemType: 1, ItemID: 84189, ItemCode: "89860401791508277319", WarnMethods: MethodPlatform, WarnStage: 2} for _, test := range []struct { name string creator int64 card int64 expected int }{ {"enterprise creator", 133, 84189, 1}, {"another creator in same department", 134, 84189, 1}, {"sibling organization", 133, 84190, 0}, {"direct descendant card", 133, 84199, 1}, {"deep descendant card", 133, 84200, 1}, {"ancestor organization", 133, 84201, 0}, {"missing card organization", 133, 84202, 0}, {"different card tenant", 133, 84191, 0}, {"different user tenant", 135, 84189, 0}, {"disabled creator", 136, 84189, 0}, {"deleted creator", 137, 84189, 0}, {"missing creator", 999, 84189, 0}, } { t.Run(test.name, func(t *testing.T) { event := base event.CreatedBy = test.creator event.ItemID = test.card collector := NewCollector() for page := 0; page < 2; page++ { event.EventID = int64(page + 1) if err := collector.Add(ctx, []Event{event}); err != nil { t.Fatal(err) } } sender := &batchRecordingSender{} restore := SetSender(sender) defer restore() if err := collector.Flush(ctx); err != nil { t.Fatal(err) } platformCount := 0 for _, batch := range sender.batches { if batch.Method == MethodWechat { t.Fatal("wechat subscription batch must not be sent") } if batch.Method == MethodPlatform { platformCount++ } } if test.expected > 0 && platformCount == 0 { t.Fatal("eligible creator lost in-app notification") } legacy := Batch{Method: MethodWechat, Business: BusinessSimWarning, TenantID: "tenant", Items: []Event{event}} eligible := 0 for _, delivery := range resolveWechatDeliveries(ctx, legacy) { if delivery.Group.SendUserType == sendUserTypeAgent && len(delivery.Group.UserIDs) == 1 && delivery.Group.UserIDs[0] == test.creator { eligible++ } } if eligible != test.expected { t.Fatalf("legacy eligibility = %d, want %d", eligible, test.expected) } }) } } func TestWechatPreparedDeliveryDoesNotResolveAgain(t *testing.T) { batch := Batch{Business: BusinessSimWarning, Method: MethodWechat, prepared: &platformRecipientGroup{SendUserType: sendUserTypeAgent, UserIDs: []int64{133}}, Items: []Event{{CreatedBy: 133, DeptID: 175, ItemType: 1, ItemID: 84189}}} deliveries := resolveWechatDeliveries(context.Background(), batch) if len(deliveries) != 1 || len(deliveries[0].Group.UserIDs) != 1 || deliveries[0].Group.UserIDs[0] != 133 { t.Fatalf("unexpected prepared deliveries: %+v", deliveries) } }