105 lines
3.0 KiB
Go
105 lines
3.0 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
smsprovider "hfb_sys/backend/internal/integrations/sms"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type recordProvider struct {
|
|
sentPhones []string
|
|
}
|
|
|
|
func (p *recordProvider) SendLoginCode(ctx context.Context, phone string, code string) error {
|
|
p.sentPhones = append(p.sentPhones, phone)
|
|
return nil
|
|
}
|
|
|
|
func (p *recordProvider) SendTemplate(ctx context.Context, req smsprovider.TemplateRequest) error {
|
|
p.sentPhones = append(p.sentPhones, req.Phone)
|
|
return nil
|
|
}
|
|
|
|
type mockResolver struct {
|
|
customProvider smsprovider.Provider
|
|
calledSites []string
|
|
}
|
|
|
|
func (m *mockResolver) ResolveSMSProvider(ctx context.Context, siteCode, domain string) (smsprovider.Provider, error) {
|
|
m.calledSites = append(m.calledSites, siteCode)
|
|
if siteCode == "site_custom" {
|
|
return m.customProvider, nil
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
func TestSendSMSCode_SiteResolutionAndFallback(t *testing.T) {
|
|
rdb := redis.NewClient(&redis.Options{
|
|
Addr: "127.0.0.1:16379",
|
|
DB: 14,
|
|
})
|
|
ctx := t.Context()
|
|
if err := rdb.Ping(ctx).Err(); err != nil {
|
|
t.Skipf("跳过测试:未检测到测试 Redis: %v", err)
|
|
}
|
|
t.Cleanup(func() {
|
|
_ = rdb.FlushDB(context.Background()).Err()
|
|
_ = rdb.Close()
|
|
})
|
|
_ = rdb.FlushDB(ctx)
|
|
|
|
defaultProv := &recordProvider{}
|
|
customProv := &recordProvider{}
|
|
resolver := &mockResolver{customProvider: customProv}
|
|
|
|
svc := NewService(nil, rdb, nil, defaultProv, zap.NewNop())
|
|
svc.SetSiteSMSResolver(resolver)
|
|
|
|
// 1. 无分站标识 -> 使用默认主站 provider
|
|
if err := rdb.Set(ctx, "captcha:auth:sms:cap1", "ABCD", time.Minute).Err(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
phone1 := "13800138001"
|
|
err := svc.SendSMSCode(ctx, phone1, "cap1", "ABCD")
|
|
if err != nil {
|
|
t.Fatalf("SendSMSCode failed: %v", err)
|
|
}
|
|
if len(defaultProv.sentPhones) != 1 || defaultProv.sentPhones[0] != phone1 {
|
|
t.Fatalf("expected default provider to send, got %v", defaultProv.sentPhones)
|
|
}
|
|
if len(customProv.sentPhones) != 0 {
|
|
t.Fatalf("custom provider should not be called without site")
|
|
}
|
|
|
|
// 2. 携带自定义短信分站标识 -> 使用 custom provider
|
|
if err := rdb.Set(ctx, "captcha:auth:sms:cap2", "EFGH", time.Minute).Err(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
phone2 := "13800138002"
|
|
err = svc.SendSMSCode(ctx, phone2, "cap2", "EFGH", "site_custom")
|
|
if err != nil {
|
|
t.Fatalf("SendSMSCode with custom site failed: %v", err)
|
|
}
|
|
if len(customProv.sentPhones) != 1 || customProv.sentPhones[0] != phone2 {
|
|
t.Fatalf("expected custom provider to send, got %v", customProv.sentPhones)
|
|
}
|
|
|
|
// 3. 携带未配置短信分站标识 -> 优雅降级到 default provider
|
|
if err := rdb.Set(ctx, "captcha:auth:sms:cap3", "JKLM", time.Minute).Err(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
phone3 := "13800138003"
|
|
err = svc.SendSMSCode(ctx, phone3, "cap3", "JKLM", "site_fallback")
|
|
if err != nil {
|
|
t.Fatalf("SendSMSCode with fallback site failed: %v", err)
|
|
}
|
|
if len(defaultProv.sentPhones) != 2 || defaultProv.sentPhones[1] != phone3 {
|
|
t.Fatalf("expected default provider to handle fallback, got %v", defaultProv.sentPhones)
|
|
}
|
|
}
|