From 815b7d5af7b41636020e8b8a4405a1df0e6730b7 Mon Sep 17 00:00:00 2001
From: mathieui <mathieui@mathieui.net>
Date: Sun, 27 Feb 2022 16:22:59 +0100
Subject: Fix join_muc_wait: end join only upon receiving the room subject

---
 slixmpp/plugins/xep_0045/muc.py | 37 ++++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/slixmpp/plugins/xep_0045/muc.py b/slixmpp/plugins/xep_0045/muc.py
index 52988d44..8e021750 100644
--- a/slixmpp/plugins/xep_0045/muc.py
+++ b/slixmpp/plugins/xep_0045/muc.py
@@ -254,6 +254,7 @@ class XEP_0045(BasePlugin):
         if msg['body'] or msg['thread']:
             return
         self.xmpp.event('groupchat_subject', msg)
+        self.xmpp.event('muc::%s::groupchat_subject' % msg['from'].bare)
 
     async def join_muc_wait(self, room: JID, nick: str, *,
                             password: Optional[str] = None,
@@ -262,7 +263,7 @@ class XEP_0045(BasePlugin):
                             seconds: Optional[int] = None,
                             since: Optional[datetime] = None,
                             presence_options: Optional[PresenceArgs] = None,
-                            timeout: Optional[int] = None) -> Presence:
+                            timeout: Optional[int] = None) -> Tuple[Presence, Message]:
         """
         Try to join a MUC and block until we are joined or get an error.
 
@@ -282,7 +283,7 @@ class XEP_0045(BasePlugin):
                  presence error.
         :raises: An asyncio.TimeoutError if there is neither success nor
                 presence error when the timeout is reached.
-        :return: Our own presence
+        :return: Our own presence and the subject
         """
         if presence_options is None:
             presence_options = {}
@@ -306,22 +307,32 @@ class XEP_0045(BasePlugin):
         self.our_nicks[room] = nick
         stanza.send()
 
-        future: asyncio.Future = asyncio.Future()
-        context1 = self.xmpp.event_handler("muc::%s::self-presence" % room, future.set_result)
-        context2 = self.xmpp.event_handler("muc::%s::presence-error" % room, future.set_result)
-        with context1, context2:
+        presence_done: asyncio.Future = asyncio.Future()
+        topic_received: asyncio.Future = asyncio.Future()
+        context0 = self.xmpp.event_handler("muc::%s::groupchat_subject" % room, topic_received.set_result)
+        context1 = self.xmpp.event_handler("muc::%s::self-presence" % room, presence_done.set_result)
+        context2 = self.xmpp.event_handler("muc::%s::presence-error" % room, presence_done.set_result)
+        with context0:
+            with context1, context2:
+                done, pending = await asyncio.wait(
+                    [presence_done],
+                    timeout=timeout,
+                )
+            if pending:
+                raise asyncio.TimeoutError()
+            pres: Presence = presence_done.result()
+            if pres['type'] == 'error':
+                raise PresenceError(pres)
             done, pending = await asyncio.wait(
-                [future],
+                [topic_received],
                 timeout=timeout,
             )
-        if pending:
-            raise asyncio.TimeoutError()
-        pres = await future
-        if pres['type'] == 'error':
-            raise PresenceError(pres)
+            if pending:
+                raise asyncio.TimeoutError()
+        subject: Message = topic_received.result()
         # update known nick in case it has changed
         self.our_nicks[room] = pres['from'].resource
-        return pres
+        return (pres, subject)
 
     def join_muc(self, room: JID, nick: str, maxhistory="0", password='',
                  pstatus='', pshow='', pfrom='') -> asyncio.Future:
-- 
cgit v1.2.3