xmpp.chapril.org-conversejs/spec/me-messages.js
JC Brand f9650f33be Add support for XEP-0393 message styling
Fixes #1083

Directives are rendered as templates and their bodies are MessageText instances.
We thereby achieve the necessary nesting of directives (and other rich
elements inside directives) by letting each directive
body render itself similarly to how the whole message body is rendered.
2020-11-24 16:06:48 +01:00

115 lines
5.8 KiB
JavaScript

/*global mock, converse */
const { u, sizzle, $msg } = converse.env;
describe("A Groupchat Message", function () {
it("supports the /me command",
mock.initConverse(
['rosterGroupsFetched'], {},
async function (done, _converse) {
await mock.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
await mock.waitForRoster(_converse, 'current');
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
const view = _converse.chatboxviews.get('lounge@montague.lit');
if (!view.el.querySelectorAll('.chat-area').length) {
view.renderChatArea();
}
let message = '/me is tired';
const nick = mock.chatroom_names[0];
let msg = $msg({
'from': 'lounge@montague.lit/'+nick,
'id': u.getUniqueId(),
'to': 'romeo@montague.lit',
'type': 'groupchat'
}).c('body').t(message).tree();
await view.model.handleMessageStanza(msg);
await u.waitUntil(() => sizzle('.chat-msg:last .chat-msg__text', view.content).pop());
expect(view.el.querySelector('.chat-msg__author').textContent.includes('**Dyon van de Wege')).toBeTruthy();
expect(view.el.querySelector('.chat-msg__text').textContent.trim()).toBe('is tired');
message = '/me is as well';
msg = $msg({
from: 'lounge@montague.lit/Romeo Montague',
id: u.getUniqueId(),
to: 'romeo@montague.lit',
type: 'groupchat'
}).c('body').t(message).tree();
await view.model.handleMessageStanza(msg);
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg').length === 2);
expect(sizzle('.chat-msg__author:last', view.el).pop().textContent.includes('**Romeo Montague')).toBeTruthy();
expect(sizzle('.chat-msg__text:last', view.el).pop().textContent.trim()).toBe('is as well');
// Check rendering of a mention inside a me message
const msg_text = "/me mentions romeo";
msg = $msg({
from: 'lounge@montague.lit/gibson',
id: u.getUniqueId(),
to: 'romeo@montague.lit',
type: 'groupchat'
}).c('body').t(msg_text).up()
.c('reference', {'xmlns':'urn:xmpp:reference:0', 'begin':'13', 'end':'19', 'type':'mention', 'uri':'xmpp:romeo@montague.lit'}).nodeTree;
await view.model.handleMessageStanza(msg);
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg__text').length === 3);
await u.waitUntil(() => sizzle('.chat-msg__text:last', view.el).pop().innerHTML.replace(/<!---->/g, '') ===
'mentions <span class="mention mention--self badge badge-info">romeo</span>');
done();
}));
});
describe("A Message", function () {
it("supports the /me command", mock.initConverse(['rosterGroupsFetched'], {}, async function (done, _converse) {
await mock.waitForRoster(_converse, 'current');
await mock.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
await mock.openControlBox(_converse);
expect(_converse.chatboxes.length).toEqual(1);
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
let message = '/me is tired';
const msg = $msg({
from: sender_jid,
to: _converse.connection.jid,
type: 'chat',
id: u.getUniqueId()
}).c('body').t(message).up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
await _converse.handleMessageStanza(msg);
const view = _converse.chatboxviews.get(sender_jid);
await u.waitUntil(() => view.el.querySelector('.chat-msg__text'));
expect(view.el.querySelectorAll('.chat-msg--action').length).toBe(1);
expect(view.el.querySelector('.chat-msg__author').textContent.includes('**Mercutio')).toBeTruthy();
expect(view.el.querySelector('.chat-msg__text').textContent).toBe('is tired');
message = '/me is as well';
await mock.sendMessage(view, message);
expect(view.el.querySelectorAll('.chat-msg--action').length).toBe(2);
await u.waitUntil(() => sizzle('.chat-msg__author:last', view.el).pop().textContent.trim() === '**Romeo Montague');
const last_el = sizzle('.chat-msg__text:last', view.el).pop();
await u.waitUntil(() => last_el.textContent === 'is as well');
expect(u.hasClass('chat-msg--followup', last_el)).toBe(false);
// Check that /me messages after a normal message don't
// get the 'chat-msg--followup' class.
message = 'This a normal message';
await mock.sendMessage(view, message);
const msg_txt_sel = 'converse-chat-message:last-child .chat-msg__text';
await u.waitUntil(() => view.el.querySelector(msg_txt_sel).textContent.trim() === message);
let el = view.el.querySelector('converse-chat-message:last-child .chat-msg__body');
expect(u.hasClass('chat-msg--followup', el)).toBeFalsy();
message = '/me wrote a 3rd person message';
await mock.sendMessage(view, message);
await u.waitUntil(() => view.el.querySelector(msg_txt_sel).textContent.trim() === message.replace('/me ', ''));
el = view.el.querySelector('converse-chat-message:last-child .chat-msg__body');
expect(view.el.querySelectorAll('.chat-msg--action').length).toBe(3);
expect(sizzle('.chat-msg__text:last', view.el).pop().textContent).toBe('wrote a 3rd person message');
expect(u.isVisible(sizzle('.chat-msg__author:last', view.el).pop())).toBeTruthy();
done();
}));
});