UNPKG

converse.js

Version:
558 lines (491 loc) 30.4 kB
/*global mock, converse */ const { Strophe, sizzle, stx, u } = converse.env; describe("An incoming groupchat message", function () { beforeAll(() => jasmine.addMatchers({ toEqualStanza: jasmine.toEqualStanza })); it("is specially marked when you are mentioned in it", mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterMUC(_converse, muc_jid, 'romeo'); const view = _converse.chatboxviews.get(muc_jid); if (!view.querySelectorAll('.chat-area').length) { view.renderChatArea(); } const message = 'romeo: Your attention is required'; const nick = mock.chatroom_names[0]; const msg = stx`<message from="lounge@montague.lit/${nick}" id="${u.getUniqueId()}" to="romeo@montague.lit" type="groupchat" xmlns="jabber:client"> <body>${message}</body> </message>`; await view.model.handleMessageStanza(msg); await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length); expect(u.hasClass('mentioned', view.querySelector('.chat-msg'))).toBeTruthy(); })); it("highlights all users mentioned via XEP-0372 references", mock.initConverse([], {}, async function (_converse) { const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterMUC(_converse, muc_jid, 'tom'); const view = _converse.chatboxviews.get(muc_jid); ['z3r0', 'mr.robot', 'gibson', 'sw0rdf1sh'].forEach((nick) => { _converse.api.connection.get()._dataRecv(mock.createRequest( stx`<presence to="tom@montague.lit/resource" from="lounge@montague.lit/${nick}" xmlns="jabber:client"> <x xmlns="${Strophe.NS.MUC_USER}"> <item affiliation="none" jid="${nick}@montague.lit/resource" role="participant"/> </x> </presence>` )); }); await view.model.handleMessageStanza( stx`<message from="lounge@montague.lit/gibson" id="${u.getUniqueId()}" to="romeo@montague.lit" type="groupchat" xmlns="jabber:client"> <body>hello z3r0 tom mr.robot, how are you?</body> <reference xmlns="urn:xmpp:reference:0" begin="6" end="10" type="mention" uri="xmpp:z3r0@montague.lit"/> <reference xmlns="urn:xmpp:reference:0" begin="11" end="14" type="mention" uri="xmpp:romeo@montague.lit"/> <reference xmlns="urn:xmpp:reference:0" begin="15" end="23" type="mention" uri="xmpp:mr.robot@montague.lit"/> </message>`.tree()); await u.waitUntil(() => view.querySelector('.chat-msg__text')?.innerHTML.replace(/<!-.*?->/g, '') === 'hello <span class="mention" data-uri="xmpp:z3r0@montague.lit">z3r0</span> '+ '<span class="mention mention--self badge badge-info" data-uri="xmpp:romeo@montague.lit">tom</span> '+ '<span class="mention" data-uri="xmpp:mr.robot@montague.lit">mr.robot</span>, how are you?'); let message = view.querySelector('.chat-msg__text'); expect(message.classList.length).toEqual(1); await view.model.handleMessageStanza( stx`<message from="lounge@montague.lit/sw0rdf1sh" id="${u.getUniqueId()}" to="romeo@montague.lit" type="groupchat" xmlns="jabber:client"> <body>@gibson</body> <reference xmlns="urn:xmpp:reference:0" begin="1" end="7" type="mention" uri="xmpp:gibson@montague.lit"/> </message>`.tree()); await u.waitUntil(() => view.querySelectorAll('.chat-msg__text .mention').length === 4); message = sizzle('converse-chat-message:last .chat-msg__text', view).pop(); expect(message.classList.length).toEqual(1); expect(message.innerHTML.replace(/<!-.*?->/g, '')).toBe('@<span class="mention" data-uri="xmpp:gibson@montague.lit">gibson</span>'); })); it("properly renders mentions that contain the pipe character", mock.initConverse([], {}, async function (_converse) { const { api } = _converse; const { jid: own_jid } = api.connection.get(); const muc_jid = 'lounge@montague.lit'; const nick = 'romeo'; const muc = await mock.openAndEnterMUC(_converse, muc_jid, nick); const view = _converse.chatboxviews.get(muc_jid); api.connection.get()._dataRecv(mock.createRequest( stx`<presence to="romeo@montague.lit/resource" from="lounge@montague.lit/ThUnD3r|Gr33n" xmlns="jabber:client"> <x xmlns="${Strophe.NS.MUC_USER}"> <item affiliation="none" jid="${nick}@montague.lit/resource" role="participant"/> </x> </presence>` )); await u.waitUntil(() => muc.occupants.length === 1); const textarea = await u.waitUntil(() => view.querySelector('.chat-textarea')); textarea.value = 'hello @ThUnD3r|Gr33n' const enter_event = { 'target': textarea, 'preventDefault': function preventDefault () {}, 'stopPropagation': function stopPropagation () {}, key: "Enter", } const message_form = view.querySelector('converse-muc-message-form'); message_form.onKeyDown(enter_event); await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length); await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length); const sent_stanzas = _converse.api.connection.get().sent_stanzas; const msg = await u.waitUntil(() => sent_stanzas.filter(s => s.nodeName.toLowerCase() === 'message').pop()); expect(msg).toEqualStanza( stx`<message from="${own_jid}" id="${msg.getAttribute("id")}" to="lounge@montague.lit" type="groupchat" xmlns="jabber:client"> <body>hello ThUnD3r|Gr33n</body> <active xmlns="http://jabber.org/protocol/chatstates"/> <reference begin="6" end="19" type="mention" uri="xmpp:lounge@montague.lit/ThUnD3r%7CGr33n" xmlns="urn:xmpp:reference:0"/> <origin-id id="${msg.querySelector('origin-id').getAttribute("id")}" xmlns="urn:xmpp:sid:0"/> </message>`); const message = await u.waitUntil(() => view.querySelector('.chat-msg__text')); expect(message.innerHTML.replace(/<!-.*?->/g, '')).toBe('hello <span class="mention" data-uri="xmpp:lounge@montague.lit/ThUnD3r%7CGr33n">ThUnD3r|Gr33n</span>'); })); it("highlights all users mentioned via XEP-0372 references in a quoted message", mock.initConverse([], {}, async function (_converse) { const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterMUC(_converse, muc_jid, 'tom'); const view = _converse.chatboxviews.get(muc_jid); ['z3r0', 'mr.robot', 'gibson', 'sw0rdf1sh'].forEach((nick) => { _converse.api.connection.get()._dataRecv(mock.createRequest( stx`<presence to="tom@montague.lit/resource" from="lounge@montague.lit/${nick}" xmlns="jabber:client"> <x xmlns="${Strophe.NS.MUC_USER}"> <item affiliation="none" jid="${nick}@montague.lit/resource" role="participant"/> </x> </presence>` )); }); await view.model.handleMessageStanza( stx`<message from="lounge@montague.lit/gibson" id="${u.getUniqueId()}" to="romeo@montague.lit" type="groupchat" xmlns="jabber:client"> <body>>hello z3r0 tom mr.robot, how are you?</body> <reference xmlns="urn:xmpp:reference:0" begin="7" end="11" type="mention" uri="xmpp:z3r0@montague.lit"/> <reference xmlns="urn:xmpp:reference:0" begin="12" end="15" type="mention" uri="xmpp:romeo@montague.lit"/> <reference xmlns="urn:xmpp:reference:0" begin="16" end="24" type="mention" uri="xmpp:mr.robot@montague.lit"/> </message>`.tree()); await u.waitUntil(() => view.querySelector('.chat-msg__text')?.innerHTML.replace(/<!-.*?->/g, '') === '<blockquote>hello <span class="mention" data-uri="xmpp:z3r0@montague.lit">z3r0</span> '+ '<span class="mention mention--self badge badge-info" data-uri="xmpp:romeo@montague.lit">tom</span> '+ '<span class="mention" data-uri="xmpp:mr.robot@montague.lit">mr.robot</span>, how are you?</blockquote>'); const message = view.querySelector('.chat-msg__text'); expect(message.classList.length).toEqual(1); })); }); describe("A sent groupchat message", function () { beforeAll(() => jasmine.addMatchers({ toEqualStanza: jasmine.toEqualStanza })); describe("in which someone is mentioned", function () { it("gets parsed for mentions which get turned into references", mock.initConverse([], {}, async function (_converse) { const muc_jid = 'lounge@montague.lit'; // Making the MUC non-anonymous so that real JIDs are included const features = [ 'http://jabber.org/protocol/muc', 'jabber:iq:register', Strophe.NS.SID, Strophe.NS.MAM, 'muc_passwordprotected', 'muc_hidden', 'muc_temporary', 'muc_open', 'muc_unmoderated', 'muc_nonanonymous' ]; await mock.openAndEnterMUC(_converse, muc_jid, 'tom', features); const view = _converse.chatboxviews.get(muc_jid); ['z3r0', 'mr.robot', 'gibson', 'sw0rdf1sh', 'Link Mauve', 'robot'].forEach((nick) => { _converse.api.connection.get()._dataRecv(mock.createRequest( stx`<presence to="tom@montague.lit/resource" from="lounge@montague.lit/${nick}" xmlns="jabber:client"> <x xmlns="${Strophe.NS.MUC_USER}"> <item affiliation="none" jid="${nick.replace(/\s/g, '-')}@montague.lit/resource" role="participant"/> </x> </presence>`)) }); // Also check that nicks from received messages, (but for which we don't have occupant objects) can be mentioned. const stanza = stx` <message xmlns="jabber:client" from="${muc_jid}/gh0st" to="${_converse.session.get('bare_jid')}" type="groupchat"> <body>Boo!</body> </message>`; await view.model.handleMessageStanza(stanza); // Run a few unit tests for the parseTextForReferences method let [text, references] = view.model.parseTextForReferences('yo @robot') expect(text).toBe('yo robot'); expect(references) .toEqual([{"begin":3,"end":8,"value":"robot","type":"mention","uri":"xmpp:robot@montague.lit"}]); [text, references] = view.model.parseTextForReferences('@@gh0st') expect(text).toBe('@gh0st'); expect(references.length).toBe(1); expect(references) .toEqual([{"begin":1,"end":6,"value":"gh0st","type":"mention","uri":"xmpp:lounge@montague.lit/gh0st"}]); [text, references] = view.model.parseTextForReferences('hello z3r0') expect(references.length).toBe(0); expect(text).toBe('hello z3r0'); [text, references] = view.model.parseTextForReferences('hello @z3r0') expect(references.length).toBe(1); expect(text).toBe('hello z3r0'); expect(references) .toEqual([{"begin":6,"end":10,"value":"z3r0","type":"mention","uri":"xmpp:z3r0@montague.lit"}]); [text, references] = view.model.parseTextForReferences('hello @some1 @z3r0 @gibson @mr.robot, how are you?') expect(text).toBe('hello @some1 z3r0 gibson mr.robot, how are you?'); expect(references) .toEqual([{"begin":13,"end":17,"value":"z3r0","type":"mention","uri":"xmpp:z3r0@montague.lit"}, {"begin":18,"end":24,"value":"gibson","type":"mention","uri":"xmpp:gibson@montague.lit"}, {"begin":25,"end":33,"value":"mr.robot","type":"mention","uri":"xmpp:mr.robot@montague.lit"}]); [text, references] = view.model.parseTextForReferences('yo @gib') expect(text).toBe('yo @gib'); expect(references.length).toBe(0); [text, references] = view.model.parseTextForReferences('yo @gibsonian') expect(text).toBe('yo @gibsonian'); expect(references.length).toBe(0); [text, references] = view.model.parseTextForReferences('yo @GiBsOn') expect(text).toBe('yo gibson'); expect(references.length).toBe(1); [text, references] = view.model.parseTextForReferences('@gibson') expect(text).toBe('gibson'); expect(references.length).toBe(1); expect(references) .toEqual([{"begin":0,"end":6,"value":"gibson","type":"mention","uri":"xmpp:gibson@montague.lit"}]); [text, references] = view.model.parseTextForReferences('hi @Link Mauve how are you?') expect(text).toBe('hi Link Mauve how are you?'); expect(references.length).toBe(1); expect(references) .toEqual([{"begin":3,"end":13,"value":"Link Mauve","type":"mention","uri":"xmpp:Link-Mauve@montague.lit"}]); [text, references] = view.model.parseTextForReferences('https://example.org/@gibson') expect(text).toBe('https://example.org/@gibson'); expect(references.length).toBe(0); expect(references).toEqual([]); [text, references] = view.model.parseTextForReferences('mail@gibson.com') expect(text).toBe('mail@gibson.com'); expect(references.length).toBe(0); expect(references) .toEqual([]); [text, references] = view.model.parseTextForReferences( "Welcome @gibson 💩 We have a guide on how to do that here: https://conversejs.org/docs/html/index.html"); expect(text).toBe("Welcome gibson 💩 We have a guide on how to do that here: https://conversejs.org/docs/html/index.html"); expect(references.length).toBe(1); expect(references).toEqual([{"begin":8,"end":14,"value":"gibson","type":"mention","uri":"xmpp:gibson@montague.lit"}]); [text, references] = view.model.parseTextForReferences( 'https://linkmauve.fr@Link Mauve/ https://linkmauve.fr/@github/is_back gibson@gibson.com gibson@Link Mauve.fr') expect(text).toBe( 'https://linkmauve.fr@Link Mauve/ https://linkmauve.fr/@github/is_back gibson@gibson.com gibson@Link Mauve.fr'); expect(references.length).toBe(0); expect(references) .toEqual([]); [text, references] = view.model.parseTextForReferences('@gh0st where are you?') expect(text).toBe('gh0st where are you?'); expect(references.length).toBe(1); expect(references) .toEqual([{"begin":0,"end":5,"value":"gh0st","type":"mention","uri":"xmpp:lounge@montague.lit/gh0st"}]); })); it("gets parsed for mentions as indicated with an @ preceded by a space or at the start of the text", mock.initConverse([], {}, async function (_converse) { const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterMUC(_converse, muc_jid, 'tom'); const view = _converse.chatboxviews.get(muc_jid); ['NotAnAdress', 'darnuria'].forEach((nick) => { _converse.api.connection.get()._dataRecv(mock.createRequest( stx`<presence to="tom@montague.lit/resource" from="lounge@montague.lit/${nick}" xmlns="jabber:client"> <x xmlns="${Strophe.NS.MUC_USER}"> <item affiliation="none" jid="${nick.replace(/\s/g, '-')}@montague.lit/resource" role="participant"/> </x> </presence>`)) }); // Test that we don't match @nick in email adresses. let [text, references] = view.model.parseTextForReferences('contact contact@NotAnAdress.eu'); expect(references.length).toBe(0); expect(text).toBe('contact contact@NotAnAdress.eu'); // Test that we don't match @nick in url [text, references] = view.model.parseTextForReferences('nice website https://darnuria.eu/@darnuria'); expect(references.length).toBe(0); expect(text).toBe('nice website https://darnuria.eu/@darnuria'); })); it("properly encodes the URIs in sent out references", mock.initConverse([], {}, async function (_converse) { const { api } = _converse; const { jid: own_jid } = api.connection.get(); const nick = 'tom'; const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterMUC(_converse, muc_jid, nick); const view = _converse.chatboxviews.get(muc_jid); _converse.api.connection.get()._dataRecv(mock.createRequest( stx`<presence to="tom@montague.lit/resource" from="lounge@montague.lit/Link Mauve" xmlns="jabber:client"> <x xmlns="${Strophe.NS.MUC_USER}"> <item affiliation="none" role="participant"/> </x> </presence>`)); await u.waitUntil(() => view.model.occupants.length === 2); const textarea = await u.waitUntil(() => view.querySelector('.chat-textarea')); textarea.value = 'hello @Link Mauve' const enter_event = { 'target': textarea, 'preventDefault': function preventDefault () {}, 'stopPropagation': function stopPropagation () {}, key: "Enter", } const message_form = view.querySelector('converse-muc-message-form'); message_form.onKeyDown(enter_event); await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length); const sent_stanzas = _converse.api.connection.get().sent_stanzas; const msg = await u.waitUntil(() => sent_stanzas.filter(s => s.nodeName.toLowerCase() === 'message').pop()); expect(msg).toEqualStanza(stx` <message from="${own_jid}" id="${msg.getAttribute("id")}" to="lounge@montague.lit" type="groupchat" xmlns="jabber:client"> <body>hello Link Mauve</body> <active xmlns="http://jabber.org/protocol/chatstates"/> <reference begin="6" end="16" type="mention" uri="xmpp:lounge@montague.lit/Link%20Mauve" xmlns="urn:xmpp:reference:0"/> <origin-id id="${msg.querySelector('origin-id').getAttribute("id")}" xmlns="urn:xmpp:sid:0"/> </message>`); })); it("can get corrected and given new references", mock.initConverse([], {}, async function (_converse) { const muc_jid = 'lounge@montague.lit'; const { api } = _converse; const { jid: own_jid } = api.connection.get(); // Making the MUC non-anonymous so that real JIDs are included const features = [ 'http://jabber.org/protocol/muc', 'jabber:iq:register', Strophe.NS.SID, Strophe.NS.MAM, 'muc_passwordprotected', 'muc_hidden', 'muc_temporary', 'muc_open', 'muc_unmoderated', 'muc_nonanonymous' ]; await mock.openAndEnterMUC(_converse, muc_jid, 'tom', features); const view = _converse.chatboxviews.get(muc_jid); ['z3r0', 'mr.robot', 'gibson', 'sw0rdf1sh'].forEach((nick) => { _converse.api.connection.get()._dataRecv(mock.createRequest( stx`<presence to="tom@montague.lit/resource" from="lounge@montague.lit/${nick}" xmlns="jabber:client"> <x xmlns="${Strophe.NS.MUC_USER}"> <item affiliation="none" jid="${nick}@montague.lit/resource" role="participant"/> </x> </presence>` )); }); await u.waitUntil(() => view.model.occupants.length === 5); const textarea = await u.waitUntil(() => view.querySelector('textarea.chat-textarea')); textarea.value = 'hello @z3r0 @gibson @mr.robot, how are you?' const enter_event = { 'target': textarea, 'preventDefault': function preventDefault () {}, 'stopPropagation': function stopPropagation () {}, key: "Enter", } const message_form = view.querySelector('converse-muc-message-form'); message_form.onKeyDown(enter_event); await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length); const last_msg_sel = 'converse-chat-message:last-child .chat-msg__text'; await u.waitUntil(() => view.querySelector(last_msg_sel).innerHTML.replace(/<!-.*?->/g, '') === 'hello <span class="mention" data-uri="xmpp:z3r0@montague.lit">z3r0</span> '+ '<span class="mention" data-uri="xmpp:gibson@montague.lit">gibson</span> '+ '<span class="mention" data-uri="xmpp:mr.robot@montague.lit">mr.robot</span>, how are you?' ); const sent_stanzas = _converse.api.connection.get().sent_stanzas; const msg = await u.waitUntil(() => sent_stanzas.filter(s => s.nodeName.toLowerCase() === 'message').pop()); expect(msg).toEqualStanza(stx` <message from="${own_jid}" id="${msg.getAttribute("id")}" to="lounge@montague.lit" type="groupchat" xmlns="jabber:client"> <body>hello z3r0 gibson mr.robot, how are you?</body> <active xmlns="http://jabber.org/protocol/chatstates"/> <reference begin="6" end="10" type="mention" uri="xmpp:z3r0@montague.lit" xmlns="urn:xmpp:reference:0"/> <reference begin="11" end="17" type="mention" uri="xmpp:gibson@montague.lit" xmlns="urn:xmpp:reference:0"/> <reference begin="18" end="26" type="mention" uri="xmpp:mr.robot@montague.lit" xmlns="urn:xmpp:reference:0"/> <origin-id id="${msg.querySelector('origin-id').getAttribute("id")}" xmlns="urn:xmpp:sid:0"/> </message>`); const action = await u.waitUntil(() => view.querySelector('.chat-msg .chat-msg__action')); action.style.opacity = 1; action.click(); await u.waitUntil(() => textarea.value === 'hello @z3r0 @gibson @mr.robot, how are you?'); expect(view.model.messages.at(0).get('correcting')).toBe(true); expect(view.querySelectorAll('.chat-msg').length).toBe(1); await u.waitUntil(() => u.hasClass('correcting', view.querySelector('.chat-msg')), 500); textarea.value = 'hello @z3r0 @gibson @sw0rdf1sh, how are you?'; message_form.onKeyDown(enter_event); await u.waitUntil(() => view.querySelector('.chat-msg__text').textContent === 'hello z3r0 gibson sw0rdf1sh, how are you?', 500); const correction = sent_stanzas.filter(s => s.nodeName.toLowerCase() === 'message').pop(); expect(correction).toEqualStanza(stx` <message from="${own_jid}" id="${correction.getAttribute("id")}" to="lounge@montague.lit" type="groupchat" xmlns="jabber:client"> <body>hello z3r0 gibson sw0rdf1sh, how are you?</body> <active xmlns="http://jabber.org/protocol/chatstates"/> <reference begin="6" end="10" type="mention" uri="xmpp:z3r0@montague.lit" xmlns="urn:xmpp:reference:0"/> <reference begin="11" end="17" type="mention" uri="xmpp:gibson@montague.lit" xmlns="urn:xmpp:reference:0"/> <reference begin="18" end="27" type="mention" uri="xmpp:sw0rdf1sh@montague.lit" xmlns="urn:xmpp:reference:0"/> <replace id="${msg.getAttribute("id")}" xmlns="urn:xmpp:message-correct:0"/> <origin-id id="${correction.querySelector('origin-id').getAttribute("id")}" xmlns="urn:xmpp:sid:0"/> </message>`); })); it("includes a XEP-0372 references to that person", mock.initConverse([], { auto_register_muc_nickname: false }, async function (_converse) { const { api } = _converse; const { jid: own_jid } = api.connection.get(); const nick = 'romeo'; const muc_jid = 'lounge@montague.lit'; const muc = await mock.openAndEnterMUC(_converse, muc_jid, nick); const view = _converse.chatboxviews.get(muc_jid); ['z3r0', 'mr.robot', 'gibson', 'sw0rdf1sh'].forEach((nick) => { _converse.api.connection.get()._dataRecv(mock.createRequest( stx`<presence to="tom@montague.lit/resource" from="lounge@montague.lit/${nick}" xmlns="jabber:client"> <x xmlns="${Strophe.NS.MUC_USER}"> <item affiliation="none" jid="${nick}@montague.lit/resource" role="participant"/> </x> </presence>`)); }); await u.waitUntil(() => muc.occupants.length === 5); spyOn(_converse.api.connection.get(), 'send'); const textarea = await u.waitUntil(() => view.querySelector('.chat-textarea')); textarea.value = 'hello @z3r0 @gibson @mr.robot, how are you?' const enter_event = { 'target': textarea, 'preventDefault': function preventDefault () {}, 'stopPropagation': function stopPropagation () {}, key: "Enter", } const message_form = view.querySelector('converse-muc-message-form'); message_form.onKeyDown(enter_event); await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length); const msg = _converse.api.connection.get().send.calls.all()[0].args[0]; expect(msg).toEqualStanza( stx`<message from="${own_jid}" id="${msg.getAttribute("id")}" to="lounge@montague.lit" type="groupchat" xmlns="jabber:client"> <body>hello z3r0 gibson mr.robot, how are you?</body> <active xmlns="http://jabber.org/protocol/chatstates"/> <reference begin="6" end="10" type="mention" uri="xmpp:${muc_jid}/z3r0" xmlns="urn:xmpp:reference:0"/> <reference begin="11" end="17" type="mention" uri="xmpp:${muc_jid}/gibson" xmlns="urn:xmpp:reference:0"/> <reference begin="18" end="26" type="mention" uri="xmpp:${muc_jid}/mr.robot" xmlns="urn:xmpp:reference:0"/> <origin-id id="${msg.querySelector('origin-id').getAttribute("id")}" xmlns="urn:xmpp:sid:0"/> </message>`); })); }); it("highlights all users mentioned via XEP-0372 references in a quoted message", mock.initConverse([], {}, async function (_converse) { const members = [{'jid': 'gibson@gibson.net', 'nick': 'gibson', 'affiliation': 'member'}]; const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterMUC(_converse, muc_jid, 'tom', [], members); const view = _converse.chatboxviews.get(muc_jid); const textarea = await u.waitUntil(() => view.querySelector('.chat-textarea')); textarea.value = "Welcome @gibson 💩 We have a guide on how to do that here: https://conversejs.org/docs/html/index.html"; const enter_event = { 'target': textarea, 'preventDefault': function preventDefault () {}, 'stopPropagation': function stopPropagation () {}, key: "Enter", } const message_form = view.querySelector('converse-muc-message-form'); message_form.onKeyDown(enter_event); const message = await u.waitUntil(() => view.querySelector('.chat-msg__text')); expect(message.innerHTML.replace(/<!-.*?->/g, '')).toEqual( `Welcome <span class="mention" data-uri="xmpp:${muc_jid}/gibson">gibson</span> <span title=":poop:">💩</span> `+ `We have a guide on how to do that here: `+ `<a target="_blank" rel="noopener" href="https://conversejs.org/docs/html/index.html">https://conversejs.org/docs/html/index.html</a>`); })); });