"""Live smoke test against the real homeserver, bound strictly to the dedicated test room (never the production room). NISSE_MATRIX_HOMESERVER alone decides whether this runs: if it is set, the live path is expected to work, and anything else missing is a *failure*, not a skip. A half-configured environment must not pass quietly as a skip — that is how a broken CI credential hides.""" import os import uuid from pathlib import Path import pytest from nisse_dev.envfile import load_env_file from nisse_dev.matrix import MatrixConfig, MatrixTransport load_env_file(Path(__file__).resolve().parents[2] / ".env") SENTINEL = "NISSE_MATRIX_HOMESERVER" ALSO_REQUIRED = ( "NISSE_MATRIX_USER_ID", "NISSE_MATRIX_TOKEN", "NISSE_MATRIX_TEST_ROOM_ID", ) pytestmark = [ pytest.mark.integration, pytest.mark.skipif( not os.environ.get(SENTINEL), reason=f"no live homeserver configured ({SENTINEL} unset)", ), ] def _assert_testing_identity(transport: MatrixTransport, config: MatrixConfig) -> None: """Two invariants that only a live homeserver can check. The configured user id must be the token's real owner, because the transport filters its own messages by comparing sender to that value — a mismatch would make the bot read its own posts as operator input. And tests must run as a testing identity, so a stray live run can never act as the production agent. """ whoami = transport._http.get("/account/whoami") whoami.raise_for_status() actual = whoami.json()["user_id"] assert actual == config.user_id, ( f"NISSE_MATRIX_USER_ID is {config.user_id} but the token belongs to " f"{actual}; the self-message filter would not match" ) assert "testing" in actual, ( f"live tests must run as a testing identity, not {actual}" ) def test_send_lands_in_test_room() -> None: missing = [var for var in ALSO_REQUIRED if not os.environ.get(var)] assert not missing, ( f"{SENTINEL} is set, so the live Matrix path is expected to work, " f"but these are missing: {', '.join(missing)}" ) config = MatrixConfig.from_env(room_var="NISSE_MATRIX_TEST_ROOM_ID") marker = f"transport smoke test {uuid.uuid4().hex}" transport = MatrixTransport(config) try: _assert_testing_identity(transport, config) transport.send_message(marker) response = transport._http.get( f"/rooms/{config.room_id}/messages", params={"dir": "b", "limit": "10"}, ) response.raise_for_status() bodies = [ event.get("content", {}).get("body") for event in response.json().get("chunk", []) ] assert marker in bodies finally: transport.close()