Files
iotlcm/server/internal/logic/warningnotify/delivery_test.go
T
2026-10-29 14:36:49 +08:00

151 lines
4.7 KiB
Go

package warningnotify
import (
"context"
"errors"
"testing"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/consts"
)
type failureRecordingSender struct{ calls int }
func (sender *failureRecordingSender) Send(ctx context.Context, batch Batch) error {
sender.calls++
return errors.New("send failed")
}
func TestDispatchContinuesAfterDeliveryFailure(t *testing.T) {
sender := &failureRecordingSender{}
restore := SetSender(sender)
defer restore()
events := []Event{{TenantID: "tenant", ItemType: 1, ItemCode: "card", Category: "traffic", WarnMethods: MethodEmail, WarnEmails: "xxx@example.com", AppNotifyEnabled: true}}
expected := len(BuildBatches(events))
if expected < 2 {
t.Fatal("expected multiple channels")
}
if err := Dispatch(context.Background(), events); err == nil {
t.Fatal("failure must propagate")
}
if sender.calls != expected {
t.Fatalf("calls=%d expected=%d", sender.calls, expected)
}
}
func TestBuildBatchesOnlyCreatesPlatformAndConfiguredChannels(t *testing.T) {
batches := BuildBatches([]Event{{
Business: BusinessSimWarning,
TenantID: "tenant",
ItemCode: "card-1",
WarnMethods: MethodEmail,
WarnEmails: "xxx@example.com",
AppNotifyEnabled: false,
}})
methods := make(map[string]bool, len(batches))
for _, batch := range batches {
methods[batch.Method] = true
}
for _, method := range []string{MethodPlatform, MethodEmail} {
if !methods[method] {
t.Errorf("expected %q batch to be generated", method)
}
}
if methods[MethodWechat] {
t.Error("wechat subscription batch must not be generated")
}
}
func TestBuildBatchesIgnoresLegacyWechatFlag(t *testing.T) {
for _, enabled := range []bool{false, true} {
for _, business := range []string{BusinessSimWarning, BusinessTrafficCutoff} {
batches := BuildBatches([]Event{{
Business: business,
TenantID: "tenant",
ItemCode: "card-1",
AppNotifyEnabled: enabled,
}})
if len(batches) != 1 || batches[0].Method != MethodPlatform {
t.Errorf("business=%q enabled=%t: expected platform only, got %+v", business, enabled, batches)
}
}
}
}
func TestEnterpriseWarningRecipientEligibility(t *testing.T) {
if !enterpriseWarningRecipientEligible(consts.SysUserTypeSys, 175, 175, "") {
t.Fatal("same-organization enterprise creator should be eligible")
}
for _, test := range []struct {
name string
userType string
userDeptID int64
cardDeptID int64
}{
{name: "app user", userType: consts.SysUserTypeAPP, userDeptID: 175, cardDeptID: 175},
{name: "different organization", userType: consts.SysUserTypeSys, userDeptID: 176, cardDeptID: 175},
{name: "missing organization", userType: consts.SysUserTypeSys, userDeptID: 0, cardDeptID: 175},
} {
t.Run(test.name, func(t *testing.T) {
if enterpriseWarningRecipientEligible(test.userType, test.userDeptID, test.cardDeptID, "") {
t.Fatal("recipient should not be eligible")
}
})
}
}
func TestEnterpriseWarningAncestorScope(t *testing.T) {
for _, test := range []struct {
name string
ancestors string
expected bool
}{
{"direct descendant", "0,100,175,", true},
{"deep descendant", "0,100,175,185", true},
{"whitespace", "0, 175 ,185", true},
{"partial identifier", "0,100,1175,1750", false},
{"unrelated branch", "0,100,176", false},
{"missing path", "", false},
} {
t.Run(test.name, func(t *testing.T) {
if actual := enterpriseWarningRecipientEligible(consts.SysUserTypeSys, 175, 195, test.ancestors); actual != test.expected {
t.Fatalf("eligible = %v, want %v", actual, test.expected)
}
})
}
}
func TestWechatTokenInvalidCodes(t *testing.T) {
for _, code := range []int{40001, 40014, 42001} {
if !warningWechatTokenInvalid(code) {
t.Fatalf("code %d must refresh token", code)
}
}
for _, code := range []int{0, 43101, 47003, 40003} {
if warningWechatTokenInvalid(code) {
t.Fatalf("code %d must not refresh token", code)
}
}
}
func TestWechatDefaultTemplateMatchesMiniProgram(t *testing.T) {
const expected = "DMDP2PKktdtG1ES_3Ic1JcR0LGELQmWE6LunYyerHCY"
if actual := wechatTemplateID(nil, consts.WarningWechatTemplateIDDefault); actual != expected {
t.Fatalf("default template = %q, expected %q", actual, expected)
}
}
func TestTrafficCutoffPlatformRecipientsExcludeCreator(t *testing.T) {
got := platformAgentRecipientIDs(BusinessTrafficCutoff, []int64{130}, 1)
if len(got) != 1 || got[0] != 130 {
t.Fatalf("traffic cutoff recipients = %v, want [130] without admin creator 1", got)
}
}
func TestOtherPlatformRecipientsRetainCreator(t *testing.T) {
got := platformAgentRecipientIDs(BusinessSimWarning, []int64{130}, 1)
if len(got) != 2 || got[0] != 130 || got[1] != 1 {
t.Fatalf("regular warning recipients = %v, want [130 1]", got)
}
}