portfolio-optimiser/tests/test_run_smoke.py

40 lines
1.4 KiB
Python

"""Step 12 smoke — run_project composes the slice end-to-end on an injected FakeChatClient.
Returns a ValidatedProposal with a populated first-class ProvenanceStamp. Pattern:
tests/test_smoke.py.
"""
from spikes._harness import FakeChatClient
from portfolio_optimiser.provenance import ProvenanceStamp
from portfolio_optimiser.run import run_project
from portfolio_optimiser.validator import ValidatedProposal
_VALID = (
'{"project_id":"FV42-GSV-E1","measure":"Reduce scope",'
'"affected_items":[{"code":"05.2","quantity":4300,"unit_cost":215},'
'{"code":"03.1","quantity":1800,"unit_cost":310}],"claimed_saving_nok":200000}'
)
async def test_run_project_smoke(tmp_path) -> None:
docs = tmp_path / "docs"
docs.mkdir()
(docs / "cost.txt").write_text(
"Asphalt Ab11 unit rate renegotiation reduced the paving cost on the school stretch.",
encoding="utf-8",
)
def factory(role: str) -> FakeChatClient:
return FakeChatClient(default_reply=_VALID)
result = await run_project(
"FV42-GSV-E1",
"local",
docs_dir=str(docs),
verdict_input={"decision": "approved", "rationale": "feasible within range"},
client_factory=factory,
)
assert isinstance(result.outcome, ValidatedProposal)
assert isinstance(result.provenance, ProvenanceStamp)
assert len(result.provenance.citations) >= 1