mike-backend / backend /python-service /tests /test_playbook_flows.py
bardd's picture
Deploy Mike backend-only Space
06671aa verified
Raw History Blame Contribute Delete
4.84 kB
from __future__ import annotations
import json
import sys
import unittest
from pathlib import Path
from unittest.mock import AsyncMock, patch
SERVICE_ROOT = Path(__file__).resolve().parents[1]
if str(SERVICE_ROOT) not in sys.path:
sys.path.insert(0, str(SERVICE_ROOT))
from tabular_agent import run_chat, run_review # noqa: E402
class PlaybookFlowTests(unittest.IsolatedAsyncioTestCase):
async def test_run_review_builds_canonical_payload_and_normalizes_findings(
self,
) -> None:
raw_review = json.dumps(
{
"workflow_id": "buyer",
"findings": [
{
"id": "finding_001",
"risk_level": "high",
"clause_type": "Payment",
"issue": "Payment period is too long.",
"comment": "Reduce the payment period.",
"target_text": "Payment is due in 90 days.",
"start_paragraph_id": "P_0001",
"end_paragraph_id": "P_0001",
"confidence": 0.9,
}
],
}
)
mocked_post = AsyncMock(
return_value=(
raw_review,
{"totalTokenCount": 42},
{"candidates": [{"content": {"parts": [{"text": raw_review}]}}]},
)
)
with patch("tabular_agent._post", mocked_post):
result, usage, _trace_id = await run_review(
review_text="[P_0001] Payment is due in 90 days.",
document_text="Payment is due in 90 days.",
document_name="contract.docx",
playbook_id="buyer",
playbook_name="Buyer Playbook",
playbook_text="Payment must be due within 30 days.",
max_findings=10,
)
self.assertEqual(result.workflow_id, "buyer")
self.assertEqual(len(result.findings), 1)
self.assertEqual(result.findings[0].issue, "Payment period is too long.")
self.assertEqual(result.model, "TabularAgent")
self.assertEqual(usage, {"totalTokenCount": 42})
call = mocked_post.await_args
self.assertEqual(call.kwargs["feature_id"], "python-review")
payload_text = call.args[0]["messages"][1]["content"]
self.assertIn("SYSTEM INSTRUCTIONS:", payload_text)
self.assertIn("USER INPUT:", payload_text)
self.assertIn("Buyer Playbook", payload_text)
self.assertIn("Payment must be due within 30 days.", payload_text)
self.assertIn("Payment is due in 90 days.", payload_text)
async def test_run_chat_builds_canonical_payload_and_renders_sources(
self,
) -> None:
source_url = "https://example.test/payment-terms"
raw_chat = json.dumps(
{
"answer_paragraphs": [
{
"text": "The clause exceeds the playbook position.",
"citation_urls": [source_url],
}
],
"sources": [
{
"title": "Payment Terms Guidance",
"url": source_url,
}
],
}
)
mocked_post = AsyncMock(
return_value=(
raw_chat,
{"totalTokenCount": 24},
{"candidates": [{"content": {"parts": [{"text": raw_chat}]}}]},
)
)
with patch("tabular_agent._post", mocked_post):
text, usage, _trace_id = await run_chat(
message="Does this payment clause comply?",
document_text="Payment is due in 90 days.",
document_name="contract.docx",
playbook_id="buyer",
playbook_name="Buyer Playbook",
role_brief="Protect the buyer.",
)
self.assertIn("The clause exceeds the playbook position.", text)
self.assertIn(
"[Payment Terms Guidance](https://example.test/payment-terms)",
text,
)
self.assertIn("Sources:", text)
self.assertEqual(usage, {"totalTokenCount": 24})
call = mocked_post.await_args
self.assertEqual(call.kwargs["feature_id"], "python-chat")
payload_text = call.args[0]["messages"][1]["content"]
self.assertIn("SYSTEM INSTRUCTIONS:", payload_text)
self.assertIn("USER INPUT:", payload_text)
self.assertIn("Protect the buyer.", payload_text)
self.assertIn("Does this payment clause comply?", payload_text)
self.assertIn("Payment is due in 90 days.", payload_text)
if __name__ == "__main__":
unittest.main()