Files
cms-server/internal/kyc/passport_test.go
Asai Neko 82c412d839
All checks were successful
Server Check Build (NixCN CMS) TeamCity build finished
Add more tests for modules co worked by claude
Signed-off-by: Asai Neko <sugar@sne.moe>
2026-03-26 23:36:40 +08:00

192 lines
5.6 KiB
Go

package kyc
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// startMockPassportServer spins up an httptest.Server backed by mux, points
// viper's kyc.passport_reader_endpoint at it, and registers cleanup on t.
func startMockPassportServer(t *testing.T, mux *http.ServeMux) *httptest.Server {
t.Helper()
srv := httptest.NewServer(mux)
viper.Reset()
viper.Set("kyc.passport_reader_endpoint", srv.URL)
viper.Set("kyc.passport_reader_public_key", "pub")
viper.Set("kyc.passport_reader_secret", "sec")
t.Cleanup(func() {
srv.Close()
viper.Reset()
})
return srv
}
func writeJSON(w http.ResponseWriter, v any) {
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(v)
}
// ---- CreateSession ----
func TestCreateSessionSuccess(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/session.create", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodPost, r.Method)
writeJSON(w, PassportReaderSessionResponse{ID: 42, Token: "tok"})
})
startMockPassportServer(t, mux)
resp, err := CreateSession(context.Background())
require.NoError(t, err)
assert.Equal(t, 42, resp.ID)
assert.Equal(t, "tok", resp.Token)
}
func TestCreateSessionAPIError(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/session.create", func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "internal error", http.StatusInternalServerError)
})
startMockPassportServer(t, mux)
_, err := CreateSession(context.Background())
assert.Error(t, err)
}
// ---- GetSessionState ----
func TestGetSessionStateSuccess(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/session.state", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodPost, r.Method)
assert.Equal(t, "application/json", r.Header.Get("Content-Type"))
var req PassportReaderGetSessionRequest
require.NoError(t, json.NewDecoder(r.Body).Decode(&req))
assert.Equal(t, 42, req.ID)
writeJSON(w, PassportReaderStateResponse{State: StateApproved})
})
startMockPassportServer(t, mux)
state, err := GetSessionState(context.Background(), 42)
require.NoError(t, err)
assert.Equal(t, StateApproved, state)
}
func TestGetSessionStateEachKnownState(t *testing.T) {
knownStates := []string{
StateCreated, StateInitiated, StateCompleted,
StateApproved, StateFailed, StateAborted, StateRejected,
}
for _, s := range knownStates {
s := s
t.Run(s, func(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/session.state", func(w http.ResponseWriter, r *http.Request) {
writeJSON(w, PassportReaderStateResponse{State: s})
})
startMockPassportServer(t, mux)
got, err := GetSessionState(context.Background(), 1)
require.NoError(t, err)
assert.Equal(t, s, got)
})
}
}
func TestGetSessionStateAPIError(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/session.state", func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "bad", http.StatusBadRequest)
})
startMockPassportServer(t, mux)
_, err := GetSessionState(context.Background(), 1)
assert.Error(t, err)
}
// ---- GetSessionDetails ----
func TestGetSessionDetailsSuccess(t *testing.T) {
want := &PassportReaderSessionDetailResponse{
State: StateApproved,
GivenNames: "John",
Surname: "Doe",
Nationality: "USA",
DateOfBirth: "1990-01-01",
DocumentType: "PASSPORT",
DocumentNumber: "X12345678",
ExpiryDate: "2030-01-01",
}
mux := http.NewServeMux()
mux.HandleFunc("/session.get", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, http.MethodPost, r.Method)
assert.Equal(t, "application/json", r.Header.Get("Content-Type"))
var req PassportReaderGetSessionRequest
require.NoError(t, json.NewDecoder(r.Body).Decode(&req))
assert.Equal(t, 7, req.ID)
writeJSON(w, want)
})
startMockPassportServer(t, mux)
got, err := GetSessionDetails(context.Background(), 7)
require.NoError(t, err)
assert.Equal(t, want, got)
}
func TestGetSessionDetailsAPIError(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/session.get", func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "not found", http.StatusNotFound)
})
startMockPassportServer(t, mux)
_, err := GetSessionDetails(context.Background(), 1)
assert.Error(t, err)
}
// ---- HTTP mechanics ----
func TestPassportRequestSendsBasicAuth(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/session.create", func(w http.ResponseWriter, r *http.Request) {
user, pass, ok := r.BasicAuth()
assert.True(t, ok, "Authorization header must be present")
assert.Equal(t, "pub", user)
assert.Equal(t, "sec", pass)
writeJSON(w, PassportReaderSessionResponse{})
})
startMockPassportServer(t, mux)
_, _ = CreateSession(context.Background())
}
func TestPassportRequestSetsContentTypeForBody(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/session.state", func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "application/json", r.Header.Get("Content-Type"))
writeJSON(w, PassportReaderStateResponse{State: StateCreated})
})
startMockPassportServer(t, mux)
_, _ = GetSessionState(context.Background(), 1)
}
func TestPassportRequestNoContentTypeWithoutBody(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/session.create", func(w http.ResponseWriter, r *http.Request) {
assert.Empty(t, r.Header.Get("Content-Type"), "no Content-Type when body is nil")
writeJSON(w, PassportReaderSessionResponse{})
})
startMockPassportServer(t, mux)
_, _ = CreateSession(context.Background())
}