Files
dcc-rpg/tests/test_integration.py
truetype 6b048dc0cc
test / test (push) Has been cancelled
feat(engine): persistenza enigmi, inventario strutturato, HP mostri
Fase 2 del remediation plan:
- set_puzzle_state / is_puzzle_solved per enigmi area
- update_inventory su character_items con add/remove/equip/list
- combat() legge HP da combat_state e persiste danno
- dm_cycle inietta campaign_id nei tool che ne hanno bisogno
- helpers db: dedup inventario, remove/equip per nome

Fase 4 del remediation plan:
- test integrazione dm_cycle con LLM mockato (5 test)
- test WebSocket handler con mock (4 test)
- CI minimo .gitea/workflows/test.yml
2026-06-27 18:29:32 +02:00

96 lines
3.0 KiB
Python

"""Integration test: dm_cycle con LLM mockato."""
import json
import sys
sys.path.insert(0, "src")
from unittest.mock import patch
from src.engine import db, dm
MOCK_TOOL_RESP = json.dumps({
"tool": "roll_dice",
"params": {"die": "d20", "count": 1},
"narration": "Tendi l'orecchio nel buio...",
})
MOCK_COMBAT_RESP = json.dumps({
"tool": "combat",
"params": {
"character_id": 1,
"target_ac": 12,
"attack_bonus": 2,
"damage_die": "d8",
},
"narration": "Affronti il guardiano con la spada sguainata!",
})
def _setup_campaign():
conn = db.init_db()
camp_id = db.create_campaign("Test Integrazione", "Avventura")
char_id = db.create_character(camp_id, "Eroe", "guerriero", "soldato")
db.update_character(
char_id,
level=1, str=15, agi=11, sta=14,
per=9, int=8, lck=10,
hp_current=12, hp_max=12, ac=15,
armor_type="light",
)
db.seed_adventure_state(camp_id)
return camp_id, char_id
@patch("src.engine.dm.llm_ask", return_value=MOCK_TOOL_RESP)
def test_dm_cycle_returns_tool_params_narration(mock_ask):
camp_id, _ = _setup_campaign()
out = dm.dm_cycle(camp_id, "Provo a sentire rumori")
assert "tool" in out
assert "params" in out
assert "narration" in out
assert out["tool"] == "roll_dice"
assert out["params"]["die"] == "d20"
assert "Tendi l'orecchio" in out["narration"]
@patch("src.engine.dm.llm_ask", return_value=MOCK_TOOL_RESP)
def test_dm_cycle_advances_turn(mock_ask):
camp_id, _ = _setup_campaign()
turn_before = db.get_campaign(camp_id)["turn"]
out = dm.dm_cycle(camp_id, "Provo a sentire rumori")
assert out["turn"] == turn_before + 1
assert db.get_campaign(camp_id)["turn"] == turn_before + 1
@patch("src.engine.dm.llm_ask", return_value=MOCK_TOOL_RESP)
def test_dm_cycle_writes_log(mock_ask):
camp_id, _ = _setup_campaign()
out = dm.dm_cycle(camp_id, "Provo a sentire rumori")
log = db.get_log(camp_id, limit=1)
assert len(log) >= 1
assert log[0]["action"] == "Provo a sentire rumori"
assert "Tendi l'orecchio" in log[0]["result"]
@patch("src.engine.dm.llm_ask", return_value=MOCK_COMBAT_RESP)
def test_dm_cycle_combat_injects_campaign_id(mock_ask):
camp_id, char_id = _setup_campaign()
# Replace character_id placeholder in mock with real ID
resp = json.loads(MOCK_COMBAT_RESP)
resp["params"]["character_id"] = char_id
with patch("src.engine.dm.llm_ask", return_value=json.dumps(resp)):
out = dm.dm_cycle(camp_id, "Attacco il guardiano")
assert out["tool"] == "combat"
assert out["params"].get("campaign_id") == camp_id
@patch("src.engine.dm.llm_ask", return_value="{}")
def test_dm_cycle_fallback_on_empty_json(mock_ask):
camp_id, _ = _setup_campaign()
out = dm.dm_cycle(camp_id, "saluto il guardiano")
# Fallback heuristic: should produce dm_override narrate
assert out["tool"] in ("combat", "dm_override")
assert out["full_output"]