Merge branch 'main' into dev

This commit is contained in:
yml2213
2026-10-07 14:52:22 +08:00
8 changed files with 128 additions and 117 deletions
+44 -17
View File
@@ -34,24 +34,39 @@ GOODS_AVAILABLE = {
"startTime": "1769153181",
"endTime": "1795967999",
"storeStatus": 1,
"status": 0, # 0=未达兑换上限(可兑换)
"pic": "https://sta-op.douyucdn.cn/x.png",
}
#: 账号 558(已兑换)的同一商品项,只有这三项不同
GOODS_OWNED = {**GOODS_AVAILABLE, "count": 0, "foreverCount": 0, "storeStatus": 0}
#: 账号 558(已兑换)的同一商品项,status=1 为官方声明已达兑换上限
GOODS_OWNED = {
**GOODS_AVAILABLE,
"count": 0,
"foreverCount": 0,
"storeStatus": 0,
"status": 1,
}
class TestOwnedJudgement:
"""「是否已获得」的判定 —— 本功能的核心,也是最容易判错的地方。
"""「是否已获得 / 已达兑换上限」的判定。
⚠️ **判定只看官方兑换记录**。第一版拿限兑商品列表的 `count`/`storeStatus` 判,
依据是「558 兑换过 count=0 / 15407 没兑换 count=96982」——
那两条记录相隔两个月,我把**时间差异**当成了**账号差异**。
同一时刻对比才发现:三个账号(两个兑换过、一个没有)的商品项**字段完全一致**,
`count`/`foreverCount`/`storeStatus` 是**全局库存**,不暴露账号维度信息。
改用官方兑换记录后完美区分(558/607 有「破片手榴弹-兔兔白日梦」,15507 是 0 条)。
最高裁判:官方商城商品 status == 1 表示「已达兑换上限」(限量 1 件已满)。
即使斗鱼官方兑换记录已被官方清理为空,status == 1 也必须断定已获得。
"""
def test_owned_when_status_is_1_even_if_records_empty(self):
"""核心准入:即使官方兑换记录已被清理为空,只要商城 status==1 就必须判定已拥有。"""
goods_blocked = {**GOODS_AVAILABLE, "status": 1}
got = extract_high_value_goods([goods_blocked], [RABBIT], [])
assert got[0]["owned"] is True
assert "已达兑换上限" in got[0]["reason"]
def test_not_owned_when_status_is_0_and_records_empty(self):
"""未兑换账号:status==0 且兑换记录为空,必须判定为未拥有(可兑换)。"""
goods_free = {**GOODS_AVAILABLE, "status": 0}
got = extract_high_value_goods([goods_free], [RABBIT], [])
assert got[0]["owned"] is False
def test_owned_comes_from_official_records(self):
got = extract_high_value_goods(
[GOODS_AVAILABLE], [RABBIT], [{"commodityName": "破片手榴弹-兔兔白日梦"}]
@@ -64,13 +79,16 @@ class TestOwnedJudgement:
assert got[0]["owned"] is False
def test_global_stock_never_implies_owned(self):
"""**回归用例**:全局库存为 0 或售罄,都不能推出「这个账号已拥有」。
这正是第一版踩的坑 —— 用全局字段判账号维度的事。
"""
sold_out = {**GOODS_AVAILABLE, "count": 0, "foreverCount": 0, "storeStatus": 0}
"""回归用例:全局库存为 0 或售罄,但 status==0 时,不能推出「这个账号已拥有」"""
sold_out = {
**GOODS_AVAILABLE,
"count": 0,
"foreverCount": 0,
"storeStatus": 0,
"status": 0,
}
got = extract_high_value_goods([sold_out], [RABBIT], [])
assert got[0]["owned"] is False, "全局售罄不等于该账号拥有"
assert got[0]["owned"] is False, "全局售罄但 status=0 时不等于该账号拥有"
def test_stock_and_owned_are_independent(self):
"""展示用的全局信息与账号判定互不影响。"""
@@ -155,12 +173,21 @@ class _FakeClient:
def acf_ccn(self, **_):
return "ctn"
def list_goods(self, **_):
self._maybe("goods")
return {
"goods": [
GOODS_OWNED,
{**GOODS_AVAILABLE, "commodityName": "套装-狂战萌兔", "status": 0},
]
}
def query_limited_goods(self, **_):
self._maybe("goods")
return {
"limited_goods": [
GOODS_OWNED,
{**GOODS_AVAILABLE, "commodityName": "套装-狂战萌兔"},
{**GOODS_AVAILABLE, "commodityName": "套装-狂战萌兔", "status": 0},
]
}