Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
@@ -27,8 +27,8 @@ func TestOrderStatusName(t *testing.T) {
|
||||
3: "closed",
|
||||
4: "failed",
|
||||
5: "finished",
|
||||
6: "refunded",
|
||||
7: "unknown",
|
||||
6: "claimed",
|
||||
7: "refunded",
|
||||
}
|
||||
|
||||
for input, want := range tests {
|
||||
@@ -96,14 +96,64 @@ func TestBuildRefundAuditLog(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestRefundOrder_RejectsWhenRefundLogExists 验证 HIF-131 / HIF-132 修复:
|
||||
// 当 system_logs 已存在该订单的 333 退款佣金日志时,再次调用 RefundOrder 必须:
|
||||
func TestRefundOrder_SetsStatusRefunded(t *testing.T) {
|
||||
const (
|
||||
orderID = int64(1000)
|
||||
orderNo = "ORD-REFUND-SUCCESS"
|
||||
operatorUID = int64(519)
|
||||
userID = int64(7000)
|
||||
subscribeID = int64(8000)
|
||||
userSubID = int64(9000)
|
||||
)
|
||||
|
||||
db, mock, cleanup := newRefundOrderTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
mock.ExpectBegin()
|
||||
mock.ExpectQuery("FROM `order`").
|
||||
WithArgs(orderID, 1).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"id", "order_no", "status", "type", "commission", "user_id", "subscribe_id"}).
|
||||
AddRow(orderID, orderNo, uint8(5), uint8(1), int64(0), userID, subscribeID))
|
||||
mock.ExpectQuery("FROM `system_logs`").
|
||||
WithArgs(uint8(24), fmt.Sprintf(`%%"order_no":"%s"%%`, orderNo)).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"id", "content"}))
|
||||
mock.ExpectQuery("FROM `system_logs`").
|
||||
WithArgs(uint8(33), fmt.Sprintf(`%%"order_no":"%s"%%`, orderNo)).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"id", "content"}))
|
||||
mock.ExpectQuery("FROM `user_subscribe`").
|
||||
WithArgs(orderID, 1).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "order_id", "subscribe_id", "status", "expire_time"}).
|
||||
AddRow(userSubID, userID, orderID, subscribeID, uint8(1), time.Now().Add(24*time.Hour)))
|
||||
mock.ExpectQuery("FROM `system_logs`").
|
||||
WithArgs(uint8(33), fmt.Sprintf(`%%"order_no":"%s"%%`, orderNo)).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"id", "content"}))
|
||||
mock.ExpectExec("UPDATE `order`").
|
||||
WithArgs(orderStatusRefunded, sqlmock.AnyArg(), orderID, 2, 5).
|
||||
WillReturnResult(sqlmock.NewResult(0, 1))
|
||||
mock.ExpectExec("UPDATE `user_subscribe`").
|
||||
WillReturnResult(sqlmock.NewResult(0, 1))
|
||||
mock.ExpectExec("INSERT INTO `system_logs`").
|
||||
WillReturnResult(sqlmock.NewResult(1, 1))
|
||||
mock.ExpectCommit()
|
||||
|
||||
logic := newTestRefundOrderLogic(t, db, operatorUID)
|
||||
err := logic.RefundOrder(&types.RefundOrderRequest{Id: orderID, Reason: "manual refund"})
|
||||
if err != nil {
|
||||
t.Fatalf("RefundOrder error: %v", err)
|
||||
}
|
||||
if err := mock.ExpectationsWereMet(); err != nil {
|
||||
t.Fatalf("unmet sql expectations: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestRefundOrder_RejectsWhenRefundLogExists 验证 HIF-16 修复:
|
||||
// 当 system_logs 已存在该订单的 24 退款审计日志时,再次调用 RefundOrder 必须:
|
||||
// 1. 返回 OrderAlreadyRefunded 错误码;
|
||||
// 2. 不再查询 / 锁定 commission 来源(lockCommissionSource 不应触发);
|
||||
// 3. 不写入新的 333 日志、不更新 user.commission、不更新 order.status。
|
||||
//
|
||||
// 通过 sqlmock 严格定义期望 SQL:只允许出现 BEGIN / SELECT order FOR UPDATE /
|
||||
// SELECT system_logs(命中 333)/ ROLLBACK,不允许出现 commission 锁/更新/插入。
|
||||
// SELECT system_logs(命中 24)/ ROLLBACK,不允许出现 commission 锁/更新/插入。
|
||||
func TestRefundOrder_RejectsWhenRefundLogExists(t *testing.T) {
|
||||
const (
|
||||
orderID = int64(53647)
|
||||
@@ -120,9 +170,9 @@ func TestRefundOrder_RejectsWhenRefundLogExists(t *testing.T) {
|
||||
WillReturnRows(sqlmock.NewRows([]string{"id", "order_no", "status", "type", "commission", "user_id"}).
|
||||
AddRow(orderID, orderNo, uint8(5), uint8(2), int64(2250), int64(72028)))
|
||||
mock.ExpectQuery("FROM `system_logs`").
|
||||
WithArgs(uint8(33), fmt.Sprintf(`%%"order_no":"%s"%%`, orderNo)).
|
||||
WithArgs(uint8(24), fmt.Sprintf(`%%"order_no":"%s"%%`, orderNo)).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"id", "content"}).
|
||||
AddRow(1, fmt.Sprintf(`{"type":333,"order_no":"%s","amount":-2250,"timestamp":0}`, orderNo)))
|
||||
AddRow(1, fmt.Sprintf(`{"order_id":%d,"order_no":"%s","order_status_before":5,"order_status_after":7}`, orderID, orderNo)))
|
||||
mock.ExpectRollback()
|
||||
|
||||
logic := newTestRefundOrderLogic(t, db, operatorUID)
|
||||
@@ -138,12 +188,12 @@ func TestRefundOrder_RejectsWhenRefundLogExists(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestRefundOrder_RejectsWhenStatusAlreadyRefunded 覆盖既有 status==6 拒绝路径,
|
||||
// TestRefundOrder_RejectsWhenStatusAlreadyRefunded 覆盖既有 status==7 拒绝路径,
|
||||
// 确保新增的 333 日志校验不会破坏原有「订单已被标记为退款」短路逻辑。
|
||||
func TestRefundOrder_RejectsWhenStatusAlreadyRefunded(t *testing.T) {
|
||||
const (
|
||||
orderID = int64(1001)
|
||||
orderNo = "ORD-STATUS-6"
|
||||
orderNo = "ORD-STATUS-7"
|
||||
operatorUID = int64(519)
|
||||
)
|
||||
|
||||
@@ -306,6 +356,9 @@ func TestRefundOrder_NoTargetSubscriptionDoesNotRefundOrder(t *testing.T) {
|
||||
WithArgs(orderID, 1).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"id", "order_no", "status", "type", "commission", "user_id", "subscribe_id"}).
|
||||
AddRow(orderID, orderNo, uint8(5), uint8(1), int64(0), userID, subscribeID))
|
||||
mock.ExpectQuery("FROM `system_logs`").
|
||||
WithArgs(uint8(24), fmt.Sprintf(`%%"order_no":"%s"%%`, orderNo)).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"id", "content"}))
|
||||
mock.ExpectQuery("FROM `system_logs`").
|
||||
WithArgs(uint8(33), fmt.Sprintf(`%%"order_no":"%s"%%`, orderNo)).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"id", "content"}))
|
||||
|
||||
Reference in New Issue
Block a user