Files
qitongxue-api/internal/logic/order_pay_owner_test.go
2026-09-29 10:57:01 +08:00

77 lines
2.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package logic
import (
"context"
"net/http"
"testing"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gcfg"
"tool-api/internal/consts"
)
// ============================================================================
// 订单越权回归(真库 IT,IT_DB 门控)
//
// 两步式(N1)下,订单归属校验必须发生在「详情」与「支付」两条链路:
// 访问**他人**订单的 out_trade_no → 一律 4015(订单不存在 / 不属于当前用户)。
// 运行:$env:IT_DB=1; go test ./internal/logic/ -run TestOrderOwnership4015 -count=1 -v
// ============================================================================
// ctxWithUser 构造带登录用户 id 的最小请求上下文(CtxUserId 依赖 g.RequestFromCtx)。
func ctxWithUser(userId int64) context.Context {
req := &ghttp.Request{Request: &http.Request{}}
req.SetCtxVar(consts.CtxUserId, userId)
return req.Context()
}
// ensureXPayConfig 注入最小可用的 wx.pay 配置,使 buildPayParams 越过「未配置」闸门,
// 从而真正走到「支付人 = 登录人」的越权校验(本用例的目的:验证 4015,而非支付配置)。
func ensureXPayConfig(t *testing.T) {
t.Helper()
if xpayConfig(context.Background()).Configured() {
return
}
adapter, err := gcfg.NewAdapterFile()
if err != nil {
t.Fatalf("创建配置适配器失败: %v", err)
}
adapter.SetContent(
"wx:\n appId: \"probe\"\n appSecret: \"probe\"\n pay:\n offerId: \"probe\"\n appKey: \"probe\"\n env: 0\n",
)
g.Cfg().SetAdapter(adapter)
if !xpayConfig(context.Background()).Configured() {
t.Fatalf("wx.pay 配置注入后仍未生效")
}
}
// TestOrderOwnership4015 越权访问他人订单:详情 / 支付均须 4015。
func TestOrderOwnership4015(t *testing.T) {
ctx := requireOrderIT(t)
p := setupOrderProbe(ctx, t)
defer p.cleanup(ctx)
res := createMemberOrder(ctx, t, p) // 属于 p.userId 的待支付单
other := ctxWithUser(p.userId + 1)
if _, err := MemberOrderDetail(other, res.OutTradeNo); err == nil {
t.Fatalf("/member/order/detail 他人订单应 4015,实得 nil")
} else if codeOf(err) != consts.CodeOrderInvalid {
t.Fatalf("/member/order/detail 他人订单应 4015,实得 code=%d err=%v", codeOf(err), err)
}
ensureXPayConfig(t)
if _, err := MemberOrderPay(other, res.OutTradeNo, "probe-code"); err == nil {
t.Fatalf("/member/order/pay 他人订单应 4015,实得 nil")
} else if codeOf(err) != consts.CodeOrderInvalid {
t.Fatalf("/member/order/pay 他人订单应 4015,实得 code=%d err=%v", codeOf(err), err)
}
// 反证:本人取详情应放行
if _, err := MemberOrderDetail(ctxWithUser(p.userId), res.OutTradeNo); err != nil {
t.Fatalf("本人订单详情应放行,实得 err=%v", err)
}
}