Use async/await in MAM code and tests
This commit is contained in:
parent
6e05f3b67c
commit
79bfb45639
629
spec/mam.js
629
spec/mam.js
@ -2,12 +2,12 @@
|
|||||||
define(["jasmine", "mock", "test-utils"], factory);
|
define(["jasmine", "mock", "test-utils"], factory);
|
||||||
} (this, function (jasmine, mock, test_utils) {
|
} (this, function (jasmine, mock, test_utils) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var _ = converse.env._;
|
const _ = converse.env._;
|
||||||
var Backbone = converse.env.Backbone;
|
const Backbone = converse.env.Backbone;
|
||||||
var Strophe = converse.env.Strophe;
|
const Strophe = converse.env.Strophe;
|
||||||
var $iq = converse.env.$iq;
|
const $iq = converse.env.$iq;
|
||||||
var $msg = converse.env.$msg;
|
const $msg = converse.env.$msg;
|
||||||
var moment = converse.env.moment;
|
const moment = converse.env.moment;
|
||||||
// See: https://xmpp.org/rfcs/rfc3921.html
|
// See: https://xmpp.org/rfcs/rfc3921.html
|
||||||
|
|
||||||
describe("Message Archive Management", function () {
|
describe("Message Archive Management", function () {
|
||||||
@ -18,48 +18,46 @@
|
|||||||
it("aren't shown as duplicates",
|
it("aren't shown as duplicates",
|
||||||
mock.initConverseWithPromises(
|
mock.initConverseWithPromises(
|
||||||
null, ['discoInitialized'], {},
|
null, ['discoInitialized'], {},
|
||||||
function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
|
||||||
let view, stanza;
|
await test_utils.openAndEnterChatRoom(_converse, 'trek-radio', 'conference.lightwitch.org', 'jcbrand');
|
||||||
|
const view = _converse.chatboxviews.get('trek-radio@conference.lightwitch.org');
|
||||||
|
let stanza = Strophe.xmlHtmlNode(
|
||||||
|
`<message xmlns="jabber:client" to="jcbrand@lightwitch.org/converse.js-73057452" type="groupchat" from="trek-radio@conference.lightwitch.org/comndrdukath#0805 (STO)">
|
||||||
|
<body>negan</body>
|
||||||
|
<stanza-id xmlns="urn:xmpp:sid:0" id="45fbbf2a-1059-479d-9283-c8effaf05621" by="trek-radio@conference.lightwitch.org"/>
|
||||||
|
</message>`
|
||||||
|
).firstElementChild;
|
||||||
|
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||||
|
await test_utils.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
|
||||||
|
// XXX: we wait here until the first message appears before
|
||||||
|
// sending the duplicate. If we don't do that, then the
|
||||||
|
// duplicate appears before the promise for `createMessage`
|
||||||
|
// has been resolved, which means that the `isDuplicate`
|
||||||
|
// check fails because the first message doesn't exist yet.
|
||||||
|
//
|
||||||
|
// Not sure whether such a race-condition might pose a problem
|
||||||
|
// in "real-world" situations.
|
||||||
|
stanza = Strophe.xmlHtmlNode(
|
||||||
|
`<message xmlns="jabber:client" to="jcbrand@lightwitch.org/converse.js-73057452">
|
||||||
|
<result xmlns="urn:xmpp:mam:2" queryid="82d9db27-6cf8-4787-8c2c-5a560263d823" id="45fbbf2a-1059-479d-9283-c8effaf05621">
|
||||||
|
<forwarded xmlns="urn:xmpp:forward:0">
|
||||||
|
<delay xmlns="urn:xmpp:delay" stamp="2018-01-09T06:17:23Z"/>
|
||||||
|
<message from="trek-radio@conference.lightwitch.org/comndrdukath#0805 (STO)" type="groupchat">
|
||||||
|
<body>negan</body>
|
||||||
|
</message>
|
||||||
|
</forwarded>
|
||||||
|
</result>
|
||||||
|
</message>`).firstElementChild;
|
||||||
|
|
||||||
|
spyOn(view.model, 'isDuplicate').and.callThrough();
|
||||||
|
view.model.onMessage(stanza);
|
||||||
|
await test_utils.waitUntil(() => view.model.isDuplicate.calls.count());
|
||||||
|
expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
|
||||||
|
done();
|
||||||
|
}));
|
||||||
|
|
||||||
test_utils.openAndEnterChatRoom(_converse, 'trek-radio', 'conference.lightwitch.org', 'jcbrand')
|
|
||||||
.then(() => {
|
|
||||||
view = _converse.chatboxviews.get('trek-radio@conference.lightwitch.org');
|
|
||||||
stanza = Strophe.xmlHtmlNode(
|
|
||||||
`<message xmlns="jabber:client" to="jcbrand@lightwitch.org/converse.js-73057452" type="groupchat" from="trek-radio@conference.lightwitch.org/comndrdukath#0805 (STO)">
|
|
||||||
<body>negan</body>
|
|
||||||
<stanza-id xmlns="urn:xmpp:sid:0" id="45fbbf2a-1059-479d-9283-c8effaf05621" by="trek-radio@conference.lightwitch.org"/>
|
|
||||||
</message>`).firstElementChild;
|
|
||||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
|
||||||
return test_utils.waitUntil(() => view.content.querySelectorAll('.chat-msg').length)
|
|
||||||
}).then(() => {
|
|
||||||
// XXX: we wait here until the first message appears before
|
|
||||||
// sending the duplicate. If we don't do that, then the
|
|
||||||
// duplicate appears before the promise for `createMessage`
|
|
||||||
// has been resolved, which means that the `isDuplicate`
|
|
||||||
// check fails because the first message doesn't exist yet.
|
|
||||||
//
|
|
||||||
// Not sure whether such a race-condition might pose a problem
|
|
||||||
// in "real-world" situations.
|
|
||||||
stanza = Strophe.xmlHtmlNode(
|
|
||||||
`<message xmlns="jabber:client" to="jcbrand@lightwitch.org/converse.js-73057452">
|
|
||||||
<result xmlns="urn:xmpp:mam:2" queryid="82d9db27-6cf8-4787-8c2c-5a560263d823" id="45fbbf2a-1059-479d-9283-c8effaf05621">
|
|
||||||
<forwarded xmlns="urn:xmpp:forward:0"><delay xmlns="urn:xmpp:delay" stamp="2018-01-09T06:17:23Z"/>
|
|
||||||
<message from="trek-radio@conference.lightwitch.org/comndrdukath#0805 (STO)" type="groupchat">
|
|
||||||
<body>negan</body>
|
|
||||||
</message>
|
|
||||||
</forwarded>
|
|
||||||
</result>
|
|
||||||
</message>`).firstElementChild;
|
|
||||||
|
|
||||||
spyOn(view.model, 'isDuplicate').and.callThrough();
|
|
||||||
view.model.onMessage(stanza);
|
|
||||||
return test_utils.waitUntil(() => view.model.isDuplicate.calls.count());
|
|
||||||
}).then(() => {
|
|
||||||
expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
|
|
||||||
done();
|
|
||||||
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
|
||||||
}))
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("The archive.query API", function () {
|
describe("The archive.query API", function () {
|
||||||
@ -86,78 +84,76 @@
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
it("can be used to query for all messages to/from a particular JID",
|
it("can be used to query for all messages to/from a particular JID",
|
||||||
mock.initConverseWithPromises(
|
mock.initConverseWithPromises(
|
||||||
null, [], {},
|
null, [], {},
|
||||||
function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
|
||||||
_converse.api.disco.entities.get(_converse.domain).then(function (entity) {
|
const entity = await _converse.api.disco.entities.get(_converse.domain);
|
||||||
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||||
}
|
}
|
||||||
var sent_stanza, IQ_id;
|
let sent_stanza, IQ_id;
|
||||||
var sendIQ = _converse.connection.sendIQ;
|
const sendIQ = _converse.connection.sendIQ;
|
||||||
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
||||||
sent_stanza = iq;
|
sent_stanza = iq;
|
||||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||||
});
|
|
||||||
_converse.api.archive.query({'with':'juliet@capulet.lit'});
|
|
||||||
var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
|
||||||
expect(sent_stanza.toString()).toBe(
|
|
||||||
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
|
||||||
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
|
|
||||||
`<x type="submit" xmlns="jabber:x:data">`+
|
|
||||||
`<field type="hidden" var="FORM_TYPE">`+
|
|
||||||
`<value>urn:xmpp:mam:2</value>`+
|
|
||||||
`</field>`+
|
|
||||||
`<field var="with">`+
|
|
||||||
`<value>juliet@capulet.lit</value>`+
|
|
||||||
`</field>`+
|
|
||||||
`</x>`+
|
|
||||||
`</query>`+
|
|
||||||
`</iq>`);
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
_converse.api.archive.query({'with':'juliet@capulet.lit'});
|
||||||
|
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
||||||
|
expect(sent_stanza.toString()).toBe(
|
||||||
|
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
||||||
|
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
|
||||||
|
`<x type="submit" xmlns="jabber:x:data">`+
|
||||||
|
`<field type="hidden" var="FORM_TYPE">`+
|
||||||
|
`<value>urn:xmpp:mam:2</value>`+
|
||||||
|
`</field>`+
|
||||||
|
`<field var="with">`+
|
||||||
|
`<value>juliet@capulet.lit</value>`+
|
||||||
|
`</field>`+
|
||||||
|
`</x>`+
|
||||||
|
`</query>`+
|
||||||
|
`</iq>`);
|
||||||
|
done();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("can be used to query for archived messages from a chat room",
|
it("can be used to query for archived messages from a chat room",
|
||||||
mock.initConverseWithPromises(
|
mock.initConverseWithPromises(
|
||||||
null, [], {},
|
null, [], {},
|
||||||
function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
|
||||||
_converse.api.disco.entities.get(_converse.domain).then(function (entity) {
|
const entity = await _converse.api.disco.entities.get(_converse.domain);
|
||||||
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||||
}
|
}
|
||||||
|
|
||||||
var sent_stanza, IQ_id;
|
let sent_stanza, IQ_id;
|
||||||
var sendIQ = _converse.connection.sendIQ;
|
const sendIQ = _converse.connection.sendIQ;
|
||||||
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
||||||
sent_stanza = iq;
|
sent_stanza = iq;
|
||||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||||
});
|
|
||||||
var callback = jasmine.createSpy('callback');
|
|
||||||
|
|
||||||
_converse.api.archive.query({'with': 'coven@chat.shakespeare.lit', 'groupchat': true}, callback);
|
|
||||||
var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
|
||||||
|
|
||||||
expect(sent_stanza.toString()).toBe(
|
|
||||||
`<iq id="${IQ_id}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
|
|
||||||
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
|
|
||||||
`<x type="submit" xmlns="jabber:x:data">`+
|
|
||||||
`<field type="hidden" var="FORM_TYPE">`+
|
|
||||||
`<value>urn:xmpp:mam:2</value>`+
|
|
||||||
`</field>`+
|
|
||||||
`</x>`+
|
|
||||||
`</query>`+
|
|
||||||
`</iq>`);
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
const callback = jasmine.createSpy('callback');
|
||||||
|
|
||||||
|
_converse.api.archive.query({'with': 'coven@chat.shakespeare.lit', 'groupchat': true}, callback);
|
||||||
|
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
||||||
|
|
||||||
|
expect(sent_stanza.toString()).toBe(
|
||||||
|
`<iq id="${IQ_id}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
|
||||||
|
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
|
||||||
|
`<x type="submit" xmlns="jabber:x:data">`+
|
||||||
|
`<field type="hidden" var="FORM_TYPE">`+
|
||||||
|
`<value>urn:xmpp:mam:2</value>`+
|
||||||
|
`</field>`+
|
||||||
|
`</x>`+
|
||||||
|
`</query>`+
|
||||||
|
`</iq>`);
|
||||||
|
done();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("checks whether returned MAM messages from a MUC room are from the right JID",
|
it("checks whether returned MAM messages from a MUC room are from the right JID",
|
||||||
mock.initConverseWithPromises(
|
mock.initConverseWithPromises(
|
||||||
null, [], {},
|
null, [], {},
|
||||||
async function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
|
||||||
const entity = await _converse.api.disco.entities.get(_converse.domain);
|
const entity = await _converse.api.disco.entities.get(_converse.domain);
|
||||||
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||||
@ -233,47 +229,46 @@
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
it("can be used to query for all messages in a certain timespan",
|
it("can be used to query for all messages in a certain timespan",
|
||||||
mock.initConverseWithPromises(
|
mock.initConverseWithPromises(
|
||||||
null, [], {},
|
null, [], {},
|
||||||
function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
|
||||||
var sent_stanza, IQ_id;
|
let sent_stanza, IQ_id;
|
||||||
var sendIQ = _converse.connection.sendIQ;
|
const sendIQ = _converse.connection.sendIQ;
|
||||||
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
||||||
sent_stanza = iq;
|
sent_stanza = iq;
|
||||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||||
});
|
});
|
||||||
_converse.api.disco.entities.get().then(function (entities) {
|
const entities = await _converse.api.disco.entities.get();
|
||||||
if (!entities.get(_converse.domain).features.findWhere({'var': Strophe.NS.MAM})) {
|
if (!entities.get(_converse.domain).features.findWhere({'var': Strophe.NS.MAM})) {
|
||||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||||
}
|
}
|
||||||
var start = '2010-06-07T00:00:00Z';
|
const start = '2010-06-07T00:00:00Z';
|
||||||
var end = '2010-07-07T13:23:54Z';
|
const end = '2010-07-07T13:23:54Z';
|
||||||
_converse.api.archive.query({
|
_converse.api.archive.query({
|
||||||
'start': start,
|
'start': start,
|
||||||
'end': end
|
'end': end
|
||||||
|
|
||||||
});
|
|
||||||
var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
|
||||||
expect(sent_stanza.toString()).toBe(
|
|
||||||
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
|
||||||
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
|
|
||||||
`<x type="submit" xmlns="jabber:x:data">`+
|
|
||||||
`<field type="hidden" var="FORM_TYPE">`+
|
|
||||||
`<value>urn:xmpp:mam:2</value>`+
|
|
||||||
`</field>`+
|
|
||||||
`<field var="start">`+
|
|
||||||
`<value>${moment(start).format()}</value>`+
|
|
||||||
`</field>`+
|
|
||||||
`<field var="end">`+
|
|
||||||
`<value>${moment(end).format()}</value>`+
|
|
||||||
`</field>`+
|
|
||||||
`</x>`+
|
|
||||||
`</query>`+
|
|
||||||
`</iq>`
|
|
||||||
);
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
||||||
|
expect(sent_stanza.toString()).toBe(
|
||||||
|
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
||||||
|
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
|
||||||
|
`<x type="submit" xmlns="jabber:x:data">`+
|
||||||
|
`<field type="hidden" var="FORM_TYPE">`+
|
||||||
|
`<value>urn:xmpp:mam:2</value>`+
|
||||||
|
`</field>`+
|
||||||
|
`<field var="start">`+
|
||||||
|
`<value>${moment(start).format()}</value>`+
|
||||||
|
`</field>`+
|
||||||
|
`<field var="end">`+
|
||||||
|
`<value>${moment(end).format()}</value>`+
|
||||||
|
`</field>`+
|
||||||
|
`</x>`+
|
||||||
|
`</query>`+
|
||||||
|
`</iq>`
|
||||||
|
);
|
||||||
|
done();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("throws a TypeError if an invalid date is provided",
|
it("throws a TypeError if an invalid date is provided",
|
||||||
@ -292,208 +287,202 @@
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
it("can be used to query for all messages after a certain time",
|
it("can be used to query for all messages after a certain time",
|
||||||
mock.initConverseWithPromises(
|
mock.initConverseWithPromises(
|
||||||
null, [], {},
|
null, [], {},
|
||||||
function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
|
||||||
_converse.api.disco.entities.get(_converse.domain).then(function (entity) {
|
const entity = await _converse.api.disco.entities.get(_converse.domain);
|
||||||
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||||
}
|
}
|
||||||
var sent_stanza, IQ_id;
|
let sent_stanza, IQ_id;
|
||||||
var sendIQ = _converse.connection.sendIQ;
|
const sendIQ = _converse.connection.sendIQ;
|
||||||
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
||||||
sent_stanza = iq;
|
sent_stanza = iq;
|
||||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||||
});
|
});
|
||||||
if (!_converse.disco_entities.get(_converse.domain).features.findWhere({'var': Strophe.NS.MAM})) {
|
if (!_converse.disco_entities.get(_converse.domain).features.findWhere({'var': Strophe.NS.MAM})) {
|
||||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||||
}
|
}
|
||||||
var start = '2010-06-07T00:00:00Z';
|
const start = '2010-06-07T00:00:00Z';
|
||||||
_converse.api.archive.query({'start': start});
|
_converse.api.archive.query({'start': start});
|
||||||
var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
||||||
expect(sent_stanza.toString()).toBe(
|
expect(sent_stanza.toString()).toBe(
|
||||||
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
`<iq id="${IQ_id}" 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">`+
|
||||||
|
`<value>urn:xmpp:mam:2</value>`+
|
||||||
|
`</field>`+
|
||||||
|
`<field var="start">`+
|
||||||
|
`<value>${moment(start).format()}</value>`+
|
||||||
|
`</field>`+
|
||||||
|
`</x>`+
|
||||||
|
`</query>`+
|
||||||
|
`</iq>`
|
||||||
|
);
|
||||||
|
done();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it("can be used to query for a limited set of results",
|
||||||
|
mock.initConverseWithPromises(
|
||||||
|
null, [], {},
|
||||||
|
async function (done, _converse) {
|
||||||
|
|
||||||
|
const entity = await _converse.api.disco.entities.get(_converse.domain);
|
||||||
|
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||||
|
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||||
|
}
|
||||||
|
let sent_stanza, IQ_id;
|
||||||
|
const sendIQ = _converse.connection.sendIQ;
|
||||||
|
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
||||||
|
sent_stanza = iq;
|
||||||
|
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||||
|
});
|
||||||
|
const start = '2010-06-07T00:00:00Z';
|
||||||
|
_converse.api.archive.query({'start': start, 'max':10});
|
||||||
|
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
||||||
|
expect(sent_stanza.toString()).toBe(
|
||||||
|
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
||||||
|
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
|
||||||
|
`<x type="submit" xmlns="jabber:x:data">`+
|
||||||
`<field type="hidden" var="FORM_TYPE">`+
|
`<field type="hidden" var="FORM_TYPE">`+
|
||||||
`<value>urn:xmpp:mam:2</value>`+
|
`<value>urn:xmpp:mam:2</value>`+
|
||||||
`</field>`+
|
`</field>`+
|
||||||
`<field var="start">`+
|
`<field var="start">`+
|
||||||
`<value>${moment(start).format()}</value>`+
|
`<value>${moment(start).format()}</value>`+
|
||||||
`</field>`+
|
`</field>`+
|
||||||
`</x>`+
|
`</x>`+
|
||||||
`</query>`+
|
`<set xmlns="http://jabber.org/protocol/rsm">`+
|
||||||
`</iq>`
|
`<max>10</max>`+
|
||||||
);
|
`</set>`+
|
||||||
done();
|
`</query>`+
|
||||||
});
|
`</iq>`
|
||||||
}));
|
);
|
||||||
|
done();
|
||||||
it("can be used to query for a limited set of results",
|
|
||||||
mock.initConverseWithPromises(
|
|
||||||
null, [], {},
|
|
||||||
function (done, _converse) {
|
|
||||||
|
|
||||||
_converse.api.disco.entities.get(_converse.domain).then(function (entity) {
|
|
||||||
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
|
||||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
|
||||||
}
|
|
||||||
|
|
||||||
var sent_stanza, IQ_id;
|
|
||||||
var sendIQ = _converse.connection.sendIQ;
|
|
||||||
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
|
||||||
sent_stanza = iq;
|
|
||||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
|
||||||
});
|
|
||||||
var start = '2010-06-07T00:00:00Z';
|
|
||||||
_converse.api.archive.query({'start': start, 'max':10});
|
|
||||||
var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
|
||||||
expect(sent_stanza.toString()).toBe(
|
|
||||||
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
|
||||||
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
|
|
||||||
`<x type="submit" xmlns="jabber:x:data">`+
|
|
||||||
`<field type="hidden" var="FORM_TYPE">`+
|
|
||||||
`<value>urn:xmpp:mam:2</value>`+
|
|
||||||
`</field>`+
|
|
||||||
`<field var="start">`+
|
|
||||||
`<value>${moment(start).format()}</value>`+
|
|
||||||
`</field>`+
|
|
||||||
`</x>`+
|
|
||||||
`<set xmlns="http://jabber.org/protocol/rsm">`+
|
|
||||||
`<max>10</max>`+
|
|
||||||
`</set>`+
|
|
||||||
`</query>`+
|
|
||||||
`</iq>`
|
|
||||||
);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("can be used to page through results",
|
it("can be used to page through results",
|
||||||
mock.initConverseWithPromises(
|
mock.initConverseWithPromises(
|
||||||
null, [], {},
|
null, [], {},
|
||||||
function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
|
||||||
_converse.api.disco.entities.get(_converse.domain).then(function (entity) {
|
const entity = await _converse.api.disco.entities.get(_converse.domain);
|
||||||
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||||
}
|
}
|
||||||
var sent_stanza, IQ_id;
|
let sent_stanza, IQ_id;
|
||||||
var sendIQ = _converse.connection.sendIQ;
|
const sendIQ = _converse.connection.sendIQ;
|
||||||
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
||||||
sent_stanza = iq;
|
sent_stanza = iq;
|
||||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||||
});
|
|
||||||
var start = '2010-06-07T00:00:00Z';
|
|
||||||
_converse.api.archive.query({
|
|
||||||
'start': start,
|
|
||||||
'after': '09af3-cc343-b409f',
|
|
||||||
'max':10
|
|
||||||
});
|
|
||||||
var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
|
||||||
expect(sent_stanza.toString()).toBe(
|
|
||||||
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
|
||||||
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
|
|
||||||
`<x type="submit" xmlns="jabber:x:data">`+
|
|
||||||
`<field type="hidden" var="FORM_TYPE">`+
|
|
||||||
`<value>urn:xmpp:mam:2</value>`+
|
|
||||||
`</field>`+
|
|
||||||
`<field var="start">`+
|
|
||||||
`<value>${moment(start).format()}</value>`+
|
|
||||||
`</field>`+
|
|
||||||
`</x>`+
|
|
||||||
`<set xmlns="http://jabber.org/protocol/rsm">`+
|
|
||||||
`<max>10</max>`+
|
|
||||||
`<after>09af3-cc343-b409f</after>`+
|
|
||||||
`</set>`+
|
|
||||||
`</query>`+
|
|
||||||
`</iq>`);
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
const start = '2010-06-07T00:00:00Z';
|
||||||
|
_converse.api.archive.query({
|
||||||
|
'start': start,
|
||||||
|
'after': '09af3-cc343-b409f',
|
||||||
|
'max':10
|
||||||
|
});
|
||||||
|
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
||||||
|
expect(sent_stanza.toString()).toBe(
|
||||||
|
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
||||||
|
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
|
||||||
|
`<x type="submit" xmlns="jabber:x:data">`+
|
||||||
|
`<field type="hidden" var="FORM_TYPE">`+
|
||||||
|
`<value>urn:xmpp:mam:2</value>`+
|
||||||
|
`</field>`+
|
||||||
|
`<field var="start">`+
|
||||||
|
`<value>${moment(start).format()}</value>`+
|
||||||
|
`</field>`+
|
||||||
|
`</x>`+
|
||||||
|
`<set xmlns="http://jabber.org/protocol/rsm">`+
|
||||||
|
`<max>10</max>`+
|
||||||
|
`<after>09af3-cc343-b409f</after>`+
|
||||||
|
`</set>`+
|
||||||
|
`</query>`+
|
||||||
|
`</iq>`);
|
||||||
|
done();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("accepts \"before\" with an empty string as value to reverse the order",
|
it("accepts \"before\" with an empty string as value to reverse the order",
|
||||||
mock.initConverseWithPromises(
|
mock.initConverseWithPromises(
|
||||||
null, [], {},
|
null, [], {},
|
||||||
function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
|
||||||
_converse.api.disco.entities.get(_converse.domain).then(function (entity) {
|
const entity = await _converse.api.disco.entities.get(_converse.domain);
|
||||||
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||||
}
|
}
|
||||||
var sent_stanza, IQ_id;
|
let sent_stanza, IQ_id;
|
||||||
var sendIQ = _converse.connection.sendIQ;
|
const sendIQ = _converse.connection.sendIQ;
|
||||||
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
||||||
sent_stanza = iq;
|
sent_stanza = iq;
|
||||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||||
});
|
|
||||||
_converse.api.archive.query({'before': '', 'max':10});
|
|
||||||
var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
|
||||||
expect(sent_stanza.toString()).toBe(
|
|
||||||
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
|
||||||
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
|
|
||||||
`<x type="submit" xmlns="jabber:x:data">`+
|
|
||||||
`<field type="hidden" var="FORM_TYPE">`+
|
|
||||||
`<value>urn:xmpp:mam:2</value>`+
|
|
||||||
`</field>`+
|
|
||||||
`</x>`+
|
|
||||||
`<set xmlns="http://jabber.org/protocol/rsm">`+
|
|
||||||
`<max>10</max>`+
|
|
||||||
`<before></before>`+
|
|
||||||
`</set>`+
|
|
||||||
`</query>`+
|
|
||||||
`</iq>`);
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
_converse.api.archive.query({'before': '', 'max':10});
|
||||||
|
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
||||||
|
expect(sent_stanza.toString()).toBe(
|
||||||
|
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
||||||
|
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
|
||||||
|
`<x type="submit" xmlns="jabber:x:data">`+
|
||||||
|
`<field type="hidden" var="FORM_TYPE">`+
|
||||||
|
`<value>urn:xmpp:mam:2</value>`+
|
||||||
|
`</field>`+
|
||||||
|
`</x>`+
|
||||||
|
`<set xmlns="http://jabber.org/protocol/rsm">`+
|
||||||
|
`<max>10</max>`+
|
||||||
|
`<before></before>`+
|
||||||
|
`</set>`+
|
||||||
|
`</query>`+
|
||||||
|
`</iq>`);
|
||||||
|
done();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("accepts a Strophe.RSM object for the query options",
|
it("accepts a Strophe.RSM object for the query options",
|
||||||
mock.initConverseWithPromises(
|
mock.initConverseWithPromises(
|
||||||
null, [], {},
|
null, [], {},
|
||||||
function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
|
||||||
_converse.api.disco.entities.get(_converse.domain).then(function (entity) {
|
const entity = await _converse.api.disco.entities.get(_converse.domain);
|
||||||
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
if (!entity.features.findWhere({'var': Strophe.NS.MAM})) {
|
||||||
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
_converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM});
|
||||||
}
|
}
|
||||||
var sent_stanza, IQ_id;
|
let sent_stanza, IQ_id;
|
||||||
var sendIQ = _converse.connection.sendIQ;
|
const sendIQ = _converse.connection.sendIQ;
|
||||||
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
|
||||||
sent_stanza = iq;
|
sent_stanza = iq;
|
||||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||||
});
|
|
||||||
// Normally the user wouldn't manually make a Strophe.RSM object
|
|
||||||
// and pass it in. However, in the callback method an RSM object is
|
|
||||||
// returned which can be reused for easy paging. This test is
|
|
||||||
// more for that usecase.
|
|
||||||
var rsm = new Strophe.RSM({'max': '10'});
|
|
||||||
rsm['with'] = 'romeo@montague.lit'; // eslint-disable-line dot-notation
|
|
||||||
rsm.start = '2010-06-07T00:00:00Z';
|
|
||||||
_converse.api.archive.query(rsm);
|
|
||||||
|
|
||||||
var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
|
||||||
expect(sent_stanza.toString()).toBe(
|
|
||||||
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
|
||||||
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
|
|
||||||
`<x type="submit" xmlns="jabber:x:data">`+
|
|
||||||
`<field type="hidden" var="FORM_TYPE">`+
|
|
||||||
`<value>urn:xmpp:mam:2</value>`+
|
|
||||||
`</field>`+
|
|
||||||
`<field var="with">`+
|
|
||||||
`<value>romeo@montague.lit</value>`+
|
|
||||||
`</field>`+
|
|
||||||
`<field var="start">`+
|
|
||||||
`<value>${moment(rsm.start).format()}</value>`+
|
|
||||||
`</field>`+
|
|
||||||
`</x>`+
|
|
||||||
`<set xmlns="http://jabber.org/protocol/rsm">`+
|
|
||||||
`<max>10</max>`+
|
|
||||||
`</set>`+
|
|
||||||
`</query>`+
|
|
||||||
`</iq>`);
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
// Normally the user wouldn't manually make a Strophe.RSM object
|
||||||
|
// and pass it in. However, in the callback method an RSM object is
|
||||||
|
// returned which can be reused for easy paging. This test is
|
||||||
|
// more for that usecase.
|
||||||
|
const rsm = new Strophe.RSM({'max': '10'});
|
||||||
|
rsm['with'] = 'romeo@montague.lit'; // eslint-disable-line dot-notation
|
||||||
|
rsm.start = '2010-06-07T00:00:00Z';
|
||||||
|
_converse.api.archive.query(rsm);
|
||||||
|
|
||||||
|
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
|
||||||
|
expect(sent_stanza.toString()).toBe(
|
||||||
|
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
|
||||||
|
`<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
|
||||||
|
`<x type="submit" xmlns="jabber:x:data">`+
|
||||||
|
`<field type="hidden" var="FORM_TYPE">`+
|
||||||
|
`<value>urn:xmpp:mam:2</value>`+
|
||||||
|
`</field>`+
|
||||||
|
`<field var="with">`+
|
||||||
|
`<value>romeo@montague.lit</value>`+
|
||||||
|
`</field>`+
|
||||||
|
`<field var="start">`+
|
||||||
|
`<value>${moment(rsm.start).format()}</value>`+
|
||||||
|
`</field>`+
|
||||||
|
`</x>`+
|
||||||
|
`<set xmlns="http://jabber.org/protocol/rsm">`+
|
||||||
|
`<max>10</max>`+
|
||||||
|
`</set>`+
|
||||||
|
`</query>`+
|
||||||
|
`</iq>`);
|
||||||
|
done();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("accepts a callback function, which it passes the messages and a Strophe.RSM object",
|
it("accepts a callback function, which it passes the messages and a Strophe.RSM object",
|
||||||
|
@ -331,10 +331,10 @@ converse.plugins.add('converse-omemo', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getMessageAttributesFromStanza (stanza, original_stanza) {
|
async getMessageAttributesFromStanza (stanza, original_stanza) {
|
||||||
const { _converse } = this.__super__,
|
const { _converse } = this.__super__,
|
||||||
encrypted = sizzle(`encrypted[xmlns="${Strophe.NS.OMEMO}"]`, original_stanza).pop(),
|
encrypted = sizzle(`encrypted[xmlns="${Strophe.NS.OMEMO}"]`, original_stanza).pop(),
|
||||||
attrs = this.__super__.getMessageAttributesFromStanza.apply(this, arguments);
|
attrs = await this.__super__.getMessageAttributesFromStanza.apply(this, arguments);
|
||||||
|
|
||||||
if (!encrypted || !_converse.config.get('trusted')) {
|
if (!encrypted || !_converse.config.get('trusted')) {
|
||||||
return attrs;
|
return attrs;
|
||||||
|
@ -557,31 +557,22 @@ converse.plugins.add('converse-chatboxes', {
|
|||||||
return attrs;
|
return attrs;
|
||||||
},
|
},
|
||||||
|
|
||||||
createMessage (message, original_stanza) {
|
async createMessage (message, original_stanza) {
|
||||||
/* Create a Backbone.Message object inside this chat box
|
/* Create a Backbone.Message object inside this chat box
|
||||||
* based on the identified message stanza.
|
* based on the identified message stanza.
|
||||||
*/
|
*/
|
||||||
const that = this;
|
const attrs = await this.getMessageAttributesFromStanza(message, original_stanza),
|
||||||
function _create (attrs) {
|
is_csn = u.isOnlyChatStateNotification(attrs);
|
||||||
const is_csn = u.isOnlyChatStateNotification(attrs);
|
|
||||||
if (is_csn && (attrs.is_delayed ||
|
if (is_csn && (attrs.is_delayed || (attrs.type === 'groupchat' && Strophe.getResourceFromJid(attrs.from) == this.get('nick')))) {
|
||||||
(attrs.type === 'groupchat' && Strophe.getResourceFromJid(attrs.from) == that.get('nick')))) {
|
// XXX: MUC leakage
|
||||||
// XXX: MUC leakage
|
// No need showing delayed or our own CSN messages
|
||||||
// No need showing delayed or our own CSN messages
|
return;
|
||||||
return;
|
} else if (!is_csn && !attrs.file && !attrs.plaintext && !attrs.message && !attrs.oob_url && attrs.type !== 'error') {
|
||||||
} else if (!is_csn && !attrs.file && !attrs.plaintext && !attrs.message && !attrs.oob_url && attrs.type !== 'error') {
|
// TODO: handle <subject> messages (currently being done by ChatRoom)
|
||||||
// TODO: handle <subject> messages (currently being done by ChatRoom)
|
return;
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
return that.messages.create(attrs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const result = this.getMessageAttributesFromStanza(message, original_stanza)
|
|
||||||
if (typeof result.then === "function") {
|
|
||||||
return new Promise((resolve, reject) => result.then(attrs => resolve(_create(attrs))));
|
|
||||||
} else {
|
} else {
|
||||||
const message = _create(result)
|
return this.messages.create(attrs);
|
||||||
return Promise.resolve(message);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -133,20 +133,10 @@ converse.plugins.add('converse-mam', {
|
|||||||
// New functions which don't exist yet can also be added.
|
// New functions which don't exist yet can also be added.
|
||||||
ChatBox: {
|
ChatBox: {
|
||||||
|
|
||||||
getMessageAttributesFromStanza (message, original_stanza) {
|
async getMessageAttributesFromStanza (message, original_stanza) {
|
||||||
function _process (attrs) {
|
const attrs = await this.__super__.getMessageAttributesFromStanza.apply(this, arguments);
|
||||||
const archive_id = getMessageArchiveID(original_stanza);
|
attrs.archive_id = getMessageArchiveID(original_stanza);
|
||||||
if (archive_id) {
|
return attrs;
|
||||||
attrs.archive_id = archive_id;
|
|
||||||
}
|
|
||||||
return attrs;
|
|
||||||
}
|
|
||||||
const result = this.__super__.getMessageAttributesFromStanza.apply(this, arguments)
|
|
||||||
if (result instanceof Promise) {
|
|
||||||
return new Promise((resolve, reject) => result.then((attrs) => resolve(_process(attrs))).catch(reject));
|
|
||||||
} else {
|
|
||||||
return _process(result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user