feat: native matrix URI pills for {user}/{room} + major rendering & codebase refactor
This change introduces native `matrix:` URI-based rendering for `{user}` and `{room}` placeholders,
replacing previous plaintext and matrix.to-based links. Users and rooms are now rendered as clickable
pills in supporting clients, with a clean display using display names and room names (no @/# prefixes).
Reporting, moderation, and auto-redaction messages have been updated to use the same rendering logic.
Inspect and event links now also use native `matrix:` URIs for direct in-client navigation.
Internally, URI generation and rendering logic have been unified via central helper functions,
ensuring consistent handling of user IDs, room IDs, aliases, and event IDs.
This commit also includes a broader refactor of the codebase:
- decomposed complex flows (e.g. join handling) into smaller helpers
- moved mutable class-level state to instance-level
- reduced duplicate API calls and redundant logic
- improved overall structure and maintainability
Test coverage has been extended for URI helpers and rendering logic to prevent regressions.
No breaking changes to existing template parameters like `{user_link}` or `{room_link}`.
This commit is contained in:
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
@@ -0,0 +1,56 @@
|
||||
import html
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
from community.bot import CommunityBot, DEFAULT_ROOM_PILL_PREFIX, DEFAULT_USER_PILL_PREFIX
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def bot() -> CommunityBot:
|
||||
plugin = CommunityBot.__new__(CommunityBot)
|
||||
plugin.config = {}
|
||||
return plugin
|
||||
|
||||
|
||||
def test_user_uri_helper_strips_at_and_uses_chat_action(bot: CommunityBot) -> None:
|
||||
assert bot._matrix_user_uri("@alice:example.org") == "matrix:u/alice:example.org?action=chat"
|
||||
|
||||
|
||||
def test_room_uri_helper_prefers_alias(bot: CommunityBot) -> None:
|
||||
assert bot._matrix_room_uri("!roomid:example.org", "#general:example.org") == "matrix:r/general:example.org"
|
||||
|
||||
|
||||
def test_room_uri_helper_falls_back_to_room_id_without_bang(bot: CommunityBot) -> None:
|
||||
assert bot._matrix_room_uri("!roomid:example.org", None) == "matrix:roomid/roomid:example.org"
|
||||
|
||||
|
||||
def test_event_uri_helper_strips_prefixes(bot: CommunityBot) -> None:
|
||||
assert bot._matrix_event_uri("!roomid:example.org", "$eventid") == "matrix:roomid/roomid:example.org/e/eventid"
|
||||
|
||||
|
||||
def test_format_user_pill_uses_clean_default_prefix(bot: CommunityBot) -> None:
|
||||
plain, formatted = bot._format_user_pill("@alice:example.org", "Alice")
|
||||
assert plain == f"{DEFAULT_USER_PILL_PREFIX}Alice"
|
||||
assert 'href="matrix:u/alice:example.org?action=chat"' in formatted
|
||||
assert ">Alice<" in formatted
|
||||
|
||||
|
||||
def test_format_room_pill_uses_alias_when_available(bot: CommunityBot) -> None:
|
||||
plain, formatted = bot._format_room_pill("!roomid:example.org", "General", "#general:example.org")
|
||||
assert plain == f"{DEFAULT_ROOM_PILL_PREFIX}General"
|
||||
assert formatted == '<a href="matrix:r/general:example.org">General</a>'
|
||||
|
||||
|
||||
def test_format_room_pill_falls_back_to_room_id(bot: CommunityBot) -> None:
|
||||
plain, formatted = bot._format_room_pill("!roomid:example.org", "General", None)
|
||||
assert plain == f"{DEFAULT_ROOM_PILL_PREFIX}General"
|
||||
assert formatted == '<a href="matrix:roomid/roomid:example.org">General</a>'
|
||||
|
||||
|
||||
def test_format_user_pill_escapes_displayname(bot: CommunityBot) -> None:
|
||||
plain, formatted = bot._format_user_pill("@alice:example.org", '<Admin & Ops>')
|
||||
assert plain == f"{DEFAULT_USER_PILL_PREFIX}<Admin & Ops>"
|
||||
# Keep this broad enough to avoid coupling to quote style.
|
||||
assert "matrix:u/alice:example.org?action=chat" in formatted
|
||||
assert html.escape('<Admin & Ops>') in formatted
|
||||
Executable → Regular
@@ -0,0 +1,10 @@
|
||||
from community.bot import CommunityBot
|
||||
|
||||
|
||||
def test_matrix_uri_wrappers_delegate_to_canonical_helpers() -> None:
|
||||
bot = CommunityBot.__new__(CommunityBot)
|
||||
bot.config = {}
|
||||
assert bot._matrix_user_uri("@alice:example.org") == "matrix:u/alice:example.org?action=chat"
|
||||
assert bot._matrix_room_uri("!roomid:example.org") == "matrix:roomid/roomid:example.org"
|
||||
assert bot._matrix_room_uri("!roomid:example.org", "#general:example.org") == "matrix:r/general:example.org"
|
||||
assert bot._matrix_event_uri("!roomid:example.org", "$eventid") == "matrix:roomid/roomid:example.org/e/eventid"
|
||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
+50
-3
@@ -12,7 +12,11 @@ from community.bot import CommunityBot
|
||||
def bot():
|
||||
bot = CommunityBot.__new__(CommunityBot)
|
||||
bot.client = Mock()
|
||||
bot.config = {"matrix_to_base_url": "https://matrix.to"}
|
||||
bot.config = {
|
||||
"matrix_to_base_url": "https://matrix.to",
|
||||
"user_pill_prefix": "@",
|
||||
"room_pill_prefix": "#",
|
||||
}
|
||||
return bot
|
||||
|
||||
|
||||
@@ -51,7 +55,50 @@ def test_render_message_template_supports_user_id_and_user_link(bot):
|
||||
"General",
|
||||
)
|
||||
|
||||
assert plain == "Alice / @alice:example.org / https://matrix.to/#/@alice:example.org"
|
||||
assert "Alice / @alice:example.org / " in html
|
||||
assert plain == "@Alice / @alice:example.org / https://matrix.to/#/@alice:example.org"
|
||||
assert "@Alice / @alice:example.org / " in html
|
||||
assert '<a href=' in html
|
||||
assert '>Alice</a>' in html
|
||||
|
||||
|
||||
def test_render_message_template_uses_configurable_user_and_room_pill_prefixes(bot):
|
||||
bot.config["user_pill_prefix"] = ""
|
||||
bot.config["room_pill_prefix"] = ""
|
||||
|
||||
plain, html = bot._render_message_template(
|
||||
"{user} has joined {room}.",
|
||||
"@alice:example.org",
|
||||
"Alice",
|
||||
"!room:example.org",
|
||||
"General",
|
||||
)
|
||||
|
||||
assert plain == "Alice has joined General."
|
||||
assert "<a href='matrix:u/alice:example.org?action=chat'>Alice</a>" in html
|
||||
assert "<a href='matrix:roomid/room:example.org'>General</a>" in html
|
||||
|
||||
|
||||
def test_render_message_template_defaults_to_prefixed_user_and_room_pills(bot):
|
||||
plain, html = bot._render_message_template(
|
||||
"{user} has joined {room}.",
|
||||
"@alice:example.org",
|
||||
"Alice",
|
||||
"!room:example.org",
|
||||
"General",
|
||||
)
|
||||
|
||||
assert plain == "@Alice has joined #General."
|
||||
assert "<a href='matrix:u/alice:example.org?action=chat'>@Alice</a>" in html
|
||||
assert "<a href='matrix:roomid/room:example.org'>#General</a>" in html
|
||||
|
||||
|
||||
def test_matrix_uri_helpers_are_consistent():
|
||||
from community.bot import CommunityBot
|
||||
|
||||
bot = CommunityBot.__new__(CommunityBot)
|
||||
bot.config = {}
|
||||
|
||||
assert bot._matrix_user_uri("@alice:example.org") == "matrix:u/alice:example.org?action=chat"
|
||||
assert bot._matrix_room_uri("!roomid:example.org", "#general:example.org") == "matrix:r/general:example.org"
|
||||
assert bot._matrix_room_uri("!roomid:example.org", None) == "matrix:roomid/roomid:example.org"
|
||||
assert bot._matrix_event_uri("!roomid:example.org", "$eventid") == "matrix:roomid/roomid:example.org/e/eventid"
|
||||
|
||||
Executable → Regular
Reference in New Issue
Block a user