128 lines
4.0 KiB
Python
128 lines
4.0 KiB
Python
import os
|
|
|
|
import pytest
|
|
|
|
os.environ.setdefault("USE_MOCK_LLM", "true")
|
|
|
|
from agent_framework.guardrails.calibrated import apply_output_rails, compliance_anatel
|
|
from agent_framework.guardrails.calibrated._compat import RailResult
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Testes unitários diretos em compliance_anatel
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def test_fluxo_nao_ajuste_passa_sem_verificar():
|
|
"""Quando o fluxo não exige protocolo, o rail não deve bloquear."""
|
|
r = compliance_anatel("Sua fatura está disponível.", context={})
|
|
assert isinstance(r, RailResult)
|
|
assert r.allowed is True
|
|
assert r.code == "CMP"
|
|
assert r.mechanism == "regex"
|
|
|
|
|
|
def test_fluxo_ajuste_com_protocolo_passa():
|
|
r = compliance_anatel(
|
|
"O ajuste foi realizado. Protocolo: 123456.",
|
|
context={"tipo_fluxo": "ajuste"},
|
|
)
|
|
assert r.allowed is True
|
|
assert r.code == "CMP"
|
|
|
|
|
|
def test_fluxo_ajuste_sem_protocolo_bloqueia():
|
|
r = compliance_anatel(
|
|
"O ajuste foi realizado com sucesso.",
|
|
context={"tipo_fluxo": "ajuste"},
|
|
)
|
|
assert r.allowed is False
|
|
assert r.code == "CMP"
|
|
assert "protocolo" in r.reason.lower()
|
|
|
|
|
|
def test_requer_protocolo_true_com_protocolo_passa():
|
|
r = compliance_anatel(
|
|
"Cancelamento efetuado. Protocolo: 9876543.",
|
|
context={"requer_protocolo": True},
|
|
)
|
|
assert r.allowed is True
|
|
|
|
|
|
def test_requer_protocolo_true_sem_protocolo_bloqueia():
|
|
r = compliance_anatel(
|
|
"Cancelamento efetuado com sucesso.",
|
|
context={"requer_protocolo": True},
|
|
)
|
|
assert r.allowed is False
|
|
|
|
|
|
@pytest.mark.parametrize("text", [
|
|
"Protocolo: 123456",
|
|
"protocolo - 9876543",
|
|
"PROTOCOLO: 1000001",
|
|
"Seu protocolo é 200001.",
|
|
"O número de protocolo: 654321 foi registrado.",
|
|
])
|
|
def test_formatos_de_protocolo_aceitos(text):
|
|
r = compliance_anatel(text, context={"tipo_fluxo": "ajuste"})
|
|
assert r.allowed is True
|
|
|
|
|
|
@pytest.mark.parametrize("text", [
|
|
"O ajuste foi feito.",
|
|
"Tudo certo com sua solicitação.",
|
|
"Protocolo: 12345", # apenas 5 dígitos — insuficiente
|
|
"protocolo ABC123", # não começa com dígitos
|
|
])
|
|
def test_formatos_invalidos_ou_ausentes_bloqueiam(text):
|
|
r = compliance_anatel(text, context={"tipo_fluxo": "ajuste"})
|
|
assert r.allowed is False
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Testes de integração via apply_output_rails
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def test_pipeline_ajuste_sem_protocolo_nao_bloqueia_cmp():
|
|
d = apply_output_rails(
|
|
text="O ajuste foi realizado com sucesso.",
|
|
user_text="O ajuste foi realizado com sucesso.",
|
|
tool_calls=None,
|
|
context={"tipo_fluxo": "ajuste"},
|
|
)
|
|
assert d.allowed is True
|
|
assert d.code is None
|
|
assert all(r.code != "CMP" for r in d.results)
|
|
|
|
|
|
def test_pipeline_ajuste_com_protocolo_passa():
|
|
d = apply_output_rails(
|
|
text="Ajuste concluído. Protocolo: 123456.",
|
|
user_text="Ajuste concluído. Protocolo: 123456.",
|
|
tool_calls=None,
|
|
context={"tipo_fluxo": "ajuste"},
|
|
)
|
|
assert d.allowed is True
|
|
|
|
|
|
def test_pipeline_sem_context_nao_exige_protocolo():
|
|
"""Sem context, CMP não deve bloquear — fluxo não é de ajuste."""
|
|
d = apply_output_rails(
|
|
text="O ajuste foi realizado.",
|
|
user_text="O ajuste foi realizado.",
|
|
tool_calls=None,
|
|
)
|
|
assert d.allowed is True
|
|
assert all(r.code != "CMP" for r in d.results)
|
|
|
|
|
|
def test_pipeline_cmp_nao_entra_nos_results():
|
|
"""CMP roda no fallback determinístico do agente, fora do output rail."""
|
|
d = apply_output_rails(
|
|
text="Posso te ajudar com mais alguma coisa?",
|
|
user_text="Posso te ajudar com mais alguma coisa?",
|
|
tool_calls=None,
|
|
context={"tipo_fluxo": "consulta"},
|
|
)
|
|
assert all(r.code != "CMP" for r in d.results)
|