Fix Signal messages and replies
This commit is contained in:
225
core/tests/test_command_variant_policy.py
Normal file
225
core/tests/test_command_variant_policy.py
Normal file
@@ -0,0 +1,225 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from asgiref.sync import async_to_sync
|
||||
from django.test import TransactionTestCase
|
||||
|
||||
from core.commands.base import CommandContext
|
||||
from core.commands.handlers.bp import BPCommandHandler
|
||||
from core.commands.policies import ensure_variant_policies_for_profile
|
||||
from core.models import (
|
||||
BusinessPlanDocument,
|
||||
AI,
|
||||
ChatSession,
|
||||
CommandAction,
|
||||
CommandChannelBinding,
|
||||
CommandProfile,
|
||||
CommandVariantPolicy,
|
||||
Message,
|
||||
Person,
|
||||
PersonIdentifier,
|
||||
User,
|
||||
)
|
||||
|
||||
|
||||
class CommandVariantPolicyTests(TransactionTestCase):
|
||||
def setUp(self):
|
||||
self.user = User.objects.create_user(
|
||||
username="variant-user",
|
||||
email="variant@example.com",
|
||||
password="x",
|
||||
)
|
||||
self.person = Person.objects.create(user=self.user, name="Variant Person")
|
||||
self.identifier = PersonIdentifier.objects.create(
|
||||
user=self.user,
|
||||
person=self.person,
|
||||
service="whatsapp",
|
||||
identifier="120363402761690215",
|
||||
)
|
||||
self.session = ChatSession.objects.create(user=self.user, identifier=self.identifier)
|
||||
self.profile = CommandProfile.objects.create(
|
||||
user=self.user,
|
||||
slug="bp",
|
||||
name="Business Plan",
|
||||
enabled=True,
|
||||
trigger_token="#bp#",
|
||||
reply_required=True,
|
||||
exact_match_only=True,
|
||||
visibility_mode="status_in_source",
|
||||
template_text="TEMPLATE SHOULD NOT LEAK INTO bp set",
|
||||
)
|
||||
AI.objects.create(
|
||||
user=self.user,
|
||||
base_url="https://example.invalid",
|
||||
api_key="test-key",
|
||||
model="gpt-4o-mini",
|
||||
)
|
||||
CommandAction.objects.create(
|
||||
profile=self.profile,
|
||||
action_type="extract_bp",
|
||||
enabled=True,
|
||||
position=0,
|
||||
)
|
||||
CommandAction.objects.create(
|
||||
profile=self.profile,
|
||||
action_type="save_document",
|
||||
enabled=True,
|
||||
position=1,
|
||||
)
|
||||
CommandAction.objects.create(
|
||||
profile=self.profile,
|
||||
action_type="post_result",
|
||||
enabled=True,
|
||||
position=2,
|
||||
)
|
||||
CommandChannelBinding.objects.create(
|
||||
profile=self.profile,
|
||||
direction="ingress",
|
||||
service="whatsapp",
|
||||
channel_identifier="120363402761690215",
|
||||
enabled=True,
|
||||
)
|
||||
CommandChannelBinding.objects.create(
|
||||
profile=self.profile,
|
||||
direction="egress",
|
||||
service="whatsapp",
|
||||
channel_identifier="120363402761690215",
|
||||
enabled=True,
|
||||
)
|
||||
|
||||
def _ctx(self, trigger: Message, text: str) -> CommandContext:
|
||||
return CommandContext(
|
||||
service="whatsapp",
|
||||
channel_identifier="120363402761690215",
|
||||
message_id=str(trigger.id),
|
||||
user_id=self.user.id,
|
||||
message_text=text,
|
||||
payload={},
|
||||
)
|
||||
|
||||
def test_ensure_variant_policies_backfills_bp_defaults(self):
|
||||
rows = ensure_variant_policies_for_profile(self.profile)
|
||||
self.assertSetEqual(set(rows.keys()), {"bp", "bp_set", "bp_set_range"})
|
||||
self.assertEqual("ai", rows["bp"].generation_mode)
|
||||
self.assertEqual("verbatim", rows["bp_set"].generation_mode)
|
||||
self.assertEqual("verbatim", rows["bp_set_range"].generation_mode)
|
||||
self.assertTrue(rows["bp"].send_plan_to_egress)
|
||||
self.assertTrue(rows["bp"].send_status_to_source)
|
||||
|
||||
def test_bp_primary_can_run_in_verbatim_mode_without_ai(self):
|
||||
ensure_variant_policies_for_profile(self.profile)
|
||||
policy = CommandVariantPolicy.objects.get(profile=self.profile, variant_key="bp")
|
||||
policy.generation_mode = "verbatim"
|
||||
policy.send_plan_to_egress = False
|
||||
policy.send_status_to_source = False
|
||||
policy.send_status_to_egress = False
|
||||
policy.save()
|
||||
|
||||
anchor = Message.objects.create(
|
||||
user=self.user,
|
||||
session=self.session,
|
||||
sender_uuid="peer",
|
||||
text="anchor line",
|
||||
ts=1000,
|
||||
source_service="whatsapp",
|
||||
source_chat_id="120363402761690215",
|
||||
)
|
||||
trigger = Message.objects.create(
|
||||
user=self.user,
|
||||
session=self.session,
|
||||
sender_uuid="me",
|
||||
text="#bp#",
|
||||
ts=2000,
|
||||
source_service="whatsapp",
|
||||
source_chat_id="120363402761690215",
|
||||
reply_to=anchor,
|
||||
)
|
||||
|
||||
result = async_to_sync(BPCommandHandler().execute)(self._ctx(trigger, "#bp#"))
|
||||
self.assertTrue(result.ok)
|
||||
doc = BusinessPlanDocument.objects.get(trigger_message=trigger)
|
||||
self.assertEqual("anchor line\n#bp#", doc.content_markdown)
|
||||
|
||||
def test_bp_set_ai_mode_ignores_template(self):
|
||||
ensure_variant_policies_for_profile(self.profile)
|
||||
policy = CommandVariantPolicy.objects.get(profile=self.profile, variant_key="bp_set")
|
||||
policy.generation_mode = "ai"
|
||||
policy.send_plan_to_egress = False
|
||||
policy.send_status_to_source = False
|
||||
policy.send_status_to_egress = False
|
||||
policy.save()
|
||||
|
||||
trigger = Message.objects.create(
|
||||
user=self.user,
|
||||
session=self.session,
|
||||
sender_uuid="me",
|
||||
text="#bp set# text to transform",
|
||||
ts=1000,
|
||||
source_service="whatsapp",
|
||||
source_chat_id="120363402761690215",
|
||||
)
|
||||
|
||||
with patch(
|
||||
"core.commands.handlers.bp.ai_runner.run_prompt",
|
||||
new=AsyncMock(return_value="AI RESULT"),
|
||||
) as mocked:
|
||||
result = async_to_sync(BPCommandHandler().execute)(
|
||||
self._ctx(trigger, trigger.text)
|
||||
)
|
||||
|
||||
self.assertTrue(result.ok)
|
||||
doc = BusinessPlanDocument.objects.get(trigger_message=trigger)
|
||||
self.assertEqual("AI RESULT", doc.content_markdown)
|
||||
call_args = mocked.await_args.args
|
||||
prompt_payload = call_args[0]
|
||||
self.assertNotIn("TEMPLATE SHOULD NOT LEAK", str(prompt_payload))
|
||||
|
||||
def test_delivery_flags_control_source_and_egress_status(self):
|
||||
ensure_variant_policies_for_profile(self.profile)
|
||||
policy = CommandVariantPolicy.objects.get(
|
||||
profile=self.profile,
|
||||
variant_key="bp_set_range",
|
||||
)
|
||||
policy.generation_mode = "verbatim"
|
||||
policy.store_document = False
|
||||
policy.send_plan_to_egress = False
|
||||
policy.send_status_to_source = True
|
||||
policy.send_status_to_egress = True
|
||||
policy.save()
|
||||
|
||||
anchor = Message.objects.create(
|
||||
user=self.user,
|
||||
session=self.session,
|
||||
sender_uuid="peer",
|
||||
text="line one",
|
||||
ts=1000,
|
||||
source_service="whatsapp",
|
||||
source_chat_id="120363402761690215",
|
||||
)
|
||||
trigger = Message.objects.create(
|
||||
user=self.user,
|
||||
session=self.session,
|
||||
sender_uuid="me",
|
||||
text="#bp set range#",
|
||||
ts=2000,
|
||||
source_service="whatsapp",
|
||||
source_chat_id="120363402761690215",
|
||||
reply_to=anchor,
|
||||
)
|
||||
|
||||
with patch(
|
||||
"core.commands.handlers.bp.post_status_in_source",
|
||||
new=AsyncMock(return_value=True),
|
||||
) as source_status, patch(
|
||||
"core.commands.handlers.bp.post_to_channel_binding",
|
||||
new=AsyncMock(return_value=True),
|
||||
) as binding_send:
|
||||
result = async_to_sync(BPCommandHandler().execute)(
|
||||
self._ctx(trigger, trigger.text)
|
||||
)
|
||||
|
||||
self.assertTrue(result.ok)
|
||||
source_status.assert_awaited()
|
||||
self.assertEqual(1, binding_send.await_count)
|
||||
self.assertFalse(BusinessPlanDocument.objects.filter(trigger_message=trigger).exists())
|
||||
Reference in New Issue
Block a user