194 lines
6.8 KiB
Python
194 lines
6.8 KiB
Python
from __future__ import annotations
|
|
|
|
from types import SimpleNamespace
|
|
from unittest.mock import AsyncMock
|
|
|
|
from adapter.matrix.bot import send_outgoing
|
|
from adapter.matrix.converter import from_room_event
|
|
from adapter.matrix.handlers.confirm import make_handle_cancel, make_handle_confirm
|
|
from adapter.matrix.store import get_pending_confirm, set_room_meta
|
|
from core.auth import AuthManager
|
|
from core.chat import ChatManager
|
|
from core.protocol import Attachment, OutgoingMessage, OutgoingUI, UIButton
|
|
from core.settings import SettingsManager
|
|
from core.store import InMemoryStore
|
|
from sdk.mock import MockPlatformClient
|
|
|
|
|
|
async def test_mat06_outgoing_ui_renders_text_with_yes_no():
|
|
client = SimpleNamespace(room_send=AsyncMock())
|
|
store = InMemoryStore()
|
|
await set_room_meta(store, "!confirm:example.org", {"matrix_user_id": "@alice:example.org"})
|
|
event = OutgoingUI(
|
|
chat_id="C7",
|
|
text="Удалить файл?",
|
|
buttons=[UIButton(label="Подтвердить", action="confirm")],
|
|
)
|
|
|
|
await send_outgoing(client, "!confirm:example.org", event, store=store)
|
|
|
|
client.room_send.assert_awaited_once()
|
|
body = client.room_send.call_args.args[2]["body"]
|
|
assert "Удалить файл?" in body
|
|
assert "!yes" in body
|
|
assert "!no" in body
|
|
assert "Подтвердить" in body
|
|
|
|
|
|
async def test_mat07_outgoing_ui_no_reaction_sent():
|
|
client = SimpleNamespace(room_send=AsyncMock())
|
|
store = InMemoryStore()
|
|
await set_room_meta(store, "!confirm:example.org", {"matrix_user_id": "@alice:example.org"})
|
|
event = OutgoingUI(
|
|
chat_id="C7",
|
|
text="Confirm action?",
|
|
buttons=[UIButton(label="OK", action="confirm", payload={"id": 1})],
|
|
)
|
|
|
|
await send_outgoing(client, "!confirm:example.org", event, store=store)
|
|
|
|
assert client.room_send.await_count == 1
|
|
assert client.room_send.call_args.args[1] == "m.room.message"
|
|
for call in client.room_send.call_args_list:
|
|
assert call.args[1] != "m.reaction"
|
|
|
|
pending = await get_pending_confirm(store, "@alice:example.org", "!confirm:example.org")
|
|
assert pending == {
|
|
"action_id": "confirm",
|
|
"description": "Confirm action?",
|
|
"payload": {"id": 1},
|
|
}
|
|
|
|
|
|
async def test_outgoing_ui_yes_round_trip_uses_user_and_room_scope():
|
|
client = SimpleNamespace(room_send=AsyncMock())
|
|
store = InMemoryStore()
|
|
platform = MockPlatformClient()
|
|
chat_mgr = ChatManager(platform, store)
|
|
auth_mgr = AuthManager(platform, store)
|
|
settings_mgr = SettingsManager(platform, store)
|
|
await set_room_meta(store, "!confirm:example.org", {"matrix_user_id": "@alice:example.org"})
|
|
await set_room_meta(store, "!other:example.org", {"matrix_user_id": "@bob:example.org"})
|
|
|
|
await send_outgoing(
|
|
client,
|
|
"!confirm:example.org",
|
|
OutgoingUI(
|
|
chat_id="C7",
|
|
text="Archive room",
|
|
buttons=[UIButton(label="Confirm", action="archive", payload={"id": 7})],
|
|
),
|
|
store=store,
|
|
)
|
|
await send_outgoing(
|
|
client,
|
|
"!other:example.org",
|
|
OutgoingUI(
|
|
chat_id="C8",
|
|
text="Keep other room",
|
|
buttons=[UIButton(label="Confirm", action="archive", payload={"id": 8})],
|
|
),
|
|
store=store,
|
|
)
|
|
|
|
callback = from_room_event(
|
|
SimpleNamespace(
|
|
sender="@alice:example.org",
|
|
body="!yes",
|
|
event_id="$yes",
|
|
msgtype="m.text",
|
|
replyto_event_id=None,
|
|
),
|
|
room_id="!confirm:example.org",
|
|
chat_id="C7",
|
|
)
|
|
result = await make_handle_confirm(store)(callback, auth_mgr, platform, chat_mgr, settings_mgr)
|
|
|
|
assert "Archive room" in result[0].text
|
|
assert await get_pending_confirm(store, "@alice:example.org", "!confirm:example.org") is None
|
|
assert await get_pending_confirm(store, "@bob:example.org", "!other:example.org") is not None
|
|
|
|
|
|
async def test_outgoing_ui_no_round_trip_uses_user_and_room_scope():
|
|
client = SimpleNamespace(room_send=AsyncMock())
|
|
store = InMemoryStore()
|
|
platform = MockPlatformClient()
|
|
chat_mgr = ChatManager(platform, store)
|
|
auth_mgr = AuthManager(platform, store)
|
|
settings_mgr = SettingsManager(platform, store)
|
|
await set_room_meta(store, "!confirm:example.org", {"matrix_user_id": "@alice:example.org"})
|
|
await set_room_meta(store, "!other:example.org", {"matrix_user_id": "@bob:example.org"})
|
|
|
|
await send_outgoing(
|
|
client,
|
|
"!confirm:example.org",
|
|
OutgoingUI(
|
|
chat_id="C7",
|
|
text="Delete room",
|
|
buttons=[UIButton(label="Confirm", action="delete", payload={"id": 7})],
|
|
),
|
|
store=store,
|
|
)
|
|
await send_outgoing(
|
|
client,
|
|
"!other:example.org",
|
|
OutgoingUI(
|
|
chat_id="C8",
|
|
text="Keep other room",
|
|
buttons=[UIButton(label="Confirm", action="archive", payload={"id": 8})],
|
|
),
|
|
store=store,
|
|
)
|
|
|
|
callback = from_room_event(
|
|
SimpleNamespace(
|
|
sender="@alice:example.org",
|
|
body="!no",
|
|
event_id="$no",
|
|
msgtype="m.text",
|
|
replyto_event_id=None,
|
|
),
|
|
room_id="!confirm:example.org",
|
|
chat_id="C7",
|
|
)
|
|
result = await make_handle_cancel(store)(callback, auth_mgr, platform, chat_mgr, settings_mgr)
|
|
|
|
assert "отменено" in result[0].text.lower()
|
|
assert await get_pending_confirm(store, "@alice:example.org", "!confirm:example.org") is None
|
|
assert await get_pending_confirm(store, "@bob:example.org", "!other:example.org") is not None
|
|
|
|
|
|
async def test_send_outgoing_uploads_workspace_file_attachment(tmp_path, monkeypatch):
|
|
workspace_file = tmp_path / "surfaces" / "matrix" / "alice" / "room" / "inbox" / "result.txt"
|
|
workspace_file.parent.mkdir(parents=True, exist_ok=True)
|
|
workspace_file.write_text("ready")
|
|
monkeypatch.setenv("SURFACES_WORKSPACE_DIR", str(tmp_path))
|
|
|
|
client = SimpleNamespace(
|
|
upload=AsyncMock(return_value=(SimpleNamespace(content_uri="mxc://server/file"), {})),
|
|
room_send=AsyncMock(),
|
|
)
|
|
|
|
await send_outgoing(
|
|
client,
|
|
"!room:example.org",
|
|
OutgoingMessage(
|
|
chat_id="!room:example.org",
|
|
text="Файл готов",
|
|
attachments=[
|
|
Attachment(
|
|
type="document",
|
|
filename="result.txt",
|
|
mime_type="text/plain",
|
|
workspace_path="surfaces/matrix/alice/room/inbox/result.txt",
|
|
)
|
|
],
|
|
),
|
|
)
|
|
|
|
client.upload.assert_awaited_once()
|
|
client.room_send.assert_awaited()
|
|
assert client.room_send.await_args_list[0].args[2]["body"] == "Файл готов"
|
|
file_call = client.room_send.await_args_list[1]
|
|
assert file_call.args[2]["msgtype"] == "m.file"
|
|
assert file_call.args[2]["url"] == "mxc://server/file"
|