converse.js
Version:
Browser based XMPP chat client
253 lines (211 loc) • 14.1 kB
JavaScript
/*global mock, converse */
const Model = converse.env.Model;
const { Strophe, sizzle, u, stx } = converse.env;
describe("Groupchats", function () {
describe("The \"rooms\" API", function () {
it("has a method 'close' which closes rooms by JID or all rooms when called with no arguments",
mock.initConverse([], {}, async function (_converse) {
await mock.openAndEnterMUC(_converse, 'lounge@montague.lit', 'romeo');
const { api } = _converse;
const connection = api.connection.get();
connection.IQ_stanzas = [];
await mock.openAndEnterMUC(_converse, 'leisure@montague.lit', 'romeo');
connection.IQ_stanzas = [];
await mock.openAndEnterMUC(_converse, 'news@montague.lit', 'romeo');
expect(u.isVisible(_converse.chatboxviews.get('lounge@montague.lit'))).toBeTruthy();
expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit'))).toBeTruthy();
expect(u.isVisible(_converse.chatboxviews.get('news@montague.lit'))).toBeTruthy();
_converse.chatboxviews.get('lounge@montague.lit').close();
await u.waitUntil(() => !_converse.chatboxviews.get('lounge@montague.lit'));
expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit'))).toBeTruthy();
expect(u.isVisible(_converse.chatboxviews.get('news@montague.lit'))).toBeTruthy();
_converse.chatboxviews.get('leisure@montague.lit').close();
await u.waitUntil(() => !_converse.chatboxviews.get('leisure@montague.lit'));
_converse.chatboxviews.get('news@montague.lit').close();
await u.waitUntil(() => !_converse.chatboxviews.get('news@montague.lit'));
expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined();
expect(_converse.chatboxviews.get('leisure@montague.lit')).toBeUndefined();
expect(_converse.chatboxviews.get('news@montague.lit')).toBeUndefined();
await mock.openAndEnterMUC(_converse, 'lounge@montague.lit', 'romeo');
await mock.openAndEnterMUC(_converse, 'leisure@montague.lit', 'romeo');
expect(u.isVisible(_converse.chatboxviews.get('lounge@montague.lit'))).toBeTruthy();
expect(u.isVisible(_converse.chatboxviews.get('leisure@montague.lit'))).toBeTruthy();
_converse.chatboxviews.get('leisure@montague.lit').close();
await u.waitUntil(() => !_converse.chatboxviews.get('leisure@montague.lit'));
_converse.chatboxviews.get('lounge@montague.lit').close();
await u.waitUntil(() => !_converse.chatboxviews.get('lounge@montague.lit'));
expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined();
expect(_converse.chatboxviews.get('leisure@montague.lit')).toBeUndefined();
}));
it("has a method 'get' which returns a wrapped groupchat (if it exists)",
mock.initConverse([], {}, async function (_converse) {
await mock.waitForRoster(_converse, 'current');
await mock.openControlBox(_converse);
const rosterview = document.querySelector('converse-roster');
await u.waitUntil(() => rosterview.querySelectorAll('.roster-group .group-toggle').length, 300);
let muc_jid = 'chillout@montague.lit';
await mock.openAndEnterMUC(_converse, muc_jid, 'romeo');
let room = await _converse.api.rooms.get(muc_jid);
expect(room instanceof Object).toBeTruthy();
let chatroomview = _converse.chatboxviews.get(muc_jid);
expect(chatroomview.is_chatroom).toBeTruthy();
expect(u.isVisible(chatroomview)).toBeTruthy();
await chatroomview.close();
// Test with mixed case
muc_jid = 'Leisure@montague.lit';
await mock.openAndEnterMUC(_converse, muc_jid, 'romeo');
room = await _converse.api.rooms.get(muc_jid);
expect(room instanceof Object).toBeTruthy();
chatroomview = _converse.chatboxviews.get(muc_jid.toLowerCase());
expect(u.isVisible(chatroomview)).toBeTruthy();
muc_jid = 'leisure@montague.lit';
room = await _converse.api.rooms.get(muc_jid);
expect(room instanceof Object).toBeTruthy();
chatroomview = _converse.chatboxviews.get(muc_jid.toLowerCase());
expect(u.isVisible(chatroomview)).toBeTruthy();
muc_jid = 'leiSure@montague.lit';
room = await _converse.api.rooms.get(muc_jid);
expect(room instanceof Object).toBeTruthy();
chatroomview = _converse.chatboxviews.get(muc_jid.toLowerCase());
expect(u.isVisible(chatroomview)).toBeTruthy();
chatroomview.close();
// Non-existing room
muc_jid = 'chillout2@montague.lit';
room = await _converse.api.rooms.get(muc_jid);
expect(room).toBe(null);
}));
it("has a method 'open' which opens (optionally configures) and returns a wrapped chat box",
mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) {
const { api } = _converse;
// Mock 'getDiscoInfo', otherwise the room won't be
// displayed as it waits first for the features to be returned
// (when it's a new room being created).
spyOn(_converse.ChatRoom.prototype, 'getDiscoInfo').and.callFake(() => Promise.resolve());
let jid = 'lounge@montague.lit';
const nick = 'romeo';
await mock.openControlBox(_converse);
await mock.waitForRoster(_converse, 'current');
const rosterview = document.querySelector('converse-roster');
await u.waitUntil(() => rosterview.querySelectorAll('.roster-group .group-toggle').length);
// Test on groupchat that's not yet open
let promise = _converse.api.rooms.open(jid);
await mock.waitForMUCDiscoInfo(_converse, jid);
await mock.waitForReservedNick(_converse, jid, nick);
let room = await promise;
expect(room instanceof Model).toBeTruthy();
let mucview = await u.waitUntil(() => _converse.chatboxviews.get(jid));
expect(mucview.is_chatroom).toBeTruthy();
await u.waitUntil(() => u.isVisible(mucview));
// Test again, now that the room exists.
room = await _converse.api.rooms.open(jid);
expect(room instanceof Model).toBeTruthy();
mucview = await u.waitUntil(() => _converse.chatboxviews.get(jid));
expect(mucview.is_chatroom).toBeTruthy();
expect(u.isVisible(mucview)).toBeTruthy();
await mucview.close();
// Test with mixed case in JID
jid = 'Leisure@montague.lit';
promise = _converse.api.rooms.open(jid);
await mock.waitForMUCDiscoInfo(_converse, jid);
await mock.waitForReservedNick(_converse, jid, nick);
room = await promise;
expect(room instanceof Model).toBeTruthy();
mucview = await u.waitUntil(() => _converse.chatboxviews.get(jid.toLowerCase()));
await u.waitUntil(() => u.isVisible(mucview));
jid = 'leisure@montague.lit';
room = await _converse.api.rooms.open(jid);
expect(room instanceof Model).toBeTruthy();
mucview = await u.waitUntil(() => _converse.chatboxviews.get(jid.toLowerCase()));
await u.waitUntil(() => u.isVisible(mucview));
jid = 'leiSure@montague.lit';
room = await _converse.api.rooms.open(jid);
expect(room instanceof Model).toBeTruthy();
mucview = await u.waitUntil(() => _converse.chatboxviews.get(jid.toLowerCase()));
await u.waitUntil(() => u.isVisible(mucview));
mucview.close();
api.settings.set('muc_instant_rooms', false);
// Test with configuration
jid = 'room@conference.example.org';
promise = _converse.api.rooms.open(jid, {
'nick': 'some1',
'auto_configure': true,
'roomconfig': {
'getmemberlist': ['moderator', 'participant'],
'changesubject': false,
'membersonly': true,
'persistentroom': true,
'publicroom': true,
'roomdesc': 'Welcome to this groupchat',
'whois': 'anyone'
}
});
await mock.waitForMUCDiscoInfo(_converse, jid);
room = await promise;
expect(room instanceof Model).toBeTruthy();
_converse.api.connection.get()._dataRecv(mock.createRequest(stx`
<presence xmlns="jabber:client" to="romeo@montague.lit/pda" from="room@conference.example.org/some1">
<x xmlns="http://jabber.org/protocol/muc#user">
<item affiliation="owner" jid="romeo@montague.lit/pda" role="moderator"/>
<status code="110"/>
<status code="201"/>
</x>
</presence>`));
const IQ_stanzas = _converse.api.connection.get().IQ_stanzas;
const iq = await u.waitUntil(() => IQ_stanzas.filter((s) => sizzle(`query[xmlns="${Strophe.NS.MUC_OWNER}"]`, s).length).pop());
expect(Strophe.serialize(iq)).toBe(
`<iq id="${iq.getAttribute('id')}" to="room@conference.example.org" type="get" xmlns="jabber:client">`+
`<query xmlns="http://jabber.org/protocol/muc#owner"/></iq>`);
const node = stx`
<iq xmlns="jabber:client"
type="result"
to="romeo@montague.lit/pda"
from="room@conference.example.org" id="${iq.getAttribute('id')}">
<query xmlns="http://jabber.org/protocol/muc#owner">
<x xmlns="jabber:x:data" type="form">
<title>Configuration for room@conference.example.org</title>
<instructions>Complete and submit this form to configure the room.</instructions>
<field var="FORM_TYPE" type="hidden">
<value>http://jabber.org/protocol/muc#roomconfig</value>
</field>
<field type="text-single" var="muc#roomconfig_roomname" label="Name">
<value>Room</value>
</field>
<field type="text-single" var="muc#roomconfig_roomdesc" label="Description"><value/></field>
<field type="boolean" var="muc#roomconfig_persistentroom" label="Make Room Persistent?"/>
<field type="boolean" var="muc#roomconfig_publicroom" label="Make Room Publicly Searchable?"><value>1</value></field>
<field type="boolean" var="muc#roomconfig_changesubject" label="Allow Occupants to Change Subject?"/>
<field type="list-single" var="muc#roomconfig_whois" label="Who May Discover Real JIDs?"><option label="Moderators Only">
<value>moderators</value></option><option label="Anyone"><value>anyone</value></option>
</field>
<field label="Roles and Affiliations that May Retrieve Member List"
type="list-multi"
var="muc#roomconfig_getmemberlist">
<value>moderator</value>
<value>participant</value>
<value>visitor</value>
</field>
<field type="text-private" var="muc#roomconfig_roomsecret" label="Password"><value/></field>
<field type="boolean" var="muc#roomconfig_moderatedroom" label="Make Room Moderated?"/>
<field type="boolean" var="muc#roomconfig_membersonly" label="Make Room Members-Only?"/>
<field type="text-single" var="muc#roomconfig_historylength" label="Maximum Number of History Messages Returned by Room">
<value>20</value></field>
</x>
</query>
</iq>`;
mucview = _converse.chatboxviews.get('room@conference.example.org');
spyOn(mucview.model, 'sendConfiguration').and.callThrough();
_converse.api.connection.get()._dataRecv(mock.createRequest(node));
await u.waitUntil(() => mucview.model.sendConfiguration.calls.count() === 1);
const sent_stanza = IQ_stanzas.filter(s => s.getAttribute('type') === 'set').pop();
expect(sizzle('field[var="muc#roomconfig_roomname"] value', sent_stanza).pop().textContent.trim()).toBe('Room');
expect(sizzle('field[var="muc#roomconfig_roomdesc"] value', sent_stanza).pop().textContent.trim()).toBe('Welcome to this groupchat');
expect(sizzle('field[var="muc#roomconfig_persistentroom"] value', sent_stanza).pop().textContent.trim()).toBe('1');
expect(sizzle('field[var="muc#roomconfig_getmemberlist"] value', sent_stanza).map(e => e.textContent.trim()).join(' ')).toBe('moderator participant');
expect(sizzle('field[var="muc#roomconfig_publicroom"] value ', sent_stanza).pop().textContent.trim()).toBe('1');
expect(sizzle('field[var="muc#roomconfig_changesubject"] value', sent_stanza).pop().textContent.trim()).toBe('0');
expect(sizzle('field[var="muc#roomconfig_whois"] value ', sent_stanza).pop().textContent.trim()).toBe('anyone');
expect(sizzle('field[var="muc#roomconfig_membersonly"] value', sent_stanza).pop().textContent.trim()).toBe('1');
expect(sizzle('field[var="muc#roomconfig_historylength"] value', sent_stanza).pop().textContent.trim()).toBe('20');
}));
});
});