202 lines
5.6 KiB
Go
202 lines
5.6 KiB
Go
package binancerecharge
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"chatapp3-golang/internal/config"
|
|
"chatapp3-golang/internal/integration"
|
|
"chatapp3-golang/internal/model"
|
|
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func TestSaveConfigKeepsExistingSecretWhenBlank(t *testing.T) {
|
|
db := newBinanceRechargeTestDB(t)
|
|
service := NewService(config.Config{}, db, &fakeBinanceJavaGateway{})
|
|
|
|
if _, err := service.SaveConfig(context.Background(), SaveConfigRequest{
|
|
SysOrigin: "LIKEI",
|
|
APIKey: "key-1",
|
|
APISecret: "secret-1",
|
|
Enabled: true,
|
|
Rates: []RateConfigRequest{
|
|
{MinAmount: "0", MaxAmount: "100", GoldPerUSD: "80000"},
|
|
},
|
|
}); err != nil {
|
|
t.Fatalf("initial save config: %v", err)
|
|
}
|
|
|
|
resp, err := service.SaveConfig(context.Background(), SaveConfigRequest{
|
|
SysOrigin: "LIKEI",
|
|
APIKey: "key-2",
|
|
Enabled: true,
|
|
Rates: []RateConfigRequest{
|
|
{MinAmount: "0", MaxAmount: "0", GoldPerUSD: "82000"},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("update config: %v", err)
|
|
}
|
|
if resp.APIKey != "key-2" {
|
|
t.Fatalf("APIKey = %q, want key-2", resp.APIKey)
|
|
}
|
|
if !resp.APISecretConfigured {
|
|
t.Fatalf("APISecretConfigured = false, want true")
|
|
}
|
|
|
|
var row model.BinanceRechargeConfig
|
|
if err := db.Where("sys_origin = ?", "LIKEI").First(&row).Error; err != nil {
|
|
t.Fatalf("query config: %v", err)
|
|
}
|
|
if row.APISecret != "secret-1" {
|
|
t.Fatalf("APISecret = %q, want secret-1", row.APISecret)
|
|
}
|
|
}
|
|
|
|
func TestVerifyAndRechargeIsIdempotent(t *testing.T) {
|
|
db := newBinanceRechargeTestDB(t)
|
|
java := &fakeBinanceJavaGateway{
|
|
profile: integration.UserProfile{
|
|
ID: integration.Int64Value(200),
|
|
OriginSys: "LIKEI",
|
|
},
|
|
balanceExists: true,
|
|
}
|
|
service := NewService(config.Config{}, db, java)
|
|
service.SetBinanceVerifier(&fakeBinanceVerifier{})
|
|
|
|
if _, err := service.SaveConfig(context.Background(), SaveConfigRequest{
|
|
SysOrigin: "LIKEI",
|
|
APIKey: "key",
|
|
APISecret: "secret",
|
|
Enabled: true,
|
|
Rates: []RateConfigRequest{
|
|
{MinAmount: "0", MaxAmount: "100", GoldPerUSD: "80000"},
|
|
{MinAmount: "100", MaxAmount: "0", GoldPerUSD: "82000"},
|
|
},
|
|
}); err != nil {
|
|
t.Fatalf("save config: %v", err)
|
|
}
|
|
|
|
req := VerifyRechargeRequest{
|
|
TargetUserID: 200,
|
|
OrderNo: "order-1",
|
|
TransferAmount: "12.5",
|
|
TransferType: TransferTypeBinancePay,
|
|
BillNo: "bill-1",
|
|
}
|
|
resp, err := service.VerifyAndRecharge(context.Background(), AuthUser{
|
|
UserID: 100,
|
|
SysOrigin: "LIKEI",
|
|
}, req)
|
|
if err != nil {
|
|
t.Fatalf("verify recharge: %v", err)
|
|
}
|
|
if resp.Idempotent {
|
|
t.Fatalf("first response idempotent = true, want false")
|
|
}
|
|
if resp.GoldAmount != 1_000_000 {
|
|
t.Fatalf("GoldAmount = %d, want 1000000", resp.GoldAmount)
|
|
}
|
|
if java.changeCalls != 1 {
|
|
t.Fatalf("changeCalls = %d, want 1", java.changeCalls)
|
|
}
|
|
if java.lastChange.RechargeType != rechargeTypeUSDT {
|
|
t.Fatalf("RechargeType = %q, want %q", java.lastChange.RechargeType, rechargeTypeUSDT)
|
|
}
|
|
if java.lastChange.AcceptAmount != "1000000" {
|
|
t.Fatalf("AcceptAmount = %q, want 1000000", java.lastChange.AcceptAmount)
|
|
}
|
|
if java.lastChange.OrderAmount != "12.5" {
|
|
t.Fatalf("OrderAmount = %q, want 12.5", java.lastChange.OrderAmount)
|
|
}
|
|
|
|
resp, err = service.VerifyAndRecharge(context.Background(), AuthUser{
|
|
UserID: 100,
|
|
SysOrigin: "LIKEI",
|
|
}, req)
|
|
if err != nil {
|
|
t.Fatalf("verify idempotent recharge: %v", err)
|
|
}
|
|
if !resp.Idempotent {
|
|
t.Fatalf("second response idempotent = false, want true")
|
|
}
|
|
if java.changeCalls != 1 {
|
|
t.Fatalf("changeCalls after idempotent call = %d, want 1", java.changeCalls)
|
|
}
|
|
|
|
var count int64
|
|
if err := db.Model(&model.BinanceRechargeVerifyRecord{}).Where("status = ?", verifyStatusSuccess).Count(&count).Error; err != nil {
|
|
t.Fatalf("count success records: %v", err)
|
|
}
|
|
if count != 1 {
|
|
t.Fatalf("success record count = %d, want 1", count)
|
|
}
|
|
}
|
|
|
|
func newBinanceRechargeTestDB(t *testing.T) *gorm.DB {
|
|
t.Helper()
|
|
db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{})
|
|
if err != nil {
|
|
t.Fatalf("open sqlite: %v", err)
|
|
}
|
|
if err := db.AutoMigrate(
|
|
&model.BinanceRechargeConfig{},
|
|
&model.BinanceRechargeRate{},
|
|
&model.BinanceRechargeVerifyRecord{},
|
|
); err != nil {
|
|
t.Fatalf("auto migrate: %v", err)
|
|
}
|
|
return db
|
|
}
|
|
|
|
type fakeBinanceVerifier struct{}
|
|
|
|
func (f *fakeBinanceVerifier) Verify(_ context.Context, _ BinanceCredential, query BinanceVerifyQuery) (VerifiedTransaction, error) {
|
|
return VerifiedTransaction{
|
|
TransactionID: query.BillNo,
|
|
OrderType: query.TransferType,
|
|
Amount: query.Amount,
|
|
RawJSON: `{"transactionId":"` + query.BillNo + `"}`,
|
|
}, nil
|
|
}
|
|
|
|
type fakeBinanceJavaGateway struct {
|
|
profile integration.UserProfile
|
|
balanceExists bool
|
|
sellerExists bool
|
|
changeCalls int
|
|
lastChange integration.FreightBalanceChangeRequest
|
|
}
|
|
|
|
func (f *fakeBinanceJavaGateway) GetUserProfile(_ context.Context, userID int64) (integration.UserProfile, error) {
|
|
if int64(f.profile.ID) == 0 {
|
|
f.profile.ID = integration.Int64Value(userID)
|
|
}
|
|
return f.profile, nil
|
|
}
|
|
|
|
func (f *fakeBinanceJavaGateway) ExistsFreightBalance(context.Context, int64) (bool, error) {
|
|
return f.balanceExists, nil
|
|
}
|
|
|
|
func (f *fakeBinanceJavaGateway) ExistsFreightSeller(context.Context, int64) (bool, error) {
|
|
return f.sellerExists, nil
|
|
}
|
|
|
|
func (f *fakeBinanceJavaGateway) ChangeFreightBalance(_ context.Context, req integration.FreightBalanceChangeRequest) error {
|
|
f.changeCalls++
|
|
f.lastChange = req
|
|
return nil
|
|
}
|
|
|
|
func (f *fakeBinanceJavaGateway) AddFreightAgentReview(context.Context, integration.FreightAgentReviewRequest) error {
|
|
return nil
|
|
}
|
|
|
|
func (f *fakeBinanceJavaGateway) IncreaseFreightRechargeRecord(context.Context, int64, string) error {
|
|
return nil
|
|
}
|