package service import ( "testing" "cmautobuy/admin/model" "cmautobuy/admin/repository" ) func TestShopeeSoftDelete_保留关联且可恢复(t *testing.T) { db := newTestDB(t) now := model.NowISO() admin := &model.User{UserID: "ADMIN-DELETE", Username: "delete-admin", PasswordHash: "test", Role: model.RoleAdmin, Status: model.UserActive, PasswordChangedAt: now, CreatedAt: now, UpdatedAt: now} if err := repository.CreateUser(db, *admin); err != nil { t.Fatal(err) } if _, err := db.Exec(`INSERT INTO pdd_products(goods_id,url,collect_status,created_at,updated_at) VALUES('P-DEL','https://example.com/p','collected',?,?)`, now, now); err != nil { t.Fatal(err) } if _, err := db.Exec(`INSERT INTO shopee_products(goods_id,title,pdd_goods_id,pdd_goods_url,source,created_at,updated_at) VALUES('S-DEL','商品','P-DEL','https://example.com/p','report',?,?)`, now, now); err != nil { t.Fatal(err) } if _, err := db.Exec(`INSERT INTO shopee_skus(sku_id,goods_id,spec_raw,spec_key,parse_ok,is_manual,source,created_at,updated_at) VALUES('SKU-DEL','S-DEL','黑色,M','黑色,M',1,0,'report',?,?)`, now, now); err != nil { t.Fatal(err) } count, err := DeleteShopeeProducts(db, admin, []string{"S-DEL", "S-DEL"}) if err != nil || count != 1 { t.Fatalf("软删除失败:count=%d err=%v", count, err) } if product, _ := repository.GetShopeeProductByGoodsID(db, "S-DEL"); product != nil { t.Fatal("默认查询不应返回已删除商品") } var skuCount int if err := db.QueryRow(`SELECT COUNT(*) FROM shopee_skus WHERE goods_id='S-DEL'`).Scan(&skuCount); err != nil || skuCount != 1 { t.Fatalf("软删除不应删除 SKU:count=%d err=%v", skuCount, err) } count, err = RestoreShopeeProducts(db, admin, []string{"S-DEL"}) if err != nil || count != 1 { t.Fatalf("恢复失败:count=%d err=%v", count, err) } product, err := repository.GetShopeeProductByGoodsID(db, "S-DEL") if err != nil || product == nil || product.PddGoodsID != "P-DEL" { t.Fatalf("恢复后关联丢失:product=%+v err=%v", product, err) } } func TestShopeeSoftDelete_进行中任务阻止整批删除(t *testing.T) { db := newTestDB(t) now := model.NowISO() admin := &model.User{UserID: "ADMIN-BUSY", Username: "busy-admin", PasswordHash: "test", Role: model.RoleAdmin, Status: model.UserActive, PasswordChangedAt: now, CreatedAt: now, UpdatedAt: now} if err := repository.CreateUser(db, *admin); err != nil { t.Fatal(err) } for _, id := range []string{"S-BUSY", "S-FREE"} { if _, err := db.Exec(`INSERT INTO shopee_products(goods_id,title,source,created_at,updated_at) VALUES(?,?,'report',?,?)`, id, id, now, now); err != nil { t.Fatal(err) } } if _, err := db.Exec(`INSERT INTO tasks(task_id,task_type,status,goods_id,pdd_goods_url,created_at,updated_at) VALUES('cg999','purchase','pending','S-BUSY','https://example.com/p',?,?)`, now, now); err != nil { t.Fatal(err) } if _, err := DeleteShopeeProducts(db, admin, []string{"S-BUSY", "S-FREE"}); err == nil || !IsValidationError(err) { t.Fatalf("有进行中任务时应阻止整批删除,实际 err=%v", err) } var deleted int if err := db.QueryRow(`SELECT COUNT(*) FROM shopee_products WHERE deleted_at IS NOT NULL`).Scan(&deleted); err != nil || deleted != 0 { t.Fatalf("整批删除应回滚:deleted=%d err=%v", deleted, err) } }