Files

120 lines
5.4 KiB
Go
Raw Permalink Normal View History

package onboarding
import (
"context"
"errors"
"testing"
"github.com/google/uuid"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
sms "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms/v20210111"
)
type fakeTencentSMSSender struct {
request *sms.SendSmsRequest
result *sms.SendSmsResponse
err error
calls int
}
func (f *fakeTencentSMSSender) SendSmsWithContext(_ context.Context, request *sms.SendSmsRequest) (*sms.SendSmsResponse, error) {
f.calls++
f.request = request
return f.result, f.err
}
func TestTencentSMSProviderUsesApprovedTemplateAndChecksPerPhoneStatus(t *testing.T) {
provider, err := NewTencentSMSProvider("secret-id", "secret-key", "1400006666", "安芯伴", "123456")
if err != nil {
t.Fatal(err)
}
p := provider.(*TencentSMSProvider)
fake := &fakeTencentSMSSender{result: &sms.SendSmsResponse{Response: &sms.SendSmsResponseParams{SendStatusSet: []*sms.SendStatus{{Code: common.StringPtr("Ok")}}}}}
p.client = fake
id := uuid.NewString()
if err = p.Send(context.Background(), "+8613800000000", "123456", id); err != nil {
t.Fatal(err)
}
r := fake.request
if fake.calls != 1 || *r.SmsSdkAppId != "1400006666" || *r.SignName != "安芯伴" || *r.TemplateId != "123456" ||
len(r.PhoneNumberSet) != 1 || *r.PhoneNumberSet[0] != "+8613800000000" ||
len(r.TemplateParamSet) != 1 || *r.TemplateParamSet[0] != "123456" || *r.SessionContext != id {
t.Fatal("Tencent SMS request does not match approved OTP template")
}
fake.result.Response.SendStatusSet[0].Code = common.StringPtr("FailedOperation")
if err = p.Send(context.Background(), "+8613800000000", "123456", uuid.NewString()); err == nil {
t.Fatal("provider accepted a failed per-phone send status")
}
fake.err = errors.New("transport timeout")
if err = p.Send(context.Background(), "+8613800000000", "123456", uuid.NewString()); err == nil {
t.Fatal("provider accepted an uncertain send")
}
before := fake.calls
if err = p.Send(context.Background(), "+15551234567", "123456", uuid.NewString()); err == nil || fake.calls != before {
t.Fatal("domestic template sent to an international phone")
}
}
func TestTencentSMSProviderRejectsMissingConfiguration(t *testing.T) {
for _, config := range [][5]string{
{"", "key", "1400006666", "安芯伴", "123456"},
{"id", "", "1400006666", "安芯伴", "123456"},
{"id", "key", "not-numeric", "安芯伴", "123456"},
{"id", "key", "1400006666", "", "123456"},
{"id", "key", "1400006666", "安芯伴", ""},
} {
if _, err := NewTencentSMSProvider(config[0], config[1], config[2], config[3], config[4]); err == nil {
t.Fatal("invalid Tencent SMS configuration accepted")
}
}
}
func TestTencentSMSRoutesEachPurposeToItsOwnTemplate(t *testing.T) {
templates := map[string]string{"login": "101", "register": "102", "change_password": "103", "change_phone": "104"}
provider, err := NewTencentSMSProviderWithTemplates("id", "key", "1400006666", "安芯伴", templates)
if err != nil {
t.Fatal(err)
}
p := provider.(*TencentSMSProvider)
fake := &fakeTencentSMSSender{result: &sms.SendSmsResponse{Response: &sms.SendSmsResponseParams{SendStatusSet: []*sms.SendStatus{{Code: common.StringPtr("Ok")}}}}}
p.client = fake
for purpose, want := range map[string]string{SMSPurposeLogin: "101", SMSPurposeRegister: "102", SMSPurposeChangePassword: "103", SMSPurposeChangePhone: "104"} {
if err := p.SendForPurpose(context.Background(), "+8613800000000", "123456", uuid.NewString(), purpose); err != nil || *fake.request.TemplateId != want {
t.Fatalf("purpose %s did not select its own template: %v", purpose, err)
}
}
if err := p.SendForPurpose(context.Background(), "+8613800000000", "123456", uuid.NewString(), "UNKNOWN"); err == nil || fake.calls != 4 {
t.Fatal("unknown purpose sent a message")
}
delete(templates, "change_phone")
if _, err := NewTencentSMSProviderWithTemplates("id", "key", "1400006666", "安芯伴", templates); err == nil {
t.Fatal("missing purpose silently fell back to another template")
}
}
func TestTencentSMSRegistrationIncludesConfiguredExpiryParameter(t *testing.T) {
templates := map[string]string{"login": "101", "register": "102", "change_password": "103", "change_phone": "104"}
provider, err := NewTencentSMSProviderWithTemplates("id", "key", "1400006666", "安芯伴", templates, map[string][]string{"register": {"code", "expires_minutes"}})
if err != nil {
t.Fatal(err)
}
p := provider.(*TencentSMSProvider)
fake := &fakeTencentSMSSender{result: &sms.SendSmsResponse{Response: &sms.SendSmsResponseParams{SendStatusSet: []*sms.SendStatus{{Code: common.StringPtr("Ok")}}}}}
p.client = fake
if err := p.SendForPurpose(context.Background(), "+8613800000000", "123456", uuid.NewString(), SMSPurposeRegister); err != nil {
t.Fatal(err)
}
params := fake.request.TemplateParamSet
if len(params) != 2 || *params[0] != "123456" || *params[1] != "5" {
t.Fatal("registration template must receive code followed by its real expiry in minutes")
}
if err := p.Send(context.Background(), "+8613800000000", "123456", uuid.NewString()); err != nil || len(fake.request.TemplateParamSet) != 1 {
t.Fatal("registration parameters leaked into login template")
}
for _, params := range [][]string{{}, {"expires_minutes"}, {"code", "unknown"}, {"code", "code"}} {
if _, err := NewTencentSMSProviderWithTemplates("id", "key", "1400006666", "安芯伴", templates, map[string][]string{"register": params}); err == nil {
t.Fatal("invalid parameters accepted")
}
}
}