Lightweight containerized prosody tooling + moved auth scripts + xmpp reconnect/auth stabilization
This commit is contained in:
132
core/tests/test_event_projection_shadow.py
Normal file
132
core/tests/test_event_projection_shadow.py
Normal file
@@ -0,0 +1,132 @@
|
||||
from io import StringIO
|
||||
import time
|
||||
|
||||
from django.core.management import call_command
|
||||
from django.test import TestCase, override_settings
|
||||
|
||||
from core.events.ledger import append_event_sync
|
||||
from core.events.projection import shadow_compare_session
|
||||
from core.models import ChatSession, Message, Person, PersonIdentifier, User
|
||||
|
||||
|
||||
@override_settings(EVENT_LEDGER_DUAL_WRITE=True)
|
||||
class EventProjectionShadowTests(TestCase):
|
||||
def setUp(self):
|
||||
self.user = User.objects.create_user(
|
||||
username="projection-user",
|
||||
email="projection@example.com",
|
||||
password="x",
|
||||
)
|
||||
self.person = Person.objects.create(user=self.user, name="Projection Person")
|
||||
self.identifier = PersonIdentifier.objects.create(
|
||||
user=self.user,
|
||||
person=self.person,
|
||||
service="signal",
|
||||
identifier="+15555550333",
|
||||
)
|
||||
self.session = ChatSession.objects.create(user=self.user, identifier=self.identifier)
|
||||
|
||||
def test_shadow_compare_has_zero_mismatch_when_projection_matches(self):
|
||||
message = Message.objects.create(
|
||||
user=self.user,
|
||||
session=self.session,
|
||||
ts=1700000000000,
|
||||
sender_uuid="+15555550333",
|
||||
text="hello",
|
||||
delivered_ts=1700000000000,
|
||||
read_ts=1700000000500,
|
||||
receipt_payload={
|
||||
"reactions": [
|
||||
{
|
||||
"source_service": "signal",
|
||||
"actor": "user:1:signal",
|
||||
"emoji": "👍",
|
||||
"removed": False,
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
append_event_sync(
|
||||
user=self.user,
|
||||
session=self.session,
|
||||
ts=1700000000000,
|
||||
event_type="message_created",
|
||||
direction="in",
|
||||
origin_transport="signal",
|
||||
origin_message_id=str(message.id),
|
||||
payload={"message_id": str(message.id), "text": "hello"},
|
||||
)
|
||||
append_event_sync(
|
||||
user=self.user,
|
||||
session=self.session,
|
||||
ts=1700000000500,
|
||||
event_type="read_receipt",
|
||||
direction="system",
|
||||
origin_transport="signal",
|
||||
origin_message_id=str(message.id),
|
||||
payload={"message_id": str(message.id), "read_ts": 1700000000500},
|
||||
)
|
||||
append_event_sync(
|
||||
user=self.user,
|
||||
session=self.session,
|
||||
ts=1700000000600,
|
||||
event_type="reaction_added",
|
||||
direction="system",
|
||||
actor_identifier="user:1:signal",
|
||||
origin_transport="signal",
|
||||
origin_message_id=str(message.id),
|
||||
payload={
|
||||
"message_id": str(message.id),
|
||||
"emoji": "👍",
|
||||
"source_service": "signal",
|
||||
"actor": "user:1:signal",
|
||||
},
|
||||
)
|
||||
|
||||
compared = shadow_compare_session(self.session, detail_limit=10)
|
||||
self.assertEqual(0, compared["mismatch_total"])
|
||||
|
||||
def test_shadow_compare_detects_missing_projection_row(self):
|
||||
Message.objects.create(
|
||||
user=self.user,
|
||||
session=self.session,
|
||||
ts=1700000000000,
|
||||
sender_uuid="+15555550333",
|
||||
text="no-event",
|
||||
)
|
||||
compared = shadow_compare_session(self.session, detail_limit=10)
|
||||
self.assertGreater(compared["counters"]["missing_in_projection"], 0)
|
||||
|
||||
def test_management_command_emits_summary(self):
|
||||
out = StringIO()
|
||||
call_command(
|
||||
"event_projection_shadow",
|
||||
user_id=str(self.user.id),
|
||||
limit_sessions=5,
|
||||
stdout=out,
|
||||
)
|
||||
rendered = out.getvalue()
|
||||
self.assertIn("shadow compare:", rendered)
|
||||
self.assertIn("cause_counts=", rendered)
|
||||
|
||||
def test_management_command_supports_service_and_recent_filters(self):
|
||||
Message.objects.create(
|
||||
user=self.user,
|
||||
session=self.session,
|
||||
ts=int(time.time() * 1000),
|
||||
sender_uuid="+15550000000",
|
||||
text="recent",
|
||||
source_service="signal",
|
||||
source_message_id="recent-1",
|
||||
)
|
||||
out = StringIO()
|
||||
call_command(
|
||||
"event_projection_shadow",
|
||||
user_id=str(self.user.id),
|
||||
service="signal",
|
||||
recent_minutes=120,
|
||||
limit_sessions=5,
|
||||
stdout=out,
|
||||
)
|
||||
rendered = out.getvalue()
|
||||
self.assertIn("shadow compare:", rendered)
|
||||
Reference in New Issue
Block a user