from __future__ import annotations from datetime import datetime, timedelta import pytest from pydantic import ValidationError from yuxi.channels.models import ( FetchOptions, HistoricalMessage, SessionScope, ThreadContext, ThreadType, ) class TestThreadType: def test_native(self): assert ThreadType.NATIVE == "native" def test_topic(self): assert ThreadType.TOPIC == "topic" def test_simulated(self): assert ThreadType.SIMULATED == "simulated" def test_all_values_strings(self): for member in ThreadType: assert isinstance(member.value, str) class TestSessionScope: def test_direct(self): assert SessionScope.DIRECT == "dm" def test_group(self): assert SessionScope.GROUP == "group" def test_thread(self): assert SessionScope.THREAD == "thread" def test_all_values_strings(self): for member in SessionScope: assert isinstance(member.value, str) class TestThreadContext: def test_minimal(self): ctx = ThreadContext(thread_id="t1") assert ctx.thread_id == "t1" assert ctx.thread_type == ThreadType.DIRECT assert ctx.parent_id is None assert ctx.participants == [] assert ctx.metadata == {} def test_full(self): ctx = ThreadContext( thread_id="t2", thread_type=ThreadType.NATIVE, parent_id="p1", root_message_id="root_1", participants=["u1", "u2"], created_at=datetime.now(), metadata={"key": "val"}, ) assert ctx.thread_type == ThreadType.NATIVE assert len(ctx.participants) == 2 assert ctx.metadata["key"] == "val" def test_thread_id_required(self): with pytest.raises(ValidationError): ThreadContext() class TestHistoricalMessage: def test_minimal(self): msg = HistoricalMessage( message_id="m1", sender_id="s1", sender_name="Alice", content="hello", timestamp=datetime.now(), ) assert msg.message_id == "m1" assert msg.sender_name == "Alice" assert msg.is_from_bot is False assert msg.reply_to_id is None def test_bot_message(self): msg = HistoricalMessage( message_id="m2", sender_id="bot1", sender_name="Bot", content="hello", timestamp=datetime.now(), is_from_bot=True, ) assert msg.is_from_bot is True def test_with_reply(self): msg = HistoricalMessage( message_id="m3", sender_id="s3", sender_name="Bob", content="reply", timestamp=datetime.now(), reply_to_id="m2", ) assert msg.reply_to_id == "m2" def test_required_fields(self): with pytest.raises(ValidationError): HistoricalMessage(sender_id="s1", sender_name="Alice", content="hi", timestamp=datetime.now()) def test_sender_id_required(self): with pytest.raises(ValidationError): HistoricalMessage(message_id="m1", sender_name="Alice", content="hi", timestamp=datetime.now()) class TestFetchOptions: def test_defaults(self): opts = FetchOptions() assert opts.max_messages == 50 assert opts.max_chars == 4000 assert opts.include_bot_messages is True assert opts.before_message_id is None assert opts.after_message_id is None def test_custom(self): opts = FetchOptions( max_messages=10, max_chars=1000, include_bot_messages=False, before_message_id="mid_123", ) assert opts.max_messages == 10 assert opts.max_chars == 1000 assert opts.include_bot_messages is False assert opts.before_message_id == "mid_123"