修复发货提交卡死恢复
This commit is contained in:
@@ -7,8 +7,10 @@ import (
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"affiliate_dash/internal/model"
|
||||
"affiliate_dash/internal/pkg/timeutil"
|
||||
)
|
||||
|
||||
func TestDeliveryLinkGenerateAuthorizeAndRevoke(t *testing.T) {
|
||||
@@ -112,7 +114,9 @@ func TestDeliveryMerchantApiBindAndSubmit(t *testing.T) {
|
||||
t.Fatalf("create merchant product: %v", err)
|
||||
}
|
||||
|
||||
var bindCalls, boundCalls, queueCreateCalls, queuePatchCalls, upstreamCalls int32
|
||||
fulfillmentSvc := NewFulfillmentService(db, nil)
|
||||
var bindCalls, boundCalls, queueCreateCalls, queuePatchCalls, upstreamCalls, upstreamSawCanShip int32
|
||||
orderNoForUpstreamCheck := ""
|
||||
var requestLog []string
|
||||
mockBFF := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/sign-proxy" {
|
||||
@@ -167,6 +171,14 @@ func TestDeliveryMerchantApiBindAndSubmit(t *testing.T) {
|
||||
case "/public/users/orders-queue":
|
||||
if payload.Method == http.MethodPost {
|
||||
atomic.AddInt32(&queueCreateCalls, 1)
|
||||
if orderNoForUpstreamCheck != "" {
|
||||
openOrder, err := fulfillmentSvc.QueryOpenOrder(orderNoForUpstreamCheck)
|
||||
if err == nil && openOrder.Status == model.OrderStatusPaid && openOrder.CanShip {
|
||||
atomic.StoreInt32(&upstreamSawCanShip, 1)
|
||||
} else {
|
||||
atomic.StoreInt32(&upstreamSawCanShip, -1)
|
||||
}
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"code": 0,
|
||||
"data": map[string]interface{}{
|
||||
@@ -202,7 +214,6 @@ func TestDeliveryMerchantApiBindAndSubmit(t *testing.T) {
|
||||
}))
|
||||
defer mockBFF.Close()
|
||||
|
||||
fulfillmentSvc := NewFulfillmentService(db, nil)
|
||||
deliverySvc := NewDeliveryService(fulfillmentSvc, mockBFF.URL, "dlc", "https://shop.example", "link-secret", 60)
|
||||
|
||||
created, err := fulfillmentSvc.CreateOrder(CreateFulfillmentOrderInput{
|
||||
@@ -214,6 +225,7 @@ func TestDeliveryMerchantApiBindAndSubmit(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("create order: %v", err)
|
||||
}
|
||||
orderNoForUpstreamCheck = created.Order.OrderNo
|
||||
|
||||
info, err := deliverySvc.GetMerchantOrder(merchantID, created.Order.OrderNo)
|
||||
if err != nil {
|
||||
@@ -248,6 +260,9 @@ func TestDeliveryMerchantApiBindAndSubmit(t *testing.T) {
|
||||
if atomic.LoadInt32(&queueCreateCalls) != 1 || atomic.LoadInt32(&upstreamCalls) != 1 {
|
||||
t.Fatalf("first submit should only create one queue, queue=%d upstream=%d requests=%v", queueCreateCalls, upstreamCalls, requestLog)
|
||||
}
|
||||
if atomic.LoadInt32(&upstreamSawCanShip) != 1 {
|
||||
t.Fatalf("upstream re-query during submit should still see paid/can_ship=true")
|
||||
}
|
||||
second, err := deliverySvc.SubmitForMerchant(merchantID, 88, created.Order.OrderNo, "4808146277", bind.BindUUID)
|
||||
if err != nil {
|
||||
t.Fatalf("repeat submit for merchant: %v", err)
|
||||
@@ -263,6 +278,76 @@ func TestDeliveryMerchantApiBindAndSubmit(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeliveryClaimBlocksRecentInProgressStage(t *testing.T) {
|
||||
recentStartedAt := time.Now().Add(-time.Minute)
|
||||
merchantID, deliverySvc, order := createDeliveryOrderWithSubmitStage(t, "delivery-claim-recent", deliveryStageClaimed, recentStartedAt, 1)
|
||||
|
||||
claimed, claimedNow, err := deliverySvc.claimDeliverySubmission(merchantID, 88, order.OrderNo)
|
||||
if err != nil {
|
||||
t.Fatalf("claim recent in-progress order: %v", err)
|
||||
}
|
||||
if claimedNow {
|
||||
t.Fatalf("recent in-progress stage should still block duplicate claim")
|
||||
}
|
||||
if got := resultDataNumber(claimed.ResultData, "ship_attempts"); got != 1 {
|
||||
t.Fatalf("blocked claim should keep attempts, got %d", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeliveryClaimRecoversStaleInProgressStage(t *testing.T) {
|
||||
staleStartedAt := time.Now().Add(-deliverySubmissionStaleTimeout - time.Minute)
|
||||
merchantID, deliverySvc, order := createDeliveryOrderWithSubmitStage(t, "delivery-claim-stale", deliveryStageQueueCreated, staleStartedAt, 1)
|
||||
|
||||
claimed, claimedNow, err := deliverySvc.claimDeliverySubmission(merchantID, 88, order.OrderNo)
|
||||
if err != nil {
|
||||
t.Fatalf("claim stale in-progress order: %v", err)
|
||||
}
|
||||
if !claimedNow {
|
||||
t.Fatalf("stale in-progress stage should allow a fresh claim")
|
||||
}
|
||||
if got := resultDataString(claimed.ResultData, "provider_order_stage"); got != deliveryStageClaimed {
|
||||
t.Fatalf("stale claim should reset stage to claimed, got %q", got)
|
||||
}
|
||||
if got := resultDataNumber(claimed.ResultData, "ship_attempts"); got != 2 {
|
||||
t.Fatalf("stale claim should count a new attempt, got %d", got)
|
||||
}
|
||||
if got := resultDataString(claimed.ResultData, "submit_started_at"); got == "" || got == timeutil.FormatAPITime(staleStartedAt) {
|
||||
t.Fatalf("stale claim should refresh submit_started_at, got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func createDeliveryOrderWithSubmitStage(t *testing.T, merchantCode, stage string, startedAt time.Time, attempts int64) (uint, *DeliveryService, *model.FulfillmentOrder) {
|
||||
t.Helper()
|
||||
db := newServiceTestDB(t)
|
||||
merchantID, product := seedFulfillmentMerchant(t, db, merchantCode, 5000, 5, 100)
|
||||
fulfillmentSvc := NewFulfillmentService(db, nil)
|
||||
created, err := fulfillmentSvc.CreateOrder(CreateFulfillmentOrderInput{
|
||||
MerchantID: merchantID,
|
||||
APIClientID: 1,
|
||||
ClientOrderNo: merchantCode + "-001",
|
||||
SKU: product.SKU,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create order: %v", err)
|
||||
}
|
||||
resultData := mergeResultData(created.Order.ResultData, map[string]interface{}{
|
||||
"provider_order_stage": stage,
|
||||
"submit_started_at": timeutil.FormatAPITime(startedAt),
|
||||
"ship_attempts": attempts,
|
||||
})
|
||||
if err := db.Model(&model.FulfillmentOrder{}).
|
||||
Where("id = ?", created.Order.ID).
|
||||
Update("result_data", resultData).Error; err != nil {
|
||||
t.Fatalf("seed submit stage: %v", err)
|
||||
}
|
||||
var order model.FulfillmentOrder
|
||||
if err := db.First(&order, created.Order.ID).Error; err != nil {
|
||||
t.Fatalf("reload order: %v", err)
|
||||
}
|
||||
deliverySvc := NewDeliveryService(fulfillmentSvc, "https://bff.example", "dlc", "https://shop.example", "link-secret", 60)
|
||||
return merchantID, deliverySvc, &order
|
||||
}
|
||||
|
||||
func TestDeliveryResubmitBlockedAfterUpstreamSubmission(t *testing.T) {
|
||||
db := newServiceTestDB(t)
|
||||
merchantID, _ := seedFulfillmentMerchant(t, db, "delivery-guard", 5000, 5, 100)
|
||||
|
||||
Reference in New Issue
Block a user