Files
cmautobuy/tools/test_import_catalog_xlsx.py
T

161 lines
5.4 KiB
Python

import importlib.util
import json
import sys
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
from openpyxl import Workbook
MODULE_PATH = Path(__file__).with_name("import_catalog_xlsx.py")
SPEC = importlib.util.spec_from_file_location("import_catalog_xlsx", MODULE_PATH)
assert SPEC and SPEC.loader
catalog = importlib.util.module_from_spec(SPEC)
sys.modules[SPEC.name] = catalog
SPEC.loader.exec_module(catalog)
HEADERS = [
"商品ID",
"商品标题",
"主货号",
"货源URL",
"货源平台",
"货源ID",
"货源店铺名",
"价格",
"币种",
"库存",
"销量",
"浏览量",
"收藏量",
"评论数",
"商品状态",
"店铺显示名",
"平台店铺ID",
"创建时间",
"更新时间",
"缩略图URL",
"变种属性值一",
"变种属性值二",
]
def sample_row(shopee_id, pdd_id, first, second):
return [
shopee_id,
f"商品 {shopee_id}",
"MAIN",
f"https://mobile.yangkeduo.com/goods.html?goods_id={pdd_id}&tracking=removed",
"拼多多",
pdd_id,
"PDD 店铺",
"100",
"TWD",
10,
"",
"",
"",
"",
"NORMAL",
"蝦皮店铺",
"SHOP",
"2026-08-10 08:00:00",
"2026-08-11 09:30:00",
"https://img.example.com/a.jpg",
first,
second,
]
class CatalogXLSXTest(unittest.TestCase):
def make_workbook(self, rows):
temp = tempfile.TemporaryDirectory()
path = Path(temp.name) / "sample.xlsx"
workbook = Workbook()
sheet = workbook.active
sheet.title = "在线商品"
sheet.append(HEADERS)
for row in rows:
sheet.append(row)
workbook.save(path)
workbook.close()
self.addCleanup(temp.cleanup)
return path
def test_聚合规格且不猜颜色尺码并按PDD去重(self):
path = self.make_workbook(
[
sample_row("S-1", "P-1", "黑色", "M"),
sample_row("S-1", "P-1", "白色", "L"),
sample_row("S-2", "P-1", "均码", "红色"),
]
)
plan = catalog.prepare_batches(path, 200, "fill_missing")
self.assertEqual((plan.groups, plan.skus, plan.unique_pdd_products), (2, 3, 1))
self.assertEqual(len(plan.batches), 1)
payload = json.loads(plan.batches[0].body)
self.assertEqual(len(payload["pdd_products"]), 1)
self.assertEqual(payload["pdd_products"][0]["url"], "https://mobile.yangkeduo.com/goods.html?goods_id=P-1")
self.assertEqual(payload["shopee_skus"][2]["spec_raw"], "均码,红色")
self.assertEqual(payload["shopee_skus"][2]["color"], "")
self.assertEqual(payload["shopee_skus"][2]["size"], "")
self.assertFalse(payload["shopee_skus"][2]["parse_ok"])
def test_相同文件重复规划生成完全相同请求(self):
path = self.make_workbook([sample_row("S-1", "P-1", "黑色", "M")])
first = catalog.prepare_batches(path, 200, "fill_missing")
second = catalog.prepare_batches(path, 200, "fill_missing")
self.assertEqual(first.batches[0].batch_id, second.batches[0].batch_id)
self.assertEqual(first.batches[0].body, second.batches[0].body)
changed_policy = catalog.prepare_batches(path, 200, "insert_only")
changed_size = catalog.prepare_batches(path, 1, "fill_missing")
self.assertNotEqual(first.batches[0].batch_id, changed_policy.batches[0].batch_id)
self.assertNotEqual(first.batches[0].batch_id, changed_size.batches[0].batch_id)
def test_商品不跨批且批次满足限制(self):
rows = []
for product in range(3):
rows.extend(
sample_row(f"S-{product}", f"P-{product}", f"颜色-{sku}", "M")
for sku in range(3)
)
path = self.make_workbook(rows)
plan = catalog.prepare_batches(path, 2, "fill_missing")
self.assertEqual([batch.shopee_products for batch in plan.batches], [2, 1])
self.assertEqual([batch.shopee_skus for batch in plan.batches], [6, 3])
for batch in plan.batches:
self.assertLessEqual(batch.shopee_products + batch.pdd_products, 500)
self.assertLessEqual(batch.shopee_skus, 5000)
self.assertLessEqual(len(batch.body), 5 << 20)
def test_重复规格明确停止(self):
row = sample_row("S-1", "P-1", "黑色", "M")
path = self.make_workbook([row, row])
with self.assertRaisesRegex(catalog.CatalogImportError, "规格重复"):
catalog.prepare_batches(path, 200, "fill_missing")
def test_临时接口错误重试且不改变请求(self):
batch = catalog.PreparedBatch("B-1", b"{}", 1, 1, 1, 1)
success = {"batch_id": "B-1", "status": "succeeded"}
with patch.object(
catalog,
"post_batch",
side_effect=[
catalog.CatalogHTTPError(503, "TEMPORARY", "稍后重试", True),
success,
],
) as post:
got = catalog.submit_with_retry(
"https://example.com/api", "secret", batch, 10, 1, sleep=lambda _: None
)
self.assertEqual(got, success)
self.assertEqual(post.call_count, 2)
self.assertEqual(post.call_args_list[0].args[2], post.call_args_list[1].args[2])
if __name__ == "__main__":
unittest.main()