/*global mock, converse */ const { Strophe } = converse.env; const u = converse.env.utils; // See: https://xmpp.org/rfcs/rfc3921.html describe("XEP-0437 Room Activity Indicators", function () { it("will be activated for a MUC that becomes hidden", mock.initConverse( [], { 'allow_bookmarks': false, // Hack to get the rooms list to render 'muc_subscribe_to_rai': true, 'view_mode': 'fullscreen'}, async function (done, _converse) { expect(_converse.session.get('rai_enabled_domains')).toBe(undefined); const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); const view = _converse.api.chatviews.get(muc_jid); expect(view.model.get('hidden')).toBe(false); const sent_IQs = _converse.connection.IQ_stanzas; const iq_get = await u.waitUntil(() => sent_IQs.filter(iq => iq.querySelector(`iq query[xmlns="${Strophe.NS.MAM}"]`)).pop()); const first_msg_id = _converse.connection.getUniqueId(); const last_msg_id = _converse.connection.getUniqueId(); let message = u.toStanza( ` 1st MAM Message `); _converse.connection._dataRecv(mock.createRequest(message)); message = u.toStanza( ` 2nd MAM Message `); _converse.connection._dataRecv(mock.createRequest(message)); const result = u.toStanza( ` ${first_msg_id} ${last_msg_id} 2 `); _converse.connection._dataRecv(mock.createRequest(result)); await u.waitUntil(() => view.model.messages.length === 2); const sent_stanzas = []; spyOn(_converse.connection, 'send').and.callFake(s => sent_stanzas.push(s?.nodeTree ?? s)); view.model.save({'hidden': true}); await u.waitUntil(() => sent_stanzas.length === 3); expect(Strophe.serialize(sent_stanzas[0])).toBe( ``+ ``+ `` ); expect(Strophe.serialize(sent_stanzas[1])).toBe( ``+ `0`+ ``+ `` ); expect(Strophe.serialize(sent_stanzas[2])).toBe( ``+ `0`+ ``+ ``+ `` ); await u.waitUntil(() => view.model.session.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED); expect(view.model.get('has_activity')).toBe(false); const room_el = await u.waitUntil(() => document.querySelector("converse-rooms-list .available-chatroom")); expect(Array.from(room_el.classList).includes('unread-msgs')).toBeFalsy(); const activity_stanza = u.toStanza(` ${muc_jid} `); _converse.connection._dataRecv(mock.createRequest(activity_stanza)); await u.waitUntil(() => view.model.get('has_activity')); expect(Array.from(room_el.classList).includes('unread-msgs')).toBeTruthy(); done(); })); it("will be activated for a MUC that starts out hidden", mock.initConverse( [], { 'allow_bookmarks': false, // Hack to get the rooms list to render 'muc_subscribe_to_rai': true, 'view_mode': 'fullscreen'}, async function (done, _converse) { const { api } = _converse; expect(_converse.session.get('rai_enabled_domains')).toBe(undefined); const muc_jid = 'lounge@montague.lit'; const nick = 'romeo'; const sent_stanzas = _converse.connection.sent_stanzas; const muc_creation_promise = await api.rooms.open(muc_jid, {nick, 'hidden': true}, false); await mock.getRoomFeatures(_converse, muc_jid, []); await mock.receiveOwnMUCPresence(_converse, muc_jid, nick); await muc_creation_promise; const view = api.chatviews.get(muc_jid); await u.waitUntil(() => (view.model.session.get('connection_status') === converse.ROOMSTATUS.ENTERED)); expect(view.model.get('hidden')).toBe(true); const getSentPresences = () => sent_stanzas.filter(s => s.nodeName === 'presence'); await u.waitUntil(() => getSentPresences().length === 3, 500); const sent_presences = getSentPresences(); expect(Strophe.serialize(sent_presences[1])).toBe( ``+ `0`+ ``+ `` ); expect(Strophe.serialize(sent_presences[2])).toBe( ``+ `0`+ ``+ ``+ `` ); await u.waitUntil(() => view.model.session.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED); expect(view.model.get('has_activity')).toBe(false); const room_el = await u.waitUntil(() => document.querySelector("converse-rooms-list .available-chatroom")); expect(Array.from(room_el.classList).includes('unread-msgs')).toBeFalsy(); const activity_stanza = u.toStanza(` ${muc_jid} `); _converse.connection._dataRecv(mock.createRequest(activity_stanza)); await u.waitUntil(() => view.model.get('has_activity')); expect(Array.from(room_el.classList).includes('unread-msgs')).toBeTruthy(); done(); })); it("may not be activated due to server resource constraints", mock.initConverse( [], { 'allow_bookmarks': false, // Hack to get the rooms list to render 'muc_subscribe_to_rai': true, 'view_mode': 'fullscreen'}, async function (done, _converse) { expect(_converse.session.get('rai_enabled_domains')).toBe(undefined); const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); const view = _converse.api.chatviews.get(muc_jid); expect(view.model.get('hidden')).toBe(false); const sent_stanzas = []; spyOn(_converse.connection, 'send').and.callFake(s => sent_stanzas.push(s?.nodeTree ?? s)); view.model.save({'hidden': true}); await u.waitUntil(() => sent_stanzas.filter(s => s.nodeName === 'presence').length === 2); expect(Strophe.serialize(sent_stanzas[0])).toBe( ``+ `0`+ ``+ `` ); expect(Strophe.serialize(sent_stanzas[1])).toBe( ``+ `0`+ ``+ ``+ `` ); // If an error presence with "resource-constraint" is returned, we rejoin const activity_stanza = u.toStanza(` `); _converse.connection._dataRecv(mock.createRequest(activity_stanza)); await u.waitUntil(() => view.model.session.get('connection_status') === converse.ROOMSTATUS.CONNECTING); done(); })); });