quickblox 2.17.9-logger → 2.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +4 -0
- package/README.md +1 -2
- package/package.json +2 -1
- package/quickblox.js +111 -7055
- package/quickblox.min.js +1 -1
- package/src/modules/chat/qbChat.js +17 -27
- package/src/modules/webrtc/qbWebRTCSignalingProcessor.js +1 -2
- package/src/modules/webrtc/qbWebRTCSignalingProvider.js +1 -2
- package/src/qbConfig.js +2 -2
- package/src/qbStrophe.js +49 -59
- package/{src/libs/strophe → strophejs-1.4.0/dist}/strophe.common.js +14 -14
- package/{src/libs/strophe → strophejs-1.4.0/dist}/strophe.esm.js +14 -14
- package/{src/libs/strophe → strophejs-1.4.0/dist}/strophe.umd.js +17 -17
- package/strophejs-1.4.0/dist/strophe.umd.min.js +1 -0
- package/src/libs/strophe/strophe.umd.min.js +0 -1
- package/strophejs-1.4.0/.eslintrc.json +0 -264
- package/strophejs-1.4.0/.gitattributes +0 -1
- package/strophejs-1.4.0/CHANGELOG.md +0 -250
- package/strophejs-1.4.0/LICENSE.txt +0 -19
- package/strophejs-1.4.0/Makefile +0 -92
- package/strophejs-1.4.0/README.md +0 -45
- package/strophejs-1.4.0/RELEASE_CHECKLIST.md +0 -16
- package/strophejs-1.4.0/contrib/discojs/README.txt +0 -42
- package/strophejs-1.4.0/contrib/discojs/css/disco.css +0 -16
- package/strophejs-1.4.0/contrib/discojs/index.html +0 -47
- package/strophejs-1.4.0/contrib/discojs/punjab.tac +0 -18
- package/strophejs-1.4.0/contrib/discojs/scripts/basic.js +0 -102
- package/strophejs-1.4.0/contrib/discojs/scripts/disco.js +0 -60
- package/strophejs-1.4.0/docs.css +0 -797
- package/strophejs-1.4.0/examples/amd.html +0 -21
- package/strophejs-1.4.0/examples/attach/README +0 -37
- package/strophejs-1.4.0/examples/attach/__init__.py +0 -0
- package/strophejs-1.4.0/examples/attach/attacher/__init__.py +0 -0
- package/strophejs-1.4.0/examples/attach/attacher/views.py +0 -18
- package/strophejs-1.4.0/examples/attach/boshclient.py +0 -158
- package/strophejs-1.4.0/examples/attach/manage.py +0 -11
- package/strophejs-1.4.0/examples/attach/settings.py +0 -85
- package/strophejs-1.4.0/examples/attach/templates/attacher/index.html +0 -88
- package/strophejs-1.4.0/examples/attach/urls.py +0 -19
- package/strophejs-1.4.0/examples/basic.html +0 -23
- package/strophejs-1.4.0/examples/basic.js +0 -73
- package/strophejs-1.4.0/examples/echobot.html +0 -25
- package/strophejs-1.4.0/examples/echobot.js +0 -79
- package/strophejs-1.4.0/examples/main.js +0 -59
- package/strophejs-1.4.0/examples/prebind.html +0 -39
- package/strophejs-1.4.0/examples/prebind.js +0 -103
- package/strophejs-1.4.0/examples/restore.html +0 -24
- package/strophejs-1.4.0/examples/restore.js +0 -71
- package/strophejs-1.4.0/package-lock.json +0 -8634
- package/strophejs-1.4.0/package.json +0 -84
- package/strophejs-1.4.0/rollup.config.js +0 -76
- package/strophejs-1.4.0/src/bosh.js +0 -916
- package/strophejs-1.4.0/src/core.js +0 -3535
- package/strophejs-1.4.0/src/md5.js +0 -204
- package/strophejs-1.4.0/src/sha1.js +0 -172
- package/strophejs-1.4.0/src/shared-connection-worker.js +0 -114
- package/strophejs-1.4.0/src/shims.js +0 -123
- package/strophejs-1.4.0/src/strophe.js +0 -14
- package/strophejs-1.4.0/src/utils.js +0 -63
- package/strophejs-1.4.0/src/websocket.js +0 -561
- package/strophejs-1.4.0/src/worker-websocket.js +0 -152
- package/strophejs-1.4.0/tests/index.html +0 -21
- package/strophejs-1.4.0/tests/main.js +0 -49
- package/strophejs-1.4.0/tests/tests.js +0 -929
- package/strophejs-1.6.1/.eslintrc.json +0 -264
- package/strophejs-1.6.1/.gitattributes +0 -1
- package/strophejs-1.6.1/.nvmrc +0 -1
- package/strophejs-1.6.1/CHANGELOG.md +0 -288
- package/strophejs-1.6.1/LICENSE.txt +0 -19
- package/strophejs-1.6.1/Makefile +0 -92
- package/strophejs-1.6.1/README.md +0 -46
- package/strophejs-1.6.1/RELEASE_CHECKLIST.md +0 -18
- package/strophejs-1.6.1/babel.config.json +0 -10
- package/strophejs-1.6.1/contrib/discojs/README.txt +0 -42
- package/strophejs-1.6.1/contrib/discojs/css/disco.css +0 -16
- package/strophejs-1.6.1/contrib/discojs/index.html +0 -47
- package/strophejs-1.6.1/contrib/discojs/punjab.tac +0 -18
- package/strophejs-1.6.1/contrib/discojs/scripts/basic.js +0 -102
- package/strophejs-1.6.1/contrib/discojs/scripts/disco.js +0 -60
- package/strophejs-1.6.1/docs.css +0 -797
- package/strophejs-1.6.1/examples/amd.html +0 -21
- package/strophejs-1.6.1/examples/attach/README +0 -37
- package/strophejs-1.6.1/examples/attach/__init__.py +0 -0
- package/strophejs-1.6.1/examples/attach/attacher/__init__.py +0 -0
- package/strophejs-1.6.1/examples/attach/attacher/views.py +0 -18
- package/strophejs-1.6.1/examples/attach/boshclient.py +0 -158
- package/strophejs-1.6.1/examples/attach/manage.py +0 -11
- package/strophejs-1.6.1/examples/attach/settings.py +0 -85
- package/strophejs-1.6.1/examples/attach/templates/attacher/index.html +0 -88
- package/strophejs-1.6.1/examples/attach/urls.py +0 -19
- package/strophejs-1.6.1/examples/basic.html +0 -23
- package/strophejs-1.6.1/examples/basic.js +0 -73
- package/strophejs-1.6.1/examples/echobot.html +0 -25
- package/strophejs-1.6.1/examples/echobot.js +0 -79
- package/strophejs-1.6.1/examples/main.js +0 -59
- package/strophejs-1.6.1/examples/prebind.html +0 -39
- package/strophejs-1.6.1/examples/prebind.js +0 -103
- package/strophejs-1.6.1/examples/restore.html +0 -24
- package/strophejs-1.6.1/examples/restore.js +0 -71
- package/strophejs-1.6.1/package-lock.json +0 -18461
- package/strophejs-1.6.1/package.json +0 -87
- package/strophejs-1.6.1/rollup.config.js +0 -70
- package/strophejs-1.6.1/src/bosh.js +0 -916
- package/strophejs-1.6.1/src/builder.js +0 -239
- package/strophejs-1.6.1/src/constants.js +0 -155
- package/strophejs-1.6.1/src/core.js +0 -2377
- package/strophejs-1.6.1/src/sasl-anon.js +0 -17
- package/strophejs-1.6.1/src/sasl-external.js +0 -27
- package/strophejs-1.6.1/src/sasl-oauthbearer.js +0 -30
- package/strophejs-1.6.1/src/sasl-plain.js +0 -32
- package/strophejs-1.6.1/src/sasl-sha1.js +0 -24
- package/strophejs-1.6.1/src/sasl-sha256.js +0 -24
- package/strophejs-1.6.1/src/sasl-sha384.js +0 -24
- package/strophejs-1.6.1/src/sasl-sha512.js +0 -24
- package/strophejs-1.6.1/src/sasl-xoauth2.js +0 -27
- package/strophejs-1.6.1/src/sasl.js +0 -143
- package/strophejs-1.6.1/src/scram.js +0 -182
- package/strophejs-1.6.1/src/shared-connection-worker.js +0 -114
- package/strophejs-1.6.1/src/shims.js +0 -122
- package/strophejs-1.6.1/src/strophe.js +0 -15
- package/strophejs-1.6.1/src/utils.js +0 -626
- package/strophejs-1.6.1/src/websocket.js +0 -556
- package/strophejs-1.6.1/src/worker-websocket.js +0 -149
- package/strophejs-1.6.1/tests.js +0 -993
package/strophejs-1.6.1/tests.js
DELETED
|
@@ -1,993 +0,0 @@
|
|
|
1
|
-
/*global Strophe, $iq, $msg, $build, $pres, QUnit */
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Mock xhr, provides getAllResponseHeaders function.
|
|
5
|
-
* @param status
|
|
6
|
-
* @param readyState
|
|
7
|
-
* @param responseText
|
|
8
|
-
*/
|
|
9
|
-
const xhr = function (status, readyState, responseText) {
|
|
10
|
-
this.status = status;
|
|
11
|
-
this.readyState = readyState;
|
|
12
|
-
this.responseText = responseText;
|
|
13
|
-
this.getAllResponseHeaders = () => null;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class SASLFoo extends Strophe.SASLMechanism {
|
|
18
|
-
constructor () {
|
|
19
|
-
super("FOO", false, 10);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
static get name () {
|
|
23
|
-
return "FOO";
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function makeRequest (stanza) {
|
|
28
|
-
const req = new Strophe.Request(stanza, () => {});
|
|
29
|
-
req.getResponse = function () {
|
|
30
|
-
const env = new Strophe.Builder('env', {type: 'mock'}).tree();
|
|
31
|
-
env.appendChild(stanza);
|
|
32
|
-
return env;
|
|
33
|
-
};
|
|
34
|
-
return req;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const { module, test } = QUnit;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
module("Utility Methods");
|
|
41
|
-
|
|
42
|
-
test("xvalidTag", (assert) => {
|
|
43
|
-
/* Utility method to determine whether a tag is allowed
|
|
44
|
-
* in the XHTML_IM namespace.
|
|
45
|
-
*
|
|
46
|
-
* Used in the createHtml function to filter incoming html into the allowed XHTML-IM subset.
|
|
47
|
-
* See http://xmpp.org/extensions/xep-0071.html#profile-summary for the list of recommended
|
|
48
|
-
*/
|
|
49
|
-
// Tags must always be lower case (as per XHMTL)
|
|
50
|
-
assert.equal(Strophe.XHTML.validTag('BODY'), false);
|
|
51
|
-
assert.equal(Strophe.XHTML.validTag('A'), false);
|
|
52
|
-
assert.equal(Strophe.XHTML.validTag('Img'), false);
|
|
53
|
-
assert.equal(Strophe.XHTML.validTag('IMg'), false);
|
|
54
|
-
|
|
55
|
-
// Check all tags mentioned in XEP-0071
|
|
56
|
-
assert.equal(Strophe.XHTML.validTag('a'), true);
|
|
57
|
-
assert.equal(Strophe.XHTML.validTag('blockquote'), true);
|
|
58
|
-
assert.equal(Strophe.XHTML.validTag('body'), true);
|
|
59
|
-
assert.equal(Strophe.XHTML.validTag('br'), true);
|
|
60
|
-
assert.equal(Strophe.XHTML.validTag('cite'), true);
|
|
61
|
-
assert.equal(Strophe.XHTML.validTag('em'), true);
|
|
62
|
-
assert.equal(Strophe.XHTML.validTag('img'), true);
|
|
63
|
-
assert.equal(Strophe.XHTML.validTag('li'), true);
|
|
64
|
-
assert.equal(Strophe.XHTML.validTag('ol'), true);
|
|
65
|
-
assert.equal(Strophe.XHTML.validTag('p'), true);
|
|
66
|
-
assert.equal(Strophe.XHTML.validTag('span'), true);
|
|
67
|
-
assert.equal(Strophe.XHTML.validTag('strong'), true);
|
|
68
|
-
assert.equal(Strophe.XHTML.validTag('ul'), true);
|
|
69
|
-
|
|
70
|
-
// Check tags not mentioned in XEP-0071
|
|
71
|
-
assert.equal(Strophe.XHTML.validTag('script'), false);
|
|
72
|
-
assert.equal(Strophe.XHTML.validTag('blink'), false);
|
|
73
|
-
assert.equal(Strophe.XHTML.validTag('article'), false);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
test("_getRequestStatus", (assert) => {
|
|
77
|
-
const req = new Strophe.Request('', function (){});
|
|
78
|
-
req.xhr = new xhr(200, 4);
|
|
79
|
-
assert.equal(Strophe.Bosh._getRequestStatus(req), 200, "Returns the status");
|
|
80
|
-
req.xhr = new xhr(500, 4);
|
|
81
|
-
assert.equal(Strophe.Bosh._getRequestStatus(req), 500,
|
|
82
|
-
"Returns the default if the request is not finished yet");
|
|
83
|
-
|
|
84
|
-
req.xhr = new xhr(200, 3);
|
|
85
|
-
assert.equal(Strophe.Bosh._getRequestStatus(req), 0,
|
|
86
|
-
"Returns the default if the request is not finished yet");
|
|
87
|
-
|
|
88
|
-
req.xhr = new xhr(undefined, 4);
|
|
89
|
-
assert.equal(Strophe.Bosh._getRequestStatus(req, -1), -1,
|
|
90
|
-
"Returns the default if the request doesn't have a status");
|
|
91
|
-
|
|
92
|
-
assert.equal(Strophe.Bosh._getRequestStatus(req, 0), 0,
|
|
93
|
-
"Returns the default if the request doesn't have a status");
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
module("JIDs");
|
|
97
|
-
|
|
98
|
-
test("Normal JID", (assert) => {
|
|
99
|
-
const jid = "darcy@pemberley.lit/library";
|
|
100
|
-
assert.equal(Strophe.getNodeFromJid(jid), "darcy",
|
|
101
|
-
"Node should be 'darcy'");
|
|
102
|
-
assert.equal(Strophe.getDomainFromJid(jid), "pemberley.lit",
|
|
103
|
-
"Domain should be 'pemberley.lit'");
|
|
104
|
-
assert.equal(Strophe.getResourceFromJid(jid), "library",
|
|
105
|
-
"Node should be 'library'");
|
|
106
|
-
assert.equal(Strophe.getBareJidFromJid(jid),
|
|
107
|
-
"darcy@pemberley.lit",
|
|
108
|
-
"Bare JID should be 'darcy@pemberley.lit'");
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
test("Weird node (unescaped)", (assert) => {
|
|
112
|
-
const jid = "darcy@netherfield.lit@pemberley.lit/library";
|
|
113
|
-
assert.equal(Strophe.getNodeFromJid(jid), "darcy",
|
|
114
|
-
"Node should be 'darcy'");
|
|
115
|
-
assert.equal(Strophe.getDomainFromJid(jid),
|
|
116
|
-
"netherfield.lit@pemberley.lit",
|
|
117
|
-
"Domain should be 'netherfield.lit@pemberley.lit'");
|
|
118
|
-
assert.equal(Strophe.getResourceFromJid(jid), "library",
|
|
119
|
-
"Resource should be 'library'");
|
|
120
|
-
assert.equal(Strophe.getBareJidFromJid(jid),
|
|
121
|
-
"darcy@netherfield.lit@pemberley.lit",
|
|
122
|
-
"Bare JID should be 'darcy@netherfield.lit@pemberley.lit'");
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
test("Weird node (escaped)", (assert) => {
|
|
126
|
-
const escapedNode = Strophe.escapeNode("darcy@netherfield.lit");
|
|
127
|
-
const jid = escapedNode + "@pemberley.lit/library";
|
|
128
|
-
assert.equal(Strophe.getNodeFromJid(jid), "darcy\\40netherfield.lit",
|
|
129
|
-
"Node should be 'darcy\\40netherfield.lit'");
|
|
130
|
-
assert.equal(Strophe.getDomainFromJid(jid),
|
|
131
|
-
"pemberley.lit",
|
|
132
|
-
"Domain should be 'pemberley.lit'");
|
|
133
|
-
assert.equal(Strophe.getResourceFromJid(jid), "library",
|
|
134
|
-
"Resource should be 'library'");
|
|
135
|
-
assert.equal(Strophe.getBareJidFromJid(jid),
|
|
136
|
-
"darcy\\40netherfield.lit@pemberley.lit",
|
|
137
|
-
"Bare JID should be 'darcy\\40netherfield.lit@pemberley.lit'");
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
test("Weird resource", (assert) => {
|
|
141
|
-
const jid = "books@chat.pemberley.lit/darcy@pemberley.lit/library";
|
|
142
|
-
assert.equal(Strophe.getNodeFromJid(jid), "books",
|
|
143
|
-
"Node should be 'books'");
|
|
144
|
-
assert.equal(Strophe.getDomainFromJid(jid), "chat.pemberley.lit",
|
|
145
|
-
"Domain should be 'chat.pemberley.lit'");
|
|
146
|
-
assert.equal(Strophe.getResourceFromJid(jid),
|
|
147
|
-
"darcy@pemberley.lit/library",
|
|
148
|
-
"Resource should be 'darcy@pemberley.lit/library'");
|
|
149
|
-
assert.equal(Strophe.getBareJidFromJid(jid),
|
|
150
|
-
"books@chat.pemberley.lit",
|
|
151
|
-
"Bare JID should be 'books@chat.pemberley.lit'");
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
module("Builder");
|
|
155
|
-
|
|
156
|
-
test("The root() method", (assert) => {
|
|
157
|
-
const builder = new Strophe.Builder('root');
|
|
158
|
-
const el = builder.c('child').c('grandchild').c('greatgrandchild').root();
|
|
159
|
-
assert.equal(el.node.nodeName, 'root', 'root() jump back to the root of the tree');
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
test("Correct namespace (#32)", (assert) => {
|
|
163
|
-
const stanzas = [new Strophe.Builder("message", {foo: "asdf"}).tree(),
|
|
164
|
-
$build("iq", {}).tree(),
|
|
165
|
-
$pres().tree()];
|
|
166
|
-
|
|
167
|
-
stanzas.forEach((s) => assert.equal(
|
|
168
|
-
s.getAttribute('xmlns'),
|
|
169
|
-
Strophe.NS.CLIENT,
|
|
170
|
-
`Namespace should be '${Strophe.NS.CLIENT}'`)
|
|
171
|
-
);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
test("Strophe.Connection.prototype.send() accepts Builders (#27)", (assert) => {
|
|
175
|
-
const stanza = $pres();
|
|
176
|
-
const conn = new Strophe.Connection("");
|
|
177
|
-
const sendStub = sinon.stub(XMLHttpRequest.prototype, "send");
|
|
178
|
-
const timeoutStub = sinon.stub(window, "setTimeout").callsFake(function (func) {
|
|
179
|
-
// Stub setTimeout to immediately call functions, otherwise our
|
|
180
|
-
// assertions fail due to async execution.
|
|
181
|
-
func.apply(arguments);
|
|
182
|
-
});
|
|
183
|
-
conn.send(stanza);
|
|
184
|
-
assert.equal(sendStub.called, true, "XMLHttpRequest.send was called");
|
|
185
|
-
sendStub.restore();
|
|
186
|
-
timeoutStub.restore();
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
module("Strophe.Connection options");
|
|
190
|
-
|
|
191
|
-
test("withCredentials can be set on the XMLHttpRequest object", (assert) => {
|
|
192
|
-
const stanza = $pres();
|
|
193
|
-
// Stub XMLHttpRequest.protototype.send so that it doesn't
|
|
194
|
-
// actually try to send out the request.
|
|
195
|
-
const sendStub = sinon.stub(XMLHttpRequest.prototype, "send");
|
|
196
|
-
// Stub setTimeout to immediately call functions, otherwise our
|
|
197
|
-
// assertions fail due to async execution.
|
|
198
|
-
const timeoutStub = sinon.stub(window, "setTimeout").callsFake(function (func) {
|
|
199
|
-
func.apply(arguments);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
let conn = new Strophe.Connection("example.org");
|
|
203
|
-
conn.send(stanza);
|
|
204
|
-
assert.equal(sendStub.called, true);
|
|
205
|
-
assert.equal(sendStub.getCalls()[0].thisValue.withCredentials, false);
|
|
206
|
-
|
|
207
|
-
conn = new Strophe.Connection(
|
|
208
|
-
"example.org",
|
|
209
|
-
{ "withCredentials": true });
|
|
210
|
-
conn.send(stanza);
|
|
211
|
-
assert.equal(sendStub.called, true);
|
|
212
|
-
assert.equal(sendStub.getCalls()[1].thisValue.withCredentials, true);
|
|
213
|
-
sendStub.restore();
|
|
214
|
-
timeoutStub.restore();
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
test("content type can be set on the XMLHttpRequest object", (assert) => {
|
|
218
|
-
const stanza = $pres();
|
|
219
|
-
// Stub XMLHttpRequest.protototype.send so that it doesn't
|
|
220
|
-
// actually try to send out the request.
|
|
221
|
-
const sendStub = sinon.stub(XMLHttpRequest.prototype, "send");
|
|
222
|
-
// Stub setTimeout to immediately call functions, otherwise our
|
|
223
|
-
// assertions fail due to async execution.
|
|
224
|
-
const timeoutStub = sinon.stub(window, "setTimeout").callsFake(function (func) {
|
|
225
|
-
func.apply(arguments);
|
|
226
|
-
});
|
|
227
|
-
const setRetRequestHeaderStub = sinon.stub(XMLHttpRequest.prototype, "setRequestHeader");
|
|
228
|
-
let conn = new Strophe.Connection("example.org");
|
|
229
|
-
conn.send(stanza);
|
|
230
|
-
assert.equal(setRetRequestHeaderStub.getCalls()[0].args[0], "Content-Type");
|
|
231
|
-
assert.equal(setRetRequestHeaderStub.getCalls()[0].args[1], "text/xml; charset=utf-8");
|
|
232
|
-
|
|
233
|
-
conn = new Strophe.Connection(
|
|
234
|
-
"example.org",
|
|
235
|
-
{ contentType: "text/plain; charset=utf-8" });
|
|
236
|
-
conn.send(stanza);
|
|
237
|
-
assert.equal(setRetRequestHeaderStub.getCalls()[1].args[0], "Content-Type");
|
|
238
|
-
assert.equal(setRetRequestHeaderStub.getCalls()[1].args[1], "text/plain; charset=utf-8");
|
|
239
|
-
sendStub.restore();
|
|
240
|
-
timeoutStub.restore();
|
|
241
|
-
setRetRequestHeaderStub.restore();
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
test("Cookies can be added to the document passing them as options to Strophe.Connection", (assert) => {
|
|
245
|
-
const stanza = $pres();
|
|
246
|
-
let conn = new Strophe.Connection(
|
|
247
|
-
"localhost",
|
|
248
|
-
{ "cookies": {
|
|
249
|
-
"_xxx": {
|
|
250
|
-
"value": "1234",
|
|
251
|
-
"path": "/",
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
assert.notEqual(document.cookie.indexOf('_xxx'), -1);
|
|
256
|
-
let start = document.cookie.indexOf('_xxx');
|
|
257
|
-
let end = document.cookie.indexOf(";", start);
|
|
258
|
-
end = end == -1 ? document.cookie.length : end;
|
|
259
|
-
assert.equal(document.cookie.substring(start, end), '_xxx=1234');
|
|
260
|
-
|
|
261
|
-
// Also test when passing only a string
|
|
262
|
-
conn = new Strophe.Connection(
|
|
263
|
-
"localhost",
|
|
264
|
-
{ "cookies": { "_yyy": "4321" },
|
|
265
|
-
"withCredentials": true
|
|
266
|
-
});
|
|
267
|
-
assert.notEqual(document.cookie.indexOf('_yyy'), -1);
|
|
268
|
-
start = document.cookie.indexOf('_yyy');
|
|
269
|
-
end = document.cookie.indexOf(";", start);
|
|
270
|
-
end = end == -1 ? document.cookie.length : end;
|
|
271
|
-
assert.equal(document.cookie.substring(start, end), '_yyy=4321');
|
|
272
|
-
|
|
273
|
-
// Stub XMLHttpRequest.protototype.send so that it doesn't
|
|
274
|
-
// actually try to send out the request.
|
|
275
|
-
const sendStub = sinon.stub(XMLHttpRequest.prototype, "send");
|
|
276
|
-
// Stub setTimeout to immediately call functions, otherwise our
|
|
277
|
-
// assertions fail due to async execution.
|
|
278
|
-
const timeoutStub = sinon.stub(window, "setTimeout").callsFake(function (func) {
|
|
279
|
-
func.apply(arguments);
|
|
280
|
-
});
|
|
281
|
-
conn.send(stanza);
|
|
282
|
-
// Unfortunately there's no way to test the headers set in the
|
|
283
|
-
// request (only in the response). They can however be checked with
|
|
284
|
-
// the browser's developer tools.
|
|
285
|
-
assert.equal(sendStub.called, true);
|
|
286
|
-
sendStub.restore();
|
|
287
|
-
timeoutStub.restore();
|
|
288
|
-
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
test("send() does not accept strings", (assert) => {
|
|
292
|
-
const stanza = "<presence/>";
|
|
293
|
-
const conn = new Strophe.Connection("");
|
|
294
|
-
// fake connection callback to avoid errors
|
|
295
|
-
conn.connect_callback = () => {};
|
|
296
|
-
try {
|
|
297
|
-
conn.send(stanza);
|
|
298
|
-
} catch (e) {
|
|
299
|
-
assert.equal(e.name, "StropheError", "send() should throw exception");
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
test("Builder with XML attribute escaping test", (assert) => {
|
|
304
|
-
let text = "<b>";
|
|
305
|
-
let expected = '<presence to="<b>" xmlns="jabber:client"/>';
|
|
306
|
-
let pres = $pres({to: text});
|
|
307
|
-
assert.equal(pres.toString(), expected, "< should be escaped");
|
|
308
|
-
|
|
309
|
-
text = "foo&bar";
|
|
310
|
-
expected = '<presence to="foo&bar" xmlns="jabber:client"/>';
|
|
311
|
-
pres = $pres({to: text});
|
|
312
|
-
assert.equal(pres.toString(), expected, "& should be escaped");
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
test("c() accepts text and passes it to xmlElement", (assert) => {
|
|
316
|
-
const pres = $pres({from: "darcy@pemberley.lit", to: "books@chat.pemberley.lit"})
|
|
317
|
-
.c("nick", {xmlns: "http://jabber.org/protocol/nick"}, "Darcy");
|
|
318
|
-
const expected = '<presence from="darcy@pemberley.lit" to="books@chat.pemberley.lit" xmlns="jabber:client">'+
|
|
319
|
-
'<nick xmlns="http://jabber.org/protocol/nick">Darcy</nick>'+
|
|
320
|
-
'</presence>';
|
|
321
|
-
assert.equal(pres.toString(), expected, "'Darcy' should be a child of <presence>");
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
test("c() return the child element if it is a text node.", (assert) => {
|
|
325
|
-
// See this issue: https://github.com/strophe/strophejs/issues/124
|
|
326
|
-
let pres = $pres({from: "darcy@pemberley.lit", to: "books@chat.pemberley.lit"})
|
|
327
|
-
.c("show", {}, "dnd")
|
|
328
|
-
.c("status", {}, "In a meeting");
|
|
329
|
-
|
|
330
|
-
let expected = '<presence from="darcy@pemberley.lit" to="books@chat.pemberley.lit" xmlns="jabber:client">'+
|
|
331
|
-
'<show>dnd</show><status>In a meeting</status>'+
|
|
332
|
-
'</presence>';
|
|
333
|
-
assert.equal(pres.toString(), expected, "");
|
|
334
|
-
|
|
335
|
-
pres = $pres({from: "darcy@pemberley.lit", to: "books@chat.pemberley.lit"})
|
|
336
|
-
.c("show", {}, "")
|
|
337
|
-
.c("status", {}, "");
|
|
338
|
-
expected = '<presence from="darcy@pemberley.lit" to="books@chat.pemberley.lit" xmlns="jabber:client">'+
|
|
339
|
-
'<show/><status/>'+
|
|
340
|
-
'</presence>';
|
|
341
|
-
assert.equal(pres.toString(), expected, "");
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
module("XML");
|
|
345
|
-
|
|
346
|
-
test("XML escaping test", (assert) => {
|
|
347
|
-
const text = "s & p";
|
|
348
|
-
const textNode = Strophe.xmlTextNode(text);
|
|
349
|
-
assert.equal(Strophe.getText(textNode), "s & p", "should be escaped");
|
|
350
|
-
const text0 = "s < & > p";
|
|
351
|
-
const textNode0 = Strophe.xmlTextNode(text0);
|
|
352
|
-
assert.equal(Strophe.getText(textNode0), "s < & > p", "should be escaped");
|
|
353
|
-
const text1 = "s's or \"p\"";
|
|
354
|
-
const textNode1 = Strophe.xmlTextNode(text1);
|
|
355
|
-
assert.equal(Strophe.getText(textNode1), "s's or "p"", "should be escaped");
|
|
356
|
-
const text2 = "<![CDATA[<foo>]]>";
|
|
357
|
-
const textNode2 = Strophe.xmlTextNode(text2);
|
|
358
|
-
assert.equal(Strophe.getText(textNode2), "<![CDATA[<foo>]]>", "should be escaped");
|
|
359
|
-
const text3 = "<![CDATA[]]]]><![CDATA[>]]>";
|
|
360
|
-
const textNode3 = Strophe.xmlTextNode(text3);
|
|
361
|
-
assert.equal(Strophe.getText(textNode3), "<![CDATA[]]]]><![CDATA[>]]>", "should be escaped");
|
|
362
|
-
const text4 = "<foo><![CDATA[<foo>]]>";
|
|
363
|
-
const textNode4 = Strophe.xmlTextNode(text4);
|
|
364
|
-
assert.equal(Strophe.getText(textNode4), "&lt;foo&gt;<![CDATA[<foo>]]>", "should be escaped");
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
test("XML element creation", (assert) => {
|
|
368
|
-
const elem = Strophe.xmlElement("message");
|
|
369
|
-
assert.equal(elem.tagName, "message", "Element name should be the same");
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
test("copyElement() double escape bug", function (assert) {
|
|
373
|
-
const cloned = Strophe.copyElement(Strophe.xmlGenerator().createTextNode('<><>'));
|
|
374
|
-
assert.equal(cloned.nodeValue, '<><>');
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
test("XML serializing", function (assert) {
|
|
378
|
-
const parser = new DOMParser();
|
|
379
|
-
// Attributes
|
|
380
|
-
const element1 = parser.parseFromString("<foo attr1='abc' attr2='edf'>bar</foo>", "text/xml").documentElement;
|
|
381
|
-
assert.equal(Strophe.serialize(element1), '<foo attr1="abc" attr2="edf">bar</foo>', 'should be serialized');
|
|
382
|
-
const element2 = parser.parseFromString("<foo attr1=\"abc\" attr2=\"edf\">bar</foo>","text/xml").documentElement;
|
|
383
|
-
assert.equal(Strophe.serialize(element2), '<foo attr1="abc" attr2="edf">bar</foo>', 'should be serialized');
|
|
384
|
-
// Escaping values
|
|
385
|
-
const element3 = parser.parseFromString("<foo>a > 'b' & "b" < c</foo>","text/xml").documentElement;
|
|
386
|
-
assert.equal(Strophe.serialize(element3), '<foo>a > 'b' & "b" < c</foo>', 'should be serialized');
|
|
387
|
-
// Escaping attributes
|
|
388
|
-
const element4 = parser.parseFromString("<foo attr='<a> 'b''>bar</foo>","text/xml").documentElement;
|
|
389
|
-
assert.equal(Strophe.serialize(element4), '<foo attr="<a> 'b'">bar</foo>', 'should be serialized');
|
|
390
|
-
const element5 = parser.parseFromString("<foo attr=\"<a> "b"\">bar</foo>","text/xml").documentElement;
|
|
391
|
-
assert.equal(Strophe.serialize(element5), '<foo attr="<a> "b"">bar</foo>', 'should be serialized');
|
|
392
|
-
// Empty elements
|
|
393
|
-
const element6 = parser.parseFromString("<foo><empty></empty></foo>","text/xml").documentElement;
|
|
394
|
-
assert.equal(Strophe.serialize(element6), "<foo><empty/></foo>", "should be serialized");
|
|
395
|
-
// Children
|
|
396
|
-
const element7 = parser.parseFromString("<foo><bar>a</bar><baz><wibble>b</wibble></baz></foo>","text/xml").documentElement;
|
|
397
|
-
assert.equal(Strophe.serialize(element7), "<foo><bar>a</bar><baz><wibble>b</wibble></baz></foo>", "should be serialized");
|
|
398
|
-
const element8 = parser.parseFromString("<foo><bar>a</bar><baz>b<wibble>c</wibble>d</baz></foo>","text/xml").documentElement;
|
|
399
|
-
assert.equal(Strophe.serialize(element8), "<foo><bar>a</bar><baz>b<wibble>c</wibble>d</baz></foo>", "should be serialized");
|
|
400
|
-
// CDATA
|
|
401
|
-
const element9 = parser.parseFromString("<foo><![CDATA[<foo>]]></foo>","text/xml").documentElement;
|
|
402
|
-
assert.equal(Strophe.serialize(element9), "<foo><![CDATA[<foo>]]></foo>", "should be serialized");
|
|
403
|
-
const element10 = parser.parseFromString("<foo><![CDATA[]]]]><![CDATA[>]]></foo>","text/xml").documentElement;
|
|
404
|
-
assert.equal(Strophe.serialize(element10), "<foo><![CDATA[]]]]><![CDATA[>]]></foo>", "should be serialized");
|
|
405
|
-
const element11 = parser.parseFromString("<foo><foo><![CDATA[<foo>]]></foo>","text/xml").documentElement;
|
|
406
|
-
assert.equal(Strophe.serialize(element11), "<foo><foo><![CDATA[<foo>]]></foo>", "should be serialized");
|
|
407
|
-
});
|
|
408
|
-
|
|
409
|
-
module("Handler");
|
|
410
|
-
|
|
411
|
-
test("HTTP errors", (assert) => {
|
|
412
|
-
const spy500 = sinon.spy();
|
|
413
|
-
const spy401 = sinon.spy();
|
|
414
|
-
const conn = new Strophe.Connection("http://fake");
|
|
415
|
-
conn.addProtocolErrorHandler('HTTP', 500, spy500);
|
|
416
|
-
conn.addProtocolErrorHandler('HTTP', 401, spy401);
|
|
417
|
-
const req = new Strophe.Request('', () => {});
|
|
418
|
-
req.xhr = new xhr(200, 4);
|
|
419
|
-
conn._proto._onRequestStateChange(() => {}, req);
|
|
420
|
-
assert.equal(spy500.called, false, "Error handler does not get called when no HTTP error");
|
|
421
|
-
assert.equal(spy401.called, false, "Error handler does not get called when no HTTP error");
|
|
422
|
-
|
|
423
|
-
req.xhr = new xhr(401, 4);
|
|
424
|
-
conn._proto._onRequestStateChange(() => {}, req);
|
|
425
|
-
assert.equal(spy500.called, false, "Error handler does not get called when no HTTP 500 error");
|
|
426
|
-
assert.equal(spy401.called, true, "Error handler does get called when HTTP 401 error");
|
|
427
|
-
|
|
428
|
-
req.xhr = new xhr(500, 4);
|
|
429
|
-
conn._proto._onRequestStateChange(() => {}, req);
|
|
430
|
-
assert.equal(spy500.called, true, "Error handler gets called on HTTP 500 error");
|
|
431
|
-
});
|
|
432
|
-
|
|
433
|
-
test("IQ fallback handler", (assert) => {
|
|
434
|
-
// Strophe returns an IQ error stanza to unhandled incoming IQ get and set stanzas
|
|
435
|
-
const conn = new Strophe.Connection("http://fake");
|
|
436
|
-
conn.authenticated = true;
|
|
437
|
-
const spy = sinon.spy(conn, 'send');
|
|
438
|
-
|
|
439
|
-
conn._dataRecv(makeRequest($iq({'type': 'get', 'id': '1'}).tree()));
|
|
440
|
-
assert.equal(spy.calledOnce, true, "send was called only once");
|
|
441
|
-
assert.equal(
|
|
442
|
-
Strophe.serialize(spy.args[0][0].nodeTree),
|
|
443
|
-
'<iq id="1" type="error" xmlns="jabber:client">'+
|
|
444
|
-
'<error type="cancel"><service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error>'+
|
|
445
|
-
'</iq>'
|
|
446
|
-
);
|
|
447
|
-
|
|
448
|
-
conn._dataRecv(makeRequest($iq({'type': 'get', 'id': '2'}).tree()));
|
|
449
|
-
assert.equal(spy.calledTwice, true, "send was called twice");
|
|
450
|
-
assert.equal(
|
|
451
|
-
Strophe.serialize(spy.args[1][0].nodeTree),
|
|
452
|
-
'<iq id="2" type="error" xmlns="jabber:client">'+
|
|
453
|
-
'<error type="cancel"><service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error>'+
|
|
454
|
-
'</iq>'
|
|
455
|
-
);
|
|
456
|
-
|
|
457
|
-
// When there is a handler, then the fallback handler isn't called.
|
|
458
|
-
const handlerStub = sinon.stub();
|
|
459
|
-
handlerStub.returns(true);
|
|
460
|
-
conn.addHandler(handlerStub, null, 'iq');
|
|
461
|
-
|
|
462
|
-
conn._dataRecv(makeRequest($iq({'type': 'set'}).tree()));
|
|
463
|
-
assert.equal(spy.calledTwice, true, "send was called twice");
|
|
464
|
-
|
|
465
|
-
conn._dataRecv(makeRequest($iq({'type': 'get'}).tree()));
|
|
466
|
-
assert.equal(spy.calledTwice, true, "send was called twice");
|
|
467
|
-
|
|
468
|
-
assert.equal(handlerStub.calledTwice, true, "The manually registered IQ handler was called twice");
|
|
469
|
-
});
|
|
470
|
-
|
|
471
|
-
test("Full JID matching", (assert) => {
|
|
472
|
-
const elem = $msg({from: 'darcy@pemberley.lit/library'}).tree();
|
|
473
|
-
|
|
474
|
-
let hand = new Strophe.Handler(null, null, null, null, null,
|
|
475
|
-
'darcy@pemberley.lit/library');
|
|
476
|
-
assert.equal(hand.isMatch(elem), true, "Full JID should match");
|
|
477
|
-
|
|
478
|
-
hand = new Strophe.Handler(null, null, null, null, null,
|
|
479
|
-
'darcy@pemberley.lit');
|
|
480
|
-
assert.equal(hand.isMatch(elem), false, "Bare JID shouldn't match");
|
|
481
|
-
});
|
|
482
|
-
|
|
483
|
-
test("Bare JID matching", (assert) => {
|
|
484
|
-
const elem = $msg({from: 'darcy@pemberley.lit/library'}).tree();
|
|
485
|
-
|
|
486
|
-
let hand = new Strophe.Handler(null, null, null, null, null,
|
|
487
|
-
'darcy@pemberley.lit/library',
|
|
488
|
-
{matchBareFromJid: true});
|
|
489
|
-
assert.equal(hand.isMatch(elem), true, "Full JID should match");
|
|
490
|
-
|
|
491
|
-
hand = new Strophe.Handler(null, null, null, null, null,
|
|
492
|
-
'darcy@pemberley.lit',
|
|
493
|
-
{matchBareFromJid: true});
|
|
494
|
-
assert.equal(hand.isMatch(elem), true, "Bare JID should match");
|
|
495
|
-
});
|
|
496
|
-
|
|
497
|
-
test("Namespace matching", (assert) => {
|
|
498
|
-
const elemNoFrag = $msg({xmlns: 'http://jabber.org/protocol/muc'}).tree();
|
|
499
|
-
const elemWithFrag = $msg({xmlns: 'http://jabber.org/protocol/muc#user'}).tree();
|
|
500
|
-
let hand = new Strophe.Handler(
|
|
501
|
-
null, 'http://jabber.org/protocol/muc',
|
|
502
|
-
null, null, null, null
|
|
503
|
-
);
|
|
504
|
-
assert.equal(hand.isMatch(elemNoFrag), true, "The handler should match on stanza namespace");
|
|
505
|
-
assert.equal(hand.isMatch(elemWithFrag), false, "The handler should not match on stanza namespace with fragment");
|
|
506
|
-
|
|
507
|
-
hand = new Strophe.Handler(
|
|
508
|
-
null, 'http://jabber.org/protocol/muc',
|
|
509
|
-
null, null, null, null,
|
|
510
|
-
{'ignoreNamespaceFragment': true}
|
|
511
|
-
);
|
|
512
|
-
assert.equal(hand.isMatch(elemNoFrag), true, "The handler should match on stanza namespace");
|
|
513
|
-
assert.equal(hand.isMatch(elemWithFrag), true, "The handler should match on stanza namespace, even with fragment");
|
|
514
|
-
});
|
|
515
|
-
|
|
516
|
-
test("Stanza name matching", (assert) => {
|
|
517
|
-
const elem = $iq().tree();
|
|
518
|
-
let hand = new Strophe.Handler(null, null, 'iq');
|
|
519
|
-
assert.equal(hand.isMatch(elem), true, "The handler should match on stanza name");
|
|
520
|
-
|
|
521
|
-
hand = new Strophe.Handler(null, null, 'message');
|
|
522
|
-
assert.notEqual(hand.isMatch(elem), true, "The handler should not match wrong stanza name");
|
|
523
|
-
});
|
|
524
|
-
|
|
525
|
-
test("Stanza type matching", (assert) => {
|
|
526
|
-
const elem = $iq({type: 'error'}).tree();
|
|
527
|
-
let hand = new Strophe.Handler(null, null, 'iq', 'error');
|
|
528
|
-
assert.equal(hand.isMatch(elem), true, "The handler should match on stanza type");
|
|
529
|
-
|
|
530
|
-
hand = new Strophe.Handler(null, null, 'iq', 'result');
|
|
531
|
-
assert.notEqual(hand.isMatch(elem), true, "The handler should not match wrong stanza type");
|
|
532
|
-
|
|
533
|
-
hand = new Strophe.Handler(null, null, 'iq', ['error', 'result']);
|
|
534
|
-
assert.equal(hand.isMatch(elem), true, "The handler should match if stanza type is in array of types");
|
|
535
|
-
});
|
|
536
|
-
|
|
537
|
-
module("Misc");
|
|
538
|
-
|
|
539
|
-
test("Function binding", (assert) => {
|
|
540
|
-
const spy = sinon.spy();
|
|
541
|
-
const obj = {};
|
|
542
|
-
const arg1 = "foo";
|
|
543
|
-
const arg2 = "bar";
|
|
544
|
-
const arg3 = "baz";
|
|
545
|
-
|
|
546
|
-
const f = spy.bind(obj, arg1, arg2);
|
|
547
|
-
f(arg3);
|
|
548
|
-
assert.equal(spy.called, true, "bound function should be called");
|
|
549
|
-
assert.equal(spy.calledOn(obj), true,
|
|
550
|
-
"bound function should have correct context");
|
|
551
|
-
assert.equal(spy.alwaysCalledWithExactly(arg1, arg2, arg3),
|
|
552
|
-
true,
|
|
553
|
-
"bound function should get all arguments");
|
|
554
|
-
});
|
|
555
|
-
|
|
556
|
-
test("Connfail for invalid XML", (assert) => {
|
|
557
|
-
const req = new Strophe.Request('', function (){});
|
|
558
|
-
req.xhr = new xhr(undefined, undefined, 'text')
|
|
559
|
-
|
|
560
|
-
const conn = new Strophe.Connection("http://fake");
|
|
561
|
-
conn.connect_callback = function (status, condition) {
|
|
562
|
-
if (status === Strophe.Status.CONNFAIL) {
|
|
563
|
-
assert.equal(condition, "bad-format", "connection should fail with condition bad-format");
|
|
564
|
-
}
|
|
565
|
-
};
|
|
566
|
-
conn._connect_cb(req);
|
|
567
|
-
});
|
|
568
|
-
|
|
569
|
-
module("XHR error handling");
|
|
570
|
-
|
|
571
|
-
// Note that these tests are pretty dependent on the actual code.
|
|
572
|
-
|
|
573
|
-
test("Aborted requests do nothing", (assert) => {
|
|
574
|
-
Strophe.Connection.prototype._onIdle = () => {};
|
|
575
|
-
const conn = new Strophe.Connection("http://fake");
|
|
576
|
-
|
|
577
|
-
// simulate a finished but aborted request
|
|
578
|
-
const req = {id: 43,
|
|
579
|
-
sends: 1,
|
|
580
|
-
xhr: new xhr(undefined, 4),
|
|
581
|
-
abort: true};
|
|
582
|
-
|
|
583
|
-
conn._requests = [req];
|
|
584
|
-
const spy = sinon.spy();
|
|
585
|
-
conn._proto._onRequestStateChange(spy, req);
|
|
586
|
-
|
|
587
|
-
assert.equal(req.abort, false, "abort flag should be toggled");
|
|
588
|
-
assert.equal(conn._requests.length, 1, "_requests should be same length");
|
|
589
|
-
assert.equal(spy.called, false, "callback should not be called");
|
|
590
|
-
});
|
|
591
|
-
|
|
592
|
-
test("Incomplete requests do nothing", (assert) => {
|
|
593
|
-
Strophe.Connection.prototype._onIdle = () => {};
|
|
594
|
-
const conn = new Strophe.Connection("http://fake");
|
|
595
|
-
// simulate a finished but aborted request
|
|
596
|
-
const req = {id: 44,
|
|
597
|
-
sends: 1,
|
|
598
|
-
xhr: new xhr(undefined, 3)
|
|
599
|
-
};
|
|
600
|
-
conn._requests = [req];
|
|
601
|
-
const spy = sinon.spy();
|
|
602
|
-
conn._proto._onRequestStateChange(spy, req);
|
|
603
|
-
assert.equal(conn._requests.length, 1, "_requests should be same length");
|
|
604
|
-
assert.equal(spy.called, false, "callback should not be called");
|
|
605
|
-
});
|
|
606
|
-
|
|
607
|
-
module("SASL Mechanisms");
|
|
608
|
-
|
|
609
|
-
test("Default mechanisms will be registered if none are provided", (assert) => {
|
|
610
|
-
const conn = new Strophe.Connection('localhost');
|
|
611
|
-
assert.equal(Object.keys(conn.mechanisms).length, 9, 'Ten by default registered SASL mechanisms');
|
|
612
|
-
assert.equal('ANONYMOUS' in conn.mechanisms, true, 'ANONYMOUS is registered');
|
|
613
|
-
assert.equal('EXTERNAL' in conn.mechanisms, true, 'EXTERNAL is registered');
|
|
614
|
-
assert.equal('OAUTHBEARER' in conn.mechanisms, true, 'OAUTHBEARER is registered');
|
|
615
|
-
assert.equal('PLAIN' in conn.mechanisms, true, 'PLAIN is registered');
|
|
616
|
-
assert.equal('SCRAM-SHA-1' in conn.mechanisms, true, 'SCRAM-SHA-1 is registered');
|
|
617
|
-
assert.equal('SCRAM-SHA-256' in conn.mechanisms, true, 'SCRAM-SHA-256 is registered');
|
|
618
|
-
assert.equal('SCRAM-SHA-384' in conn.mechanisms, true, 'SCRAM-SHA-384 is registered');
|
|
619
|
-
assert.equal('SCRAM-SHA-512' in conn.mechanisms, true, 'SCRAM-SHA-512 is registered');
|
|
620
|
-
assert.equal('X-OAUTH2' in conn.mechanisms, true, 'X-OAUTH2 is registered');
|
|
621
|
-
});
|
|
622
|
-
|
|
623
|
-
test("Custom mechanisms be specified when instantiating Strophe.Connection", (assert) => {
|
|
624
|
-
let conn = new Strophe.Connection('localhost', {'mechanisms': [SASLFoo]});
|
|
625
|
-
assert.equal(Object.keys(conn.mechanisms).length, 1, 'Only one registered SASL mechanism');
|
|
626
|
-
assert.equal('FOO' in conn.mechanisms, true, 'FOO is registered');
|
|
627
|
-
assert.notEqual('PLAIN' in conn.mechanisms, true, 'PLAIN is not registered');
|
|
628
|
-
|
|
629
|
-
conn = new Strophe.Connection('localhost',
|
|
630
|
-
{ 'mechanisms': [
|
|
631
|
-
SASLFoo,
|
|
632
|
-
Strophe.SASLPlain
|
|
633
|
-
]});
|
|
634
|
-
assert.equal(Object.keys(conn.mechanisms).length, 2, 'Only two registered SASL mechanisms');
|
|
635
|
-
assert.equal('FOO' in conn.mechanisms, true, 'FOO is registered');
|
|
636
|
-
assert.equal('PLAIN' in conn.mechanisms, true, 'PLAIN is registered');
|
|
637
|
-
});
|
|
638
|
-
|
|
639
|
-
test("The supported mechanism with the highest priority will be used", (assert) => {
|
|
640
|
-
Strophe.SASLExternal.prototype.priority = 10;
|
|
641
|
-
Strophe.SASLSHA1.prototype.priority = 20;
|
|
642
|
-
const conn = new Strophe.Connection('localhost',
|
|
643
|
-
{ 'mechanisms': [
|
|
644
|
-
Strophe.SASLSHA1,
|
|
645
|
-
Strophe.SASLExternal
|
|
646
|
-
]});
|
|
647
|
-
const authSpy = sinon.spy(conn, '_attemptSASLAuth');
|
|
648
|
-
assert.equal(authSpy.called, false);
|
|
649
|
-
conn.connect('dummy@localhost', 'secret');
|
|
650
|
-
|
|
651
|
-
const mechanisms = Object.values(conn.mechanisms);
|
|
652
|
-
conn.authenticate(mechanisms);
|
|
653
|
-
assert.equal(authSpy.called, true);
|
|
654
|
-
assert.equal(authSpy.returnValues.length, 1);
|
|
655
|
-
assert.equal(authSpy.returnValues[0], true);
|
|
656
|
-
assert.equal(conn._sasl_mechanism.mechname, 'SCRAM-SHA-1');
|
|
657
|
-
|
|
658
|
-
mechanisms[0].priority = 20;
|
|
659
|
-
mechanisms[1].priority = 30;
|
|
660
|
-
conn.connect('dummy@localhost', 'secret');
|
|
661
|
-
conn.authenticate(Object.values(mechanisms));
|
|
662
|
-
assert.equal(conn._sasl_mechanism.mechname, 'EXTERNAL');
|
|
663
|
-
});
|
|
664
|
-
|
|
665
|
-
test("SASL PLAIN Auth", async (assert) => {
|
|
666
|
-
const conn = {pass: "password", authcid: "user", authzid: "user@xmpp.org", domain: "xmpp.org"};
|
|
667
|
-
const saslplain = new Strophe.SASLPlain();
|
|
668
|
-
saslplain.onStart(conn);
|
|
669
|
-
assert.ok(saslplain.test(conn), "PLAIN is enabled by default.");
|
|
670
|
-
const response = await saslplain.onChallenge(conn);
|
|
671
|
-
assert.equal(response, ['', conn.authcid, conn.pass].join("\u0000"),
|
|
672
|
-
"checking plain auth challenge");
|
|
673
|
-
saslplain.onSuccess();
|
|
674
|
-
});
|
|
675
|
-
|
|
676
|
-
test("SASL PLAIN Auth with authzid", async (assert) => {
|
|
677
|
-
const conn = {pass: "password", authcid: "user", authzid: "admin@xmpp.org", domain: "xmpp.org"};
|
|
678
|
-
const saslplain = new Strophe.SASLPlain();
|
|
679
|
-
saslplain.onStart(conn);
|
|
680
|
-
assert.ok(saslplain.test(conn), "PLAIN is enabled by default.");
|
|
681
|
-
const response = await saslplain.onChallenge(conn, null);
|
|
682
|
-
assert.equal(response, [conn.authzid, conn.authcid, conn.pass].join("\u0000"),
|
|
683
|
-
"checking plain auth challenge");
|
|
684
|
-
saslplain.onSuccess();
|
|
685
|
-
});
|
|
686
|
-
|
|
687
|
-
test("SASL SCRAM-SHA-1 Auth", async (assert) => {
|
|
688
|
-
/* This is a simple example of a SCRAM-SHA-1 authentication exchange
|
|
689
|
-
* when the client doesn't support channel bindings (username 'user' and
|
|
690
|
-
* password 'pencil' are used):
|
|
691
|
-
*
|
|
692
|
-
* C: n,,n=user,r=fyko+d2lbbFgONRv9qkxdawL
|
|
693
|
-
* S: r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,
|
|
694
|
-
* i=4096
|
|
695
|
-
* C: c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,
|
|
696
|
-
* p=v0X8v3Bz2T0CJGbJQyF0X+HI4Ts=
|
|
697
|
-
* S: v=rmF9pqV8S7suAoZWja4dJRkFsKQ=
|
|
698
|
-
*
|
|
699
|
-
*/
|
|
700
|
-
const conn = {
|
|
701
|
-
pass: "pencil",
|
|
702
|
-
authcid: "user",
|
|
703
|
-
authzid: "user@xmpp.org",
|
|
704
|
-
_sasl_data: []
|
|
705
|
-
};
|
|
706
|
-
const saslsha1 = new Strophe.SASLSHA1();
|
|
707
|
-
saslsha1.onStart(conn);
|
|
708
|
-
assert.ok(saslsha1.test(conn), "SHA-1 is enabled by default.");
|
|
709
|
-
// test taken from example section on:
|
|
710
|
-
// URL: http://tools.ietf.org/html/rfc5802#section-5
|
|
711
|
-
let response = await saslsha1.clientChallenge(conn, "fyko+d2lbbFgONRv9qkxdawL");
|
|
712
|
-
assert.equal(response, "n,,n=user,r=fyko+d2lbbFgONRv9qkxdawL", "checking first auth challenge");
|
|
713
|
-
|
|
714
|
-
response = await saslsha1.onChallenge(conn, "r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=4096");
|
|
715
|
-
assert.equal(response, "c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,p=v0X8v3Bz2T0CJGbJQyF0X+HI4Ts=",
|
|
716
|
-
"checking second auth challenge");
|
|
717
|
-
saslsha1.onSuccess();
|
|
718
|
-
});
|
|
719
|
-
|
|
720
|
-
test("SASL SCRAM-SHA-256 Auth", async (assert) => {
|
|
721
|
-
/* This is a simple example of a SCRAM-SHA-256 authentication exchange
|
|
722
|
-
* when the client doesn't support channel bindings (username 'user' and
|
|
723
|
-
* password 'pencil' are used):
|
|
724
|
-
*
|
|
725
|
-
* C: n,,n=user,r=rOprNGfwEbeRWgbNEkqO
|
|
726
|
-
* S: r=rOprNGfwEbeRWgbNEkqO%hvYDpWUa2RaTCAfuxFIlj)hNlF$k0,
|
|
727
|
-
* s=W22ZaJ0SNY7soEsUEjb6gQ==,i=4096
|
|
728
|
-
* C: c=biws,r=rOprNGfwEbeRWgbNEkqO%hvYDpWUa2RaTCAfuxFIlj)hNlF$k0,
|
|
729
|
-
* p=dHzbZapWIk4jUhN+Ute9ytag9zjfMHgsqmmiz7AndVQ=
|
|
730
|
-
* S: v=6rriTRBi23WpRR/wtup+mMhUZUn/dB5nLTJRsjl95G4=
|
|
731
|
-
*
|
|
732
|
-
*/
|
|
733
|
-
const conn = {
|
|
734
|
-
pass: "pencil",
|
|
735
|
-
authcid: "user",
|
|
736
|
-
authzid: "user@xmpp.org",
|
|
737
|
-
_sasl_data: []
|
|
738
|
-
};
|
|
739
|
-
const saslsha256 = new Strophe.SASLSHA256();
|
|
740
|
-
saslsha256.onStart(conn);
|
|
741
|
-
assert.ok(saslsha256.test(conn), "SHA-256 is enabled by default.");
|
|
742
|
-
// test taken from example section on:
|
|
743
|
-
// URL: https://datatracker.ietf.org/doc/html/rfc7677#section-3
|
|
744
|
-
let response = await saslsha256.clientChallenge(conn, "rOprNGfwEbeRWgbNEkqO");
|
|
745
|
-
assert.equal(response, "n,,n=user,r=rOprNGfwEbeRWgbNEkqO", "checking first auth challenge");
|
|
746
|
-
|
|
747
|
-
response = await saslsha256.onChallenge(conn, "r=rOprNGfwEbeRWgbNEkqO%hvYDpWUa2RaTCAfuxFIlj)hNlF$k0,s=W22ZaJ0SNY7soEsUEjb6gQ==,i=4096");
|
|
748
|
-
assert.equal(response, "c=biws,r=rOprNGfwEbeRWgbNEkqO%hvYDpWUa2RaTCAfuxFIlj)hNlF$k0,p=dHzbZapWIk4jUhN+Ute9ytag9zjfMHgsqmmiz7AndVQ=",
|
|
749
|
-
"checking second auth challenge");
|
|
750
|
-
saslsha256.onSuccess();
|
|
751
|
-
});
|
|
752
|
-
|
|
753
|
-
test("SASL EXTERNAL Auth", async (assert) => {
|
|
754
|
-
let conn = {pass: "password", authcid: "user", authzid: "user@xmpp.org"};
|
|
755
|
-
let sasl_external = new Strophe.SASLExternal();
|
|
756
|
-
assert.ok(sasl_external.test(conn), "EXTERNAL is enabled by default.");
|
|
757
|
-
sasl_external.onStart(conn);
|
|
758
|
-
|
|
759
|
-
let response = await sasl_external.clientChallenge(conn);
|
|
760
|
-
assert.equal(response, conn.authzid,
|
|
761
|
-
"Response to EXTERNAL auth challenge should be authzid if different authcid was passed in.");
|
|
762
|
-
sasl_external.onSuccess();
|
|
763
|
-
|
|
764
|
-
conn = {pass: "password", authcid: "user", authzid: "user@xmpp.org"};
|
|
765
|
-
sasl_external = new Strophe.SASLExternal();
|
|
766
|
-
assert.ok(sasl_external.test(conn), "EXTERNAL is enabled by default.");
|
|
767
|
-
sasl_external.onStart(conn);
|
|
768
|
-
response = await sasl_external.onChallenge(conn, null);
|
|
769
|
-
assert.equal(response, conn.authzid,
|
|
770
|
-
"Response to EXTERNAL auth challenge should be empty string if authcid = authzid");
|
|
771
|
-
sasl_external.onSuccess();
|
|
772
|
-
});
|
|
773
|
-
|
|
774
|
-
module("BOSH Session resumption");
|
|
775
|
-
|
|
776
|
-
test("When passing in {keepalive: true} to Strophe.Connection, then the session tokens get cached automatically", (assert) => {
|
|
777
|
-
const conn = new Strophe.Connection("", {"keepalive": true});
|
|
778
|
-
conn.jid = 'dummy@localhost';
|
|
779
|
-
conn._proto.sid = "5332346";
|
|
780
|
-
const cacheSpy = sinon.spy(conn._proto, '_cacheSession');
|
|
781
|
-
assert.equal(cacheSpy.called, false);
|
|
782
|
-
conn._proto._buildBody();
|
|
783
|
-
assert.equal(cacheSpy.called, true);
|
|
784
|
-
assert.equal(window.sessionStorage.getItem('strophe-bosh-session'), null);
|
|
785
|
-
conn.authenticated = true;
|
|
786
|
-
conn._proto._buildBody();
|
|
787
|
-
assert.ok(window.sessionStorage.getItem('strophe-bosh-session'));
|
|
788
|
-
assert.equal(cacheSpy.called, true);
|
|
789
|
-
conn.authenticated = false;
|
|
790
|
-
conn._proto._buildBody();
|
|
791
|
-
assert.equal(window.sessionStorage.getItem('strophe-bosh-session'), null);
|
|
792
|
-
assert.equal(cacheSpy.called, true);
|
|
793
|
-
});
|
|
794
|
-
|
|
795
|
-
test('the request ID (RID) has the proper value whenever a session is restored', (assert) => {
|
|
796
|
-
window.sessionStorage.removeItem('strophe-bosh-session');
|
|
797
|
-
const conn = new Strophe.Connection("", {"keepalive": true});
|
|
798
|
-
conn.authenticated = true;
|
|
799
|
-
conn.jid = 'dummy@localhost';
|
|
800
|
-
conn._proto.rid = '123456';
|
|
801
|
-
conn._proto.sid = '987654321';
|
|
802
|
-
conn._proto._cacheSession();
|
|
803
|
-
delete conn._proto.rid;
|
|
804
|
-
conn.restore();
|
|
805
|
-
let body = conn._proto._buildBody();
|
|
806
|
-
assert.equal(body.tree().getAttribute('rid'), '123456');
|
|
807
|
-
body = conn._proto._buildBody();
|
|
808
|
-
assert.equal(body.tree().getAttribute('rid'), '123457');
|
|
809
|
-
body = conn._proto._buildBody();
|
|
810
|
-
assert.equal(body.tree().getAttribute('rid'), '123458');
|
|
811
|
-
delete conn._proto.rid;
|
|
812
|
-
conn.restore();
|
|
813
|
-
body = conn._proto._buildBody();
|
|
814
|
-
assert.equal(body.tree().getAttribute('rid'), '123459');
|
|
815
|
-
});
|
|
816
|
-
|
|
817
|
-
test("restore can only be called with BOSH and when {keepalive: true} is passed to Strophe.Connection", (assert) => {
|
|
818
|
-
let conn = new Strophe.Connection("");
|
|
819
|
-
const boshSpy = sinon.spy(conn._proto, "_restore");
|
|
820
|
-
const checkSpy = sinon.spy(conn, "_sessionCachingSupported");
|
|
821
|
-
assert.equal(conn.restored, false);
|
|
822
|
-
try {
|
|
823
|
-
conn.restore();
|
|
824
|
-
} catch (e) {
|
|
825
|
-
assert.equal(e.name, "StropheSessionError",
|
|
826
|
-
"conn.restore() should throw an exception when keepalive is false.");
|
|
827
|
-
assert.equal(e.message, "_restore: no restoreable session.",
|
|
828
|
-
"conn.restore() should throw an exception when keepalive is false");
|
|
829
|
-
}
|
|
830
|
-
assert.equal(boshSpy.called, true);
|
|
831
|
-
assert.equal(checkSpy.called, true);
|
|
832
|
-
|
|
833
|
-
conn = new Strophe.Connection("ws:localhost");
|
|
834
|
-
try {
|
|
835
|
-
conn.restore();
|
|
836
|
-
} catch (e) {
|
|
837
|
-
assert.equal(e.name, "StropheSessionError",
|
|
838
|
-
"conn.restore() should throw an exception when keepalive is false.");
|
|
839
|
-
assert.equal(e.message, 'The "restore" method can only be used with a BOSH connection.',
|
|
840
|
-
'The conn.restore method can only be used with a BOSH connection.');
|
|
841
|
-
}
|
|
842
|
-
assert.equal(conn.restored, false);
|
|
843
|
-
});
|
|
844
|
-
|
|
845
|
-
test('the _cacheSession method caches the BOSH session tokens', (assert) => {
|
|
846
|
-
window.sessionStorage.removeItem('strophe-bosh-session');
|
|
847
|
-
const conn = new Strophe.Connection("http://fake", {"keepalive": true});
|
|
848
|
-
// Nothing gets cached if there aren't tokens to cache
|
|
849
|
-
conn._proto._cacheSession();
|
|
850
|
-
assert.equal(window.sessionStorage.getItem('strophe-bosh-session'), null);
|
|
851
|
-
// Let's create some tokens to cache
|
|
852
|
-
conn.authenticated = true;
|
|
853
|
-
conn.jid = 'dummy@localhost';
|
|
854
|
-
conn._proto.rid = '123456';
|
|
855
|
-
conn._proto.sid = '987654321';
|
|
856
|
-
assert.equal(window.sessionStorage.getItem('strophe-bosh-session'), null);
|
|
857
|
-
conn._proto._cacheSession();
|
|
858
|
-
assert.notEqual(window.sessionStorage.getItem('strophe-bosh-session'), null);
|
|
859
|
-
});
|
|
860
|
-
|
|
861
|
-
test('when calling "restore" without a restorable session, an exception is raised', (assert) => {
|
|
862
|
-
window.sessionStorage.removeItem('strophe-bosh-session');
|
|
863
|
-
const conn = new Strophe.Connection("", {"keepalive": true});
|
|
864
|
-
const boshSpy = sinon.spy(conn._proto, "_restore");
|
|
865
|
-
const checkSpy = sinon.spy(conn, "_sessionCachingSupported");
|
|
866
|
-
assert.equal(conn.restored, false);
|
|
867
|
-
try {
|
|
868
|
-
conn.restore();
|
|
869
|
-
} catch (e) {
|
|
870
|
-
assert.equal(e.name, "StropheSessionError");
|
|
871
|
-
assert.equal(e.message, "_restore: no restoreable session.");
|
|
872
|
-
}
|
|
873
|
-
assert.equal(conn.restored, false);
|
|
874
|
-
assert.equal(boshSpy.called, true);
|
|
875
|
-
assert.equal(checkSpy.called, true);
|
|
876
|
-
});
|
|
877
|
-
|
|
878
|
-
test('"restore" takes an optional JID argument for more precise session verification', (assert) => {
|
|
879
|
-
window.sessionStorage.removeItem('strophe-bosh-session');
|
|
880
|
-
const conn = new Strophe.Connection("", {"keepalive": true});
|
|
881
|
-
const boshSpy = sinon.spy(conn._proto, "_restore");
|
|
882
|
-
const checkSpy = sinon.spy(conn, "_sessionCachingSupported");
|
|
883
|
-
// Let's create some tokens to cache
|
|
884
|
-
conn.authenticated = true;
|
|
885
|
-
conn.jid = 'dummy@localhost';
|
|
886
|
-
conn._proto.rid = '1234567';
|
|
887
|
-
conn._proto.sid = '9876543210';
|
|
888
|
-
conn._proto._cacheSession();
|
|
889
|
-
|
|
890
|
-
// Check that giving a different jid causes an exception to be
|
|
891
|
-
// raised.
|
|
892
|
-
try {
|
|
893
|
-
conn.restore('differentdummy@localhost');
|
|
894
|
-
} catch (e) {
|
|
895
|
-
assert.equal(e.name, "StropheSessionError");
|
|
896
|
-
assert.equal(e.message, "_restore: no restoreable session.");
|
|
897
|
-
}
|
|
898
|
-
assert.equal(conn.restored, false);
|
|
899
|
-
assert.equal(boshSpy.called, true);
|
|
900
|
-
assert.equal(checkSpy.called, true);
|
|
901
|
-
|
|
902
|
-
// Check that passing in the right jid but with a resource is not a problem.
|
|
903
|
-
conn.restore('dummy@localhost/with_resource');
|
|
904
|
-
assert.equal(conn.jid,'dummy@localhost');
|
|
905
|
-
assert.equal(conn._proto.rid,'1234567');
|
|
906
|
-
assert.equal(conn._proto.sid,'9876543210');
|
|
907
|
-
assert.equal(conn.restored, true);
|
|
908
|
-
});
|
|
909
|
-
|
|
910
|
-
test('when calling "restore" with a restorable session, bosh._attach is called with the session tokens', (assert) => {
|
|
911
|
-
window.sessionStorage.removeItem('strophe-bosh-session');
|
|
912
|
-
const conn = new Strophe.Connection("", {"keepalive": true});
|
|
913
|
-
conn.authenticated = true;
|
|
914
|
-
conn.jid = 'dummy@localhost';
|
|
915
|
-
conn._proto.rid = '123456';
|
|
916
|
-
conn._proto.sid = '987654321';
|
|
917
|
-
conn._proto._cacheSession();
|
|
918
|
-
delete conn._proto.rid;
|
|
919
|
-
delete conn._proto.sid;
|
|
920
|
-
delete conn._proto.jid;
|
|
921
|
-
assert.equal(conn.restored, false);
|
|
922
|
-
|
|
923
|
-
const boshSpy = sinon.spy(conn._proto, "_restore");
|
|
924
|
-
const checkSpy = sinon.spy(conn, "_sessionCachingSupported");
|
|
925
|
-
const attachSpsy = sinon.spy(conn._proto, "_attach");
|
|
926
|
-
conn.restore();
|
|
927
|
-
assert.equal(conn.jid,'dummy@localhost');
|
|
928
|
-
assert.equal(conn._proto.rid,'123456');
|
|
929
|
-
assert.equal(conn._proto.sid,'987654321');
|
|
930
|
-
assert.equal(conn.restored, true);
|
|
931
|
-
assert.equal(boshSpy.called, true);
|
|
932
|
-
assert.equal(checkSpy.called, true);
|
|
933
|
-
assert.equal(attachSpsy.called, true);
|
|
934
|
-
});
|
|
935
|
-
|
|
936
|
-
module("BOSH next valid request id");
|
|
937
|
-
|
|
938
|
-
test("nextValidRid is called after successful request", (assert) => {
|
|
939
|
-
Strophe.Connection.prototype._onIdle = () => {};
|
|
940
|
-
const conn = new Strophe.Connection("http://fake");
|
|
941
|
-
const spy = sinon.spy(conn, 'nextValidRid');
|
|
942
|
-
const req = {id: 43,
|
|
943
|
-
sends: 1,
|
|
944
|
-
xhr: new xhr(200, 4),
|
|
945
|
-
rid: 42
|
|
946
|
-
};
|
|
947
|
-
conn._requests = [req];
|
|
948
|
-
conn._proto._onRequestStateChange(function (){}, req);
|
|
949
|
-
assert.equal(spy.calledOnce, true, "nextValidRid was called only once");
|
|
950
|
-
assert.equal(spy.calledWith(43), true, "The RID was valid");
|
|
951
|
-
});
|
|
952
|
-
|
|
953
|
-
test("nextValidRid is not called after failed request", (assert) => {
|
|
954
|
-
Strophe.Connection.prototype._onIdle = () => {};
|
|
955
|
-
const conn = new Strophe.Connection("http://fake");
|
|
956
|
-
const spy = sinon.spy(conn, 'nextValidRid');
|
|
957
|
-
const req = {id: 43,
|
|
958
|
-
sends: 1,
|
|
959
|
-
xhr: new xhr(0, 4),
|
|
960
|
-
rid: 42
|
|
961
|
-
};
|
|
962
|
-
conn._requests = [req];
|
|
963
|
-
conn._proto._onRequestStateChange(function (){}, req);
|
|
964
|
-
assert.equal(spy.called, false, "nextValidRid was not called");
|
|
965
|
-
});
|
|
966
|
-
|
|
967
|
-
test("nextValidRid is called after failed request with disconnection", (assert) => {
|
|
968
|
-
sinon.stub(Math, "random").callsFake(() => 1);
|
|
969
|
-
Strophe.Connection.prototype._onIdle = () => {};
|
|
970
|
-
const conn = new Strophe.Connection("http://fake");
|
|
971
|
-
const spy = sinon.spy(conn, 'nextValidRid');
|
|
972
|
-
const req = {id: 43,
|
|
973
|
-
sends: 1,
|
|
974
|
-
xhr: new xhr(404, 4),
|
|
975
|
-
rid: 42
|
|
976
|
-
};
|
|
977
|
-
conn._requests = [req];
|
|
978
|
-
conn._proto._onRequestStateChange(function (){}, req);
|
|
979
|
-
assert.equal(spy.calledOnce, true, "nextValidRid was called only once");
|
|
980
|
-
assert.equal(spy.calledWith(4294967295), true, "The RID was valid");
|
|
981
|
-
Math.random.restore();
|
|
982
|
-
});
|
|
983
|
-
|
|
984
|
-
test("nextValidRid is called after connection reset", (assert) => {
|
|
985
|
-
sinon.stub(Math, "random").callsFake(() => 1);
|
|
986
|
-
Strophe.Connection.prototype._onIdle = () => {};
|
|
987
|
-
const conn = new Strophe.Connection("http://fake");
|
|
988
|
-
const spy = sinon.spy(conn, 'nextValidRid');
|
|
989
|
-
conn.reset();
|
|
990
|
-
assert.equal(spy.calledOnce, true, "nextValidRid was called only once");
|
|
991
|
-
assert.equal(spy.calledWith(4294967295), true, "The RID was valid");
|
|
992
|
-
Math.random.restore();
|
|
993
|
-
});
|