- delete_product 补 count_refs 引用检查(业务明细+发货明细 RESTRICT 外键)与并发窗口 IntegrityError→400 兜底(customer 先例同构), docstring 与两个 api 层过时注释同步更新 - 产品 schema 复用 schemas/business._check_amount:sale_price 走 (PRICE_MAX, scale=4)、stock_quantity 走 AMOUNT_MAX——此前私写 _parse_non_negative 不查小数位与容量,5 位小数被 Numeric(14,4) 静默截断(舍入即算错钱);新增 6 个秒级 schema 单测锁定口径 - 全局注册 IntegrityError handler:漏补引用保护的删除类操作收敛为 400 通用文案(e2e 撞见一个补一个的模式无法保证全覆盖),完整 异常记日志;rating/customer 的「非 1062 按 500」注释同步更正 Co-Authored-By: Claude Code <noreply@anthropic.com>
73 lines
2.6 KiB
Python
73 lines
2.6 KiB
Python
"""产品 schema 的金额口径单测(秒级,无外部依赖)。
|
||
|
||
守:产品 sale_price/stock_quantity 若私写校验不查小数位与容量,5 位小数
|
||
会被 Numeric 列静默截断(舍入即算错钱)、超容量会以 500 暴露 —— 校验
|
||
口径必须与 schemas/business._check_amount 一致(shipment/receipt 同源)。
|
||
"""
|
||
|
||
import pytest
|
||
from pydantic import ValidationError
|
||
|
||
from app.schemas.product import ProductCreateIn
|
||
|
||
|
||
class TestSalePrice:
|
||
"""单价校验:scale=4 对齐 Numeric(14,4) 列。"""
|
||
|
||
def test_四位小数通过_回显原样提交(self) -> None:
|
||
"""带精度的历史单价必须能原样提交(fba8cfc 教训:编辑被永远拒收)。"""
|
||
body = ProductCreateIn(
|
||
product_name="t_产品",
|
||
product_category="municipal_water",
|
||
sale_price="5000.1234",
|
||
)
|
||
assert body.sale_price == "5000.1234"
|
||
|
||
def test_五位小数拒绝而非静默截断(self) -> None:
|
||
with pytest.raises(ValidationError) as exc:
|
||
ProductCreateIn(
|
||
product_name="t_产品",
|
||
product_category="municipal_water",
|
||
sale_price="1.23456",
|
||
)
|
||
assert "最多四位小数" in str(exc.value)
|
||
|
||
def test_超容量拒绝(self) -> None:
|
||
"""DECIMAL(14,4) 整数部分 10 位:超出即拒绝而非溢出 500。"""
|
||
with pytest.raises(ValidationError):
|
||
ProductCreateIn(
|
||
product_name="t_产品",
|
||
product_category="municipal_water",
|
||
sale_price="99999999999.0000",
|
||
)
|
||
|
||
def test_空串归一None_负数拒绝(self) -> None:
|
||
empty = ProductCreateIn(
|
||
product_name="t_产品", product_category="municipal_water", sale_price=""
|
||
)
|
||
assert empty.sale_price is None
|
||
with pytest.raises(ValidationError):
|
||
ProductCreateIn(
|
||
product_name="t_产品", product_category="municipal_water", sale_price="-1"
|
||
)
|
||
|
||
|
||
class TestStockQuantity:
|
||
"""数量校验:默认 scale=2 对齐 Numeric(14,2) 列。"""
|
||
|
||
def test_三位小数拒绝(self) -> None:
|
||
with pytest.raises(ValidationError):
|
||
ProductCreateIn(
|
||
product_name="t_产品",
|
||
product_category="municipal_water",
|
||
stock_quantity="1.001",
|
||
)
|
||
|
||
def test_两位小数通过(self) -> None:
|
||
body = ProductCreateIn(
|
||
product_name="t_产品",
|
||
product_category="municipal_water",
|
||
stock_quantity="1.55",
|
||
)
|
||
assert body.stock_quantity == "1.55"
|