fix(tests): correct module-load detection tests (test_07)

- mod_vnc_lastactivity: the jabber:iq:last handler returns <forbidden> when
  the query has no 'to'; send it to another existing user's bare JID and
  assert the result carries a 'seconds' attribute
- set body via msg["body"] and do not await message send() (returns None)
- use unique uuid room names instead of a fixed duplicated localpart
- unlock the freshly-created (locked) room with configure_muc before a
  second user joins / is affiliated
- the unregister IQ is fire-and-forget (no reply); tolerate IqTimeout rather
  than failing the kick-tracking smoke test

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/3>
This commit is contained in:
2026-07-15 17:58:02 +02:00
co-authored by Claude Opus 4.8
parent 98c518b270
commit 54ca4e1877
+31 -13
View File
@@ -7,7 +7,9 @@ will typically return service-unavailable or item-not-found.
For modules without any IQ/presence hook, see MANUAL_TESTS.md §4.
"""
import uuid
import pytest
import slixmpp
import xml.etree.ElementTree as ET
@@ -15,19 +17,27 @@ import xml.etree.ElementTree as ET
class TestModuleLoadDetection:
"""Smoke tests for modules that would otherwise have zero coverage."""
async def test_mod_vnc_lastactivity_loaded(self, xmpp_client):
async def test_mod_vnc_lastactivity_loaded(self, xmpp_client, second_client):
"""mod_vnc_lastactivity hooks on jabber:iq:last and jabber:iq:batch.
A get request should return a result (not service-unavailable).
The handler requires a 'to' on the query: a jabber:iq:last get with no
target returns <forbidden>, so we query another existing user's bare JID.
"""
iq = xmpp_client.make_iq_get()
target = second_client.boundjid.bare
iq = xmpp_client.make_iq_get(ito=target)
ET.SubElement(iq.xml, "{jabber:iq:last}query")
try:
res = await iq.send()
assert res["type"] == "result", (
f"mod_vnc_lastactivity returned {res['type']} instead of result — module may not be loaded"
)
except Exception as e:
pytest.fail(f"mod_vnc_lastactivity IQ endpoint unreachable: {e}")
q = res.xml.find("{jabber:iq:last}query")
assert q is not None and q.get("seconds") is not None, (
"jabber:iq:last result missing the 'seconds' attribute"
)
except slixmpp.exceptions.IqError as e:
pytest.fail(f"mod_vnc_lastactivity returned an error ({e.condition}) — module may not be loaded")
async def test_mod_vnc_delfile_message_hook_present(self, xmpp_client, xmpp_config, second_client):
"""mod_vnc_delfile hooks on pre-message with a message-correction trigger.
@@ -38,13 +48,13 @@ class TestModuleLoadDetection:
pytest.skip("Need two clients for message roundtrip")
msg = xmpp_client.make_message(mto=second_client.boundjid.bare, mtype="chat")
msg.body = "delfile test"
msg["body"] = "delfile test" # slixmpp: dict-style, not msg.body
msg["id"] = "delfile-test-1"
replace = ET.SubElement(msg.xml, "{urn:xmpp:message-correct:0}replace")
replace.set("id", "original-msg-id")
try:
await msg.send()
msg.send() # message.send() returns None, not awaitable
# If no exception and no error bounce, the module at least didn't crash.
# The actual HTTP POST to del_api_url is an async side-effect we can't observe.
except Exception as e:
@@ -58,9 +68,9 @@ class TestModuleLoadDetection:
pytest.skip("Need two clients for message roundtrip")
msg = xmpp_client.make_message(mto=second_client.boundjid.bare, mtype="chat")
msg.body = "remotemucstore test"
msg["body"] = "remotemucstore test" # slixmpp: dict-style, not msg.body
try:
await msg.send()
msg.send() # message.send() returns None, not awaitable
except Exception as e:
pytest.fail(f"mod_vnc_remotemucstore message hook crashed: {e}")
@@ -74,9 +84,11 @@ class TestModuleLoadDetection:
if xmpp_client.boundjid.bare == second_client.boundjid.bare:
pytest.skip("Need two distinct accounts")
room_jid = f"reminv_{xmpp_client.boundjid.local}_{xmpp_client.boundjid.local}@{muc_domain}"
room_jid = f"reminv_{uuid.uuid4().hex[:8]}@{muc_domain}"
nick = "owner"
await xmpp_client.join_muc(room_jid, nick)
# unlock the freshly-created (locked) room so the invitee can join
await xmpp_client.configure_muc(room_jid)
await second_client.join_muc(room_jid, "invited")
try:
@@ -85,7 +97,7 @@ class TestModuleLoadDetection:
x = ET.SubElement(invite_msg.xml, "{http://jabber.org/protocol/muc#user}x")
invite = ET.SubElement(x, "{http://jabber.org/protocol/muc#user}invite")
invite.set("to", second_client.boundjid.bare)
await invite_msg.send()
invite_msg.send() # message.send() returns None, not awaitable
# If no crash, the event handler is at least present.
except Exception as e:
pytest.fail(f"mod_vnc_remotemucinvite event hook crashed: {e}")
@@ -104,18 +116,24 @@ class TestModuleLoadDetection:
if xmpp_client.boundjid.bare == second_client.boundjid.bare:
pytest.skip("Need two distinct accounts")
room_jid = f"trackk_{xmpp_client.boundjid.local}_{xmpp_client.boundjid.local}@{muc_domain}"
room_jid = f"trackk_{uuid.uuid4().hex[:8]}@{muc_domain}"
nick1 = "owner"
nick2 = "member"
await xmpp_client.join_muc(room_jid, nick1)
# unlock the freshly-created (locked) room before affiliating others
await xmpp_client.configure_muc(room_jid)
await xmpp_client.set_muc_affiliation(room_jid, second_client.boundjid.bare, "member")
try:
iq = second_client.make_iq_set(ito=room_jid)
ET.SubElement(iq.xml, "{xmpp:vnctalk:unregister}query")
await iq.send()
# If no crash, the kick event handler is at least present.
# handle_unregister_iq fires vnc-muc-kick but sends no IQ reply, so the
# send times out by design; that still proves the handler ran without crashing.
try:
await iq.send(timeout=5)
except slixmpp.exceptions.IqTimeout:
pass
except Exception as e:
pytest.fail(f"mod_vnc_track_kicks event hook crashed: {e}")
finally: