246 lines
7.7 KiB
Python
246 lines
7.7 KiB
Python
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from adapter.matrix.store import (
|
|
STAGED_ATTACHMENTS_PREFIX,
|
|
add_staged_attachment,
|
|
clear_pending_confirm,
|
|
clear_staged_attachments,
|
|
get_pending_confirm,
|
|
get_platform_chat_id,
|
|
get_room_meta,
|
|
get_room_state,
|
|
get_skills_message_id,
|
|
get_staged_attachments,
|
|
get_user_meta,
|
|
next_chat_id,
|
|
next_platform_chat_id,
|
|
remove_staged_attachment_at,
|
|
set_pending_confirm,
|
|
set_platform_chat_id,
|
|
set_room_meta,
|
|
set_room_state,
|
|
set_skills_message_id,
|
|
set_user_meta,
|
|
)
|
|
from core.store import InMemoryStore
|
|
|
|
|
|
@pytest.fixture
|
|
def store() -> InMemoryStore:
|
|
return InMemoryStore()
|
|
|
|
|
|
async def test_room_meta_roundtrip(store: InMemoryStore):
|
|
meta = {
|
|
"room_type": "chat",
|
|
"chat_id": "C1",
|
|
"display_name": "Чат 1",
|
|
"matrix_user_id": "@alice:m.org",
|
|
}
|
|
await set_room_meta(store, "!r:m.org", meta)
|
|
assert await get_room_meta(store, "!r:m.org") == meta
|
|
|
|
|
|
async def test_room_meta_roundtrip_with_platform_chat_id(store: InMemoryStore):
|
|
meta = {
|
|
"chat_id": "C1",
|
|
"matrix_user_id": "@alice:example.org",
|
|
"platform_chat_id": "chat-platform-1",
|
|
}
|
|
await set_room_meta(store, "!r:m.org", meta)
|
|
saved = await get_room_meta(store, "!r:m.org")
|
|
assert saved is not None
|
|
assert saved["platform_chat_id"] == "chat-platform-1"
|
|
|
|
|
|
async def test_platform_chat_id_helpers_roundtrip(store: InMemoryStore):
|
|
meta = {
|
|
"chat_id": "C1",
|
|
"matrix_user_id": "@alice:example.org",
|
|
"display_name": "Research",
|
|
}
|
|
await set_room_meta(store, "!r:m.org", meta)
|
|
await set_platform_chat_id(store, "!r:m.org", "chat-platform-1")
|
|
|
|
assert await get_platform_chat_id(store, "!r:m.org") == "chat-platform-1"
|
|
assert await get_room_meta(store, "!r:m.org") == {
|
|
"chat_id": "C1",
|
|
"matrix_user_id": "@alice:example.org",
|
|
"display_name": "Research",
|
|
"platform_chat_id": "chat-platform-1",
|
|
}
|
|
|
|
|
|
async def test_room_meta_missing(store: InMemoryStore):
|
|
assert await get_room_meta(store, "!nonexistent:m.org") is None
|
|
|
|
|
|
async def test_user_meta_roundtrip(store: InMemoryStore):
|
|
meta = {
|
|
"platform_user_id": "usr-1",
|
|
"display_name": "Alice",
|
|
"space_id": None,
|
|
"settings_room_id": None,
|
|
"next_chat_index": 1,
|
|
}
|
|
await set_user_meta(store, "@alice:m.org", meta)
|
|
assert await get_user_meta(store, "@alice:m.org") == meta
|
|
|
|
|
|
async def test_room_state_roundtrip(store: InMemoryStore):
|
|
await set_room_state(store, "!r:m.org", "idle")
|
|
assert await get_room_state(store, "!r:m.org") == "idle"
|
|
await set_room_state(store, "!r:m.org", "waiting_response")
|
|
assert await get_room_state(store, "!r:m.org") == "waiting_response"
|
|
|
|
|
|
async def test_room_state_default_idle(store: InMemoryStore):
|
|
assert await get_room_state(store, "!unknown:m.org") == "idle"
|
|
|
|
|
|
async def test_next_chat_id_increments(store: InMemoryStore):
|
|
uid = "@alice:m.org"
|
|
await set_user_meta(store, uid, {"next_chat_index": 1})
|
|
assert await next_chat_id(store, uid) == "C1"
|
|
assert await next_chat_id(store, uid) == "C2"
|
|
assert await next_chat_id(store, uid) == "C3"
|
|
|
|
|
|
async def test_next_platform_chat_id_increments(store: InMemoryStore):
|
|
assert await next_platform_chat_id(store) == "1"
|
|
assert await next_platform_chat_id(store) == "2"
|
|
assert await next_platform_chat_id(store) == "3"
|
|
|
|
|
|
async def test_skills_message_roundtrip(store: InMemoryStore):
|
|
await set_skills_message_id(store, "!room", "$event")
|
|
assert await get_skills_message_id(store, "!room") == "$event"
|
|
|
|
|
|
async def test_pending_confirm_roundtrip(store: InMemoryStore):
|
|
assert await get_pending_confirm(store, "!room:m.org") is None
|
|
|
|
meta = {"action_id": "test", "description": "Do thing"}
|
|
await set_pending_confirm(store, "!room:m.org", meta)
|
|
assert await get_pending_confirm(store, "!room:m.org") == meta
|
|
|
|
await clear_pending_confirm(store, "!room:m.org")
|
|
assert await get_pending_confirm(store, "!room:m.org") is None
|
|
|
|
|
|
async def test_staged_attachments_roundtrip(store: InMemoryStore):
|
|
room_id = "!room:m.org"
|
|
user_id = "@alice:m.org"
|
|
|
|
assert await get_staged_attachments(store, room_id, user_id) == []
|
|
|
|
first = {"id": "att-1", "name": "screenshot.png"}
|
|
second = {"id": "att-2", "name": "invoice.pdf"}
|
|
|
|
await add_staged_attachment(store, room_id, user_id, first)
|
|
await add_staged_attachment(store, room_id, user_id, second)
|
|
|
|
assert await get_staged_attachments(store, room_id, user_id) == [
|
|
first,
|
|
second,
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"stored_value",
|
|
[
|
|
None,
|
|
"not-a-dict",
|
|
[],
|
|
123,
|
|
],
|
|
)
|
|
async def test_staged_attachments_invalid_container_state_returns_empty_list(
|
|
store: InMemoryStore,
|
|
stored_value,
|
|
):
|
|
room_id = "!room:m.org"
|
|
user_id = "@alice:m.org"
|
|
|
|
await store.set(f"{STAGED_ATTACHMENTS_PREFIX}{room_id}:{user_id}", stored_value)
|
|
|
|
assert await get_staged_attachments(store, room_id, user_id) == []
|
|
|
|
|
|
async def test_staged_attachments_filters_invalid_entries(store: InMemoryStore):
|
|
room_id = "!room:m.org"
|
|
user_id = "@alice:m.org"
|
|
valid_one = {"id": "att-1", "name": "alpha.png"}
|
|
valid_two = {"id": "att-2", "name": "beta.pdf"}
|
|
|
|
await store.set(
|
|
f"{STAGED_ATTACHMENTS_PREFIX}{room_id}:{user_id}",
|
|
{
|
|
"attachments": [
|
|
valid_one,
|
|
"bad-entry",
|
|
None,
|
|
{"id": "ignored"},
|
|
valid_two,
|
|
]
|
|
},
|
|
)
|
|
|
|
assert await get_staged_attachments(store, room_id, user_id) == [
|
|
valid_one,
|
|
{"id": "ignored"},
|
|
valid_two,
|
|
]
|
|
|
|
|
|
async def test_staged_attachments_are_scoped_by_room_and_user(store: InMemoryStore):
|
|
room_a = "!room-a:m.org"
|
|
room_b = "!room-b:m.org"
|
|
user_a = "@alice:m.org"
|
|
user_b = "@bob:m.org"
|
|
|
|
attachment_a = {"id": "att-a", "name": "alpha.png"}
|
|
attachment_b = {"id": "att-b", "name": "beta.png"}
|
|
attachment_c = {"id": "att-c", "name": "gamma.png"}
|
|
|
|
await add_staged_attachment(store, room_a, user_a, attachment_a)
|
|
await add_staged_attachment(store, room_a, user_b, attachment_b)
|
|
await add_staged_attachment(store, room_b, user_a, attachment_c)
|
|
|
|
assert await get_staged_attachments(store, room_a, user_a) == [attachment_a]
|
|
assert await get_staged_attachments(store, room_a, user_b) == [attachment_b]
|
|
assert await get_staged_attachments(store, room_b, user_a) == [attachment_c]
|
|
assert await get_staged_attachments(store, room_b, user_b) == []
|
|
|
|
|
|
async def test_remove_staged_attachment_at_by_zero_based_index(
|
|
store: InMemoryStore,
|
|
):
|
|
room_id = "!room:m.org"
|
|
user_id = "@alice:m.org"
|
|
first = {"id": "att-1", "name": "first.png"}
|
|
second = {"id": "att-2", "name": "second.png"}
|
|
third = {"id": "att-3", "name": "third.png"}
|
|
|
|
await add_staged_attachment(store, room_id, user_id, first)
|
|
await add_staged_attachment(store, room_id, user_id, second)
|
|
await add_staged_attachment(store, room_id, user_id, third)
|
|
|
|
assert await remove_staged_attachment_at(store, room_id, user_id, 1) == second
|
|
assert await get_staged_attachments(store, room_id, user_id) == [first, third]
|
|
assert await remove_staged_attachment_at(store, room_id, user_id, 99) is None
|
|
assert await remove_staged_attachment_at(store, room_id, user_id, -1) is None
|
|
|
|
|
|
async def test_clear_staged_attachments(store: InMemoryStore):
|
|
room_id = "!room:m.org"
|
|
user_id = "@alice:m.org"
|
|
|
|
await add_staged_attachment(store, room_id, user_id, {"id": "att-1"})
|
|
await add_staged_attachment(store, room_id, user_id, {"id": "att-2"})
|
|
|
|
await clear_staged_attachments(store, room_id, user_id)
|
|
|
|
assert await get_staged_attachments(store, room_id, user_id) == []
|