xmpp.chapril.org-conversejs/spec/muc-api.js
2021-03-15 12:34:56 +01:00

256 lines
14 KiB
JavaScript

/*global mock, converse */
const Model = converse.env.Model;
const { $pres, $iq, Strophe, sizzle, u } = 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 (done, _converse) {
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
_converse.connection.IQ_stanzas = [];
await mock.openAndEnterChatRoom(_converse, 'leisure@montague.lit', 'romeo');
_converse.connection.IQ_stanzas = [];
await mock.openAndEnterChatRoom(_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();
await _converse.api.roomviews.close('lounge@montague.lit');
expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined();
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(['leisure@montague.lit', '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.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
await mock.openAndEnterChatRoom(_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();
await _converse.api.roomviews.close();
expect(_converse.chatboxviews.get('lounge@montague.lit')).toBeUndefined();
expect(_converse.chatboxviews.get('leisure@montague.lit')).toBeUndefined();
done();
}));
it("has a method 'get' which returns a wrapped groupchat (if it exists)",
mock.initConverse([], {}, async function (done, _converse) {
await mock.waitForRoster(_converse, 'current');
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.openAndEnterChatRoom(_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.openAndEnterChatRoom(_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);
done();
}));
it("has a method 'open' which opens (optionally configures) and returns a wrapped chat box",
mock.initConverse(['chatBoxesFetched'], {}, async function (done, _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';
let chatroomview, IQ_id;
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);
let room = await _converse.api.rooms.open(jid);
// Test on groupchat that's not yet open
expect(room instanceof Model).toBeTruthy();
chatroomview = _converse.chatboxviews.get(jid);
expect(chatroomview.is_chatroom).toBeTruthy();
await u.waitUntil(() => u.isVisible(chatroomview));
// Test again, now that the room exists.
room = await _converse.api.rooms.open(jid);
expect(room instanceof Model).toBeTruthy();
chatroomview = _converse.chatboxviews.get(jid);
expect(chatroomview.is_chatroom).toBeTruthy();
expect(u.isVisible(chatroomview)).toBeTruthy();
await chatroomview.close();
// Test with mixed case in JID
jid = 'Leisure@montague.lit';
room = await _converse.api.rooms.open(jid);
expect(room instanceof Model).toBeTruthy();
chatroomview = _converse.chatboxviews.get(jid.toLowerCase());
await u.waitUntil(() => u.isVisible(chatroomview));
jid = 'leisure@montague.lit';
room = await _converse.api.rooms.open(jid);
expect(room instanceof Model).toBeTruthy();
chatroomview = _converse.chatboxviews.get(jid.toLowerCase());
await u.waitUntil(() => u.isVisible(chatroomview));
jid = 'leiSure@montague.lit';
room = await _converse.api.rooms.open(jid);
expect(room instanceof Model).toBeTruthy();
chatroomview = _converse.chatboxviews.get(jid.toLowerCase());
await u.waitUntil(() => u.isVisible(chatroomview));
chatroomview.close();
_converse.muc_instant_rooms = false;
const sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
// Test with configuration
room = await _converse.api.rooms.open('room@conference.example.org', {
'nick': 'some1',
'auto_configure': true,
'roomconfig': {
'getmemberlist': ['moderator', 'participant'],
'changesubject': false,
'membersonly': true,
'persistentroom': true,
'publicroom': true,
'roomdesc': 'Welcome to this groupchat',
'whois': 'anyone'
}
});
expect(room instanceof Model).toBeTruthy();
chatroomview = _converse.chatboxviews.get('room@conference.example.org');
// We pretend this is a new room, so no disco info is returned.
const features_stanza = $iq({
from: 'room@conference.example.org',
'id': IQ_id,
'to': 'romeo@montague.lit/desktop',
'type': 'error'
}).c('error', {'type': 'cancel'})
.c('item-not-found', {'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas"});
_converse.connection._dataRecv(mock.createRequest(features_stanza));
/* <presence xmlns="jabber:client" to="romeo@montague.lit/pda" from="room@conference.example.org/yo">
* <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 presence = $pres({
from:'room@conference.example.org/some1',
to:'romeo@montague.lit/pda'
})
.c('x', {xmlns:'http://jabber.org/protocol/muc#user'})
.c('item', {
affiliation: 'owner',
jid: 'romeo@montague.lit/pda',
role: 'moderator'
}).up()
.c('status', {code:'110'}).up()
.c('status', {code:'201'});
_converse.connection._dataRecv(mock.createRequest(presence));
expect(_converse.connection.sendIQ).toHaveBeenCalled();
const IQ_stanzas = _converse.connection.IQ_stanzas;
const iq = await u.waitUntil(() => IQ_stanzas.filter(s => s.querySelector(`query[xmlns="${Strophe.NS.MUC_OWNER}"]`)).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 = u.toStanza(`
<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>`);
spyOn(chatroomview.model, 'sendConfiguration').and.callThrough();
_converse.connection._dataRecv(mock.createRequest(node));
await u.waitUntil(() => chatroomview.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');
done();
}));
});
});