bugfix reconciliation extractor
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
|
||||
from contas_mcp.servers.contas_mcp_server import main
|
||||
|
||||
|
||||
def _analysis():
|
||||
return {
|
||||
"currentInvoice": [
|
||||
{
|
||||
"type": "servicos_contratados_de_parceiros",
|
||||
"items": [
|
||||
{"desc": "Tamboro Mensal", "value": "14.99", "contestable": True, "classe": "avulso"},
|
||||
{"desc": "Tamboro Mensal", "value": "19.99", "contestable": True, "classe": "avulso"},
|
||||
{"desc": "Outro Produto", "value": "19.99", "contestable": True, "classe": "avulso"},
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def test_subject_catalog_does_not_choose_arbitrary_value_for_repeated_subject():
|
||||
catalog = main._invoice_subject_catalog({"billing_analysis": _analysis()})
|
||||
tamboro = next(x for x in catalog if x["name"] == "Tamboro Mensal")
|
||||
assert sorted(tamboro["values"]) == [14.99, 19.99]
|
||||
assert tamboro["value"] is None
|
||||
|
||||
|
||||
def test_preflight_does_not_resolve_value_from_subject_when_subject_has_multiple_values(monkeypatch):
|
||||
class DummyClient:
|
||||
def billing_analysis(self, _msisdn):
|
||||
return _analysis()
|
||||
|
||||
class DummyService:
|
||||
client = DummyClient()
|
||||
|
||||
monkeypatch.setattr(main, "service", DummyService())
|
||||
args = {
|
||||
"msisdn": "11999999999",
|
||||
"subject": "Tamboro Mensal",
|
||||
"query": "não reconheço esse Tamboro Mensal",
|
||||
"billing_analysis": _analysis(),
|
||||
"resolved_value": "25.5",
|
||||
}
|
||||
# The resolver may continue to normal validation, but it must not retain an
|
||||
# arbitrary/stale resolved_value just because the subject matched.
|
||||
main._preflight_subject("contestar_cobranca", args)
|
||||
assert args["subject"] == "Tamboro Mensal"
|
||||
assert args.get("resolved_value") is None
|
||||
|
||||
|
||||
def test_invalid_amount_is_candidate_not_resolved(monkeypatch):
|
||||
async def no_enrich(_name, _args):
|
||||
return None
|
||||
monkeypatch.setattr(main, "_enrich_invoice_context", no_enrich)
|
||||
monkeypatch.setattr(main, "_preflight_subject", lambda *_a, **_k: None)
|
||||
args = {
|
||||
"msisdn": "11999999999",
|
||||
"subject": "Tamboro Mensal",
|
||||
"valor": 25.5,
|
||||
"billing_analysis": _analysis(),
|
||||
"target_tool": "contestar_cobranca",
|
||||
}
|
||||
result = asyncio.run(main._validate_contestation(args))
|
||||
assert result["eligible"] is False
|
||||
assert result["status"] == "NEEDS_PARAMETER"
|
||||
assert result["parameter"] == "valor"
|
||||
assert result["candidate_value"] == 25.5
|
||||
assert result["resolved_value"] is None
|
||||
|
||||
|
||||
def test_valid_amount_is_resolved_only_after_subject_amount_validation(monkeypatch):
|
||||
async def no_enrich(_name, _args):
|
||||
return None
|
||||
monkeypatch.setattr(main, "_enrich_invoice_context", no_enrich)
|
||||
monkeypatch.setattr(main, "_preflight_subject", lambda *_a, **_k: None)
|
||||
args = {
|
||||
"msisdn": "11999999999",
|
||||
"subject": "Tamboro Mensal",
|
||||
"valor": 19.99,
|
||||
"billing_analysis": _analysis(),
|
||||
"target_tool": "contestar_cobranca",
|
||||
}
|
||||
result = asyncio.run(main._validate_contestation(args))
|
||||
assert result["eligible"] is True
|
||||
assert result["resolved_value"] == 19.99
|
||||
resolved = result["transaction_decision"]["resolved_arguments"]
|
||||
assert resolved["subject"] == "Tamboro Mensal"
|
||||
assert resolved["resolved_value"] == 19.99
|
||||
Reference in New Issue
Block a user