Implement Manticore fully and re-theme

This commit is contained in:
2026-03-11 02:19:08 +00:00
parent da044be68c
commit cbedcd67f6
46 changed files with 3444 additions and 944 deletions

View File

@@ -2,21 +2,13 @@ from __future__ import annotations
from django.test import TestCase
from core.models import (
ContactAvailabilityEvent,
ContactAvailabilitySettings,
ContactAvailabilitySpan,
Person,
PersonIdentifier,
User,
)
from core.models import ContactAvailabilitySettings, Person, PersonIdentifier, User
from core.presence.engine import (
AvailabilitySignal,
ensure_fading_state,
record_inferred_signal,
record_native_signal,
)
from core.presence.inference import now_ms
class PresenceEngineTests(TestCase):
@@ -31,118 +23,45 @@ class PresenceEngineTests(TestCase):
service="signal",
identifier="+15550001111",
)
ContactAvailabilitySettings.objects.update_or_create(
user=self.user,
defaults={
"enabled": True,
"show_in_chat": True,
"show_in_groups": True,
"inference_enabled": True,
"retention_days": 90,
"fade_threshold_seconds": 1,
},
)
def test_read_receipt_signal_creates_available_event(self):
ts = now_ms()
event = record_native_signal(
AvailabilitySignal(
user=self.user,
person=self.person,
person_identifier=self.identifier,
service="signal",
source_kind="read_receipt",
availability_state="available",
confidence=0.95,
ts=ts,
payload={"origin": "test"},
)
)
self.assertIsNotNone(event)
self.assertEqual(
1, ContactAvailabilityEvent.objects.filter(user=self.user).count()
)
self.assertEqual("available", event.availability_state)
def test_inactivity_transitions_to_fading(self):
base_ts = now_ms()
record_inferred_signal(
AvailabilitySignal(
user=self.user,
person=self.person,
person_identifier=self.identifier,
service="signal",
source_kind="read_receipt",
availability_state="available",
confidence=0.95,
ts=base_ts,
)
)
fade_event = ensure_fading_state(
def test_record_native_signal_is_a_compatibility_noop(self):
signal = AvailabilitySignal(
user=self.user,
person=self.person,
person_identifier=self.identifier,
service="signal",
at_ts=base_ts + 10_000,
source_kind="read_receipt",
availability_state="available",
confidence=0.95,
ts=1234,
payload={"origin": "test"},
)
self.assertIsNotNone(fade_event)
self.assertEqual("fading", fade_event.availability_state)
result = record_native_signal(signal)
self.assertIs(result, signal)
def test_explicit_unavailable_blocks_fade_inference(self):
base_ts = now_ms()
record_native_signal(
AvailabilitySignal(
user=self.user,
person=self.person,
person_identifier=self.identifier,
service="xmpp",
source_kind="native_presence",
availability_state="unavailable",
confidence=1.0,
ts=base_ts,
)
def test_record_inferred_signal_respects_settings(self):
ContactAvailabilitySettings.objects.update_or_create(
user=self.user,
defaults={"enabled": True, "inference_enabled": False},
)
fade_event = ensure_fading_state(
signal = AvailabilitySignal(
user=self.user,
person=self.person,
person_identifier=self.identifier,
service="xmpp",
at_ts=base_ts + 60_000,
)
self.assertIsNone(fade_event)
self.assertEqual(
1, ContactAvailabilityEvent.objects.filter(user=self.user).count()
service="signal",
source_kind="typing_stop",
availability_state="fading",
ts=1234,
)
self.assertIsNone(record_inferred_signal(signal))
def test_adjacent_same_state_events_extend_single_span(self):
ts0 = now_ms()
record_native_signal(
AvailabilitySignal(
def test_ensure_fading_state_no_longer_persists_shadow_rows(self):
self.assertIsNone(
ensure_fading_state(
user=self.user,
person=self.person,
person_identifier=self.identifier,
service="signal",
source_kind="typing_start",
availability_state="available",
confidence=0.9,
ts=ts0,
at_ts=1234,
)
)
record_native_signal(
AvailabilitySignal(
user=self.user,
person=self.person,
person_identifier=self.identifier,
service="signal",
source_kind="message_in",
availability_state="available",
confidence=0.8,
ts=ts0 + 5_000,
)
)
spans = list(
ContactAvailabilitySpan.objects.filter(user=self.user).order_by("start_ts")
)
self.assertEqual(1, len(spans))
self.assertEqual(ts0, spans[0].start_ts)
self.assertEqual(ts0 + 5_000, spans[0].end_ts)