fix: 优化邮件测试发信通道为单次即时发送直出真实报错

This commit is contained in:
xuans 2026-10-18 19:35:15 +08:00
parent ac19bbe12d
commit 5efa9a08ab
2 changed files with 50 additions and 7 deletions

View File

@ -309,7 +309,7 @@ func TestSmailSystemSenderUsesSameEnvelopeAndHeader(t *testing.T) {
t.Fatal("邮件头没有使用固定系统通知身份,或泄漏旧管理员发件地址")
}
if security && strings.Contains(message, "receiver@example.com") {
t.Fatal("验证码不得发送给普通通知收件人")
t.Fatal("撉諹<EFBFBD><EFBFBD><EFBFBD><EFBFBD>敺堒<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>桅<EFBFBD>𡁻<EFBFBD>𡁶䰻<EFBFBD>嗡辣鈭?)
}
})
}
@ -340,7 +340,7 @@ func TestSmailSystemNotificationUsesSMTPOnly(t *testing.T) {
server.mu.Lock()
defer server.mu.Unlock()
if len(server.messages) != 1 {
t.Fatalf("SMTP 系统通知数量错误:%d", len(server.messages))
t.Fatalf("SMTP 蝟餌<EFBFBD><EFBFBD>𡁶䰻<EFBFBD>圈<EFBFBD><EFBFBD>躰秤嚗?d", len(server.messages))
}
}
@ -449,7 +449,38 @@ func TestBuildSMTPMessageIncludesStyledHTMLAlternative(t *testing.T) {
"<p style=\"color:red\">HTML 通知</p>",
} {
if !strings.Contains(message, value) {
t.Fatalf("SMTP multipart 邮件缺少 %q:%s", value, message)
t.Fatalf("SMTP multipart <EFBFBD>桐辣蝻箏<EFBFBD> %q嚗?s", value, message)
}
}
}
func TestSendTestMailImmediateFailureOnAuthError(t *testing.T) {
server := newSMTPTestServer(t, false, true)
server.rejectAuth = true
host, port := server.address()
cfg := smtpTestConfig(host, port, "starttls")
cfg.RetryCount = 3
cfg.RetryIntervalsSecs = []int{30, 120, 600}
service := New(cfg, credentialReaderStub{values: map[string]string{
"username": "user",
"password": "wrong-password",
}})
service.smtpTLSConfig = server.clientTLSConfig
start := time.Now()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
err := service.SendTestMail(ctx, "target@example.com")
elapsed := time.Since(start)
if err == nil {
t.Fatalf("expected error on rejected auth, got nil")
}
if !strings.Contains(err.Error(), "霈方<E99C88>憭梯揖") && !strings.Contains(err.Error(), "Authentication credentials invalid") {
t.Fatalf("expected auth failure error, got: %v", err)
}
if elapsed > 2*time.Second {
t.Fatalf("SendTestMail took %v, expected immediate return without retry backoff sleep", elapsed)
}
}

View File

@ -1,4 +1,4 @@
package notification
package notification
import (
"context"
@ -9,6 +9,18 @@ import (
"time"
)
// sendSMTPDirect 单次直接发送测试邮件,避免在交互测试时进入多轮重试退避导致超时掩盖真实错误
func (s *Service) sendSMTPDirect(ctx context.Context, payload mailPayload) error {
if strings.TrimSpace(s.config.SMTPHost) == "" {
return errors.New("SMTP 主机不能为空")
}
credentials, err := s.loadSMTPCredentials(ctx)
if err != nil {
return err
}
return s.sendSMTPOnce(ctx, payload, credentials)
}
// SendTestMail 发送测试邮件,验证发信通道配置与网络连通性。
func (s *Service) SendTestMail(ctx context.Context, targetRecipient string) error {
if s == nil || (!s.config.HTTPEnabled && !s.config.SMTPEnabled) {
@ -76,7 +88,7 @@ func (s *Service) SendTestMail(ctx context.Context, targetRecipient string) erro
if !s.config.SMTPEnabled {
return errors.New("Smail 系统通知账号必须启用 SMTP 通道")
}
if err := s.sendSMTPWithRetry(ctx, payload); err != nil {
if err := s.sendSMTPDirect(ctx, payload); err != nil {
return fmt.Errorf("SMTP 测试邮件发送失败:%w", err)
}
return nil
@ -87,10 +99,10 @@ func (s *Service) SendTestMail(ctx context.Context, targetRecipient string) erro
}
}
if s.config.SMTPEnabled {
if err := s.sendSMTPWithRetry(ctx, payload); err != nil {
if err := s.sendSMTPDirect(ctx, payload); err != nil {
return fmt.Errorf("SMTP 测试邮件发送失败:%w", err)
}
return nil
}
return errors.New("测试邮件发送失败,请检查通道设置及网络连通性")
}
}