MUC: Fix error message logging

This commit is contained in:
JC Brand 2021-01-29 11:08:28 +01:00
parent 9f5dbad589
commit ea6e370347
14 changed files with 213 additions and 537 deletions

View File

@ -139,13 +139,14 @@ describe("Chatboxes", function () {
})); }));
it("is focused if its already open and you click on its corresponding roster item", it("is focused if its already open and you click on its corresponding roster item",
mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) { mock.initConverse(['chatBoxesFetched'], {'auto_focus': true}, async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
expect(_converse.chatboxes.length).toEqual(1); expect(_converse.chatboxes.length).toEqual(1);
const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit'; const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
spyOn(_converse.ChatBoxView.prototype, 'focus').and.callThrough();
const view = await mock.openChatBoxFor(_converse, contact_jid); const view = await mock.openChatBoxFor(_converse, contact_jid);
const rosterview = document.querySelector('converse-roster'); const rosterview = document.querySelector('converse-roster');
const el = sizzle('a.open-chat:contains("'+view.model.getDisplayName()+'")', rosterview.el).pop(); const el = sizzle('a.open-chat:contains("'+view.model.getDisplayName()+'")', rosterview.el).pop();
@ -153,11 +154,8 @@ describe("Chatboxes", function () {
const textarea = view.querySelector('.chat-textarea'); const textarea = view.querySelector('.chat-textarea');
await u.waitUntil(() => u.isVisible(textarea)); await u.waitUntil(() => u.isVisible(textarea));
textarea.blur(); textarea.blur();
spyOn(view.model, 'maybeShow').and.callThrough();
spyOn(view, 'focus').and.callThrough();
el.click(); el.click();
await u.waitUntil(() => view.model.maybeShow.calls.count(), 1000); await u.waitUntil(() => view.focus.calls.count(), 1000);
expect(view.model.maybeShow).toHaveBeenCalled();
expect(view.focus).toHaveBeenCalled(); expect(view.focus).toHaveBeenCalled();
expect(_converse.chatboxes.length).toEqual(2); expect(_converse.chatboxes.length).toEqual(2);
done(); done();
@ -219,16 +217,15 @@ describe("Chatboxes", function () {
it("will be removed from browserStorage when closed", it("will be removed from browserStorage when closed",
mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) { mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
spyOn(_converse.minimize, 'trimChats');
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
spyOn(_converse.minimize, 'trimChats');
const rosterview = document.querySelector('converse-roster'); const rosterview = document.querySelector('converse-roster');
await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length); await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length);
spyOn(_converse.api, "trigger").and.callThrough(); spyOn(_converse.api, "trigger").and.callThrough();
const promise = new Promise(resolve => _converse.api.listen.once('controlBoxClosed', resolve));
mock.closeControlBox(); mock.closeControlBox();
await new Promise(resolve => _converse.api.listen.once('chatBoxClosed', resolve)); await promise;
expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
expect(_converse.chatboxes.length).toEqual(1); expect(_converse.chatboxes.length).toEqual(1);
expect(_converse.chatboxes.pluck('id')).toEqual(['controlbox']); expect(_converse.chatboxes.pluck('id')).toEqual(['controlbox']);
mock.openChatBoxes(_converse, 6); mock.openChatBoxes(_converse, 6);
@ -1056,9 +1053,9 @@ describe("Chatboxes", function () {
await u.waitUntil(() => sent_stanzas.filter(s => s.nodeName === 'message').length === 1); await u.waitUntil(() => sent_stanzas.filter(s => s.nodeName === 'message').length === 1);
expect(sent_stanzas[0].querySelector('received')).toBeDefined(); expect(sent_stanzas[0].querySelector('received')).toBeDefined();
_converse.saveWindowState({'type': 'focus'}); _converse.saveWindowState({'type': 'focus'});
expect(chatbox.get('num_unread')).toBe(0);
await u.waitUntil(() => sent_stanzas.filter(s => s.nodeName === 'message').length === 2); await u.waitUntil(() => sent_stanzas.filter(s => s.nodeName === 'message').length === 2);
expect(sent_stanzas[1].querySelector('displayed')).toBeDefined(); expect(sent_stanzas[1].querySelector('displayed')).toBeDefined();
expect(chatbox.get('num_unread')).toBe(0);
done(); done();
})); }));
@ -1191,7 +1188,7 @@ describe("Chatboxes", function () {
expect(select_msgs_indicator().textContent).toBe('1'); expect(select_msgs_indicator().textContent).toBe('1');
view.viewUnreadMessages(); view.viewUnreadMessages();
rosterview.render(); rosterview.render();
expect(select_msgs_indicator()).toBeUndefined(); await u.waitUntil(() => select_msgs_indicator() === undefined);
done(); done();
})); }));

View File

@ -6,9 +6,7 @@ const u = converse.env.utils;
describe("A Chat Message", function () { describe("A Chat Message", function () {
it("can be sent as a correction by using the up arrow", it("can be sent as a correction by using the up arrow",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
@ -164,9 +162,7 @@ describe("A Chat Message", function () {
it("can be sent as a correction by clicking the pencil icon", it("can be sent as a correction by clicking the pencil icon",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
@ -291,9 +287,7 @@ describe("A Chat Message", function () {
describe("when received from someone else", function () { describe("when received from someone else", function () {
it("can be replaced with a correction", it("can be replaced with a correction",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
@ -356,9 +350,7 @@ describe("A Chat Message", function () {
describe("A Groupchat Message", function () { describe("A Groupchat Message", function () {
it("can be replaced with a correction", it("can be replaced with a correction",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -425,9 +417,7 @@ describe("A Groupchat Message", function () {
})); }));
it("keeps the same position in history after a correction", it("keeps the same position in history after a correction",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -521,9 +511,7 @@ describe("A Groupchat Message", function () {
})); }));
it("can be sent as a correction by using the up arrow", it("can be sent as a correction by using the up arrow",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');

View File

@ -8,9 +8,7 @@ const u = converse.env.utils;
describe("A XEP-0333 Chat Marker", function () { describe("A XEP-0333 Chat Marker", function () {
it("is sent when a markable message is received from a roster contact", it("is sent when a markable message is received from a roster contact",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
@ -39,9 +37,7 @@ describe("A XEP-0333 Chat Marker", function () {
})); }));
it("is not sent when a markable message is received from someone not on the roster", it("is not sent when a markable message is received from someone not on the roster",
mock.initConverse( mock.initConverse([], {'allow_non_roster_messaging': true}, async function (done, _converse) {
['rosterContactsFetched'], {'allow_non_roster_messaging': true},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 0); await mock.waitForRoster(_converse, 'current', 0);
const contact_jid = 'someone@montague.lit'; const contact_jid = 'someone@montague.lit';
@ -74,9 +70,7 @@ describe("A XEP-0333 Chat Marker", function () {
})); }));
it("is ignored if it's a carbon copy of one that I sent from a different client", it("is ignored if it's a carbon copy of one that I sent from a different client",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
await mock.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], [Strophe.NS.SID]); await mock.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], [Strophe.NS.SID]);
@ -123,9 +117,7 @@ describe("A XEP-0333 Chat Marker", function () {
it("may be returned for a MUC message", it("may be returned for a MUC message",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
@ -176,6 +168,7 @@ describe("A XEP-0333 Chat Marker", function () {
<message xml:lang="en" to="romeo@montague.lit/orchard" <message xml:lang="en" to="romeo@montague.lit/orchard"
from="lounge@montague.lit/some1" type="groupchat" xmlns="jabber:client"> from="lounge@montague.lit/some1" type="groupchat" xmlns="jabber:client">
<body>'tis I!</body> <body>'tis I!</body>
<stanza-id xmlns='urn:xmpp:sid:0' id='stanza-id-1' by='${muc_jid}'/>
<markable xmlns="urn:xmpp:chat-markers:0"/> <markable xmlns="urn:xmpp:chat-markers:0"/>
</message>`); </message>`);
_converse.connection._dataRecv(mock.createRequest(stanza)); _converse.connection._dataRecv(mock.createRequest(stanza));

View File

@ -4,11 +4,7 @@ const { u, sizzle, $msg } = converse.env;
describe("A Groupchat Message", function () { describe("A Groupchat Message", function () {
it("supports the /me command", it("supports the /me command", mock.initConverse([], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']); await mock.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname')); await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
@ -61,7 +57,7 @@ describe("A Groupchat Message", function () {
describe("A Message", function () { describe("A Message", function () {
it("supports the /me command", mock.initConverse(['rosterContactsFetched'], {}, async function (done, _converse) { it("supports the /me command", mock.initConverse([], {}, async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
await mock.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']); await mock.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname')); await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));

View File

@ -7,9 +7,7 @@ const u = converse.env.utils;
describe("An incoming groupchat message", function () { describe("An incoming groupchat message", function () {
it("is specially marked when you are mentioned in it", it("is specially marked when you are mentioned in it",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -31,9 +29,7 @@ describe("An incoming groupchat message", function () {
it("highlights all users mentioned via XEP-0372 references", it("highlights all users mentioned via XEP-0372 references",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'tom'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'tom');
@ -87,9 +83,7 @@ describe("An incoming groupchat message", function () {
})); }));
it("highlights all users mentioned via XEP-0372 references in a quoted message", it("highlights all users mentioned via XEP-0372 references in a quoted message",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'tom'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'tom');
@ -133,9 +127,7 @@ describe("A sent groupchat message", function () {
describe("in which someone is mentioned", function () { describe("in which someone is mentioned", function () {
it("gets parsed for mentions which get turned into references", it("gets parsed for mentions which get turned into references",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
@ -265,9 +257,7 @@ describe("A sent groupchat message", function () {
})); }));
it("gets parsed for mentions as indicated with an @ preceded by a space or at the start of the text", it("gets parsed for mentions as indicated with an @ preceded by a space or at the start of the text",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'tom'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'tom');
@ -299,9 +289,7 @@ describe("A sent groupchat message", function () {
})); }));
it("properly encodes the URIs in sent out references", it("properly encodes the URIs in sent out references",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'tom'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'tom');
@ -343,9 +331,7 @@ describe("A sent groupchat message", function () {
})); }));
it("can get corrected and given new references", it("can get corrected and given new references",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
@ -442,9 +428,7 @@ describe("A sent groupchat message", function () {
})); }));
it("includes a XEP-0372 references to that person", it("includes a XEP-0372 references to that person",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -493,9 +477,7 @@ describe("A sent groupchat message", function () {
}); });
it("highlights all users mentioned via XEP-0372 references in a quoted message", it("highlights all users mentioned via XEP-0372 references in a quoted message",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const members = [{'jid': 'gibson@gibson.net', 'nick': 'gibson', 'affiliation': 'member'}]; const members = [{'jid': 'gibson@gibson.net', 'nick': 'gibson', 'affiliation': 'member'}];
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';

View File

@ -7,7 +7,7 @@ const u = converse.env.utils;
describe("A Chat Message", function () { describe("A Chat Message", function () {
it("will be demarcated if it's the first newly received message", it("will be demarcated if it's the first newly received message",
mock.initConverse(['rosterContactsFetched', 'chatBoxesFetched'], {}, mock.initConverse(['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
@ -35,7 +35,7 @@ describe("A Chat Message", function () {
it("is rejected if it's an unencapsulated forwarded message", it("is rejected if it's an unencapsulated forwarded message",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 2); await mock.waitForRoster(_converse, 'current', 2);
@ -79,15 +79,14 @@ describe("A Chat Message", function () {
})); }));
it("can be received out of order, and will still be displayed in the right order", it("can be received out of order, and will still be displayed in the right order",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group').length) const rosterview = document.querySelector('converse-roster');
await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length)
_converse.filter_by_resource = true; _converse.filter_by_resource = true;
let msg = $msg({ let msg = $msg({
@ -244,9 +243,7 @@ describe("A Chat Message", function () {
})); }));
it("is ignored if it's a malformed headline message", it("is ignored if it's a malformed headline message",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
@ -273,9 +270,7 @@ describe("A Chat Message", function () {
it("can be a carbon message, as defined in XEP-0280", it("can be a carbon message, as defined in XEP-0280",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const include_nick = false; const include_nick = false;
await mock.waitForRoster(_converse, 'current', 2, include_nick); await mock.waitForRoster(_converse, 'current', 2, include_nick);
@ -324,9 +319,7 @@ describe("A Chat Message", function () {
})); }));
it("can be a carbon message that this user sent from a different client, as defined in XEP-0280", it("can be a carbon message that this user sent from a different client, as defined in XEP-0280",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']); await mock.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
@ -371,9 +364,7 @@ describe("A Chat Message", function () {
})); }));
it("will be discarded if it's a malicious message meant to look like a carbon copy", it("will be discarded if it's a malicious message meant to look like a carbon copy",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
@ -417,9 +408,7 @@ describe("A Chat Message", function () {
})); }));
it("will indicate when it has a time difference of more than a day between it and its predecessor", it("will indicate when it has a time difference of more than a day between it and its predecessor",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const include_nick = false; const include_nick = false;
await mock.waitForRoster(_converse, 'current', 2, include_nick); await mock.waitForRoster(_converse, 'current', 2, include_nick);
@ -428,7 +417,8 @@ describe("A Chat Message", function () {
const contact_name = mock.cur_names[1]; const contact_name = mock.cur_names[1];
const contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@montague.lit'; const contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group').length); const rosterview = document.querySelector('converse-roster');
await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length);
await mock.openChatBoxFor(_converse, contact_jid); await mock.openChatBoxFor(_converse, contact_jid);
const one_day_ago = dayjs().subtract(1, 'day'); const one_day_ago = dayjs().subtract(1, 'day');
@ -509,9 +499,7 @@ describe("A Chat Message", function () {
})); }));
it("is sanitized to prevent Javascript injection attacks", it("is sanitized to prevent Javascript injection attacks",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
@ -529,9 +517,7 @@ describe("A Chat Message", function () {
})); }));
it("can contain hyperlinks, which will be clickable", it("can contain hyperlinks, which will be clickable",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
@ -551,9 +537,7 @@ describe("A Chat Message", function () {
})); }));
it("will remove url query parameters from hyperlinks as set", it("will remove url query parameters from hyperlinks as set",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {'filter_url_query_params': ['utm_medium', 'utm_content', 's']},
['rosterContactsFetched', 'chatBoxesFetched'],
{'filter_url_query_params': ['utm_medium', 'utm_content', 's']},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
@ -582,11 +566,7 @@ describe("A Chat Message", function () {
done(); done();
})); }));
it("will render newlines", it("will render newlines", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
const view = await mock.openChatBoxFor(_converse, contact_jid); const view = await mock.openChatBoxFor(_converse, contact_jid);
@ -633,11 +613,7 @@ describe("A Chat Message", function () {
done(); done();
})); }));
it("will render images from their URLs", it("will render images from their URLs", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
const base_url = 'https://conversejs.org'; const base_url = 'https://conversejs.org';
let message = base_url+"/logo/conversejs-filled.svg"; let message = base_url+"/logo/conversejs-filled.svg";
@ -687,7 +663,7 @@ describe("A Chat Message", function () {
it("will render images from approved URLs only", it("will render images from approved URLs only",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {'show_images_inline': ['conversejs.org']}, ['chatBoxesFetched'], {'show_images_inline': ['conversejs.org']},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
@ -711,7 +687,7 @@ describe("A Chat Message", function () {
it("will fall back to rendering images as URLs", it("will fall back to rendering images as URLs",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
@ -755,7 +731,7 @@ describe("A Chat Message", function () {
it("will render the message time as configured", it("will render the message time as configured",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
@ -781,7 +757,7 @@ describe("A Chat Message", function () {
it("will be correctly identified and rendered as a followup message", it("will be correctly identified and rendered as a followup message",
mock.initConverse( mock.initConverse(
['rosterContactsFetched'], {'debounced_content_rendering': false}, [], {'debounced_content_rendering': false},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
@ -790,7 +766,8 @@ describe("A Chat Message", function () {
const base_time = new Date(); const base_time = new Date();
const ONE_MINUTE_LATER = 60000; const ONE_MINUTE_LATER = 60000;
await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group').length, 300); const rosterview = document.querySelector('converse-roster');
await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length, 300);
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
_converse.filter_by_resource = true; _converse.filter_by_resource = true;
@ -943,7 +920,7 @@ describe("A Chat Message", function () {
it("will appear inside the chatbox it was sent from", it("will appear inside the chatbox it was sent from",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
@ -965,7 +942,7 @@ describe("A Chat Message", function () {
it("will be trimmed of leading and trailing whitespace", it("will be trimmed of leading and trailing whitespace",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
@ -985,14 +962,13 @@ describe("A Chat Message", function () {
describe("when received from someone else", function () { describe("when received from someone else", function () {
it("will open a chatbox and be displayed inside it", it("will open a chatbox and be displayed inside it",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const include_nick = false; const include_nick = false;
await mock.waitForRoster(_converse, 'current', 1, include_nick); await mock.waitForRoster(_converse, 'current', 1, include_nick);
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group').length, 300); const rosterview = document.querySelector('converse-roster');
await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length, 300);
spyOn(_converse.api, "trigger").and.callThrough(); spyOn(_converse.api, "trigger").and.callThrough();
const message = 'This is a received message'; const message = 'This is a received message';
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
@ -1031,12 +1007,11 @@ describe("A Chat Message", function () {
})); }));
it("will be trimmed of leading and trailing whitespace", it("will be trimmed of leading and trailing whitespace",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1, false); await mock.waitForRoster(_converse, 'current', 1, false);
await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group').length, 300); const rosterview = document.querySelector('converse-roster');
await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length, 300);
const message = '\n\n This is a received message \n\n'; const message = '\n\n This is a received message \n\n';
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await _converse.handleMessageStanza( await _converse.handleMessageStanza(
@ -1062,8 +1037,7 @@ describe("A Chat Message", function () {
describe("when a chatbox is opened for someone who is not in the roster", function () { describe("when a chatbox is opened for someone who is not in the roster", function () {
it("the VCard for that user is fetched and the chatbox updated with the results", it("the VCard for that user is fetched and the chatbox updated with the results",
mock.initConverse( mock.initConverse([], {'allow_non_roster_messaging': true},
['rosterContactsFetched'], {'allow_non_roster_messaging': true},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 0); await mock.waitForRoster(_converse, 'current', 0);
@ -1117,7 +1091,7 @@ describe("A Chat Message", function () {
it("will open a chatbox and be displayed inside it if allow_non_roster_messaging is true", it("will open a chatbox and be displayed inside it if allow_non_roster_messaging is true",
mock.initConverse( mock.initConverse(
['rosterContactsFetched'], {'allow_non_roster_messaging': false}, [], {'allow_non_roster_messaging': false},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 0); await mock.waitForRoster(_converse, 'current', 0);
@ -1172,9 +1146,7 @@ describe("A Chat Message", function () {
describe("and for which then an error message is received from the server", function () { describe("and for which then an error message is received from the server", function () {
it("will have the error message displayed after itself", it("will have the error message displayed after itself",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
@ -1298,7 +1270,7 @@ describe("A Chat Message", function () {
it("will not show to the user an error message for a CSI message", it("will not show to the user an error message for a CSI message",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
// See #1317 // See #1317
@ -1338,9 +1310,7 @@ describe("A Chat Message", function () {
it("will cause the chat area to be scrolled down only if it was at the bottom originally", it("will cause the chat area to be scrolled down only if it was at the bottom originally",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
@ -1375,12 +1345,11 @@ describe("A Chat Message", function () {
})); }));
it("is ignored if it's intended for a different resource and filter_by_resource is set to true", it("is ignored if it's intended for a different resource and filter_by_resource is set to true",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group').length) const rosterview = document.querySelector('converse-roster');
await u.waitUntil(() => rosterview.querySelectorAll('.roster-group').length)
// Send a message from a different resource // Send a message from a different resource
spyOn(converse.env.log, 'error'); spyOn(converse.env.log, 'error');
spyOn(_converse.api.chatboxes, 'create').and.callThrough(); spyOn(_converse.api.chatboxes, 'create').and.callThrough();
@ -1426,7 +1395,7 @@ describe("A Chat Message", function () {
it("will render audio from oob mp3 URLs", it("will render audio from oob mp3 URLs",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
@ -1476,7 +1445,7 @@ describe("A Chat Message", function () {
it("will render video from oob mp4 URLs", it("will render video from oob mp4 URLs",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
@ -1522,7 +1491,7 @@ describe("A Chat Message", function () {
it("will render download links for files from oob URLs", it("will render download links for files from oob URLs",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
@ -1551,7 +1520,7 @@ describe("A Chat Message", function () {
it("will render images from oob URLs", it("will render images from oob URLs",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
const base_url = 'https://conversejs.org'; const base_url = 'https://conversejs.org';

View File

@ -8,8 +8,7 @@ const u = converse.env.utils;
describe("MUC Mention Notfications", function () { describe("MUC Mention Notfications", function () {
it("may be received from a MUC in which the user is not currently present", it("may be received from a MUC in which the user is not currently present",
mock.initConverse( mock.initConverse([], {
['rosterContactsFetched'], {
'allow_bookmarks': false, // Hack to get the rooms list to render 'allow_bookmarks': false, // Hack to get the rooms list to render
'muc_subscribe_to_rai': true, 'muc_subscribe_to_rai': true,
'view_mode': 'fullscreen'}, 'view_mode': 'fullscreen'},
@ -31,8 +30,7 @@ describe("MUC Mention Notfications", function () {
expect(view.model.get('hidden')).toBe(true); expect(view.model.get('hidden')).toBe(true);
await u.waitUntil(() => view.model.session.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED); await u.waitUntil(() => view.model.session.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED);
const lview = _converse.rooms_list_view const room_el = await u.waitUntil(() => document.querySelector("converse-rooms-list .available-chatroom"));
const room_el = await u.waitUntil(() => lview.querySelector(".available-chatroom"));
expect(Array.from(room_el.classList).includes('unread-msgs')).toBeFalsy(); expect(Array.from(room_el.classList).includes('unread-msgs')).toBeFalsy();
const base_time = new Date(); const base_time = new Date();

View File

@ -13,10 +13,8 @@ describe("Groupchats", function () {
describe("The \"rooms\" API", function () { describe("The \"rooms\" API", function () {
it("has a method 'close' which closes rooms by JID or all rooms when called with no arguments", fit("has a method 'close' which closes rooms by JID or all rooms when called with no arguments",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
@ -25,14 +23,15 @@ describe("Groupchats", function () {
_converse.connection.IQ_stanzas = []; _converse.connection.IQ_stanzas = [];
await mock.openAndEnterChatRoom(_converse, 'news@montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'news@montague.lit', 'romeo');
expect(u.isVisible(_converse.chatboxviews.get('lounge@montague.lit').el)).toBeTruthy();
expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit').el)).toBeTruthy(); expect(u.isVisible(_converse.chatboxviews.get('lounge@montague.lit'))).toBeTruthy();
expect(u.isVisible(_converse.chatboxviews.get('news@montague.lit').el)).toBeTruthy(); expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit'))).toBeTruthy();
expect(u.isVisible(_converse.chatboxviews.get('news@montague.lit'))).toBeTruthy();
await _converse.api.roomviews.close('lounge@montague.lit'); await _converse.api.roomviews.close('lounge@montague.lit');
expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined(); expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined();
expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit').el)).toBeTruthy(); expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit'))).toBeTruthy();
expect(u.isVisible(_converse.chatboxviews.get('news@montague.lit').el)).toBeTruthy(); expect(u.isVisible(_converse.chatboxviews.get('news@montague.lit'))).toBeTruthy();
await _converse.api.roomviews.close(['leisure@montague.lit', 'news@montague.lit']); await _converse.api.roomviews.close(['leisure@montague.lit', 'news@montague.lit']);
expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined(); expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined();
@ -40,8 +39,8 @@ describe("Groupchats", function () {
expect(_converse.chatboxviews.get('news@montague.lit')).toBeUndefined(); expect(_converse.chatboxviews.get('news@montague.lit')).toBeUndefined();
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
await mock.openAndEnterChatRoom(_converse, 'leisure@montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'leisure@montague.lit', 'romeo');
expect(u.isVisible(_converse.chatboxviews.get('lounge@montague.lit').el)).toBeTruthy(); expect(u.isVisible(_converse.chatboxviews.get('lounge@montague.lit'))).toBeTruthy();
expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit').el)).toBeTruthy(); expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit'))).toBeTruthy();
await _converse.api.roomviews.close(); await _converse.api.roomviews.close();
expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined(); expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined();
expect(_converse.chatboxviews.get('leisure@montague.lit')).toBeUndefined(); expect(_converse.chatboxviews.get('leisure@montague.lit')).toBeUndefined();
@ -49,9 +48,7 @@ describe("Groupchats", function () {
})); }));
it("has a method 'get' which returns a wrapped groupchat (if it exists)", it("has a method 'get' which returns a wrapped groupchat (if it exists)",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group .group-toggle').length, 300); await u.waitUntil(() => _converse.rosterview.querySelectorAll('.roster-group .group-toggle').length, 300);
@ -95,9 +92,7 @@ describe("Groupchats", function () {
})); }));
it("has a method 'open' which opens (optionally configures) and returns a wrapped chat box", it("has a method 'open' which opens (optionally configures) and returns a wrapped chat box",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
// Mock 'getDiscoInfo', otherwise the room won't be // Mock 'getDiscoInfo', otherwise the room won't be
// displayed as it waits first for the features to be returned // displayed as it waits first for the features to be returned
@ -265,9 +260,7 @@ describe("Groupchats", function () {
describe("An instant groupchat", function () { describe("An instant groupchat", function () {
it("will be created when muc_instant_rooms is set to true", it("will be created when muc_instant_rooms is set to true",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
let IQ_stanzas = _converse.connection.IQ_stanzas; let IQ_stanzas = _converse.connection.IQ_stanzas;
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
@ -402,8 +395,7 @@ describe("Groupchats", function () {
it("maintains its state across reloads", it("maintains its state across reloads",
mock.initConverse( mock.initConverse([], {
['rosterContactsFetched'], {
'clear_messages_on_reconnection': true, 'clear_messages_on_reconnection': true,
'enable_smacks': false 'enable_smacks': false
}, async function (done, _converse) { }, async function (done, _converse) {
@ -510,9 +502,7 @@ describe("Groupchats", function () {
describe("upon being entered", function () { describe("upon being entered", function () {
it("will fetch the member list if muc_fetch_members is true", it("will fetch the member list if muc_fetch_members is true",
mock.initConverse( mock.initConverse([], {'muc_fetch_members': true}, async function (done, _converse) {
['rosterContactsFetched'], {'muc_fetch_members': true},
async function (done, _converse) {
let sent_IQs = _converse.connection.IQ_stanzas; let sent_IQs = _converse.connection.IQ_stanzas;
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
@ -571,9 +561,7 @@ describe("Groupchats", function () {
describe("when fetching the member lists", function () { describe("when fetching the member lists", function () {
it("gracefully handles being forbidden from fetching the lists for certain affiliations", it("gracefully handles being forbidden from fetching the lists for certain affiliations",
mock.initConverse( mock.initConverse([], {'muc_fetch_members': true}, async function (done, _converse) {
['rosterContactsFetched'], {'muc_fetch_members': true},
async function (done, _converse) {
const sent_IQs = _converse.connection.IQ_stanzas; const sent_IQs = _converse.connection.IQ_stanzas;
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
@ -653,11 +641,7 @@ describe("Groupchats", function () {
describe("topic", function () { describe("topic", function () {
it("is shown the header", it("is shown the header", mock.initConverse([], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'jc'); await mock.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'jc');
const text = 'Jabber/XMPP Development | RFCs and Extensions: https://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org'; const text = 'Jabber/XMPP Development | RFCs and Extensions: https://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org';
let stanza = u.toStanza(` let stanza = u.toStanza(`
@ -687,11 +671,7 @@ describe("Groupchats", function () {
done(); done();
})); }));
it("can be toggled by the user", it("can be toggled by the user", mock.initConverse([], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'jc'); await mock.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'jc');
const text = 'Jabber/XMPP Development | RFCs and Extensions: https://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org'; const text = 'Jabber/XMPP Development | RFCs and Extensions: https://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org';
let stanza = u.toStanza(` let stanza = u.toStanza(`
@ -729,11 +709,7 @@ describe("Groupchats", function () {
done(); done();
})); }));
it("will always be shown when it's new", it("will always be shown when it's new", mock.initConverse([], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'jc'); await mock.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'jc');
const text = 'Jabber/XMPP Development | RFCs and Extensions: https://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org'; const text = 'Jabber/XMPP Development | RFCs and Extensions: https://xmpp.org/ | Protocol and XSF discussions: xsf@muc.xmpp.org';
let stanza = u.toStanza(` let stanza = u.toStanza(`
@ -768,11 +744,7 @@ describe("Groupchats", function () {
})); }));
it("causes an info message to be shown when received in real-time", it("causes an info message to be shown when received in real-time", mock.initConverse([], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched'], {},
async function (done, _converse) {
spyOn(_converse.ChatRoom.prototype, 'handleSubjectChange').and.callThrough(); spyOn(_converse.ChatRoom.prototype, 'handleSubjectChange').and.callThrough();
await mock.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'jdev@conference.jabber.org', 'romeo');
const view = _converse.chatboxviews.get('jdev@conference.jabber.org'); const view = _converse.chatboxviews.get('jdev@conference.jabber.org');
@ -832,9 +804,7 @@ describe("Groupchats", function () {
}); });
it("restores cached messages when it reconnects and clear_messages_on_reconnection and muc_clear_messages_on_leave are false", it("restores cached messages when it reconnects and clear_messages_on_reconnection and muc_clear_messages_on_leave are false",
mock.initConverse( mock.initConverse([], {
['rosterContactsFetched'],
{
'clear_messages_on_reconnection': false, 'clear_messages_on_reconnection': false,
'muc_clear_messages_on_leave': false 'muc_clear_messages_on_leave': false
}, },
@ -865,9 +835,7 @@ describe("Groupchats", function () {
it("clears cached messages when it reconnects and clear_messages_on_reconnection is true", it("clears cached messages when it reconnects and clear_messages_on_reconnection is true",
mock.initConverse( mock.initConverse([], {'clear_messages_on_reconnection': true}, async function (done, _converse) {
['rosterContactsFetched'], {'clear_messages_on_reconnection': true},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid , 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid , 'romeo');
@ -892,9 +860,7 @@ describe("Groupchats", function () {
})); }));
it("is opened when an xmpp: URI is clicked inside another groupchat", it("is opened when an xmpp: URI is clicked inside another groupchat",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
@ -921,9 +887,7 @@ describe("Groupchats", function () {
})); }));
it("shows a notification if it's not anonymous", it("shows a notification if it's not anonymous",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'coven@chat.shakespeare.lit'; const muc_jid = 'coven@chat.shakespeare.lit';
const nick = 'romeo'; const nick = 'romeo';
@ -968,9 +932,7 @@ describe("Groupchats", function () {
it("shows join/leave messages when users enter or exit a groupchat", it("shows join/leave messages when users enter or exit a groupchat",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {'muc_fetch_members': false}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {'muc_fetch_members': false},
async function (done, _converse) {
const muc_jid = 'coven@chat.shakespeare.lit'; const muc_jid = 'coven@chat.shakespeare.lit';
const nick = 'some1'; const nick = 'some1';
@ -1240,9 +1202,7 @@ describe("Groupchats", function () {
})); }));
it("combines subsequent join/leave messages when users enter or exit a groupchat", it("combines subsequent join/leave messages when users enter or exit a groupchat",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.openAndEnterChatRoom(_converse, 'coven@chat.shakespeare.lit', 'romeo') await mock.openAndEnterChatRoom(_converse, 'coven@chat.shakespeare.lit', 'romeo')
const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit'); const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
@ -1378,9 +1338,7 @@ describe("Groupchats", function () {
})); }));
it("doesn't show the disconnection messages when join_leave_events is not in muc_show_info_messages setting", it("doesn't show the disconnection messages when join_leave_events is not in muc_show_info_messages setting",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {'muc_show_info_messages': []}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {'muc_show_info_messages': []},
async function (done, _converse) {
spyOn(_converse.ChatRoom.prototype, 'onOccupantAdded').and.callThrough(); spyOn(_converse.ChatRoom.prototype, 'onOccupantAdded').and.callThrough();
spyOn(_converse.ChatRoom.prototype, 'onOccupantRemoved').and.callThrough(); spyOn(_converse.ChatRoom.prototype, 'onOccupantRemoved').and.callThrough();
@ -1419,9 +1377,7 @@ describe("Groupchats", function () {
})); }));
it("role-change messages that follow a MUC leave are left out", it("role-change messages that follow a MUC leave are left out",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
// See https://github.com/conversejs/converse.js/issues/1259 // See https://github.com/conversejs/converse.js/issues/1259
@ -1475,11 +1431,7 @@ describe("Groupchats", function () {
done(); done();
})); }));
it("can be configured if you're its owner", it("can be configured if you're its owner", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
let sent_IQ, IQ_id; let sent_IQ, IQ_id;
const sendIQ = _converse.connection.sendIQ; const sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
@ -1687,12 +1639,9 @@ describe("Groupchats", function () {
})); }));
it("shows all members even if they're not currently present in the groupchat", it("shows all members even if they're not currently present in the groupchat",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit' const muc_jid = 'lounge@montague.lit'
const members = [{ const members = [{
'nick': 'juliet', 'nick': 'juliet',
'jid': 'juliet@capulet.lit', 'jid': 'juliet@capulet.lit',
@ -1770,9 +1719,7 @@ describe("Groupchats", function () {
})); }));
it("shows users currently present in the groupchat", it("shows users currently present in the groupchat",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
var view = _converse.chatboxviews.get('lounge@montague.lit'); var view = _converse.chatboxviews.get('lounge@montague.lit');
@ -1824,9 +1771,7 @@ describe("Groupchats", function () {
})); }));
it("indicates moderators and visitors by means of a special css class and tooltip", it("indicates moderators and visitors by means of a special css class and tooltip",
mock.initConverse( mock.initConverse([], {'view_mode': 'fullscreen'}, async function (done, _converse) {
['rosterContactsFetched'], {'view_mode': 'fullscreen'},
async function (done, _converse) {
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
const view = _converse.chatboxviews.get('lounge@montague.lit'); const view = _converse.chatboxviews.get('lounge@montague.lit');
@ -1890,9 +1835,7 @@ describe("Groupchats", function () {
})); }));
it("properly handles notification that a room has been destroyed", it("properly handles notification that a room has been destroyed",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.openChatRoomViaModal(_converse, 'problematic@muc.montague.lit', 'romeo') await mock.openChatRoomViaModal(_converse, 'problematic@muc.montague.lit', 'romeo')
const presence = $pres().attrs({ const presence = $pres().attrs({
@ -1920,9 +1863,7 @@ describe("Groupchats", function () {
})); }));
it("will use the user's reserved nickname, if it exists", it("will use the user's reserved nickname, if it exists",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const IQ_stanzas = _converse.connection.IQ_stanzas; const IQ_stanzas = _converse.connection.IQ_stanzas;
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
@ -2013,9 +1954,7 @@ describe("Groupchats", function () {
})); }));
it("allows the user to invite their roster contacts to enter the groupchat", it("allows the user to invite their roster contacts to enter the groupchat",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {'view_mode': 'fullscreen'}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {'view_mode': 'fullscreen'},
async function (done, _converse) {
// We need roster contacts, so that we have someone to invite // We need roster contacts, so that we have someone to invite
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
@ -2092,9 +2031,7 @@ describe("Groupchats", function () {
})); }));
it("can be joined automatically, based upon a received invite", it("can be joined automatically, based upon a received invite",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); // We need roster contacts, who can invite us await mock.waitForRoster(_converse, 'current'); // We need roster contacts, who can invite us
const name = mock.cur_names[0]; const name = mock.cur_names[0];
@ -2128,9 +2065,7 @@ describe("Groupchats", function () {
})); }));
it("shows received groupchat messages", it("shows received groupchat messages",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const text = 'This is a received message'; const text = 'This is a received message';
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
@ -2159,11 +2094,7 @@ describe("Groupchats", function () {
done(); done();
})); }));
it("shows sent groupchat messages", it("shows sent groupchat messages", mock.initConverse([], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
spyOn(_converse.api, "trigger").and.callThrough(); spyOn(_converse.api, "trigger").and.callThrough();
const view = _converse.chatboxviews.get('lounge@montague.lit'); const view = _converse.chatboxviews.get('lounge@montague.lit');
@ -2206,9 +2137,7 @@ describe("Groupchats", function () {
})); }));
it("will cause the chat area to be scrolled down only if it was at the bottom already", it("will cause the chat area to be scrolled down only if it was at the bottom already",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const message = 'This message is received while the chat area is scrolled up'; const message = 'This message is received while the chat area is scrolled up';
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
@ -2248,9 +2177,7 @@ describe("Groupchats", function () {
})); }));
it("reconnects when no-acceptable error is returned when sending a message", it("reconnects when no-acceptable error is returned when sending a message",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'coven@chat.shakespeare.lit'; const muc_jid = 'coven@chat.shakespeare.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -2303,9 +2230,7 @@ describe("Groupchats", function () {
it("informs users if the room configuration has changed", it("informs users if the room configuration has changed",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'coven@chat.shakespeare.lit'; const muc_jid = 'coven@chat.shakespeare.lit';
await mock.openAndEnterChatRoom(_converse, 'coven@chat.shakespeare.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'coven@chat.shakespeare.lit', 'romeo');
@ -2330,9 +2255,7 @@ describe("Groupchats", function () {
it("informs users if their nicknames have been changed.", it("informs users if their nicknames have been changed.",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
/* The service then sends two presence stanzas to the full JID /* The service then sends two presence stanzas to the full JID
* of each occupant (including the occupant who is changing his * of each occupant (including the occupant who is changing his
@ -2435,9 +2358,7 @@ describe("Groupchats", function () {
})); }));
it("queries for the groupchat information before attempting to join the user", it("queries for the groupchat information before attempting to join the user",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const nick = "some1"; const nick = "some1";
const IQ_stanzas = _converse.connection.IQ_stanzas; const IQ_stanzas = _converse.connection.IQ_stanzas;
@ -2511,9 +2432,7 @@ describe("Groupchats", function () {
})); }));
it("updates the shown features when the groupchat configuration has changed", it("updates the shown features when the groupchat configuration has changed",
mock.initConverse( mock.initConverse([], {'view_mode': 'fullscreen'}, async function (done, _converse) {
['rosterContactsFetched'], {'view_mode': 'fullscreen'},
async function (done, _converse) {
let features = [ let features = [
'http://jabber.org/protocol/muc', 'http://jabber.org/protocol/muc',
@ -2717,9 +2636,7 @@ describe("Groupchats", function () {
})); }));
it("indicates when a room is no longer anonymous", it("indicates when a room is no longer anonymous",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
let IQ_id; let IQ_id;
const sendIQ = _converse.connection.sendIQ; const sendIQ = _converse.connection.sendIQ;
@ -2766,9 +2683,7 @@ describe("Groupchats", function () {
})); }));
it("informs users if they have been kicked out of the groupchat", it("informs users if they have been kicked out of the groupchat",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
/* <presence /* <presence
* from='harfleur@chat.shakespeare.lit/pistol' * from='harfleur@chat.shakespeare.lit/pistol'
@ -2823,9 +2738,7 @@ describe("Groupchats", function () {
})); }));
it("informs users if they have exited the groupchat due to a technical reason", it("informs users if they have exited the groupchat due to a technical reason",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
/* <presence /* <presence
* from='harfleur@chat.shakespeare.lit/pistol' * from='harfleur@chat.shakespeare.lit/pistol'
@ -2875,9 +2788,7 @@ describe("Groupchats", function () {
it("can be saved to, and retrieved from, browserStorage", it("can be saved to, and retrieved from, browserStorage",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.openChatRoom(_converse, 'lounge', 'montague.lit', 'romeo'); await mock.openChatRoom(_converse, 'lounge', 'montague.lit', 'romeo');
// We instantiate a new ChatBoxes collection, which by default // We instantiate a new ChatBoxes collection, which by default
@ -2909,9 +2820,7 @@ describe("Groupchats", function () {
})); }));
it("can be closed again by clicking a DOM element with class 'close-chatbox-button'", it("can be closed again by clicking a DOM element with class 'close-chatbox-button'",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.openChatRoom(_converse, 'lounge', 'montague.lit', 'romeo'); await mock.openChatRoom(_converse, 'lounge', 'montague.lit', 'romeo');
const view = _converse.chatboxviews.get('lounge@montague.lit'); const view = _converse.chatboxviews.get('lounge@montague.lit');
@ -2930,9 +2839,7 @@ describe("Groupchats", function () {
})); }));
it("informs users of role and affiliation changes", it("informs users of role and affiliation changes",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -3001,9 +2908,7 @@ describe("Groupchats", function () {
})); }));
it("notifies users of role and affiliation changes for members not currently in the groupchat", it("notifies users of role and affiliation changes for members not currently in the groupchat",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -3048,9 +2953,7 @@ describe("Groupchats", function () {
describe("Each chat groupchat can take special commands", function () { describe("Each chat groupchat can take special commands", function () {
it("takes /help to show the available commands", it("takes /help to show the available commands",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
spyOn(window, 'confirm').and.callFake(() => true); spyOn(window, 'confirm').and.callFake(() => true);
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
@ -3147,9 +3050,7 @@ describe("Groupchats", function () {
})); }));
it("takes /help to show the available commands and commands can be disabled by config", it("takes /help to show the available commands and commands can be disabled by config",
mock.initConverse( mock.initConverse([], {muc_disable_slash_commands: ['mute', 'voice']}, async function (done, _converse) {
['rosterContactsFetched'], {muc_disable_slash_commands: ['mute', 'voice']},
async function (done, _converse) {
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
const view = _converse.chatboxviews.get('lounge@montague.lit'); const view = _converse.chatboxviews.get('lounge@montague.lit');
@ -3185,9 +3086,7 @@ describe("Groupchats", function () {
})); }));
it("takes /member to make an occupant a member", it("takes /member to make an occupant a member",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
let iq_stanza; let iq_stanza;
await mock.openAndEnterChatRoom(_converse, 'lounge@muc.montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'lounge@muc.montague.lit', 'romeo');
@ -3329,11 +3228,7 @@ describe("Groupchats", function () {
done(); done();
})); }));
it("takes /topic to set the groupchat topic", it("takes /topic to set the groupchat topic", mock.initConverse([], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
const view = _converse.chatboxviews.get('lounge@montague.lit'); const view = _converse.chatboxviews.get('lounge@montague.lit');
spyOn(view, 'clearMessages'); spyOn(view, 'clearMessages');
@ -3393,11 +3288,7 @@ describe("Groupchats", function () {
done(); done();
})); }));
it("takes /clear to clear messages", it("takes /clear to clear messages", mock.initConverse([], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo'); await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
const view = _converse.chatboxviews.get('lounge@montague.lit'); const view = _converse.chatboxviews.get('lounge@montague.lit');
spyOn(view, 'clearMessages'); spyOn(view, 'clearMessages');
@ -3412,11 +3303,7 @@ describe("Groupchats", function () {
done(); done();
})); }));
it("takes /owner to make a user an owner", it("takes /owner to make a user an owner", mock.initConverse([], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched'], {},
async function (done, _converse) {
let sent_IQ, IQ_id; let sent_IQ, IQ_id;
const sendIQ = _converse.connection.sendIQ; const sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
@ -3504,11 +3391,7 @@ describe("Groupchats", function () {
done(); done();
})); }));
it("takes /ban to ban a user", it("takes /ban to ban a user", mock.initConverse([], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched'], {},
async function (done, _converse) {
let sent_IQ, IQ_id; let sent_IQ, IQ_id;
const sendIQ = _converse.connection.sendIQ; const sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
@ -3604,11 +3487,7 @@ describe("Groupchats", function () {
})); }));
it("takes a /kick command to kick a user", it("takes a /kick command to kick a user", mock.initConverse([], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched'], {},
async function (done, _converse) {
let sent_IQ, IQ_id; let sent_IQ, IQ_id;
const sendIQ = _converse.connection.sendIQ; const sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) { spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
@ -3697,9 +3576,7 @@ describe("Groupchats", function () {
it("takes /op and /deop to make a user a moderator or not", it("takes /op and /deop to make a user a moderator or not",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -3838,9 +3715,7 @@ describe("Groupchats", function () {
})); }));
it("takes /mute and /voice to mute and unmute a user", it("takes /mute and /voice to mute and unmute a user",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -3976,9 +3851,7 @@ describe("Groupchats", function () {
})); }));
it("takes /destroy to destroy a muc", it("takes /destroy to destroy a muc",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
const new_muc_jid = 'foyer@montague.lit'; const new_muc_jid = 'foyer@montague.lit';
@ -4071,8 +3944,7 @@ describe("Groupchats", function () {
describe("When attempting to enter a groupchat", function () { describe("When attempting to enter a groupchat", function () {
it("will use the nickname set in the global settings if the user doesn't have a VCard nickname", it("will use the nickname set in the global settings if the user doesn't have a VCard nickname",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {'nickname': 'Benedict-Cucumberpatch'},
['rosterContactsFetched', 'chatBoxesFetched'], {'nickname': 'Benedict-Cucumberpatch'},
async function (done, _converse) { async function (done, _converse) {
await mock.openChatRoomViaModal(_converse, 'roomy@muc.montague.lit'); await mock.openChatRoomViaModal(_converse, 'roomy@muc.montague.lit');
@ -4082,9 +3954,7 @@ describe("Groupchats", function () {
})); }));
it("will show an error message if the groupchat requires a password", it("will show an error message if the groupchat requires a password",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'protected'; const muc_jid = 'protected';
await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo'); await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo');
@ -4118,9 +3988,7 @@ describe("Groupchats", function () {
})); }));
it("will show an error message if the groupchat is members-only and the user not included", it("will show an error message if the groupchat is members-only and the user not included",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'members-only@muc.montague.lit' const muc_jid = 'members-only@muc.montague.lit'
await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo'); await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo');
@ -4167,9 +4035,7 @@ describe("Groupchats", function () {
})); }));
it("will show an error message if the user has been banned", it("will show an error message if the user has been banned",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'off-limits@muc.montague.lit' const muc_jid = 'off-limits@muc.montague.lit'
await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo'); await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo');
@ -4212,9 +4078,7 @@ describe("Groupchats", function () {
})); }));
it("will render a nickname form if a nickname conflict happens and muc_nickname_from_jid=false", it("will render a nickname form if a nickname conflict happens and muc_nickname_from_jid=false",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'conflicted@muc.montague.lit'; const muc_jid = 'conflicted@muc.montague.lit';
await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo'); await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo');
@ -4257,9 +4121,7 @@ describe("Groupchats", function () {
it("will automatically choose a new nickname if a nickname conflict happens and muc_nickname_from_jid=true", it("will automatically choose a new nickname if a nickname conflict happens and muc_nickname_from_jid=true",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'conflicting@muc.montague.lit' const muc_jid = 'conflicting@muc.montague.lit'
await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo'); await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo');
@ -4317,9 +4179,7 @@ describe("Groupchats", function () {
})); }));
it("will show an error message if the user is not allowed to have created the groupchat", it("will show an error message if the user is not allowed to have created the groupchat",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'impermissable@muc.montague.lit' const muc_jid = 'impermissable@muc.montague.lit'
await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo') await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo')
@ -4357,9 +4217,7 @@ describe("Groupchats", function () {
})); }));
it("will show an error message if the user's nickname doesn't conform to groupchat policy", it("will show an error message if the user's nickname doesn't conform to groupchat policy",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'conformist@muc.montague.lit' const muc_jid = 'conformist@muc.montague.lit'
await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo'); await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo');
@ -4398,9 +4256,7 @@ describe("Groupchats", function () {
})); }));
it("will show an error message if the groupchat doesn't yet exist", it("will show an error message if the groupchat doesn't yet exist",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'nonexistent@muc.montague.lit' const muc_jid = 'nonexistent@muc.montague.lit'
await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo'); await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo');
@ -4439,9 +4295,7 @@ describe("Groupchats", function () {
})); }));
it("will show an error message if the groupchat has reached its maximum number of participants", it("will show an error message if the groupchat has reached its maximum number of participants",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'maxed-out@muc.montague.lit' const muc_jid = 'maxed-out@muc.montague.lit'
await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo') await mock.openChatRoomViaModal(_converse, muc_jid, 'romeo')
@ -4483,9 +4337,7 @@ describe("Groupchats", function () {
describe("Someone being invited to a groupchat", function () { describe("Someone being invited to a groupchat", function () {
it("will first be added to the member list if the groupchat is members only", it("will first be added to the member list if the groupchat is members only",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 0); await mock.waitForRoster(_converse, 'current', 0);
spyOn(_converse.ChatRoomOccupants.prototype, 'fetchMembers').and.callThrough(); spyOn(_converse.ChatRoomOccupants.prototype, 'fetchMembers').and.callThrough();
@ -4630,11 +4482,7 @@ describe("Groupchats", function () {
describe("The affiliations delta", function () { describe("The affiliations delta", function () {
it("can be computed in various ways", it("can be computed in various ways", mock.initConverse([], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.openChatRoom(_converse, 'coven', 'chat.shakespeare.lit', 'romeo'); await mock.openChatRoom(_converse, 'coven', 'chat.shakespeare.lit', 'romeo');
var exclude_existing = false; var exclude_existing = false;
var remove_absentees = false; var remove_absentees = false;
@ -4698,9 +4546,7 @@ describe("Groupchats", function () {
describe("The \"Groupchats\" Add modal", function () { describe("The \"Groupchats\" Add modal", function () {
it("can be opened from a link in the \"Groupchats\" section of the controlbox", it("can be opened from a link in the \"Groupchats\" section of the controlbox",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
await mock.waitForRoster(_converse, 'current', 0); await mock.waitForRoster(_converse, 'current', 0);
@ -4740,9 +4586,7 @@ describe("Groupchats", function () {
})); }));
it("doesn't show the nickname field if locked_muc_nickname is true", it("doesn't show the nickname field if locked_muc_nickname is true",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {'locked_muc_nickname': true, 'muc_nickname_from_jid': true}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {'locked_muc_nickname': true, 'muc_nickname_from_jid': true},
async function (done, _converse) {
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
await mock.waitForRoster(_converse, 'current', 0); await mock.waitForRoster(_converse, 'current', 0);
@ -4763,9 +4607,7 @@ describe("Groupchats", function () {
})); }));
it("uses the JID node if muc_nickname_from_jid is set to true", it("uses the JID node if muc_nickname_from_jid is set to true",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {'muc_nickname_from_jid': true}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {'muc_nickname_from_jid': true},
async function (done, _converse) {
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
await mock.waitForRoster(_converse, 'current', 0); await mock.waitForRoster(_converse, 'current', 0);
@ -4782,9 +4624,7 @@ describe("Groupchats", function () {
})); }));
it("uses the nickname passed in to converse.initialize", it("uses the nickname passed in to converse.initialize",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {'nickname': 'st.nick'}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {'nickname': 'st.nick'},
async function (done, _converse) {
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
await mock.waitForRoster(_converse, 'current', 0); await mock.waitForRoster(_converse, 'current', 0);
@ -4801,9 +4641,7 @@ describe("Groupchats", function () {
})); }));
it("doesn't require the domain when muc_domain is set", it("doesn't require the domain when muc_domain is set",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {'muc_domain': 'muc.example.org'}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {'muc_domain': 'muc.example.org'},
async function (done, _converse) {
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list'); const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list');
@ -4841,8 +4679,7 @@ describe("Groupchats", function () {
})); }));
it("only uses the muc_domain is locked_muc_domain is true", it("only uses the muc_domain is locked_muc_domain is true",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {'muc_domain': 'muc.example.org', 'locked_muc_domain': true},
['rosterContactsFetched', 'chatBoxesFetched'], {'muc_domain': 'muc.example.org', 'locked_muc_domain': true},
async function (done, _converse) { async function (done, _converse) {
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
@ -4883,9 +4720,7 @@ describe("Groupchats", function () {
describe("The \"Groupchats\" List modal", function () { describe("The \"Groupchats\" List modal", function () {
it("can be opened from a link in the \"Groupchats\" section of the controlbox", it("can be opened from a link in the \"Groupchats\" section of the controlbox",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list'); const roomspanel = _converse.chatboxviews.get('controlbox').querySelector('converse-rooms-list');
@ -4960,7 +4795,7 @@ describe("Groupchats", function () {
it("is pre-filled with the muc_domain", it("is pre-filled with the muc_domain",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], ['chatBoxesFetched'],
{'muc_domain': 'muc.example.org'}, {'muc_domain': 'muc.example.org'},
async function (done, _converse) { async function (done, _converse) {
@ -4977,7 +4812,7 @@ describe("Groupchats", function () {
it("doesn't let you set the MUC domain if it's locked", it("doesn't let you set the MUC domain if it's locked",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], ['chatBoxesFetched'],
{'muc_domain': 'chat.shakespeare.lit', 'locked_muc_domain': true}, {'muc_domain': 'chat.shakespeare.lit', 'locked_muc_domain': true},
async function (done, _converse) { async function (done, _converse) {
@ -5028,7 +4863,7 @@ describe("Groupchats", function () {
it("shows the number of unread mentions received", it("shows the number of unread mentions received",
mock.initConverse( mock.initConverse(
['rosterContactsFetched'], {'allow_bookmarks': false}, [], {'allow_bookmarks': false},
async function (done, _converse) { async function (done, _converse) {
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
@ -5078,7 +4913,7 @@ describe("Groupchats", function () {
it("is is not sent out to a MUC if the user is a visitor in a moderated room", it("is is not sent out to a MUC if the user is a visitor in a moderated room",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
spyOn(_converse.ChatRoom.prototype, 'sendChatState').and.callThrough(); spyOn(_converse.ChatRoom.prototype, 'sendChatState').and.callThrough();
@ -5130,11 +4965,7 @@ describe("Groupchats", function () {
describe("A composing notification", function () { describe("A composing notification", function () {
it("will be shown if received", it("will be shown if received", mock.initConverse([], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'coven@chat.shakespeare.lit'; const muc_jid = 'coven@chat.shakespeare.lit';
const members = [ const members = [
{'affiliation': 'member', 'nick': 'majortom', 'jid': 'majortom@example.org'}, {'affiliation': 'member', 'nick': 'majortom', 'jid': 'majortom@example.org'},
@ -5255,11 +5086,7 @@ describe("Groupchats", function () {
describe("A paused notification", function () { describe("A paused notification", function () {
it("will be shown if received", it("will be shown if received", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'coven@chat.shakespeare.lit'; const muc_jid = 'coven@chat.shakespeare.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'some1'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'some1');
const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit'); const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
@ -5359,9 +5186,7 @@ describe("Groupchats", function () {
describe("A muted user", function () { describe("A muted user", function () {
it("will receive a user-friendly error message when trying to send a message", it("will receive a user-friendly error message when trying to send a message",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'trollbox@montague.lit'; const muc_jid = 'trollbox@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'troll'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'troll');
@ -5409,9 +5234,7 @@ describe("Groupchats", function () {
})); }));
it("will see an explanatory message instead of a textarea", it("will see an explanatory message instead of a textarea",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const features = [ const features = [
'http://jabber.org/protocol/muc', 'http://jabber.org/protocol/muc',
@ -5487,9 +5310,7 @@ describe("Groupchats", function () {
describe("when muc_send_probes is true", function () { describe("when muc_send_probes is true", function () {
it("sends presence probes when muc_send_probes is true", it("sends presence probes when muc_send_probes is true",
mock.initConverse( mock.initConverse([], {'muc_send_probes': true}, async function (done, _converse) {
['rosterContactsFetched'], {'muc_send_probes': true},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');

View File

@ -12,9 +12,7 @@ describe("A Groupchat Message", function () {
describe("which is succeeded by an error message", function () { describe("which is succeeded by an error message", function () {
it("will have the error displayed below it", it("will have the error displayed below it",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -57,9 +55,7 @@ describe("A Groupchat Message", function () {
describe("an info message", function () { describe("an info message", function () {
it("is not rendered as a followup message", it("is not rendered as a followup message",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -95,9 +91,7 @@ describe("A Groupchat Message", function () {
})); }));
it("is not shown if its a duplicate", it("is not shown if its a duplicate",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -130,9 +124,7 @@ describe("A Groupchat Message", function () {
it("is rejected if it's an unencapsulated forwarded message", it("is rejected if it's an unencapsulated forwarded message",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -165,9 +157,7 @@ describe("A Groupchat Message", function () {
})); }));
it("can contain a chat state notification and will still be shown", it("can contain a chat state notification and will still be shown",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -190,9 +180,7 @@ describe("A Groupchat Message", function () {
})); }));
it("can not be expected to have a unique id attribute", it("can not be expected to have a unique id attribute",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -221,9 +209,7 @@ describe("A Groupchat Message", function () {
})); }));
it("is ignored if it has the same archive-id of an already received one", it("is ignored if it has the same archive-id of an already received one",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'room@muc.example.com'; const muc_jid = 'room@muc.example.com';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -270,9 +256,7 @@ describe("A Groupchat Message", function () {
})); }));
it("is ignored if it has the same stanza-id of an already received one", it("is ignored if it has the same stanza-id of an already received one",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'room@muc.example.com'; const muc_jid = 'room@muc.example.com';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -318,9 +302,7 @@ describe("A Groupchat Message", function () {
})); }));
it("will be discarded if it's a malicious message meant to look like a carbon copy", it("will be discarded if it's a malicious message meant to look like a carbon copy",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
@ -377,9 +359,7 @@ describe("A Groupchat Message", function () {
})); }));
it("keeps track of the sender's role and affiliation", it("keeps track of the sender's role and affiliation",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -505,9 +485,7 @@ describe("A Groupchat Message", function () {
it("keeps track whether you are the sender or not", it("keeps track whether you are the sender or not",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -525,9 +503,7 @@ describe("A Groupchat Message", function () {
})); }));
it("will be shown as received upon MUC reflection", it("will be shown as received upon MUC reflection",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
@ -568,9 +544,7 @@ describe("A Groupchat Message", function () {
})); }));
it("gets updated with its stanza-id upon MUC reflection", it("gets updated with its stanza-id upon MUC reflection",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
const muc_jid = 'room@muc.example.com'; const muc_jid = 'room@muc.example.com';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -603,9 +577,7 @@ describe("A Groupchat Message", function () {
})); }));
it("can cause a delivery receipt to be returned", it("can cause a delivery receipt to be returned",
mock.initConverse( mock.initConverse([], {}, async function (done, _converse) {
['rosterContactsFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';

View File

@ -9,7 +9,7 @@ describe("XEP-0437 Room Activity Indicators", function () {
it("will be activated for a MUC that becomes hidden", it("will be activated for a MUC that becomes hidden",
mock.initConverse( mock.initConverse(
['rosterContactsFetched'], { [], {
'allow_bookmarks': false, // Hack to get the rooms list to render 'allow_bookmarks': false, // Hack to get the rooms list to render
'muc_subscribe_to_rai': true, 'muc_subscribe_to_rai': true,
'view_mode': 'fullscreen'}, 'view_mode': 'fullscreen'},
@ -96,8 +96,7 @@ describe("XEP-0437 Room Activity Indicators", function () {
await u.waitUntil(() => view.model.session.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED); await u.waitUntil(() => view.model.session.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED);
expect(view.model.get('has_activity')).toBe(false); expect(view.model.get('has_activity')).toBe(false);
const lview = _converse.rooms_list_view const room_el = await u.waitUntil(() => document.querySelector("converse-rooms-list .available-chatroom"));
const room_el = await u.waitUntil(() => lview.querySelector(".available-chatroom"));
expect(Array.from(room_el.classList).includes('unread-msgs')).toBeFalsy(); expect(Array.from(room_el.classList).includes('unread-msgs')).toBeFalsy();
const activity_stanza = u.toStanza(` const activity_stanza = u.toStanza(`
@ -116,7 +115,7 @@ describe("XEP-0437 Room Activity Indicators", function () {
it("will be activated for a MUC that starts out hidden", it("will be activated for a MUC that starts out hidden",
mock.initConverse( mock.initConverse(
['rosterContactsFetched'], { [], {
'allow_bookmarks': false, // Hack to get the rooms list to render 'allow_bookmarks': false, // Hack to get the rooms list to render
'muc_subscribe_to_rai': true, 'muc_subscribe_to_rai': true,
'view_mode': 'fullscreen'}, 'view_mode': 'fullscreen'},
@ -160,8 +159,7 @@ describe("XEP-0437 Room Activity Indicators", function () {
await u.waitUntil(() => view.model.session.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED); await u.waitUntil(() => view.model.session.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED);
expect(view.model.get('has_activity')).toBe(false); expect(view.model.get('has_activity')).toBe(false);
const lview = _converse.rooms_list_view const room_el = await u.waitUntil(() => document.querySelector("converse-rooms-list .available-chatroom"));
const room_el = await u.waitUntil(() => lview.querySelector(".available-chatroom"));
expect(Array.from(room_el.classList).includes('unread-msgs')).toBeFalsy(); expect(Array.from(room_el.classList).includes('unread-msgs')).toBeFalsy();
const activity_stanza = u.toStanza(` const activity_stanza = u.toStanza(`
@ -181,7 +179,7 @@ describe("XEP-0437 Room Activity Indicators", function () {
it("may not be activated due to server resource constraints", it("may not be activated due to server resource constraints",
mock.initConverse( mock.initConverse(
['rosterContactsFetched'], { [], {
'allow_bookmarks': false, // Hack to get the rooms list to render 'allow_bookmarks': false, // Hack to get the rooms list to render
'muc_subscribe_to_rai': true, 'muc_subscribe_to_rai': true,
'view_mode': 'fullscreen'}, 'view_mode': 'fullscreen'},

View File

@ -8,7 +8,7 @@ describe("A delivery receipt", function () {
it("is emitted for a received message which requests it", it("is emitted for a received message which requests it",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current'); await mock.waitForRoster(_converse, 'current');
@ -34,7 +34,7 @@ describe("A delivery receipt", function () {
it("is not emitted for a carbon message", it("is not emitted for a carbon message",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
@ -64,7 +64,7 @@ describe("A delivery receipt", function () {
it("is not emitted for an archived message", it("is not emitted for an archived message",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
@ -101,7 +101,7 @@ describe("A delivery receipt", function () {
it("can be received for a sent message", it("can be received for a sent message",
mock.initConverse( mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {}, ['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);

View File

@ -37,9 +37,7 @@ describe("Message Retractions", function () {
describe("A groupchat message retraction", function () { describe("A groupchat message retraction", function () {
it("is not applied if it's not from the right author", it("is not applied if it's not from the right author",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
const features = [...mock.default_muc_features, Strophe.NS.MODERATE]; const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
@ -81,9 +79,7 @@ describe("Message Retractions", function () {
})); }));
it("can be received before the message it pertains to", it("can be received before the message it pertains to",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const date = (new Date()).toISOString(); const date = (new Date()).toISOString();
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
@ -137,9 +133,7 @@ describe("Message Retractions", function () {
describe("A groupchat message moderator retraction", function () { describe("A groupchat message moderator retraction", function () {
it("can be received before the message it pertains to", it("can be received before the message it pertains to",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const date = (new Date()).toISOString(); const date = (new Date()).toISOString();
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
@ -198,9 +192,7 @@ describe("Message Retractions", function () {
describe("A message retraction", function () { describe("A message retraction", function () {
it("can be received before the message it pertains to", it("can be received before the message it pertains to",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const date = (new Date()).toISOString(); const date = (new Date()).toISOString();
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
@ -255,11 +247,7 @@ describe("Message Retractions", function () {
describe("A Received Chat Message", function () { describe("A Received Chat Message", function () {
it("can be followed up by a retraction", it("can be followed up by a retraction", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
await mock.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], [Strophe.NS.SID]); await mock.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], [Strophe.NS.SID]);
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
@ -325,11 +313,7 @@ describe("Message Retractions", function () {
describe("A Sent Chat Message", function () { describe("A Sent Chat Message", function () {
it("can be retracted by its author", it("can be retracted by its author", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
const view = await mock.openChatBoxFor(_converse, contact_jid); const view = await mock.openChatBoxFor(_converse, contact_jid);
@ -375,11 +359,7 @@ describe("Message Retractions", function () {
describe("A Received Groupchat Message", function () { describe("A Received Groupchat Message", function () {
it("can be followed up by a retraction by the author", it("can be followed up by a retraction by the author", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
const features = [...mock.default_muc_features, Strophe.NS.MODERATE]; const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
@ -420,9 +400,7 @@ describe("Message Retractions", function () {
it("can be retracted by a moderator, with the IQ response received before the retraction message", it("can be retracted by a moderator, with the IQ response received before the retraction message",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
const features = [...mock.default_muc_features, Strophe.NS.MODERATE]; const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
@ -506,9 +484,7 @@ describe("Message Retractions", function () {
})); }));
it("can not be retracted if the MUC doesn't support message moderation", it("can not be retracted if the MUC doesn't support message moderation",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo'); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
@ -532,9 +508,7 @@ describe("Message Retractions", function () {
it("can be retracted by a moderator, with the retraction message received before the IQ response", it("can be retracted by a moderator, with the retraction message received before the IQ response",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
const features = [...mock.default_muc_features, Strophe.NS.MODERATE]; const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
@ -602,11 +576,7 @@ describe("Message Retractions", function () {
describe("A Sent Groupchat Message", function () { describe("A Sent Groupchat Message", function () {
it("can be retracted by its author", it("can be retracted by its author", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
const features = [...mock.default_muc_features, Strophe.NS.MODERATE]; const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
@ -661,9 +631,7 @@ describe("Message Retractions", function () {
})); }));
it("can be retracted by its author, causing an error message in response", it("can be retracted by its author, causing an error message in response",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
const features = [...mock.default_muc_features, Strophe.NS.MODERATE]; const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
@ -710,9 +678,7 @@ describe("Message Retractions", function () {
})); }));
it("can be retracted by its author, causing a timeout error in response", it("can be retracted by its author, causing a timeout error in response",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
_converse.STANZA_TIMEOUT = 1; _converse.STANZA_TIMEOUT = 1;
@ -746,11 +712,7 @@ describe("Message Retractions", function () {
})); }));
it("can be retracted by a moderator", it("can be retracted by a moderator", mock.initConverse(['chatBoxesFetched'], {}, async function (done, _converse) {
mock.initConverse(
['rosterContactsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
const features = [...mock.default_muc_features, Strophe.NS.MODERATE]; const features = [...mock.default_muc_features, Strophe.NS.MODERATE];
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features); await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo', features);
@ -799,9 +761,7 @@ describe("Message Retractions", function () {
})); }));
it("can be retracted by the sender if they're a moderator", it("can be retracted by the sender if they're a moderator",
mock.initConverse( mock.initConverse(['chatBoxesFetched'], {'allow_message_retraction': 'moderator'}, async function (done, _converse) {
['rosterContactsFetched', 'chatBoxesFetched'], {'allow_message_retraction': 'moderator'},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';
const features = [...mock.default_muc_features, Strophe.NS.MODERATE]; const features = [...mock.default_muc_features, Strophe.NS.MODERATE];

View File

@ -5,7 +5,7 @@ const { u, Promise, $msg } = converse.env;
describe("An incoming chat Message", function () { describe("An incoming chat Message", function () {
it("can have styling disabled via an \"unstyled\" element", it("can have styling disabled via an \"unstyled\" element",
mock.initConverse(['rosterContactsFetched', 'chatBoxesFetched'], {}, mock.initConverse(['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
const include_nick = false; const include_nick = false;
@ -37,7 +37,7 @@ describe("An incoming chat Message", function () {
it("can have styling disabled via the allow_message_styling setting", it("can have styling disabled via the allow_message_styling setting",
mock.initConverse(['rosterContactsFetched', 'chatBoxesFetched'], {'allow_message_styling': false}, mock.initConverse(['chatBoxesFetched'], {'allow_message_styling': false},
async function (done, _converse) { async function (done, _converse) {
const include_nick = false; const include_nick = false;
@ -67,7 +67,7 @@ describe("An incoming chat Message", function () {
})); }));
it("can be styled with span XEP-0393 message styling hints", it("can be styled with span XEP-0393 message styling hints",
mock.initConverse(['rosterContactsFetched', 'chatBoxesFetched'], {}, mock.initConverse(['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
let msg_text, msg, msg_el; let msg_text, msg, msg_el;
@ -192,7 +192,7 @@ describe("An incoming chat Message", function () {
})); }));
it("can be styled with block XEP-0393 message styling hints", it("can be styled with block XEP-0393 message styling hints",
mock.initConverse(['rosterContactsFetched', 'chatBoxesFetched'], {}, mock.initConverse(['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
let msg_text, msg, msg_el; let msg_text, msg, msg_el;
@ -240,7 +240,7 @@ describe("An incoming chat Message", function () {
})); }));
it("can be styled with quote XEP-0393 message styling hints", it("can be styled with quote XEP-0393 message styling hints",
mock.initConverse(['rosterContactsFetched', 'chatBoxesFetched'], {}, mock.initConverse(['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
let msg_text, msg, msg_el; let msg_text, msg, msg_el;
@ -392,7 +392,7 @@ describe("An incoming chat Message", function () {
describe("A outgoing groupchat Message", function () { describe("A outgoing groupchat Message", function () {
it("can be styled with span XEP-0393 message styling hints that contain mentions", it("can be styled with span XEP-0393 message styling hints that contain mentions",
mock.initConverse(['rosterContactsFetched', 'chatBoxesFetched'], {}, mock.initConverse(['chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
const muc_jid = 'lounge@montague.lit'; const muc_jid = 'lounge@montague.lit';

View File

@ -189,9 +189,10 @@ const ChatRoomMixin = {
return; return;
} }
if (msg?.get('is_markable') || force) { if (msg?.get('is_markable') || force) {
const id = msg.get(`stanza_id ${this.get('jid')}`); const key = `stanza_id ${this.get('jid')}`;
const id = msg.get(key);
if (!id) { if (!id) {
log.error(`Can't send marker for message without stanza ID: ${msg}`); log.error(`Can't send marker for message without stanza ID: ${key}`);
return; return;
} }
const from_jid = Strophe.getBareJidFromJid(msg.get('from')); const from_jid = Strophe.getBareJidFromJid(msg.get('from'));
@ -1923,6 +1924,7 @@ const ChatRoomMixin = {
} else if (attrs.is_valid_receipt_request || attrs.is_marker || this.ignorableCSN(attrs)) { } else if (attrs.is_valid_receipt_request || attrs.is_marker || this.ignorableCSN(attrs)) {
return; return;
} }
if ( if (
(await this.handleRetraction(attrs)) || (await this.handleRetraction(attrs)) ||
(await this.handleModeration(attrs)) || (await this.handleModeration(attrs)) ||