test(approval): cover allow_session tiers in Matrix reaction seeding and gateway payload

Update the Matrix reaction-seeding contract to the four-reaction default
(once/session/always/deny), add tirith-tier (session without always) and
no-session-tier cases, and assert allow_session=True in the tirith
gateway payload.
This commit is contained in:
Teknium 2026-07-21 07:12:28 -07:00
parent 02d8cbadec
commit 9cc475cc58
2 changed files with 52 additions and 2 deletions

View file

@ -27,9 +27,56 @@ class TestMatrixExecApprovalReactions:
assert result.success is True
assert adapter._approval_prompt_by_session["sess-1"] == "$evt1"
assert adapter._approval_prompts_by_event["$evt1"].session_key == "sess-1"
assert adapter._send_reaction.await_count == 3
assert adapter._send_reaction.await_count == 4
emojis = [call.args[2] for call in adapter._send_reaction.await_args_list]
assert emojis == ["", "♾️", ""]
assert emojis == ["", "🌀", "♾️", ""]
@pytest.mark.asyncio
async def test_send_exec_approval_tirith_seeds_session_but_not_always(self, monkeypatch):
"""allow_permanent=False (tirith-only prompt) keeps the session tier
but drops the permanent reaction."""
monkeypatch.setenv("MATRIX_ALLOWED_USERS", "@liizfq:liizfq.top")
from plugins.platforms.matrix.adapter import MatrixAdapter
adapter = MatrixAdapter(PlatformConfig(enabled=True, token="tok", extra={"homeserver": "https://matrix.example.org"}))
adapter._client = types.SimpleNamespace()
adapter.send = AsyncMock(return_value=types.SimpleNamespace(success=True, message_id="$evt2"))
adapter._send_reaction = AsyncMock(return_value="$r")
result = await adapter.send_exec_approval(
chat_id="!room:example.org",
command="curl https://bit.ly/abc",
session_key="sess-2",
description="shortened URL",
allow_permanent=False,
)
assert result.success is True
emojis = [call.args[2] for call in adapter._send_reaction.await_args_list]
assert emojis == ["", "🌀", ""]
@pytest.mark.asyncio
async def test_send_exec_approval_no_session_seeds_once_deny_only(self, monkeypatch):
"""allow_session=False (Smart-DENY-style) collapses to once/deny."""
monkeypatch.setenv("MATRIX_ALLOWED_USERS", "@liizfq:liizfq.top")
from plugins.platforms.matrix.adapter import MatrixAdapter
adapter = MatrixAdapter(PlatformConfig(enabled=True, token="tok", extra={"homeserver": "https://matrix.example.org"}))
adapter._client = types.SimpleNamespace()
adapter.send = AsyncMock(return_value=types.SimpleNamespace(success=True, message_id="$evt3"))
adapter._send_reaction = AsyncMock(return_value="$r")
result = await adapter.send_exec_approval(
chat_id="!room:example.org",
command="rm -rf /tmp/x",
session_key="sess-3",
description="dangerous",
allow_session=False,
)
assert result.success is True
emojis = [call.args[2] for call in adapter._send_reaction.await_args_list]
assert emojis == ["", ""]
@pytest.mark.asyncio
async def test_reaction_resolves_pending_approval(self, monkeypatch):

View file

@ -440,6 +440,9 @@ class TestGatewayApprovalAllowPermanent:
renderer hides "Always allow"."""
payload = self._capture_gateway_payload("curl https://bit.ly/abc", "gw-no-perm")
assert payload["allow_permanent"] is False
# Session scope stays available — pure-tirith prompts are session-max,
# not once-max (salvaged from PR #67312).
assert payload["allow_session"] is True
@patch(_TIRITH_PATCH,
return_value=_tirith_result("warn",