surfaces/tests/adapter/matrix/test_chat_space.py

202 lines
6.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
from types import SimpleNamespace
from unittest.mock import AsyncMock
from nio.api import RoomVisibility
from nio.responses import RoomCreateError
from adapter.matrix.handlers.chat import (
make_handle_archive,
make_handle_new_chat,
make_handle_rename,
)
from adapter.matrix.store import get_room_meta, set_user_meta
from core.auth import AuthManager
from core.chat import ChatManager
from core.protocol import IncomingCommand, OutgoingMessage
from core.settings import SettingsManager
from core.store import InMemoryStore
from sdk.mock import MockPlatformClient
async def _setup():
platform = MockPlatformClient()
store = InMemoryStore()
chat_mgr = ChatManager(platform, store)
auth_mgr = AuthManager(platform, store)
settings_mgr = SettingsManager(platform, store)
await auth_mgr.confirm("@alice:example.org")
return platform, store, chat_mgr, auth_mgr, settings_mgr
async def test_mat04_new_chat_calls_room_put_state_with_space_id():
platform, store, chat_mgr, auth_mgr, settings_mgr = await _setup()
await set_user_meta(
store, "@alice:example.org", {"space_id": "!space:ex", "next_chat_index": 2}
)
client = SimpleNamespace(
room_create=AsyncMock(return_value=SimpleNamespace(room_id="!newroom:ex")),
room_put_state=AsyncMock(),
room_invite=AsyncMock(),
)
handler = make_handle_new_chat(client, store)
event = IncomingCommand(
user_id="@alice:example.org",
platform="matrix",
chat_id="C1",
command="new",
args=["Test"],
)
result = await handler(event, auth_mgr, platform, chat_mgr, settings_mgr)
client.room_create.assert_awaited_once_with(
name="Test",
visibility=RoomVisibility.private,
is_direct=False,
invite=["@alice:example.org"],
)
client.room_put_state.assert_awaited_once()
client.room_invite.assert_not_awaited()
kwargs = client.room_put_state.call_args.kwargs
assert kwargs.get("room_id") == "!space:ex"
assert kwargs.get("event_type") == "m.space.child"
assert kwargs.get("state_key") == "!newroom:ex"
room_meta = await get_room_meta(store, "!newroom:ex")
assert room_meta is not None
assert room_meta["platform_chat_id"] == "1"
assert any(isinstance(item, OutgoingMessage) and "Test" in item.text for item in result)
async def test_mat05_new_chat_without_space_id_returns_error():
platform, store, chat_mgr, auth_mgr, settings_mgr = await _setup()
await set_user_meta(store, "@alice:example.org", {"next_chat_index": 1})
client = SimpleNamespace(
room_create=AsyncMock(),
room_put_state=AsyncMock(),
room_invite=AsyncMock(),
)
handler = make_handle_new_chat(client, store)
event = IncomingCommand(
user_id="@alice:example.org",
platform="matrix",
chat_id="C1",
command="new",
)
result = await handler(event, auth_mgr, platform, chat_mgr, settings_mgr)
assert len(result) == 1
assert isinstance(result[0], OutgoingMessage)
assert "Space" in result[0].text or "ошибка" in result[0].text.lower()
client.room_create.assert_not_awaited()
async def test_mat10_archive_calls_chat_mgr_archive():
platform, store, chat_mgr, auth_mgr, settings_mgr = await _setup()
client = SimpleNamespace(room_leave=AsyncMock())
handler = make_handle_archive(client, store)
event = IncomingCommand(
user_id="@alice:example.org",
platform="matrix",
chat_id="C1",
command="archive",
)
await chat_mgr.get_or_create(
user_id="@alice:example.org",
chat_id="C1",
platform="matrix",
surface_ref="!room:ex",
name="Test",
)
result = await handler(event, auth_mgr, platform, chat_mgr, settings_mgr)
assert len(result) == 1
assert "архивирован" in result[0].text
client.room_leave.assert_awaited_once_with("!room:ex")
chats = await chat_mgr.list_active("@alice:example.org")
assert chats == []
async def test_mat11_rename_updates_matrix_room_name_via_state_event():
platform, store, chat_mgr, auth_mgr, settings_mgr = await _setup()
await chat_mgr.get_or_create(
user_id="@alice:example.org",
chat_id="C1",
platform="matrix",
surface_ref="!room:ex",
name="Old",
)
client = SimpleNamespace(room_put_state=AsyncMock())
handler = make_handle_rename(client, store)
event = IncomingCommand(
user_id="@alice:example.org",
platform="matrix",
chat_id="C1",
command="rename",
args=["New", "Name"],
)
result = await handler(event, auth_mgr, platform, chat_mgr, settings_mgr)
client.room_put_state.assert_awaited_once_with(
room_id="!room:ex",
event_type="m.room.name",
content={"name": "New Name"},
state_key="",
)
assert len(result) == 1
assert "Переименован" in result[0].text
async def test_mat11b_rename_from_unregistered_room_returns_error_message():
platform, store, chat_mgr, auth_mgr, settings_mgr = await _setup()
client = SimpleNamespace(room_put_state=AsyncMock())
handler = make_handle_rename(client, store)
event = IncomingCommand(
user_id="@alice:example.org",
platform="matrix",
chat_id="unregistered:!old:example.org",
command="rename",
args=["New"],
)
result = await handler(event, auth_mgr, platform, chat_mgr, settings_mgr)
client.room_put_state.assert_not_awaited()
assert len(result) == 1
assert "не найден" in result[0].text.lower() or "примите приглашение" in result[0].text.lower()
async def test_mat12_room_create_error_returns_user_message():
platform, store, chat_mgr, auth_mgr, settings_mgr = await _setup()
await set_user_meta(
store, "@alice:example.org", {"space_id": "!space:ex", "next_chat_index": 2}
)
client = SimpleNamespace(
room_create=AsyncMock(
return_value=RoomCreateError(message="rate limited", status_code="429")
),
room_put_state=AsyncMock(),
room_invite=AsyncMock(),
)
handler = make_handle_new_chat(client, store)
event = IncomingCommand(
user_id="@alice:example.org",
platform="matrix",
chat_id="C1",
command="new",
args=["Fail"],
)
result = await handler(event, auth_mgr, platform, chat_mgr, settings_mgr)
assert len(result) == 1
assert isinstance(result[0], OutgoingMessage)
assert "Не удалось" in result[0].text or "не удалось" in result[0].text
client.room_put_state.assert_not_awaited()