138 lines
4.7 KiB
Go
138 lines
4.7 KiB
Go
package service
|
|
|
|
import (
|
|
"database/sql"
|
|
"testing"
|
|
|
|
"cmautobuy/admin/model"
|
|
"cmautobuy/admin/repository"
|
|
)
|
|
|
|
func seedWorkflowOrder(t *testing.T, db *sql.DB, sybID, goodsID, spec string) model.SybOrder {
|
|
t.Helper()
|
|
order := model.SybOrder{
|
|
SybID: sybID, OrderNo: "ORDER-" + sybID, Title: "测试商品",
|
|
ProductSpec: spec, ShopeeGoodsID: goodsID, Quantity: 1, SybData: `{}`,
|
|
}
|
|
if _, err := repository.UpsertSybOrder(db, order); err != nil {
|
|
t.Fatalf("准备顺运宝明细失败: %v", err)
|
|
}
|
|
return order
|
|
}
|
|
|
|
func seedWorkflowSKU(t *testing.T, db *sql.DB, skuID, goodsID, spec string) {
|
|
t.Helper()
|
|
color, size, advice, ok := ParseSpec(spec)
|
|
if err := repository.UpsertShopeeSKU(db, skuID, goodsID, spec, color, size, advice, ok, ""); err != nil {
|
|
t.Fatalf("准备蝦皮规格失败: %v", err)
|
|
}
|
|
}
|
|
|
|
func readOrderSKU(t *testing.T, db *sql.DB, sybID string) string {
|
|
t.Helper()
|
|
var sku sql.NullString
|
|
if err := db.QueryRow(`SELECT shopee_sku_id FROM syb_orders WHERE syb_id = ?`, sybID).Scan(&sku); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return sku.String
|
|
}
|
|
|
|
func TestAutoResolveSybShopeeSKU_只采用唯一精确候选(t *testing.T) {
|
|
t.Run("规格原文唯一一致", func(t *testing.T) {
|
|
db := newSyncTestDB(t)
|
|
if err := repository.UpsertShopeeProduct(db, "SP-1", "商品", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
seedWorkflowSKU(t, db, "SKU-1", "SP-1", "黑色,M")
|
|
order := seedWorkflowOrder(t, db, "SYB-1", "SP-1", "黑色,M")
|
|
|
|
got, err := AutoResolveSybShopeeSKU(db, order)
|
|
if err != nil || got != "SKU-1" || readOrderSKU(t, db, "SYB-1") != "SKU-1" {
|
|
t.Fatalf("应自动确认唯一原文候选: got=%q stored=%q err=%v", got, readOrderSKU(t, db, "SYB-1"), err)
|
|
}
|
|
})
|
|
|
|
t.Run("解析后颜色尺码唯一一致", func(t *testing.T) {
|
|
db := newSyncTestDB(t)
|
|
if err := repository.UpsertShopeeProduct(db, "SP-2", "商品", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
seedWorkflowSKU(t, db, "SKU-2", "SP-2", "黑色,M【建議40-50公斤】")
|
|
order := seedWorkflowOrder(t, db, "SYB-2", "SP-2", "黑色,M")
|
|
|
|
got, err := AutoResolveSybShopeeSKU(db, order)
|
|
if err != nil || got != "SKU-2" {
|
|
t.Fatalf("应采用唯一颜色尺码候选: got=%q err=%v", got, err)
|
|
}
|
|
})
|
|
|
|
t.Run("多个颜色尺码候选不猜测", func(t *testing.T) {
|
|
db := newSyncTestDB(t)
|
|
if err := repository.UpsertShopeeProduct(db, "SP-3", "商品", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
seedWorkflowSKU(t, db, "SKU-3A", "SP-3", "黑色,M【建議40-50公斤】")
|
|
seedWorkflowSKU(t, db, "SKU-3B", "SP-3", "黑色,M【建議50-60公斤】")
|
|
order := seedWorkflowOrder(t, db, "SYB-3", "SP-3", "黑色,M")
|
|
|
|
got, err := AutoResolveSybShopeeSKU(db, order)
|
|
if err != nil || got != "" || readOrderSKU(t, db, "SYB-3") != "" {
|
|
t.Fatalf("多候选必须留给人工确认: got=%q stored=%q err=%v", got, readOrderSKU(t, db, "SYB-3"), err)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestAssignSybShopeeSKU_拒绝其他商品的规格(t *testing.T) {
|
|
db := newSyncTestDB(t)
|
|
for _, goodsID := range []string{"SP-A", "SP-B"} {
|
|
if err := repository.UpsertShopeeProduct(db, goodsID, goodsID, "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
seedWorkflowSKU(t, db, "SKU-A", "SP-A", "黑色,M")
|
|
seedWorkflowSKU(t, db, "SKU-B", "SP-B", "白色,L")
|
|
seedWorkflowOrder(t, db, "SYB-A", "SP-A", "未知规格")
|
|
|
|
if err := AssignSybShopeeSKU(db, "SYB-A", "SKU-B"); err == nil {
|
|
t.Fatal("不得把其他蝦皮商品的 SKU 保存到当前顺运宝明细")
|
|
}
|
|
if got := readOrderSKU(t, db, "SYB-A"); got != "" {
|
|
t.Fatalf("越权选择后不应写库,实际 %q", got)
|
|
}
|
|
if err := AssignSybShopeeSKU(db, "SYB-A", "SKU-A"); err != nil {
|
|
t.Fatalf("同商品 SKU 应保存成功: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestListSybOrdersView_阶段筛选区分蝦皮识别和PDD准备(t *testing.T) {
|
|
db := newSyncTestDB(t)
|
|
seedWorkflowOrder(t, db, "SYB-MISSING", "NOT-IMPORTED", "黑色,M")
|
|
if err := repository.UpsertShopeeProduct(db, "SP-READY", "商品", "", ""); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
seedWorkflowSKU(t, db, "SKU-READY", "SP-READY", "黑色,M")
|
|
seedWorkflowOrder(t, db, "SYB-SKU", "SP-READY", "无法自动匹配")
|
|
order := seedWorkflowOrder(t, db, "SYB-PDD", "SP-READY", "黑色,M")
|
|
if _, err := AutoResolveSybShopeeSKU(db, order); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
cases := []struct{ stage, wantID string }{
|
|
{SybStageMissingShopee, "SYB-MISSING"},
|
|
{SybStageSKUPending, "SYB-SKU"},
|
|
{SybStagePddMissing, "SYB-PDD"},
|
|
}
|
|
for _, tc := range cases {
|
|
result, err := ListSybOrdersView(db, "", tc.stage, 1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if result.Total != 1 || len(result.Rows) != 1 || result.Rows[0].SybID != tc.wantID {
|
|
t.Fatalf("阶段 %s 结果错误: %+v", tc.stage, result)
|
|
}
|
|
if result.Rows[0].StageText == "" || result.Rows[0].ActionText == "" {
|
|
t.Fatalf("阶段 %s 必须有文字和下一步: %+v", tc.stage, result.Rows[0])
|
|
}
|
|
}
|
|
}
|