120 lines
5.4 KiB
Go
120 lines
5.4 KiB
Go
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")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|