feat: 重构顺运宝规格主链路 (#88)
This commit is contained in:
+25
-47
@@ -198,49 +198,30 @@ func TestMarkCollecting_失败后可重新采集(t *testing.T) {
|
||||
|
||||
// ── 映射隔离:本工单的安全核心 ─────────────────────────
|
||||
|
||||
// insertShopeeSKU 造蝦皮商品和它的一个规格。
|
||||
// sku_mappings 有外键指向 shopee_skus,映射相关的测试都要先造它。
|
||||
func insertShopeeSKU(t *testing.T, db *sql.DB, goodsID, skuID string) {
|
||||
t.Helper()
|
||||
now := model.NowISO()
|
||||
if _, err := db.Exec(`
|
||||
INSERT INTO shopee_products (goods_id, title, created_at, updated_at)
|
||||
VALUES (?, '测试商品', ?, ?)
|
||||
ON DUPLICATE KEY UPDATE goods_id = VALUES(goods_id)`, goodsID, now, now); err != nil {
|
||||
t.Fatalf("插入蝦皮商品失败: %v", err)
|
||||
}
|
||||
if _, err := db.Exec(`
|
||||
INSERT INTO shopee_skus (sku_id, goods_id, spec_raw, created_at, updated_at)
|
||||
VALUES (?, ?, '黑色,M', ?, ?)`, skuID, goodsID, now, now); err != nil {
|
||||
t.Fatalf("插入蝦皮规格失败: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// insertMapping 造一条规格映射。
|
||||
func insertMapping(t *testing.T, db *sql.DB, shopeeSKU, pddGoodsID string, options map[string]string) {
|
||||
func insertMapping(t *testing.T, db *sql.DB, goodsID, specKey, pddGoodsID string, options map[string]string) {
|
||||
t.Helper()
|
||||
key, err := OptionKey(options)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := db.Exec(`
|
||||
INSERT INTO sku_mappings (shopee_sku_id, pdd_goods_id, pdd_option_key,
|
||||
pdd_options, goods_id, mapped_at)
|
||||
VALUES (?, ?, ?, ?, 'SHOPEE-1', ?)`,
|
||||
shopeeSKU, pddGoodsID, key, key, model.NowISO()); err != nil {
|
||||
if err := repository.UpsertSpecMapping(db, model.SpecMapping{
|
||||
ShopeeGoodsID: goodsID, SpecKey: specKey, SpecRaw: specKey,
|
||||
PddGoodsID: pddGoodsID, PddOptionKey: key, PddOptions: key, MappedAt: model.NowISO(),
|
||||
}); err != nil {
|
||||
t.Fatalf("插入映射失败: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// findMapping 模拟业务查询:**永远带上当前的 PDD 商品**。
|
||||
// 这个条件就是隔离机制本身,少了它旧映射就会被误用。
|
||||
func findMapping(t *testing.T, db *sql.DB, shopeeSKU, currentPddGoodsID string) (string, bool) {
|
||||
func findMapping(t *testing.T, db *sql.DB, goodsID, specKey, currentPddGoodsID string) (string, bool) {
|
||||
t.Helper()
|
||||
var key string
|
||||
err := db.QueryRow(`
|
||||
SELECT pdd_option_key FROM sku_mappings
|
||||
WHERE shopee_sku_id = ? AND pdd_goods_id = ?`,
|
||||
shopeeSKU, currentPddGoodsID).Scan(&key)
|
||||
SELECT pdd_option_key FROM spec_mappings
|
||||
WHERE shopee_goods_id = ? AND spec_key = ? AND pdd_goods_id = ?`,
|
||||
goodsID, specKey, currentPddGoodsID).Scan(&key)
|
||||
if err == sql.ErrNoRows {
|
||||
return "", false
|
||||
}
|
||||
@@ -254,21 +235,20 @@ func findMapping(t *testing.T, db *sql.DB, shopeeSKU, currentPddGoodsID string)
|
||||
//
|
||||
// 不隔离的话:B 恰好也有"黑色/M码"这个组合,但完全是另一件衣服,
|
||||
// 就会**静默买错东西**,而且事后查不出来。
|
||||
func TestSKUMapping_换PDD商品后查不到旧映射(t *testing.T) {
|
||||
func TestSpecMapping_换PDD商品后查不到旧映射(t *testing.T) {
|
||||
db := newTestDB(t)
|
||||
insertShopeeSKU(t, db, "SHOPEE-1", "SKU-1")
|
||||
repository.EnsurePddProduct(db, "PDD-A", "https://x/a")
|
||||
repository.EnsurePddProduct(db, "PDD-B", "https://x/b")
|
||||
|
||||
// 蝦皮 SKU 原来匹配到 PDD 商品 A 的"黑色/M码"
|
||||
insertMapping(t, db, "SKU-1", "PDD-A", map[string]string{"color": "黑色", "size": "M码"})
|
||||
// 顺运宝规格原来匹配到 PDD 商品 A 的"黑色/M码"
|
||||
insertMapping(t, db, "SHOPEE-1", "黑色,M", "PDD-A", map[string]string{"color": "黑色", "size": "M码"})
|
||||
|
||||
if _, ok := findMapping(t, db, "SKU-1", "PDD-A"); !ok {
|
||||
if _, ok := findMapping(t, db, "SHOPEE-1", "黑色,M", "PDD-A"); !ok {
|
||||
t.Fatal("前置条件不对:A 的映射应该查得到")
|
||||
}
|
||||
|
||||
// A 下架,换成 B。查 B 的映射应该查不到 —— 界面显示"待匹配"
|
||||
if key, ok := findMapping(t, db, "SKU-1", "PDD-B"); ok {
|
||||
if key, ok := findMapping(t, db, "SHOPEE-1", "黑色,M", "PDD-B"); ok {
|
||||
t.Errorf("换成 B 之后不该查到映射,却拿到了 %q —— "+
|
||||
"这正是会导致买错商品的情况", key)
|
||||
}
|
||||
@@ -277,18 +257,17 @@ func TestSKUMapping_换PDD商品后查不到旧映射(t *testing.T) {
|
||||
// 换回原来的 PDD 商品,旧映射要还能用。
|
||||
// 这是把 pdd_goods_id 放进主键(而不是换商品时删掉旧映射)换来的好处:
|
||||
// PDD 商品补货换回去时,之前的人工匹配成果直接复用。
|
||||
func TestSKUMapping_换回原商品旧映射仍可用(t *testing.T) {
|
||||
func TestSpecMapping_换回原商品旧映射仍可用(t *testing.T) {
|
||||
db := newTestDB(t)
|
||||
insertShopeeSKU(t, db, "SHOPEE-1", "SKU-1")
|
||||
repository.EnsurePddProduct(db, "PDD-A", "https://x/a")
|
||||
repository.EnsurePddProduct(db, "PDD-B", "https://x/b")
|
||||
|
||||
insertMapping(t, db, "SKU-1", "PDD-A", map[string]string{"color": "黑色", "size": "M码"})
|
||||
insertMapping(t, db, "SHOPEE-1", "黑色,M", "PDD-A", map[string]string{"color": "黑色", "size": "M码"})
|
||||
// 换到 B,也匹配一次
|
||||
insertMapping(t, db, "SKU-1", "PDD-B", map[string]string{"color": "黑色", "size": "M"})
|
||||
insertMapping(t, db, "SHOPEE-1", "黑色,M", "PDD-B", map[string]string{"color": "黑色", "size": "M"})
|
||||
|
||||
// 换回 A
|
||||
key, ok := findMapping(t, db, "SKU-1", "PDD-A")
|
||||
key, ok := findMapping(t, db, "SHOPEE-1", "黑色,M", "PDD-A")
|
||||
if !ok {
|
||||
t.Fatal("换回 A 之后,A 的旧映射应该还在")
|
||||
}
|
||||
@@ -298,24 +277,23 @@ func TestSKUMapping_换回原商品旧映射仍可用(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 同一个蝦皮 SKU 可以同时有多个 PDD 商品的映射,互不干扰。
|
||||
func TestSKUMapping_同一SKU可对多个PDD商品各有映射(t *testing.T) {
|
||||
// 同一蝦皮商品规格可以同时有多个 PDD 商品的映射,互不干扰。
|
||||
func TestSpecMapping_同一商品规格可对多个PDD商品各有映射(t *testing.T) {
|
||||
db := newTestDB(t)
|
||||
insertShopeeSKU(t, db, "SHOPEE-1", "SKU-1")
|
||||
repository.EnsurePddProduct(db, "PDD-A", "https://x/a")
|
||||
repository.EnsurePddProduct(db, "PDD-B", "https://x/b")
|
||||
|
||||
insertMapping(t, db, "SKU-1", "PDD-A", map[string]string{"color": "黑色", "size": "M码"})
|
||||
insertMapping(t, db, "SKU-1", "PDD-B", map[string]string{"color": "黑", "size": "均码"})
|
||||
insertMapping(t, db, "SHOPEE-1", "黑色,M", "PDD-A", map[string]string{"color": "黑色", "size": "M码"})
|
||||
insertMapping(t, db, "SHOPEE-1", "黑色,M", "PDD-B", map[string]string{"color": "黑", "size": "均码"})
|
||||
|
||||
var n int
|
||||
db.QueryRow(`SELECT COUNT(*) FROM sku_mappings WHERE shopee_sku_id='SKU-1'`).Scan(&n)
|
||||
db.QueryRow(`SELECT COUNT(*) FROM spec_mappings WHERE shopee_goods_id='SHOPEE-1' AND spec_key='黑色,M'`).Scan(&n)
|
||||
if n != 2 {
|
||||
t.Errorf("应能同时存在 2 条映射,实际 %d 条", n)
|
||||
}
|
||||
|
||||
kA, _ := findMapping(t, db, "SKU-1", "PDD-A")
|
||||
kB, _ := findMapping(t, db, "SKU-1", "PDD-B")
|
||||
kA, _ := findMapping(t, db, "SHOPEE-1", "黑色,M", "PDD-A")
|
||||
kB, _ := findMapping(t, db, "SHOPEE-1", "黑色,M", "PDD-B")
|
||||
if kA == kB {
|
||||
t.Error("两个 PDD 商品的映射不该相同")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user