/*global mock, converse */ const { Strophe, u } = converse.env; describe("A Groupchat Message", function () { it("will render an unfurl based on OGP data", mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { const nick = 'romeo'; const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterChatRoom(_converse, muc_jid, nick); const view = _converse.chatboxviews.get(muc_jid); const unfurl_image_src = "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg"; const unfurl_url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"; const message_stanza = u.toStanza(` https://www.youtube.com/watch?v=dQw4w9WgXcQ `); _converse.connection._dataRecv(mock.createRequest(message_stanza)); const el = await u.waitUntil(() => view.querySelector('.chat-msg__text')); expect(el.textContent).toBe('https://www.youtube.com/watch?v=dQw4w9WgXcQ'); const metadata_stanza = u.toStanza(` `); _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); const unfurl = await u.waitUntil(() => view.querySelector('converse-message-unfurl')); expect(unfurl.querySelector('.card-img-top').getAttribute('src')).toBe(unfurl_image_src); expect(unfurl.querySelector('.card-img-top').getAttribute('href')).toBe(unfurl_url); })); it("will render an unfurl with limited OGP data", mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { /* Some sites don't include ogp data such as title, description and * url. This test is to check that we fall back gracefully */ const nick = 'romeo'; const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterChatRoom(_converse, muc_jid, nick); const view = _converse.chatboxviews.get(muc_jid); const message_stanza = u.toStanza(` https://mempool.space `); _converse.connection._dataRecv(mock.createRequest(message_stanza)); const el = await u.waitUntil(() => view.querySelector('.chat-msg__text')); expect(el.textContent).toBe('https://mempool.space'); const metadata_stanza = u.toStanza(` `); _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); const unfurl = await u.waitUntil(() => view.querySelector('converse-message-unfurl')); expect(unfurl.querySelector('.card-img-top').getAttribute('src')).toBe('https://conversejs.org/dist/images/custom_emojis/converse.png'); expect(unfurl.querySelector('.card-body')).toBe(null); })); it("will render an unfurl containing a GIF", mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { const nick = 'romeo'; const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterChatRoom(_converse, muc_jid, nick); const view = _converse.chatboxviews.get(muc_jid); const unfurl_url = "https://giphy.com/gifs/giphyqa-4YY4DnqeUDBXNTcYMu"; const gif_url = "https://media4.giphy.com/media/4YY4DnqeUDBXNTcYMu/giphy.gif?foo=bar"; const message_stanza = u.toStanza(` ${unfurl_url} `); _converse.connection._dataRecv(mock.createRequest(message_stanza)); const el = await u.waitUntil(() => view.querySelector('.chat-msg__text')); expect(el.textContent).toBe(unfurl_url); const metadata_stanza = u.toStanza(` `); _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); const unfurl = await u.waitUntil(() => view.querySelector('converse-message-unfurl')); expect(unfurl.querySelector('.card-img-top').getAttribute('src')).toBe(gif_url); })); it("will render multiple unfurls based on OGP data", mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { const nick = 'romeo'; const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterChatRoom(_converse, muc_jid, nick); const view = _converse.chatboxviews.get(muc_jid); const message_stanza = u.toStanza(` Check out https://www.youtube.com/watch?v=dQw4w9WgXcQ and https://duckduckgo.com `); _converse.connection._dataRecv(mock.createRequest(message_stanza)); const el = await u.waitUntil(() => view.querySelector('.chat-msg__text')); expect(el.textContent).toBe('Check out https://www.youtube.com/watch?v=dQw4w9WgXcQ and https://duckduckgo.com'); let metadata_stanza = u.toStanza(` `); _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); await u.waitUntil(() => view.querySelectorAll('converse-message-unfurl').length === 1); metadata_stanza = u.toStanza(` `); _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); await u.waitUntil(() => view.querySelectorAll('converse-message-unfurl').length === 2); })); it("will not render an unfurl received from a MUC participant", mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { const nick = 'romeo'; const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterChatRoom(_converse, muc_jid, nick); const view = _converse.chatboxviews.get(muc_jid); const message_stanza = u.toStanza(` https://www.youtube.com/watch?v=dQw4w9WgXcQ `); _converse.connection._dataRecv(mock.createRequest(message_stanza)); const el = await u.waitUntil(() => view.querySelector('.chat-msg__text')); expect(el.textContent).toBe('https://www.youtube.com/watch?v=dQw4w9WgXcQ'); spyOn(view.model, 'handleMetadataFastening').and.callThrough(); const metadata_stanza = u.toStanza(` `); _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); await u.waitUntil(() => view.model.handleMetadataFastening.calls.count()); expect(view.model.handleMetadataFastening.calls.first().returnValue).toBe(false); expect(view.querySelector('converse-message-unfurl')).toBe(null); })); it("will not render an unfurl based on OGP data if render_media is false", mock.initConverse(['chatBoxesFetched'], { 'render_media': false }, async function (_converse) { const { api } = _converse; const nick = 'romeo'; const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterChatRoom(_converse, muc_jid, nick); const view = _converse.chatboxviews.get(muc_jid); const message_stanza = u.toStanza(` https://www.youtube.com/watch?v=dQw4w9WgXcQ `); _converse.connection._dataRecv(mock.createRequest(message_stanza)); const el = await u.waitUntil(() => view.querySelector('.chat-msg__text')); expect(el.textContent).toBe('https://www.youtube.com/watch?v=dQw4w9WgXcQ'); spyOn(view.model, 'handleMetadataFastening').and.callThrough(); const metadata_stanza = u.toStanza(` `); _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); expect(view.querySelector('converse-message-unfurl')).toBe(null); api.settings.set('render_media', true); await u.waitUntil(() => view.querySelector('converse-message-unfurl')); let button = await u.waitUntil(() => view.querySelector('.chat-msg__content .chat-msg__action-hide-previews')); expect(button.textContent.trim()).toBe('Hide media'); button.click(); await u.waitUntil(() => !view.querySelector('converse-message-unfurl'), 1000); button = await u.waitUntil(() => view.querySelector('.chat-msg__content .chat-msg__action-hide-previews')); expect(button.textContent.trim()).toBe('Show media'); })); it("will only render a single unfurl when receiving the same OGP data multiple times", mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { const nick = 'romeo'; const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterChatRoom(_converse, muc_jid, nick); const view = _converse.chatboxviews.get(muc_jid); const message_stanza = u.toStanza(` https://www.youtube.com/watch?v=dQw4w9WgXcQ `); _converse.connection._dataRecv(mock.createRequest(message_stanza)); const el = await u.waitUntil(() => view.querySelector('.chat-msg__text')); expect(el.textContent).toBe('https://www.youtube.com/watch?v=dQw4w9WgXcQ'); spyOn(view.model, 'handleMetadataFastening').and.callThrough(); const metadata_stanza = u.toStanza(` `); _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); await u.waitUntil(() => view.model.handleMetadataFastening.calls.count()); const unfurls = await u.waitUntil(() => view.querySelectorAll('converse-message-unfurl')); expect(unfurls.length).toBe(1); })); it("will not render an unfurl image if the domain is not in allowed_image_domains", mock.initConverse(['chatBoxesFetched'], {'allowed_image_domains': []}, async function (_converse) { const { api } = _converse; const nick = 'romeo'; const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterChatRoom(_converse, muc_jid, nick); const view = _converse.chatboxviews.get(muc_jid); const message_stanza = u.toStanza(` https://www.youtube.com/watch?v=dQw4w9WgXcQ `); _converse.connection._dataRecv(mock.createRequest(message_stanza)); const el = await u.waitUntil(() => view.querySelector('.chat-msg__text')); expect(el.textContent).toBe('https://www.youtube.com/watch?v=dQw4w9WgXcQ'); const metadata_stanza = u.toStanza(` `); _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); await u.waitUntil(() => !view.querySelector('converse-message-unfurl')); api.settings.set('allowed_image_domains', null); await u.waitUntil(() => view.querySelector('converse-message-unfurl')); })); it("lets the user hide an unfurl", mock.initConverse(['chatBoxesFetched'], {'render_media': true}, async function (_converse) { const { api } = _converse; const nick = 'romeo'; const muc_jid = 'lounge@montague.lit'; await mock.openAndEnterChatRoom(_converse, muc_jid, nick); const view = _converse.chatboxviews.get(muc_jid); const message_stanza = u.toStanza(` https://www.youtube.com/watch?v=dQw4w9WgXcQ `); _converse.connection._dataRecv(mock.createRequest(message_stanza)); const el = await u.waitUntil(() => view.querySelector('.chat-msg__text')); expect(el.textContent).toBe('https://www.youtube.com/watch?v=dQw4w9WgXcQ'); const metadata_stanza = u.toStanza(` `); _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); await u.waitUntil(() => view.querySelector('converse-message-unfurl')); let button = await u.waitUntil(() => view.querySelector('.chat-msg__content .chat-msg__action-hide-previews')); expect(button.textContent.trim()).toBe('Hide media'); button.click(); await u.waitUntil(() => view.querySelector('converse-message-unfurl') === null, 750); button = view.querySelector('.chat-msg__content .chat-msg__action-hide-previews'); expect(button.textContent.trim()).toBe('Show media'); button.click(); await u.waitUntil(() => view.querySelector('converse-message-unfurl'), 750); // Check that the image doesn't render if the domain is not allowed expect(view.querySelector('converse-message-unfurl .chat-image')).not.toBe(null); api.settings.set('allowed_image_domains', []); await u.waitUntil(() => view.querySelector('converse-message-unfurl .chat-image') === null); api.settings.set('allowed_image_domains', undefined); await u.waitUntil(() => view.querySelector('converse-message-unfurl .chat-image') !== null); })); it("will not render an unfurl that has been removed in a subsequent correction", mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) { const nick = 'romeo'; const muc_jid = 'lounge@muc.montague.lit'; await mock.openAndEnterChatRoom(_converse, muc_jid, nick); const view = _converse.chatboxviews.get(muc_jid); const unfurl_image_src = "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg"; const unfurl_url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"; spyOn(_converse.connection, 'send').and.callThrough(); const textarea = await u.waitUntil(() => view.querySelector('textarea.chat-textarea')); const message_form = view.querySelector('converse-muc-message-form'); textarea.value = unfurl_url; const enter_event = { 'target': textarea, 'preventDefault': function preventDefault () {}, 'stopPropagation': function stopPropagation () {}, 'keyCode': 13 // Enter } message_form.onKeyDown(enter_event); await u.waitUntil(() => view.querySelectorAll('.chat-msg').length === 1); expect(view.querySelector('.chat-msg__text').textContent) .toBe(unfurl_url); let msg = _converse.connection.send.calls.all()[1].args[0]; expect(Strophe.serialize(msg)) .toBe( ``+ `${unfurl_url}`+ ``+ ``+ ``); const el = await u.waitUntil(() => view.querySelector('.chat-msg__text')); expect(el.textContent).toBe(unfurl_url); const metadata_stanza = u.toStanza(` `); _converse.connection._dataRecv(mock.createRequest(metadata_stanza)); const unfurl = await u.waitUntil(() => view.querySelector('converse-message-unfurl')); expect(unfurl.querySelector('.card-img-top').getAttribute('src')).toBe(unfurl_image_src); expect(unfurl.querySelector('.card-img-top').getAttribute('href')).toBe(unfurl_url); // Modify the message to use a different URL expect(textarea.value).toBe(''); message_form.onKeyDown({ target: textarea, keyCode: 38 // Up arrow }); expect(textarea.value).toBe(unfurl_url); textarea.value = "never mind"; message_form.onKeyDown(enter_event); const getSentMessages = () => _converse.connection.send.calls.all().map(c => c.args[0]).filter(s => s.nodeName === 'message'); await u.waitUntil(() => getSentMessages().length == 2); msg = getSentMessages().pop(); expect(Strophe.serialize(msg)) .toBe( ``+ `never mind`+ ``+ ``+ ``+ ``); })); });