test(pay): 补 fake 三态/MockChannelEnabled 装配/devmock 端点/gateway currency_mismatch/限流 bucket 回收
This commit is contained in:
@@ -221,3 +221,63 @@ func TestCreateOrderCurrencyFromChannelCapability(t *testing.T) {
|
||||
t.Fatalf("order = %s/%d want USDT/29990000", o.Currency, o.AmountMinor)
|
||||
}
|
||||
}
|
||||
|
||||
// cnyOnlyProvider 是本测试文件专用的最小 stub provider(结算币种固定 CNY),
|
||||
// 陪 fake(结算 USDT)凑出"两个结算币种不同的方法"场景,用来直测 RetryOrder 换渠道
|
||||
// 触发 gateway.ErrCurrencyMismatch 的分支(gateway.go:177 附近)。不复用
|
||||
// internal/provider/provider_test.go 的 stubProvider——那个类型未导出且在
|
||||
// package provider_test 里,gateway_test 包拿不到。
|
||||
type cnyOnlyProvider struct{}
|
||||
|
||||
func (cnyOnlyProvider) Method() string { return "cny-only" }
|
||||
|
||||
func (cnyOnlyProvider) Capabilities() provider.Capabilities {
|
||||
return provider.Capabilities{
|
||||
RenderTypes: []provider.RenderType{provider.RenderQR},
|
||||
SettleCurrencies: []string{"CNY"},
|
||||
}
|
||||
}
|
||||
|
||||
func (cnyOnlyProvider) Create(_ context.Context, req provider.CreateRequest) (*provider.Session, error) {
|
||||
return &provider.Session{ProviderRef: "CNYONLY-" + req.OutTradeNo, RenderType: provider.RenderQR, Payload: map[string]any{}}, nil
|
||||
}
|
||||
|
||||
func (cnyOnlyProvider) VerifyCallback(context.Context, provider.CallbackInput) (*provider.PaidEvent, error) {
|
||||
return nil, errors.New("cnyOnlyProvider: not implemented")
|
||||
}
|
||||
|
||||
func (cnyOnlyProvider) Query(context.Context, provider.QueryRequest) (*provider.PaidEvent, error) {
|
||||
return &provider.PaidEvent{Status: provider.PaidPending}, nil
|
||||
}
|
||||
|
||||
// TestRetryOrderCurrencyMismatch 直测 gateway.go:177 附近的触发条件:换到一个结算
|
||||
// 币种与订单不同的渠道 retry,必须报 ErrCurrencyMismatch(而不是静默换币重定价——
|
||||
// P3 范围之外,见 RetryOrder 注释)。此前只在 handler 层经 HTTP 间接测到 409。
|
||||
func TestRetryOrderCurrencyMismatch(t *testing.T) {
|
||||
db := model.OpenTestDB(t)
|
||||
orders := store.NewOrderStore(db)
|
||||
refunds := store.NewRefundStore(db)
|
||||
subs := store.NewSubscriptionStore(db)
|
||||
chargebacks := store.NewChargebackStore(db)
|
||||
preg := provider.NewRegistry()
|
||||
preg.Register(fake.New()) // "fake" 结算 USDT
|
||||
preg.Register(cnyOnlyProvider{}) // "cny-only" 结算 CNY
|
||||
areg := accounts.New([]config.AccountConfig{
|
||||
{AccountID: "fake-a1", Channel: "fake", Region: "global", Enabled: true, Weight: 1},
|
||||
{AccountID: "cny-a1", Channel: "cny-only", Region: "global", Enabled: true, Weight: 1},
|
||||
})
|
||||
picker := accounts.NewRouter(areg, nil, nil)
|
||||
g := gateway.New(orders, refunds, preg, picker, stubResolver{}, &spyEnqueuer{}, "global", subs, chargebacks)
|
||||
ctx := context.Background()
|
||||
|
||||
// 用 cny-only 下单(结算 CNY),再 retry 到 fake(结算 USDT)→ 币种不符。
|
||||
res, err := g.CreateOrder(ctx, gateway.CreateOrderInput{SKU: "pro_year", Method: "cny-only"})
|
||||
if err != nil {
|
||||
t.Fatalf("create: %v", err)
|
||||
}
|
||||
|
||||
_, err = g.RetryOrder(ctx, res.OrderNo, "fake", nil)
|
||||
if !errors.Is(err, gateway.ErrCurrencyMismatch) {
|
||||
t.Fatalf("RetryOrder 换到结算币种不同的渠道应报 ErrCurrencyMismatch, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user