diff --git a/packages/moxxmpp/lib/src/xeps/xep_0045/xep_0045.dart b/packages/moxxmpp/lib/src/xeps/xep_0045/xep_0045.dart index 0b121c5..dc68132 100644 --- a/packages/moxxmpp/lib/src/xeps/xep_0045/xep_0045.dart +++ b/packages/moxxmpp/lib/src/xeps/xep_0045/xep_0045.dart @@ -360,14 +360,14 @@ class MUCManager extends XmppManagerBase { if (room.joined) { if (room.members.containsKey(from.resource)) { getAttributes().sendEvent( - MemberJoinedEvent( + MemberChangedEvent( bareFrom, member, ), ); } else { getAttributes().sendEvent( - MemberChangedEvent( + MemberJoinedEvent( bareFrom, member, ), diff --git a/packages/moxxmpp/test/xeps/xep_0045_test.dart b/packages/moxxmpp/test/xeps/xep_0045_test.dart index 0f92aae..de83d51 100644 --- a/packages/moxxmpp/test/xeps/xep_0045_test.dart +++ b/packages/moxxmpp/test/xeps/xep_0045_test.dart @@ -332,4 +332,361 @@ void main() { ); }, ); + + test( + 'Testing a user joining a room', + () async { + final fakeSocket = StubTCPSocket([ + StringExpectation( + "", + ''' + + + + PLAIN + + + + + ''', + ), + StringExpectation( + "AHBvbHlub21kaXZpc2lvbgBhYWFh", + '', + ), + StringExpectation( + "", + ''' + + + + + + + + + + + +''', + ), + StanzaExpectation( + '', + 'polynomdivision@test.server/MU29eEZn', + ignoreId: true, + ), + StanzaExpectation( + '', + '', + ignoreId: true, + ), + ]); + final conn = XmppConnection( + TestingSleepReconnectionPolicy(1), + AlwaysConnectedConnectivityManager(), + ClientToServerNegotiator(), + fakeSocket, + ) + ..connectionSettings = ConnectionSettings( + jid: JID.fromString('polynomdivision@test.server'), + password: 'aaaa', + ) + ..setResource('test-resource', triggerEvent: false); + await conn.registerManagers([ + DiscoManager([]), + MUCManager(), + ]); + + await conn.registerFeatureNegotiators([ + SaslPlainNegotiator(), + ResourceBindingNegotiator(), + ]); + + await conn.connect( + waitUntilLogin: true, + shouldReconnect: false, + ); + + // Join a groupchat + final roomJid = JID.fromString('channel@muc.example.org'); + final joinResult = conn.getManagerById(mucManager)!.joinRoom( + roomJid, + 'test', + maxHistoryStanzas: 0, + ); + await Future.delayed(const Duration(seconds: 1)); + + fakeSocket + ..injectRawXml( + ''' + + + + + + ''', + ) + ..injectRawXml( + ''' + + + + + + ''', + ) + ..injectRawXml( + ''' + + + + + + + ''', + ) + ..injectRawXml( + ''' + + + + ''', + ); + + await joinResult; + final room = (await conn + .getManagerById(mucManager)! + .getRoomState(roomJid))!; + expect(room.joined, true); + expect( + room.members.length, + 2, + ); + + // Now a new user joins the room. + MemberJoinedEvent? event; + conn.asBroadcastStream().listen((e) { + if (e is MemberJoinedEvent) { + event = e; + } + }); + + fakeSocket.injectRawXml( + ''' + + + + + + ''', + ); + + await Future.delayed(const Duration(seconds: 2)); + expect(event != null, true); + expect(event!.member.nick, 'papatutuwawa'); + expect(event!.member.affiliation, Affiliation.admin); + expect(event!.member.role, Role.participant); + + final roomAfterJoin = (await conn + .getManagerById(mucManager)! + .getRoomState(roomJid))!; + expect(roomAfterJoin.members.length, 3); + }, + ); + + test( + 'Testing a user leaving a room', + () async { + final fakeSocket = StubTCPSocket([ + StringExpectation( + "", + ''' + + + + PLAIN + + + + + ''', + ), + StringExpectation( + "AHBvbHlub21kaXZpc2lvbgBhYWFh", + '', + ), + StringExpectation( + "", + ''' + + + + + + + + + + + +''', + ), + StanzaExpectation( + '', + 'polynomdivision@test.server/MU29eEZn', + ignoreId: true, + ), + StanzaExpectation( + '', + '', + ignoreId: true, + ), + ]); + final conn = XmppConnection( + TestingSleepReconnectionPolicy(1), + AlwaysConnectedConnectivityManager(), + ClientToServerNegotiator(), + fakeSocket, + ) + ..connectionSettings = ConnectionSettings( + jid: JID.fromString('polynomdivision@test.server'), + password: 'aaaa', + ) + ..setResource('test-resource', triggerEvent: false); + await conn.registerManagers([ + DiscoManager([]), + MUCManager(), + ]); + + await conn.registerFeatureNegotiators([ + SaslPlainNegotiator(), + ResourceBindingNegotiator(), + ]); + + await conn.connect( + waitUntilLogin: true, + shouldReconnect: false, + ); + + // Join a groupchat + final roomJid = JID.fromString('channel@muc.example.org'); + final joinResult = conn.getManagerById(mucManager)!.joinRoom( + roomJid, + 'test', + maxHistoryStanzas: 0, + ); + await Future.delayed(const Duration(seconds: 1)); + + fakeSocket + ..injectRawXml( + ''' + + + + + + ''', + ) + ..injectRawXml( + ''' + + + + + + ''', + ) + ..injectRawXml( + ''' + + + + + + + ''', + ) + ..injectRawXml( + ''' + + + + ''', + ); + + await joinResult; + final room = (await conn + .getManagerById(mucManager)! + .getRoomState(roomJid))!; + expect(room.joined, true); + expect( + room.members.length, + 2, + ); + + // Now a new user joins the room. + MemberLeftEvent? event; + conn.asBroadcastStream().listen((e) { + if (e is MemberLeftEvent) { + event = e; + } + }); + + fakeSocket.injectRawXml( + ''' + + + + + + ''', + ); + + await Future.delayed(const Duration(seconds: 2)); + expect(event != null, true); + expect(event!.nick, 'secondwitch'); + + final roomAfterLeave = (await conn + .getManagerById(mucManager)! + .getRoomState(roomJid))!; + expect(roomAfterLeave.members.length, 1); + }, + ); }