Files
FabledScribe/tests/test_briefing_pipeline.py
T

93 lines
3.9 KiB
Python

import pytest
from unittest.mock import AsyncMock, patch, MagicMock
@pytest.mark.asyncio
async def test_get_or_create_profile_note_returns_body():
"""get_profile_body() should return empty string when no profile note exists."""
with patch("fabledassistant.services.briefing_profile.list_notes", new_callable=AsyncMock) as mock_list:
mock_list.return_value = ([], 0)
from fabledassistant.services.briefing_profile import get_profile_body
body = await get_profile_body(user_id=1)
assert body == ""
def test_format_task_for_briefing():
"""format_task() should return a compact single-line string."""
from fabledassistant.services.briefing_pipeline import format_task
task = {"title": "Write design doc", "status": "in_progress", "due_date": "2026-03-12", "priority": "high"}
result = format_task(task)
assert "Write design doc" in result
assert "in_progress" in result or "In Progress" in result
def test_slot_greeting():
"""slot_greeting() should return different strings for different slot names."""
from fabledassistant.services.briefing_pipeline import slot_greeting
assert "morning" in slot_greeting("compilation").lower() or slot_greeting("compilation")
assert slot_greeting("morning") != slot_greeting("midday")
assert slot_greeting("midday") != slot_greeting("afternoon")
def test_compute_task_snapshot_hash():
"""compute_task_hash should return a stable SHA-256 hex string."""
from fabledassistant.services.briefing_pipeline import compute_task_hash
task = {"status": "todo", "priority": "high", "due_date": "2026-03-25", "title": "Write spec"}
h = compute_task_hash(task)
assert len(h) == 64 # SHA-256 hex
assert h == compute_task_hash(task)
assert h != compute_task_hash({**task, "status": "done"})
@pytest.mark.asyncio
async def test_split_changed_tasks_all_new():
"""split_changed_tasks should return all tasks as changed when no snapshot exists."""
from fabledassistant.services.briefing_pipeline import split_changed_tasks
tasks = [
{"task_id": 1, "title": "A", "status": "todo", "priority": "none", "due_date": None},
]
with patch(
"fabledassistant.services.briefing_pipeline.async_session"
) as mock_cls:
mock_session = AsyncMock()
mock_session.__aenter__ = AsyncMock(return_value=mock_session)
mock_session.__aexit__ = AsyncMock(return_value=False)
mock_session.execute = AsyncMock(return_value=MagicMock(
scalars=MagicMock(return_value=MagicMock(all=MagicMock(return_value=[])))
))
mock_cls.return_value = mock_session
changed, unchanged_count = await split_changed_tasks(user_id=1, tasks=tasks)
assert len(changed) == 1
assert unchanged_count == 0
@pytest.mark.asyncio
async def test_post_message_accepts_metadata():
"""post_message should accept an optional metadata dict and store it."""
from unittest.mock import AsyncMock, patch, MagicMock
mock_msg = MagicMock()
mock_msg.id = 1
with patch("fabledassistant.services.briefing_conversations.async_session") as mock_session_cls:
mock_session = AsyncMock()
mock_session.__aenter__ = AsyncMock(return_value=mock_session)
mock_session.__aexit__ = AsyncMock(return_value=False)
mock_session.add = MagicMock()
mock_session.get = AsyncMock(return_value=None)
mock_session.commit = AsyncMock()
mock_session.refresh = AsyncMock()
mock_session_cls.return_value = mock_session
from fabledassistant.services.briefing_conversations import post_message
metadata = {"weather": {"location": "Berlin"}, "rss_item_ids": [1, 2]}
await post_message(1, "assistant", "Hello", metadata=metadata)
# Verify Message was constructed with msg_metadata
call_args = mock_session.add.call_args[0][0]
assert call_args.msg_metadata == metadata