88 lines
3.3 KiB
Go
88 lines
3.3 KiB
Go
package api
|
||
|
||
import (
|
||
"net/http"
|
||
"net/http/httptest"
|
||
"testing"
|
||
"time"
|
||
)
|
||
|
||
func newWaitSession(phone string) *WaitCallSession {
|
||
s := &WaitCallSession{ID: "sess-" + phone, Phone: phone, ExpiresAt: time.Now().Add(time.Minute)}
|
||
wcm.set(s)
|
||
return s
|
||
}
|
||
|
||
// Обратный вызов SMSC — публичная точка: без правильного секрета номер подтверждаться не должен.
|
||
func TestSMSCCallbackNeedsToken(t *testing.T) {
|
||
a := &API{smscCallbackToken: "s3cret-token"}
|
||
s := newWaitSession("79280000001")
|
||
|
||
for name, query := range map[string]string{
|
||
"без токена": "phone=79280000001",
|
||
"чужой токен": "phone=79280000001&token=wrong",
|
||
"пустой токен": "phone=79280000001&token=",
|
||
"токен не в query": "phone=79280000001&TOKEN=s3cret-token",
|
||
} {
|
||
rec := httptest.NewRecorder()
|
||
a.smscCallback(rec, httptest.NewRequest(http.MethodGet, "/api/v1/auth/smsc-callback?"+query, nil))
|
||
if rec.Code != http.StatusForbidden {
|
||
t.Errorf("%s: код %d, ожидали 403", name, rec.Code)
|
||
}
|
||
if s.Verified {
|
||
t.Fatalf("%s: номер подтвердился без секрета", name)
|
||
}
|
||
}
|
||
|
||
rec := httptest.NewRecorder()
|
||
a.smscCallback(rec, httptest.NewRequest(http.MethodGet, "/api/v1/auth/smsc-callback?phone=79280000001&token=s3cret-token", nil))
|
||
if rec.Code != http.StatusOK || !s.Verified {
|
||
t.Errorf("с верным токеном: код %d, подтверждён=%v", rec.Code, s.Verified)
|
||
}
|
||
}
|
||
|
||
// Если токен на сервере не задан, обратный вызов выключен полностью (в том числе с пустым token=).
|
||
func TestSMSCCallbackDisabledWithoutServerToken(t *testing.T) {
|
||
a := &API{}
|
||
s := newWaitSession("79280000002")
|
||
rec := httptest.NewRecorder()
|
||
a.smscCallback(rec, httptest.NewRequest(http.MethodGet, "/api/v1/auth/smsc-callback?phone=79280000002&token=", nil))
|
||
if rec.Code != http.StatusForbidden || s.Verified {
|
||
t.Errorf("код %d, подтверждён=%v: вызов без настроенного токена должен отклоняться", rec.Code, s.Verified)
|
||
}
|
||
}
|
||
|
||
// Одно подтверждение — одна запись: после consume повторное использование не проходит.
|
||
func TestVerificationIsOneTime(t *testing.T) {
|
||
s := newWaitSession("79280000003")
|
||
wcm.markVerified("79280000003")
|
||
if !wcm.isVerified(s.ID, "79280000003") {
|
||
t.Fatal("подтверждение не сработало")
|
||
}
|
||
wcm.consume(s.ID)
|
||
if wcm.isVerified(s.ID, "79280000003") {
|
||
t.Error("подтверждение осталось действительным после записи")
|
||
}
|
||
}
|
||
|
||
func TestLastDigits(t *testing.T) {
|
||
for in, want := range map[string]string{
|
||
"8 (928) 047-00-55": "9280470055",
|
||
"+7 928 047 00 55": "9280470055",
|
||
"89280470055": "9280470055",
|
||
"123": "123",
|
||
} {
|
||
if got := lastDigits(in, 10); got != want {
|
||
t.Errorf("lastDigits(%q)=%q, ожидали %q", in, got, want)
|
||
}
|
||
}
|
||
}
|
||
|
||
func TestMaskPhone(t *testing.T) {
|
||
for in, want := range map[string]string{"79280470055": "***0055", "+7 (928) 047-00-55": "***0055", "12": "***", "": "***"} {
|
||
if got := maskPhone(in); got != want {
|
||
t.Errorf("maskPhone(%q)=%q, ожидали %q", in, got, want)
|
||
}
|
||
}
|
||
}
|