test(ariadne): cover comms guest naming edges
This commit is contained in:
parent
c0ac1e23a7
commit
c07570494a
@ -210,12 +210,7 @@ class _CommsGuestNameMixin:
|
|||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
return resp.json().get("displayname")
|
return resp.json().get("displayname")
|
||||||
|
|
||||||
def _set_displayname(
|
def _set_displayname(self, client: httpx.Client, token: str, target: DisplayNameTarget) -> None:
|
||||||
self,
|
|
||||||
client: httpx.Client,
|
|
||||||
token: str,
|
|
||||||
target: DisplayNameTarget,
|
|
||||||
) -> None:
|
|
||||||
resp = client.put(
|
resp = client.put(
|
||||||
f"{self._settings.comms_synapse_base}/_matrix/client/v3/profile/{urllib.parse.quote(target.user_id)}/displayname",
|
f"{self._settings.comms_synapse_base}/_matrix/client/v3/profile/{urllib.parse.quote(target.user_id)}/displayname",
|
||||||
headers=_auth(token),
|
headers=_auth(token),
|
||||||
@ -313,14 +308,7 @@ class _CommsGuestNameMixin:
|
|||||||
members, existing = self._room_members(client, token, room_id)
|
members, existing = self._room_members(client, token, room_id)
|
||||||
return room_id, members, existing
|
return room_id, members, existing
|
||||||
|
|
||||||
def _rename_mas_guests(
|
def _rename_mas_guests(self, client: httpx.Client, admin_token: str, room_id: str, members: set[str], existing: set[str]) -> MasGuestResult:
|
||||||
self,
|
|
||||||
client: httpx.Client,
|
|
||||||
admin_token: str,
|
|
||||||
room_id: str,
|
|
||||||
members: set[str],
|
|
||||||
existing: set[str],
|
|
||||||
) -> MasGuestResult:
|
|
||||||
renamed = 0
|
renamed = 0
|
||||||
skipped = 0
|
skipped = 0
|
||||||
mas_usernames: set[str] = set()
|
mas_usernames: set[str] = set()
|
||||||
@ -384,27 +372,14 @@ class _CommsGuestNameMixin:
|
|||||||
localpart = user_id.split(":", 1)[0].lstrip("@")
|
localpart = user_id.split(":", 1)[0].lstrip("@")
|
||||||
return SynapseUserRef(entry=entry, user_id=user_id, localpart=localpart)
|
return SynapseUserRef(entry=entry, user_id=user_id, localpart=localpart)
|
||||||
|
|
||||||
def _maybe_prune_synapse_guest(
|
def _maybe_prune_synapse_guest(self, client: httpx.Client, token: str, entry: dict[str, Any], user_id: str, now_ms: int) -> bool:
|
||||||
self,
|
|
||||||
client: httpx.Client,
|
|
||||||
token: str,
|
|
||||||
entry: dict[str, Any],
|
|
||||||
user_id: str,
|
|
||||||
now_ms: int,
|
|
||||||
) -> bool:
|
|
||||||
if not entry.get("is_guest"):
|
if not entry.get("is_guest"):
|
||||||
return False
|
return False
|
||||||
if not self._should_prune_guest(entry, now_ms):
|
if not self._should_prune_guest(entry, now_ms):
|
||||||
return False
|
return False
|
||||||
return self._prune_guest(client, token, user_id)
|
return self._prune_guest(client, token, user_id)
|
||||||
|
|
||||||
def _needs_synapse_rename(
|
def _needs_synapse_rename(self, client: httpx.Client, token: str, user: SynapseUserRef, mas_usernames: set[str]) -> bool:
|
||||||
self,
|
|
||||||
client: httpx.Client,
|
|
||||||
token: str,
|
|
||||||
user: SynapseUserRef,
|
|
||||||
mas_usernames: set[str],
|
|
||||||
) -> bool:
|
|
||||||
if user.localpart in mas_usernames:
|
if user.localpart in mas_usernames:
|
||||||
return False
|
return False
|
||||||
is_guest = user.entry.get("is_guest")
|
is_guest = user.entry.get("is_guest")
|
||||||
@ -421,13 +396,7 @@ class _CommsGuestNameMixin:
|
|||||||
return False
|
return False
|
||||||
return self._set_displayname_admin(client, token, user_id, new_name)
|
return self._set_displayname_admin(client, token, user_id, new_name)
|
||||||
|
|
||||||
def _rename_synapse_guests(
|
def _rename_synapse_guests(self, client: httpx.Client, token: str, existing: set[str], mas_usernames: set[str]) -> SynapseGuestResult:
|
||||||
self,
|
|
||||||
client: httpx.Client,
|
|
||||||
token: str,
|
|
||||||
existing: set[str],
|
|
||||||
mas_usernames: set[str],
|
|
||||||
) -> SynapseGuestResult:
|
|
||||||
renamed = 0
|
renamed = 0
|
||||||
pruned = 0
|
pruned = 0
|
||||||
entries = self._synapse_entries(client, token)
|
entries = self._synapse_entries(client, token)
|
||||||
|
|||||||
462
tests/unit/services/test_comms_guest_names_edges.py
Normal file
462
tests/unit/services/test_comms_guest_names_edges.py
Normal file
@ -0,0 +1,462 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import types
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from ariadne.services import comms as comms_module
|
||||||
|
from ariadne.services.comms import CommsService
|
||||||
|
from ariadne.services.comms_protocol import DisplayNameTarget, SynapseUserRef
|
||||||
|
|
||||||
|
|
||||||
|
class _Response:
|
||||||
|
def __init__(self, payload=None, status_code: int = 200, text: str = "") -> None:
|
||||||
|
self._payload = payload or {}
|
||||||
|
self.status_code = status_code
|
||||||
|
self.text = text
|
||||||
|
|
||||||
|
def json(self):
|
||||||
|
return self._payload
|
||||||
|
|
||||||
|
def raise_for_status(self) -> None:
|
||||||
|
if self.status_code >= 400:
|
||||||
|
raise RuntimeError(f"status {self.status_code}")
|
||||||
|
|
||||||
|
|
||||||
|
class _Client:
|
||||||
|
def __init__(self, responses=None, *, fail_delete: bool = False, fail_post: bool = False) -> None:
|
||||||
|
self.responses = responses or {}
|
||||||
|
self.calls = []
|
||||||
|
self.fail_delete = fail_delete
|
||||||
|
self.fail_post = fail_post
|
||||||
|
|
||||||
|
def _next(self, method: str, url: str, **kwargs):
|
||||||
|
self.calls.append((method, url, kwargs))
|
||||||
|
value = self.responses.get((method, url), _Response())
|
||||||
|
if isinstance(value, list):
|
||||||
|
return value.pop(0) if value else _Response()
|
||||||
|
return value
|
||||||
|
|
||||||
|
def get(self, url: str, **kwargs):
|
||||||
|
return self._next("GET", url, **kwargs)
|
||||||
|
|
||||||
|
def post(self, url: str, **kwargs):
|
||||||
|
if self.fail_post:
|
||||||
|
raise RuntimeError("post failed")
|
||||||
|
return self._next("POST", url, **kwargs)
|
||||||
|
|
||||||
|
def put(self, url: str, **kwargs):
|
||||||
|
return self._next("PUT", url, **kwargs)
|
||||||
|
|
||||||
|
def delete(self, url: str, **kwargs):
|
||||||
|
if self.fail_delete:
|
||||||
|
raise RuntimeError("delete failed")
|
||||||
|
return self._next("DELETE", url, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def _settings(**overrides):
|
||||||
|
defaults = {
|
||||||
|
"comms_mas_admin_client_id": "client",
|
||||||
|
"comms_mas_admin_client_secret": "secret",
|
||||||
|
"comms_mas_token_url": "http://mas/token",
|
||||||
|
"comms_mas_admin_api_base": "http://mas/api/admin/v1",
|
||||||
|
"comms_synapse_base": "http://synapse",
|
||||||
|
"comms_synapse_admin_token": "admintoken",
|
||||||
|
"comms_synapse_db_password": "pw",
|
||||||
|
"comms_room_alias": "#othrys:live.bstein.dev",
|
||||||
|
"comms_server_name": "live.bstein.dev",
|
||||||
|
"comms_seeder_user": "othrys-seeder",
|
||||||
|
"comms_timeout_sec": 5.0,
|
||||||
|
"comms_guest_stale_days": 1,
|
||||||
|
}
|
||||||
|
defaults.update(overrides)
|
||||||
|
return types.SimpleNamespace(**defaults)
|
||||||
|
|
||||||
|
|
||||||
|
def _service(monkeypatch, **overrides) -> CommsService:
|
||||||
|
monkeypatch.setattr(comms_module, "settings", _settings(**overrides))
|
||||||
|
return CommsService()
|
||||||
|
|
||||||
|
|
||||||
|
def test_mas_admin_token_retries_and_validates(monkeypatch) -> None:
|
||||||
|
svc = _service(monkeypatch, comms_mas_admin_client_id="")
|
||||||
|
with pytest.raises(RuntimeError, match="credentials missing"):
|
||||||
|
svc._mas_admin_token(_Client())
|
||||||
|
|
||||||
|
svc = _service(monkeypatch)
|
||||||
|
sleeps = []
|
||||||
|
monkeypatch.setattr(svc, "_sleep", sleeps.append)
|
||||||
|
client = _Client(
|
||||||
|
{
|
||||||
|
("POST", "http://mas/token"): [
|
||||||
|
_Response({}),
|
||||||
|
_Response({"access_token": "admintoken"}),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert svc._mas_admin_token(client) == "admintoken"
|
||||||
|
assert sleeps == [1]
|
||||||
|
assert client.calls[0][2]["headers"]["Authorization"].startswith("Basic ")
|
||||||
|
|
||||||
|
|
||||||
|
def test_mas_admin_token_exhaustion_reports_last_error(monkeypatch) -> None:
|
||||||
|
svc = _service(monkeypatch)
|
||||||
|
sleeps = []
|
||||||
|
monkeypatch.setattr(svc, "_sleep", sleeps.append)
|
||||||
|
client = _Client({("POST", "http://mas/token"): _Response({})})
|
||||||
|
|
||||||
|
with pytest.raises(RuntimeError, match="missing mas access token"):
|
||||||
|
svc._mas_admin_token(client)
|
||||||
|
|
||||||
|
assert sleeps == [1, 2, 4, 8, 16]
|
||||||
|
|
||||||
|
|
||||||
|
def test_personal_session_and_revoke_failure_paths(monkeypatch) -> None:
|
||||||
|
svc = _service(monkeypatch)
|
||||||
|
invalid = _Client(
|
||||||
|
{
|
||||||
|
("POST", "http://mas/api/admin/v1/personal-sessions"): _Response(
|
||||||
|
{"data": {"id": "session-without-token"}}
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
with pytest.raises(RuntimeError, match="invalid personal session"):
|
||||||
|
svc._mas_personal_session(invalid, "admintoken", "user-1")
|
||||||
|
|
||||||
|
svc._mas_revoke_session(_Client(fail_post=True), "admintoken", "session-1")
|
||||||
|
|
||||||
|
|
||||||
|
def test_guest_listing_and_room_context_helpers(monkeypatch) -> None:
|
||||||
|
svc = _service(monkeypatch)
|
||||||
|
client = _Client(
|
||||||
|
{
|
||||||
|
("GET", "http://synapse/_matrix/client/v3/rooms/room%201/members"): _Response(
|
||||||
|
{
|
||||||
|
"chunk": [
|
||||||
|
{"state_key": "@one:live.bstein.dev", "content": {"displayname": "One"}},
|
||||||
|
{"state_key": "", "content": {"displayname": ""}},
|
||||||
|
{"content": {"displayname": "Two"}},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
),
|
||||||
|
("GET", "http://mas/api/admin/v1/users?page[size]=100"): _Response(
|
||||||
|
{
|
||||||
|
"data": [
|
||||||
|
"ignored",
|
||||||
|
{"id": "one", "meta": {"page": {"cursor": "cursor 1"}}},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
),
|
||||||
|
("GET", "http://mas/api/admin/v1/users?page[size]=100&page[after]=cursor%201"): _Response(
|
||||||
|
{"data": [{"id": "two"}]}
|
||||||
|
),
|
||||||
|
("GET", "http://synapse/_synapse/admin/v2/users?local=true&deactivated=false&limit=100"): _Response(
|
||||||
|
{"users": [{"name": "@one:live.bstein.dev"}, "ignored"], "next_token": "next 1"}
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"GET",
|
||||||
|
"http://synapse/_synapse/admin/v2/users?local=true&deactivated=false&limit=100&from=next%201",
|
||||||
|
): _Response({"users": [{"name": "@two:live.bstein.dev"}]}),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
members, existing = svc._room_members(client, "token", "room 1")
|
||||||
|
assert members == {"@one:live.bstein.dev"}
|
||||||
|
assert existing == {"One", "Two"}
|
||||||
|
assert [item["id"] for item in svc._mas_list_users(client, "admintoken")] == ["one", "two"]
|
||||||
|
assert [item["name"] for item in svc._synapse_list_users(client, "fallback")] == [
|
||||||
|
"@one:live.bstein.dev",
|
||||||
|
"@two:live.bstein.dev",
|
||||||
|
]
|
||||||
|
|
||||||
|
invalid_page = _Client({("GET", "http://mas/api/admin/v1/users?page[size]=100"): _Response({"data": "bad"})})
|
||||||
|
assert svc._mas_list_users(invalid_page, "admintoken") == []
|
||||||
|
non_dict_cursor = _Client(
|
||||||
|
{("GET", "http://mas/api/admin/v1/users?page[size]=100"): _Response({"data": [{"id": "one"}, "bad"]})}
|
||||||
|
)
|
||||||
|
assert [item["id"] for item in svc._mas_list_users(non_dict_cursor, "admintoken")] == ["one"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_prune_and_displayname_helpers(monkeypatch) -> None:
|
||||||
|
svc = _service(monkeypatch)
|
||||||
|
now_ms = 2 * 24 * 60 * 60 * 1000
|
||||||
|
|
||||||
|
assert not svc._should_prune_guest({"is_guest": False, "last_seen_ts": 0}, now_ms)
|
||||||
|
assert not svc._should_prune_guest({"is_guest": True}, now_ms)
|
||||||
|
assert not svc._should_prune_guest({"is_guest": True, "last_seen_ts": "bad"}, now_ms)
|
||||||
|
assert svc._should_prune_guest({"is_guest": True, "last_seen_ts": 0}, now_ms)
|
||||||
|
|
||||||
|
assert not svc._prune_guest(_Client(fail_delete=True), "token", "@old:live.bstein.dev")
|
||||||
|
bad_delete = _Client(
|
||||||
|
{
|
||||||
|
("DELETE", "http://synapse/_synapse/admin/v2/users/%40old%3Alive.bstein.dev"): _Response(
|
||||||
|
status_code=500,
|
||||||
|
text="boom",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert not svc._prune_guest(bad_delete, "token", "@old:live.bstein.dev")
|
||||||
|
|
||||||
|
admin_404 = _Client(
|
||||||
|
{
|
||||||
|
("GET", "http://synapse/_synapse/admin/v2/users/%40missing%3Alive.bstein.dev"): _Response(
|
||||||
|
status_code=404
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert svc._get_displayname_admin(admin_404, "token", "@missing:live.bstein.dev") is None
|
||||||
|
admin_ok = _Client(
|
||||||
|
{
|
||||||
|
("GET", "http://synapse/_synapse/admin/v2/users/%40guest%3Alive.bstein.dev"): _Response(
|
||||||
|
{"displayname": "Guest"}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert svc._get_displayname_admin(admin_ok, "token", "@guest:live.bstein.dev") == "Guest"
|
||||||
|
|
||||||
|
client = _Client()
|
||||||
|
svc._set_displayname(
|
||||||
|
client,
|
||||||
|
"token",
|
||||||
|
DisplayNameTarget(
|
||||||
|
room_id="room 1",
|
||||||
|
user_id="@guest:live.bstein.dev",
|
||||||
|
name="Atlas Guest",
|
||||||
|
in_room=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
assert [call[0] for call in client.calls] == ["PUT", "PUT"]
|
||||||
|
|
||||||
|
ok_admin = _Client(
|
||||||
|
{
|
||||||
|
("PUT", "http://synapse/_synapse/admin/v2/users/%40guest%3Alive.bstein.dev"): _Response(
|
||||||
|
status_code=201
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert svc._set_displayname_admin(ok_admin, "token", "@guest:live.bstein.dev", "Guest")
|
||||||
|
fail_admin = _Client(
|
||||||
|
{
|
||||||
|
("PUT", "http://synapse/_synapse/admin/v2/users/%40guest%3Alive.bstein.dev"): _Response(
|
||||||
|
status_code=500
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert not svc._set_displayname_admin(fail_admin, "token", "@guest:live.bstein.dev", "Guest")
|
||||||
|
|
||||||
|
|
||||||
|
def test_db_rename_numeric_empty_and_skip_paths(monkeypatch) -> None:
|
||||||
|
assert _service(monkeypatch, comms_synapse_db_password="")._db_rename_numeric(set()) == 0
|
||||||
|
|
||||||
|
svc = _service(monkeypatch)
|
||||||
|
queries = []
|
||||||
|
monkeypatch.setattr(svc, "_pick_guest_name", lambda _existing: None)
|
||||||
|
|
||||||
|
class Cursor:
|
||||||
|
def execute(self, query, params=None):
|
||||||
|
queries.append(query)
|
||||||
|
|
||||||
|
def fetchall(self):
|
||||||
|
if len(queries) == 1:
|
||||||
|
return [("1", "@123:live.bstein.dev", "guest-1")]
|
||||||
|
if len(queries) == 2:
|
||||||
|
return []
|
||||||
|
return []
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc, tb):
|
||||||
|
return False
|
||||||
|
|
||||||
|
class Conn:
|
||||||
|
closed = False
|
||||||
|
|
||||||
|
def cursor(self):
|
||||||
|
return Cursor()
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.closed = True
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc, tb):
|
||||||
|
return False
|
||||||
|
|
||||||
|
conn = Conn()
|
||||||
|
monkeypatch.setattr(svc, "_connect_synapse_db", lambda: conn)
|
||||||
|
|
||||||
|
assert svc._db_rename_numeric(set()) == 0
|
||||||
|
assert conn.closed
|
||||||
|
|
||||||
|
|
||||||
|
def test_db_rename_numeric_inserts_missing_profiles(monkeypatch) -> None:
|
||||||
|
svc = _service(monkeypatch)
|
||||||
|
executed = []
|
||||||
|
picks = iter([None, "Rhea"])
|
||||||
|
monkeypatch.setattr(svc, "_pick_guest_name", lambda _existing: next(picks))
|
||||||
|
|
||||||
|
class Cursor:
|
||||||
|
def execute(self, query, params=None):
|
||||||
|
executed.append((query, params))
|
||||||
|
|
||||||
|
def fetchall(self):
|
||||||
|
if len(executed) == 1:
|
||||||
|
return []
|
||||||
|
if len(executed) == 2:
|
||||||
|
return [
|
||||||
|
("@123:live.bstein.dev",),
|
||||||
|
("@456:live.bstein.dev",),
|
||||||
|
("@789:live.bstein.dev",),
|
||||||
|
]
|
||||||
|
if len(executed) == 3:
|
||||||
|
return [("123", "@123:live.bstein.dev")]
|
||||||
|
return []
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc, tb):
|
||||||
|
return False
|
||||||
|
|
||||||
|
class Conn:
|
||||||
|
def cursor(self):
|
||||||
|
return Cursor()
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc, tb):
|
||||||
|
return False
|
||||||
|
|
||||||
|
monkeypatch.setattr(svc, "_connect_synapse_db", Conn)
|
||||||
|
|
||||||
|
assert svc._db_rename_numeric(set()) == 1
|
||||||
|
assert any("INSERT INTO profiles" in query for query, _params in executed)
|
||||||
|
|
||||||
|
|
||||||
|
def test_guest_name_setting_validation(monkeypatch) -> None:
|
||||||
|
with pytest.raises(RuntimeError, match="mas admin secret"):
|
||||||
|
_service(monkeypatch, comms_mas_admin_client_secret="")._validate_guest_name_settings()
|
||||||
|
with pytest.raises(RuntimeError, match="synapse base"):
|
||||||
|
_service(monkeypatch, comms_synapse_base="")._validate_guest_name_settings()
|
||||||
|
|
||||||
|
|
||||||
|
def test_rename_mas_guests_exercises_skip_and_success_paths(monkeypatch) -> None:
|
||||||
|
svc = _service(monkeypatch)
|
||||||
|
users = [
|
||||||
|
{"id": "ignored", "attributes": {}},
|
||||||
|
{"id": "human", "attributes": {"username": "alice"}},
|
||||||
|
{"attributes": {"username": "guest-no-id"}},
|
||||||
|
{"id": "named", "attributes": {"username": "guest-named"}},
|
||||||
|
{"id": "no-name", "attributes": {"username": "guest-empty"}},
|
||||||
|
{"id": "rename", "attributes": {"username": "guest-rename", "legacy_guest": True}},
|
||||||
|
]
|
||||||
|
monkeypatch.setattr(svc, "_mas_list_users", lambda *_args: users)
|
||||||
|
monkeypatch.setattr(svc, "_mas_personal_session", lambda _client, _token, user_id: (f"token-{user_id}", f"sess-{user_id}"))
|
||||||
|
displays = {
|
||||||
|
"@guest-named:live.bstein.dev": "Already Human",
|
||||||
|
"@guest-empty:live.bstein.dev": None,
|
||||||
|
"@guest-rename:live.bstein.dev": None,
|
||||||
|
}
|
||||||
|
monkeypatch.setattr(svc, "_get_displayname", lambda _client, _token, user_id: displays[user_id])
|
||||||
|
picked = iter([None, "Rhea"])
|
||||||
|
monkeypatch.setattr(svc, "_pick_guest_name", lambda _existing: next(picked))
|
||||||
|
set_targets = []
|
||||||
|
revoked = []
|
||||||
|
monkeypatch.setattr(svc, "_set_displayname", lambda _client, _token, target: set_targets.append(target))
|
||||||
|
monkeypatch.setattr(svc, "_mas_revoke_session", lambda _client, _token, session_id: revoked.append(session_id))
|
||||||
|
|
||||||
|
result = svc._rename_mas_guests(_Client(), "admintoken", "room", {"@guest-rename:live.bstein.dev"}, set())
|
||||||
|
|
||||||
|
assert result.renamed == 1
|
||||||
|
assert result.skipped == 5
|
||||||
|
assert "guest-rename" in result.usernames
|
||||||
|
assert set_targets[0].in_room
|
||||||
|
assert revoked == ["sess-named", "sess-no-name", "sess-rename"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_synapse_rename_helpers_cover_prune_and_skip_paths(monkeypatch) -> None:
|
||||||
|
svc = _service(monkeypatch)
|
||||||
|
monkeypatch.setattr(svc, "_synapse_list_users", lambda *_args: (_ for _ in ()).throw(RuntimeError("boom")))
|
||||||
|
assert svc._synapse_entries(_Client(), "token") == []
|
||||||
|
monkeypatch.undo()
|
||||||
|
svc = _service(monkeypatch)
|
||||||
|
assert svc._synapse_user_id({"name": "not-matrix"}) is None
|
||||||
|
assert svc._synapse_user_id({"name": "@guest:live.bstein.dev"}).localpart == "guest"
|
||||||
|
|
||||||
|
assert not svc._maybe_prune_synapse_guest(_Client(), "token", {"is_guest": False}, "@one:live.bstein.dev", 0)
|
||||||
|
monkeypatch.setattr(svc, "_should_prune_guest", lambda _entry, _now: False)
|
||||||
|
assert not svc._maybe_prune_synapse_guest(
|
||||||
|
_Client(),
|
||||||
|
"token",
|
||||||
|
{"is_guest": True},
|
||||||
|
"@one:live.bstein.dev",
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
monkeypatch.setattr(svc, "_should_prune_guest", lambda _entry, _now: True)
|
||||||
|
monkeypatch.setattr(svc, "_prune_guest", lambda *_args: True)
|
||||||
|
assert svc._maybe_prune_synapse_guest(_Client(), "token", {"is_guest": True}, "@one:live.bstein.dev", 0)
|
||||||
|
|
||||||
|
client = _Client()
|
||||||
|
assert not svc._needs_synapse_rename(
|
||||||
|
client,
|
||||||
|
"token",
|
||||||
|
SynapseUserRef({"is_guest": True}, "@skip:live.bstein.dev", "skip"),
|
||||||
|
{"skip"},
|
||||||
|
)
|
||||||
|
assert not svc._needs_synapse_rename(
|
||||||
|
client,
|
||||||
|
"token",
|
||||||
|
SynapseUserRef({"is_guest": False}, "@alice:live.bstein.dev", "alice"),
|
||||||
|
set(),
|
||||||
|
)
|
||||||
|
monkeypatch.setattr(svc, "_get_displayname_admin", lambda *_args: "Human")
|
||||||
|
assert not svc._needs_synapse_rename(
|
||||||
|
client,
|
||||||
|
"token",
|
||||||
|
SynapseUserRef({"is_guest": True}, "@guest:live.bstein.dev", "guest"),
|
||||||
|
set(),
|
||||||
|
)
|
||||||
|
monkeypatch.setattr(svc, "_get_displayname_admin", lambda *_args: None)
|
||||||
|
assert svc._needs_synapse_rename(
|
||||||
|
client,
|
||||||
|
"token",
|
||||||
|
SynapseUserRef({"is_guest": True}, "@guest:live.bstein.dev", "guest"),
|
||||||
|
set(),
|
||||||
|
)
|
||||||
|
|
||||||
|
monkeypatch.setattr(svc, "_pick_guest_name", lambda _existing: None)
|
||||||
|
assert not svc._rename_synapse_user(client, "token", set(), "@guest:live.bstein.dev")
|
||||||
|
monkeypatch.setattr(svc, "_pick_guest_name", lambda _existing: "Guest")
|
||||||
|
monkeypatch.setattr(svc, "_set_displayname_admin", lambda *_args: True)
|
||||||
|
assert svc._rename_synapse_user(client, "token", set(), "@guest:live.bstein.dev")
|
||||||
|
|
||||||
|
entries = [
|
||||||
|
{"name": "invalid"},
|
||||||
|
{"name": "@prune:live.bstein.dev"},
|
||||||
|
{"name": "@skip:live.bstein.dev"},
|
||||||
|
{"name": "@rename:live.bstein.dev"},
|
||||||
|
]
|
||||||
|
monkeypatch.setattr(svc, "_synapse_entries", lambda *_args: entries)
|
||||||
|
monkeypatch.setattr(svc, "_time", lambda: 10.0)
|
||||||
|
monkeypatch.setattr(
|
||||||
|
svc,
|
||||||
|
"_maybe_prune_synapse_guest",
|
||||||
|
lambda _client, _token, _entry, user_id, _now: user_id.startswith("@prune"),
|
||||||
|
)
|
||||||
|
monkeypatch.setattr(
|
||||||
|
svc,
|
||||||
|
"_needs_synapse_rename",
|
||||||
|
lambda _client, _token, user, _mas_names: user.localpart == "rename",
|
||||||
|
)
|
||||||
|
monkeypatch.setattr(svc, "_rename_synapse_user", lambda *_args: True)
|
||||||
|
|
||||||
|
result = svc._rename_synapse_guests(client, "token", set(), set())
|
||||||
|
assert result.pruned == 1
|
||||||
|
assert result.renamed == 1
|
||||||
Loading…
x
Reference in New Issue
Block a user