feat(v2): 多币种 product(ProductPrice 分币价目 + v1 元回退)+ 结算币种由渠道能力驱动
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
This commit is contained in:
@@ -3,31 +3,54 @@ package gateway_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
|
||||
"github.com/wangjia/pay/internal/gateway"
|
||||
"github.com/wangjia/pay/internal/model"
|
||||
)
|
||||
|
||||
func TestDBProductResolver(t *testing.T) {
|
||||
db, err := gorm.Open(sqlite.Open("file:prodtest?mode=memory&cache=shared"),
|
||||
&gorm.Config{Logger: logger.Default.LogMode(logger.Silent), TranslateError: true})
|
||||
if err != nil {
|
||||
t.Fatalf("open: %v", err)
|
||||
}
|
||||
if err := db.AutoMigrate(&model.Product{}); err != nil {
|
||||
t.Fatalf("migrate: %v", err)
|
||||
}
|
||||
db := model.OpenTestDB(t)
|
||||
db.Create(&model.Product{Name: "标准年付", Price: "299.00", BizCode: "annual_standard", Active: true})
|
||||
|
||||
r := gateway.NewDBProductResolver(db, "CNY")
|
||||
minor, cur, subject, bizCode, err := r.Resolve("annual_standard")
|
||||
if err != nil || minor != 29900 || cur != "CNY" || subject != "标准年付" || bizCode != "annual_standard" {
|
||||
t.Fatalf("resolve = %d %s %s %s %v", minor, cur, subject, bizCode, err)
|
||||
r := gateway.NewDBProductResolver(db)
|
||||
minor, subject, bizCode, err := r.Resolve("annual_standard", "CNY")
|
||||
if err != nil || minor != 29900 || subject != "标准年付" || bizCode != "annual_standard" {
|
||||
t.Fatalf("resolve = %d %s %s %v", minor, subject, bizCode, err)
|
||||
}
|
||||
if _, _, _, _, err := r.Resolve("ghost"); err != gateway.ErrProductNotFound {
|
||||
if _, _, _, err := r.Resolve("ghost", "CNY"); err != gateway.ErrProductNotFound {
|
||||
t.Fatalf("缺套餐应 ErrProductNotFound, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDBProductResolverMultiCurrency(t *testing.T) {
|
||||
db := model.OpenTestDB(t)
|
||||
// 一个套餐:CNY 走 v1 Price 元 string 回退;USD/USDT 走 ProductPrice。
|
||||
p := model.Product{Name: "Pro 年付", Price: "199.00", BizCode: "pro_year", Active: true, MerchantID: 1}
|
||||
if err := db.Create(&p).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rows := []model.ProductPrice{
|
||||
{ProductID: p.ID, Currency: "USD", AmountMinor: 2999},
|
||||
{ProductID: p.ID, Currency: "USDT", AmountMinor: 29990000},
|
||||
}
|
||||
if err := db.Create(&rows).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r := gateway.NewDBProductResolver(db)
|
||||
|
||||
// CNY 回退 Product.Price("199.00" 元 → 19900 分)
|
||||
if amt, _, code, err := r.Resolve("pro_year", "CNY"); err != nil || amt != 19900 || code != "pro_year" {
|
||||
t.Fatalf("CNY resolve = %d,%q,%v want 19900,pro_year,nil", amt, code, err)
|
||||
}
|
||||
// USD 走 ProductPrice
|
||||
if amt, _, _, err := r.Resolve("pro_year", "USD"); err != nil || amt != 2999 {
|
||||
t.Fatalf("USD resolve = %d,%v want 2999", amt, err)
|
||||
}
|
||||
// USDT 走 ProductPrice
|
||||
if amt, _, _, err := r.Resolve("pro_year", "USDT"); err != nil || amt != 29990000 {
|
||||
t.Fatalf("USDT resolve = %d,%v want 29990000", amt, err)
|
||||
}
|
||||
// 不支持的币种 → ErrProductNotFound
|
||||
if _, _, _, err := r.Resolve("pro_year", "JPY"); err != gateway.ErrProductNotFound {
|
||||
t.Fatalf("JPY resolve err = %v want ErrProductNotFound", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user