Commit 39363d49 authored by JC Brand's avatar JC Brand

Fetch messages in MUC model

parent 46fef286
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
const Strophe = converse.env.Strophe; const Strophe = converse.env.Strophe;
const $iq = converse.env.$iq; const $iq = converse.env.$iq;
const _ = converse.env._; const _ = converse.env._;
const sizzle = converse.env.sizzle;
const u = converse.env.utils; const u = converse.env.utils;
const f = converse.env.f;
describe("XEP-0363: HTTP File Upload", function () { describe("XEP-0363: HTTP File Upload", function () {
...@@ -366,6 +366,11 @@ ...@@ -366,6 +366,11 @@
await test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.montague.tld'], 'items'); await test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.montague.tld'], 'items');
await test_utils.waitUntilDiscoConfirmed(_converse, 'upload.montague.tld', [], [Strophe.NS.HTTPUPLOAD], []); await test_utils.waitUntilDiscoConfirmed(_converse, 'upload.montague.tld', [], [Strophe.NS.HTTPUPLOAD], []);
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
// Wait until MAM query has been sent out
const sent_stanzas = _converse.connection.sent_stanzas;
await test_utils.waitUntil(() => sent_stanzas.filter(s => sizzle(`[xmlns="${Strophe.NS.MAM}"]`, s).length).pop());
const view = _converse.chatboxviews.get('lounge@localhost'); const view = _converse.chatboxviews.get('lounge@localhost');
const file = { const file = {
'type': 'image/jpeg', 'type': 'image/jpeg',
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
const $msg = converse.env.$msg; const $msg = converse.env.$msg;
const dayjs = converse.env.dayjs; const dayjs = converse.env.dayjs;
const u = converse.env.utils; const u = converse.env.utils;
const sizzle = converse.env.sizzle;
// See: https://xmpp.org/rfcs/rfc3921.html // See: https://xmpp.org/rfcs/rfc3921.html
describe("Message Archive Management", function () { describe("Message Archive Management", function () {
...@@ -215,18 +216,17 @@ ...@@ -215,18 +216,17 @@
null, [], {}, null, [], {},
async function (done, _converse) { async function (done, _converse) {
await test_utils.openAndEnterChatRoom(_converse, 'coven', 'chat.shakespeare.lit', 'nicky', [Strophe.NS.MAM]); const room_jid = 'coven@chat.shakespeare.lit';
let sent_stanza, IQ_id; _converse.api.archive.query({'with': room_jid, 'groupchat': true});
const sendIQ = _converse.connection.sendIQ; await test_utils.waitUntilDiscoConfirmed(_converse, room_jid, null, [Strophe.NS.MAM]);
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_stanza = iq; const sent_stanzas = _converse.connection.sent_stanzas;
IQ_id = sendIQ.bind(this)(iq, callback, errback); const stanza = await test_utils.waitUntil(
}); () => sent_stanzas.filter(s => sizzle(`[xmlns="${Strophe.NS.MAM}"]`, s).length).pop());
_converse.api.archive.query({'with': 'coven@chat.shakespeare.lit', 'groupchat': true});
await test_utils.waitUntil(() => sent_stanza); const queryid = stanza.querySelector('query').getAttribute('queryid');
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid'); expect(Strophe.serialize(stanza)).toBe(
expect(sent_stanza.toString()).toBe( `<iq id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
`<iq id="${IQ_id}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+ `<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
`<x type="submit" xmlns="jabber:x:data">`+ `<x type="submit" xmlns="jabber:x:data">`+
`<field type="hidden" var="FORM_TYPE">`+ `<field type="hidden" var="FORM_TYPE">`+
...@@ -243,16 +243,15 @@ ...@@ -243,16 +243,15 @@
null, [], {}, null, [], {},
async function (done, _converse) { async function (done, _converse) {
await test_utils.openAndEnterChatRoom(_converse, 'coven', 'chat.shakespeare.lit', 'nicky', [Strophe.NS.MAM]); const room_jid = 'coven@chat.shakespeare.lit';
let sent_stanza, IQ_id; const promise = _converse.api.archive.query({'with': room_jid, 'groupchat': true, 'max':'10'});
const sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) { await test_utils.waitUntilDiscoConfirmed(_converse, room_jid, null, [Strophe.NS.MAM]);
sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback); const sent_stanzas = _converse.connection.sent_stanzas;
}); const sent_stanza = await test_utils.waitUntil(
const promise = _converse.api.archive.query({'with': 'coven@chat.shakespear.lit', 'groupchat': true, 'max':'10'}); () => sent_stanzas.filter(s => sizzle(`[xmlns="${Strophe.NS.MAM}"]`, s).length).pop());
await test_utils.waitUntil(() => sent_stanza); const queryid = sent_stanza.querySelector('query').getAttribute('queryid');
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
/* <message id='iasd207' from='coven@chat.shakespeare.lit' to='hag66@shakespeare.lit/pda'> /* <message id='iasd207' from='coven@chat.shakespeare.lit' to='hag66@shakespeare.lit/pda'>
* <result xmlns='urn:xmpp:mam:2' queryid='g27' id='34482-21985-73620'> * <result xmlns='urn:xmpp:mam:2' queryid='g27' id='34482-21985-73620'>
...@@ -297,7 +296,7 @@ ...@@ -297,7 +296,7 @@
* </set> * </set>
* </iq> * </iq>
*/ */
const stanza = $iq({'type': 'result', 'id': IQ_id}) const stanza = $iq({'type': 'result', 'id': sent_stanza.getAttribute('id')})
.c('fin', {'xmlns': 'urn:xmpp:mam:2'}) .c('fin', {'xmlns': 'urn:xmpp:mam:2'})
.c('set', {'xmlns': 'http://jabber.org/protocol/rsm'}) .c('set', {'xmlns': 'http://jabber.org/protocol/rsm'})
.c('first', {'index': '0'}).t('23452-4534-1').up() .c('first', {'index': '0'}).t('23452-4534-1').up()
......
...@@ -2633,8 +2633,9 @@ ...@@ -2633,8 +2633,9 @@
<origin-id xmlns="urn:xmpp:sid:0" id="CE08D448-5ED8-4B6A-BB5B-07ED9DFE4FF0"/> <origin-id xmlns="urn:xmpp:sid:0" id="CE08D448-5ED8-4B6A-BB5B-07ED9DFE4FF0"/>
</message>`); </message>`);
spyOn(_converse.api, "trigger").and.callThrough(); spyOn(_converse.api, "trigger").and.callThrough();
spyOn(view.model, "isReceipt").and.callThrough();
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.api.trigger.calls.count() === 1); await test_utils.waitUntil(() => view.model.isReceipt.calls.count() === 1);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1); expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0); expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object)); expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
...@@ -2667,12 +2668,11 @@ ...@@ -2667,12 +2668,11 @@
from="lounge@localhost/some1" type="groupchat" xmlns="jabber:client"> from="lounge@localhost/some1" type="groupchat" xmlns="jabber:client">
<received xmlns="urn:xmpp:chat-markers:0" id="${msg_obj.get('msgid')}"/> <received xmlns="urn:xmpp:chat-markers:0" id="${msg_obj.get('msgid')}"/>
</message>`); </message>`);
spyOn(_converse.api, "trigger").and.callThrough(); spyOn(view.model, "isChatMarker").and.callThrough();
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.api.trigger.calls.count() === 1); await test_utils.waitUntil(() => view.model.isChatMarker.calls.count() === 1);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1); expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0); expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
stanza = u.toStanza(` stanza = u.toStanza(`
<message xml:lang="en" to="dummy@localhost/resource" <message xml:lang="en" to="dummy@localhost/resource"
...@@ -2680,10 +2680,9 @@ ...@@ -2680,10 +2680,9 @@
<displayed xmlns="urn:xmpp:chat-markers:0" id="${msg_obj.get('msgid')}"/> <displayed xmlns="urn:xmpp:chat-markers:0" id="${msg_obj.get('msgid')}"/>
</message>`); </message>`);
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.api.trigger.calls.count() === 2); await test_utils.waitUntil(() => view.model.isChatMarker.calls.count() === 2);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1); expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0); expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
stanza = u.toStanza(` stanza = u.toStanza(`
<message xml:lang="en" to="dummy@localhost/resource" <message xml:lang="en" to="dummy@localhost/resource"
...@@ -2692,12 +2691,9 @@ ...@@ -2692,12 +2691,9 @@
</message>`); </message>`);
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
spyOn(view.model, "isChatMarker").and.callThrough(); await test_utils.waitUntil(() => view.model.isChatMarker.calls.count() === 3);
await test_utils.waitUntil(() => view.model.isChatMarker.calls.count() === 1);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1); expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0); expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
stanza = u.toStanza(` stanza = u.toStanza(`
<message xml:lang="en" to="dummy@localhost/resource" <message xml:lang="en" to="dummy@localhost/resource"
...@@ -2706,10 +2702,9 @@ ...@@ -2706,10 +2702,9 @@
<markable xmlns="urn:xmpp:chat-markers:0"/> <markable xmlns="urn:xmpp:chat-markers:0"/>
</message>`); </message>`);
_converse.connection._dataRecv(test_utils.createRequest(stanza)); _converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.model.isChatMarker.calls.count() === 2); await test_utils.waitUntil(() => view.model.isChatMarker.calls.count() === 4);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2); expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0); expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
done(); done();
})); }));
......
...@@ -208,7 +208,7 @@ ...@@ -208,7 +208,7 @@
info_el.click(); info_el.click();
const modal = view.model.room_details_modal; const modal = view.model.room_details_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 2000); await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
let els = modal.el.querySelectorAll('p.room-info'); let els = modal.el.querySelectorAll('p.room-info');
expect(els[0].textContent).toBe("Name: A Dark Cave") expect(els[0].textContent).toBe("Name: A Dark Cave")
expect(els[1].textContent).toBe("Groupchat address (JID): coven@chat.shakespeare.lit") expect(els[1].textContent).toBe("Groupchat address (JID): coven@chat.shakespeare.lit")
......
...@@ -65,7 +65,7 @@ converse.plugins.add('converse-mam-views', { ...@@ -65,7 +65,7 @@ converse.plugins.add('converse-mam-views', {
} else { } else {
message_handler = _converse.chatboxes.onMessage.bind(_converse.chatboxes) message_handler = _converse.chatboxes.onMessage.bind(_converse.chatboxes)
} }
let result; let result = {};
try { try {
result = await _converse.api.archive.query( result = await _converse.api.archive.query(
Object.assign({ Object.assign({
......
...@@ -572,8 +572,7 @@ converse.plugins.add('converse-muc-views', { ...@@ -572,8 +572,7 @@ converse.plugins.add('converse-muc-views', {
this.enterRoom(); this.enterRoom();
}, },
async enterRoom (ev) { async enterRoom () {
if (ev) { ev.preventDefault(); }
if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED) { if (this.model.get('connection_status') !== converse.ROOMSTATUS.ENTERED) {
await this.model.getRoomFeatures(); await this.model.getRoomFeatures();
if (!u.isPersistableModel(this.model)) { if (!u.isPersistableModel(this.model)) {
...@@ -582,8 +581,6 @@ converse.plugins.add('converse-muc-views', { ...@@ -582,8 +581,6 @@ converse.plugins.add('converse-muc-views', {
return; return;
} }
this.populateAndJoin(); this.populateAndJoin();
} else {
this.model.fetchMessages();
} }
/** /**
* Triggered once a groupchat has been opened * Triggered once a groupchat has been opened
...@@ -772,7 +769,9 @@ converse.plugins.add('converse-muc-views', { ...@@ -772,7 +769,9 @@ converse.plugins.add('converse-muc-views', {
}, },
afterConnected () { afterConnected () {
if (this.model.get('connection_status') === converse.ROOMSTATUS.ENTERED) { if (this.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING) {
this.showSpinner();
} else if (this.model.get('connection_status') === converse.ROOMSTATUS.ENTERED) {
this.hideSpinner(); this.hideSpinner();
this.setChatState(_converse.ACTIVE); this.setChatState(_converse.ACTIVE);
this.scrollDown(); this.scrollDown();
...@@ -1197,7 +1196,6 @@ converse.plugins.add('converse-muc-views', { ...@@ -1197,7 +1196,6 @@ converse.plugins.add('converse-muc-views', {
populateAndJoin () { populateAndJoin () {
this.model.occupants.fetchMembers(); this.model.occupants.fetchMembers();
this.join(); this.join();
this.model.fetchMessages();
}, },
/** /**
......
...@@ -293,7 +293,6 @@ converse.plugins.add('converse-chatboxes', { ...@@ -293,7 +293,6 @@ converse.plugins.add('converse-chatboxes', {
} }
this.on('change:chat_state', this.sendChatState, this); this.on('change:chat_state', this.sendChatState, this);
this.initMessages(); this.initMessages();
this.fetchMessages();
}, },
initMessages () { initMessages () {
...@@ -302,12 +301,14 @@ converse.plugins.add('converse-chatboxes', { ...@@ -302,12 +301,14 @@ converse.plugins.add('converse-chatboxes', {
this.messages.browserStorage = new Backbone.BrowserStorage.session( this.messages.browserStorage = new Backbone.BrowserStorage.session(
`converse.messages-${this.get('jid')}-${_converse.bare_jid}`); `converse.messages-${this.get('jid')}-${_converse.bare_jid}`);
this.messages.chatbox = this; this.messages.chatbox = this;
this.messages.fetched = u.getResolveablePromise();
this.messages.on('change:upload', (message) => { this.messages.on('change:upload', (message) => {
if (message.get('upload') === _converse.SUCCESS) { if (message.get('upload') === _converse.SUCCESS) {
_converse.api.send(this.createMessageStanza(message)); _converse.api.send(this.createMessageStanza(message));
} }
}); });
this.fetchMessages();
}, },
afterMessagesFetched () { afterMessagesFetched () {
...@@ -322,12 +323,11 @@ converse.plugins.add('converse-chatboxes', { ...@@ -322,12 +323,11 @@ converse.plugins.add('converse-chatboxes', {
}, },
fetchMessages () { fetchMessages () {
this.messages.fetched = new Promise(resolve => { const resolve = this.messages.fetched.resolve;
this.messages.fetch({ this.messages.fetch({
'add': true, 'add': true,
'success': _.flow(this.afterMessagesFetched.bind(this), resolve), 'success': _.flow(this.afterMessagesFetched.bind(this), resolve),
'error': _.flow(this.afterMessagesFetched.bind(this), resolve) 'error': _.flow(this.afterMessagesFetched.bind(this), resolve)
});
}); });
}, },
......
...@@ -211,10 +211,26 @@ converse.plugins.add('converse-muc', { ...@@ -211,10 +211,26 @@ converse.plugins.add('converse-muc', {
} }
this.set('box_id', `box-${btoa(this.get('jid'))}`); this.set('box_id', `box-${btoa(this.get('jid'))}`);
this.initMessages();
this.on('change:chat_state', this.sendChatState, this); this.on('change:chat_state', this.sendChatState, this);
this.on('change:connection_status', this.onConnectionStatusChanged, this); this.on('change:connection_status', this.onConnectionStatusChanged, this);
this.initFeatures();
this.initOccupants();
this.initMessages();
this.registerHandlers();
},
async onConnectionStatusChanged () {
if (this.get('connection_status') === converse.ROOMSTATUS.ENTERED &&
_converse.auto_register_muc_nickname &&
!this.get('reserved_nick') &&
await _converse.api.disco.supports(Strophe.NS.MUC_REGISTER, this.get('jid'))) {
this.registerNickname()
}
},
initFeatures () {
const storage = _converse.config.get('storage'); const storage = _converse.config.get('storage');
const id = `converse.muc-features-${_converse.bare_jid}-${this.get('jid')}`; const id = `converse.muc-features-${_converse.bare_jid}-${this.get('jid')}`;
this.features = new Backbone.Model( this.features = new Backbone.Model(
...@@ -222,7 +238,9 @@ converse.plugins.add('converse-muc', { ...@@ -222,7 +238,9 @@ converse.plugins.add('converse-muc', {
); );
this.features.browserStorage = new Backbone.BrowserStorage.session(id); this.features.browserStorage = new Backbone.BrowserStorage.session(id);
this.features.fetch(); this.features.fetch();
},
initOccupants () {
this.occupants = new _converse.ChatRoomOccupants(); this.occupants = new _converse.ChatRoomOccupants();
this.occupants.browserStorage = new Backbone.BrowserStorage.session( this.occupants.browserStorage = new Backbone.BrowserStorage.session(
`converse.occupants-${_converse.bare_jid}${this.get('jid')}` `converse.occupants-${_converse.bare_jid}${this.get('jid')}`
...@@ -236,18 +254,6 @@ converse.plugins.add('converse-muc', { ...@@ -236,18 +254,6 @@ converse.plugins.add('converse-muc', {
'error': resolve 'error': resolve
}); });
}); });
this.registerHandlers();
},
async onConnectionStatusChanged () {
if (this.get('connection_status') === converse.ROOMSTATUS.ENTERED &&
_converse.auto_register_muc_nickname &&
!this.get('reserved_nick') &&
await _converse.api.disco.supports(Strophe.NS.MUC_REGISTER, this.get('jid'))) {
this.registerNickname()
}
}, },
registerHandlers () { registerHandlers () {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment