Files
dongarandClaude Opus 5.5 e351d0a74e
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m37s
CI / e2e (pull_request) Successful in 4m5s
nisse-core: group modules into packages by architecture section
A pure move; behaviour unchanged.

- models (L9, L7): llm, catalog, probe, render, render_anthropic, context
- log (L7, L6): canonical, views
- state (L8): store (was state), reconcile, worker, cancel, dump
- knowledge (L10, L6.4): vault, memory
- conversation (L5): transport, matrix
- execution (L13): ssh (was execution), testing
- authority (P3, P4, L4): actions
- gitea, oplog, envfile stay at the top until each gains a second module.

Every import, monkeypatch target, script and doc reference rewritten.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
2026-10-13 21:16:09 +00:00

76 lines
2.8 KiB
Python

"""Live smoke test against the real homeserver, bound strictly to the
dedicated test room that nisse-test.yaml names (never the production room)."""
import uuid
import pytest
from nisse_core.conversation.matrix import MatrixConfig, MatrixTransport
from nisse_dev.config import AgentConfig
pytestmark = pytest.mark.integration
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"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(live_config: AgentConfig) -> None:
config = live_config.matrix
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()
def test_a_threaded_post_is_kept_in_its_thread(live_config: AgentConfig) -> None:
"""The homeserver accepts the thread relation and lists the reply under
its root (L5: a work item's conversation is a thread)."""
config = live_config.matrix
marker = uuid.uuid4().hex
transport = MatrixTransport(config)
try:
_assert_testing_identity(transport, config)
root = transport.post(f"thread smoke test root {marker}")
reply = transport.post(f"thread smoke test reply {marker}", thread=root)
# The relations API is v1, not the transport's v3.
response = transport._http.get(
f"{config.homeserver}/_matrix/client/v1/rooms/{config.room_id}"
f"/relations/{root}/m.thread"
)
response.raise_for_status()
in_thread = [e["event_id"] for e in response.json().get("chunk", [])]
assert reply in in_thread
finally:
transport.close()