fix(onmyoji_gacha): 避免重复签到发放积分

This commit is contained in:
2026-06-20 19:00:41 +08:00
parent 8d26c46323
commit cbc0f5198a
3 changed files with 133 additions and 18 deletions

View File

@@ -41,6 +41,22 @@ DataManager = data_manager_module.DataManager
GachaSystem = gacha_module.GachaSystem
def load_sign_in_module():
"""直接加载签到编排模块,避免导入 NoneBot 插件入口。"""
plugin_dir = Path(__file__).resolve().parents[1] / "danding_bot" / "plugins" / "onmyoji_gacha"
module_name = "_onmyoji_gacha_sign_in_under_test"
spec = importlib.util.spec_from_file_location(module_name, plugin_dir / "sign_in.py")
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
assert spec and spec.loader
spec.loader.exec_module(module)
return module
sign_in_module = load_sign_in_module()
class FakeResponse:
"""模拟 aiohttp 响应上下文。"""
@@ -245,3 +261,60 @@ async def test_network_error_keeps_failure_shapes_and_no_sqlite(monkeypatch):
assert await manager.record_sign_in("10001", 20) is False
assert await manager.get_rank() == []
assert "sqlite3" not in inspect.getsource(data_manager_module)
@pytest.mark.asyncio
async def test_daily_sign_in_awards_points_only_after_sign_recorded():
calls = []
class FakeDataManager:
async def record_sign_in(self, user_id, points_awarded):
calls.append(("sign-in", user_id, points_awarded))
return True
class FakePointsAPI:
async def add_points(self, user_id, amount, source, reason):
calls.append(("add-points", user_id, amount, source, reason))
return True, 66
success, balance, status = await sign_in_module.award_daily_sign_in_points(
data_manager=FakeDataManager(),
points_api=FakePointsAPI(),
user_id="10001",
points=20,
source="gacha_sign",
reason="抽卡签到",
)
assert (success, balance, status) == (True, 66, "awarded")
assert calls == [
("sign-in", "10001", 20),
("add-points", "10001", 20, "gacha_sign", "抽卡签到"),
]
@pytest.mark.asyncio
async def test_daily_sign_in_repeat_does_not_award_points():
calls = []
class FakeDataManager:
async def record_sign_in(self, user_id, points_awarded):
calls.append(("sign-in", user_id, points_awarded))
return False
class FakePointsAPI:
async def add_points(self, user_id, amount, source, reason):
calls.append(("add-points", user_id, amount, source, reason))
return True, 66
success, balance, status = await sign_in_module.award_daily_sign_in_points(
data_manager=FakeDataManager(),
points_api=FakePointsAPI(),
user_id="10001",
points=20,
source="gacha_sign",
reason="抽卡签到",
)
assert (success, balance, status) == (False, 0, "signed_already_or_failed")
assert calls == [("sign-in", "10001", 20)]