@sockethub/platform-xmpp 5.0.0-alpha.3 → 5.0.0-alpha.6

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/src/index.test.js CHANGED
@@ -1,367 +1,525 @@
1
- const proxyquire = require('proxyquire');
2
- const chai = require('chai');
3
- const sinon = require('sinon');
4
- const expect = chai.expect;
1
+ import { afterEach, beforeEach, describe, expect, it } from "bun:test";
2
+ import sinon from "sinon";
5
3
 
6
- proxyquire.noPreserveCache();
7
- proxyquire.noCallThru();
4
+ import XMPP from "./index.js";
8
5
 
9
6
  const actor = {
10
- type: 'person',
11
- id: 'testingham@jabber.net',
12
- name:'testing ham'
7
+ type: "person",
8
+ id: "testingham@jabber.net",
9
+ name: "testing ham",
13
10
  };
14
11
 
15
12
  const credentials = {
16
- actor: actor,
17
- object: {
18
- type: 'credentials',
19
- userAddress: 'testingham@jabber.net',
20
- password: 'foobar',
21
- resource: 'home'
22
- }
13
+ actor: actor,
14
+ object: {
15
+ type: "credentials",
16
+ userAddress: "testingham@jabber.net",
17
+ password: "foobar",
18
+ resource: "home",
19
+ },
23
20
  };
24
21
 
25
22
  const target = {
26
- mrfoobar: {
27
- type: 'person',
28
- id: 'mrfoobar@jabber.net',
29
- name: 'Mr FooBar'
30
- },
31
- partyroom: {
32
- type: 'room',
33
- id: 'partyroom@jabber.net'
34
- },
35
- roomuser: {
36
- type: 'room',
37
- id: 'partyroom@jabber.net/ms tut'
38
- }
23
+ mrfoobar: {
24
+ type: "person",
25
+ id: "mrfoobar@jabber.net",
26
+ name: "Mr FooBar",
27
+ },
28
+ partyroom: {
29
+ type: "room",
30
+ id: "partyroom@jabber.net",
31
+ },
32
+ roomuser: {
33
+ type: "room",
34
+ id: "partyroom@jabber.net/ms tut",
35
+ },
39
36
  };
40
37
 
41
38
  const job = {
42
- connect: {
43
- context: 'xmpp',
44
- type: 'connect',
45
- actor: {
46
- id: 'slvrbckt@jabber.net/Home',
47
- type: 'person',
48
- name: 'Nick Jennings',
49
- userName: 'slvrbckt'
50
- }
51
- },
52
- join: {
53
- actor: actor,
54
- object: {
55
- type: 'update',
56
- name: 'Frank'
39
+ connect: {
40
+ context: "xmpp",
41
+ type: "connect",
42
+ actor: {
43
+ id: "slvrbckt@jabber.net/Home",
44
+ type: "person",
45
+ name: "Nick Jennings",
46
+ userName: "slvrbckt",
47
+ },
57
48
  },
58
- target: target.partyroom
59
- },
60
- leave: {
61
- actor: actor,
62
- target: target.partyroom
63
- },
64
- send: {
65
- chat: {
66
- actor: actor,
67
- object: {
68
- type: 'message',
69
- id: 'hc-1234abcd',
70
- content: 'hello'
71
- },
72
- target: target.mrfoobar
49
+ join: {
50
+ actor: actor,
51
+ object: {
52
+ type: "update",
53
+ name: "Frank",
54
+ },
55
+ target: target.partyroom,
73
56
  },
74
- groupchat: {
75
- actor: actor,
76
- object: {
77
- type: 'message',
78
- id: 'hc-1234abcd',
79
- content: 'hi all'
80
- },
81
- target: target.roomuser
57
+ leave: {
58
+ actor: actor,
59
+ target: target.partyroom,
82
60
  },
83
- correction: {
84
- actor: actor,
85
- object: {
86
- type: 'message',
87
- id: 'hc-1234abcd',
88
- content: 'hi yall',
89
- 'xmpp:replace': { id: 'hc-234bcde' }
90
- },
91
- target: target.roomuser
92
- }
93
- },
94
- update: {
95
- presenceOnline: {
96
- actor: actor,
97
- object: {
98
- type: 'presence',
99
- presence: 'online',
100
- content: 'ready to chat'
101
- }
61
+ send: {
62
+ chat: {
63
+ actor: actor,
64
+ object: {
65
+ type: "message",
66
+ id: "hc-1234abcd",
67
+ content: "hello",
68
+ },
69
+ target: target.mrfoobar,
70
+ },
71
+ groupchat: {
72
+ actor: actor,
73
+ object: {
74
+ type: "message",
75
+ id: "hc-1234abcd",
76
+ content: "hi all",
77
+ },
78
+ target: target.roomuser,
79
+ },
80
+ correction: {
81
+ actor: actor,
82
+ object: {
83
+ type: "message",
84
+ id: "hc-1234abcd",
85
+ content: "hi yall",
86
+ "xmpp:replace": { id: "hc-234bcde" },
87
+ },
88
+ target: target.roomuser,
89
+ },
102
90
  },
103
- presenceUnavailable: {
104
- actor: actor,
105
- object: {
106
- type: 'presence',
107
- presence: 'away',
108
- content: 'eating popcorn'
109
- }
91
+ update: {
92
+ presenceOnline: {
93
+ actor: actor,
94
+ object: {
95
+ type: "presence",
96
+ presence: "online",
97
+ content: "ready to chat",
98
+ },
99
+ },
100
+ presenceUnavailable: {
101
+ actor: actor,
102
+ object: {
103
+ type: "presence",
104
+ presence: "away",
105
+ content: "eating popcorn",
106
+ },
107
+ },
108
+ presenceOffline: {
109
+ actor: actor,
110
+ object: {
111
+ type: "presence",
112
+ presence: "offline",
113
+ content: "",
114
+ },
115
+ },
116
+ },
117
+ "request-friend": {
118
+ actor: actor,
119
+ target: target.mrfoobar,
120
+ },
121
+ "remove-friend": {
122
+ actor: actor,
123
+ target: target.mrfoobar,
124
+ },
125
+ "make-friend": {
126
+ actor: actor,
127
+ target: target.mrfoobar,
128
+ },
129
+ query: {
130
+ actor: actor,
131
+ target: target.partyroom,
132
+ object: {
133
+ type: "attendance",
134
+ },
110
135
  },
111
- presenceOffline: {
112
- actor: actor,
113
- object: {
114
- type: 'presence',
115
- presence: 'offline',
116
- content: ''
117
- }
118
- }
119
- },
120
- 'request-friend': {
121
- actor: actor,
122
- target: target.mrfoobar
123
- },
124
- 'remove-friend': {
125
- actor: actor,
126
- target: target.mrfoobar
127
- },
128
- 'make-friend': {
129
- actor: actor,
130
- target: target.mrfoobar
131
- },
132
- query: {
133
- actor: actor,
134
- target: target.partyroom,
135
- object: {
136
- type: 'attendance'
137
- }
138
- }
139
136
  };
140
137
 
141
- describe('Platform', () => {
142
- let shXmpp, clientFake, xmlFake, clientObjectFake, xp;
143
-
144
- beforeEach(() => {
145
- clientObjectFake = {
146
- on: sinon.fake(),
147
- start: sinon.fake.resolves(),
148
- send: sinon.fake.resolves(),
149
- join: sinon.fake.resolves(),
150
- };
151
- clientFake = sinon.fake.returns(clientObjectFake);
152
- xmlFake = sinon.fake();
153
-
154
- shXmpp = proxyquire('./index', {
155
- '@xmpp/client': {
156
- client: clientFake,
157
- xml: xmlFake
158
- },
159
- './utils': {
160
- buildXmppCredentials: sinon.fake()
161
- }
162
- });
138
+ describe("XMPP", () => {
139
+ let clientFake, xmlFake, clientObjectFake, xp;
163
140
 
164
- xp = new shXmpp({
165
- id: actor,
166
- debug: sinon.fake(),
167
- sendToClient: sinon.fake()
168
- });
169
- });
170
-
171
- afterEach(() => {
172
- sinon.restore();
173
- });
174
-
175
- describe('Successful initialization', () => {
176
- it('works as intended', (done) => {
177
- xp.connect(job.connect, credentials, () => {
178
- sinon.assert.calledOnce(clientFake);
179
- expect(xp.__client.on).to.exist;
180
- expect(xp.__client.start).to.exist;
181
- expect(xp.__client.send).to.exist;
182
- expect(xp.__client.send.callCount).to.eql(0);
183
- sinon.assert.calledOnce(clientObjectFake.start);
184
- sinon.assert.notCalled(xp.sendToClient);
185
- done();
186
- });
187
- });
188
- });
189
-
190
- describe('Bad initialization', () => {
191
- it('returns the existing __client object', (done) => {
192
- xp.__client = 'foo';
193
- xp.connect(job.connect, credentials, () => {
194
- expect(xp.__client).to.equal('foo');
195
- sinon.assert.notCalled(clientFake);
196
- sinon.assert.notCalled(xp.sendToClient);
197
- // sinon.assert.calledOnce(clientFake);
198
- // sinon.assert.calledOnce(xp.sendToClient);
199
- done();
200
- });
201
- });
141
+ beforeEach(() => {
142
+ clientObjectFake = {
143
+ on: sinon.fake(),
144
+ start: sinon.fake.resolves(),
145
+ send: sinon.fake.resolves(),
146
+ join: sinon.fake.resolves(),
147
+ stop: sinon.fake.resolves()
148
+ };
149
+ clientFake = sinon.fake.returns(clientObjectFake);
150
+
151
+ // Mock XML object with chainable .c() method for building stanzas
152
+ const mockXmlElement = {
153
+ name: "presence",
154
+ attrs: {},
155
+ children: [],
156
+ c: sinon.fake.returns({
157
+ name: "x",
158
+ attrs: { xmlns: "http://jabber.org/protocol/muc" },
159
+ parent: null
160
+ }),
161
+ getChild: sinon.fake((name, xmlns) => {
162
+ if (name === "x" && xmlns === "http://jabber.org/protocol/muc") {
163
+ return { attrs: { xmlns: "http://jabber.org/protocol/muc" } };
164
+ }
165
+ return null;
166
+ })
167
+ };
168
+
169
+ // Create a smart fake that returns complex object for presence, simple for others
170
+ xmlFake = sinon.fake((elementName) => {
171
+ if (elementName === "presence") {
172
+ return mockXmlElement;
173
+ }
174
+ return undefined; // Default return for other elements
175
+ });
176
+
177
+ class TestXMPP extends XMPP {
178
+ createClient() {
179
+ this.__clientConstructor = clientFake;
180
+ }
181
+ createXml() {
182
+ this.__xml = xmlFake;
183
+ }
184
+ }
202
185
 
203
- it('deletes the __client property on failed connect', (done) => {
204
- clientObjectFake.start = sinon.fake.rejects('foo');
205
- xp.connect(job.connect, credentials, () => {
206
- expect(xp.__client).to.be.undefined;
207
- sinon.assert.notCalled(xp.sendToClient);
208
- done();
209
- });
186
+ xp = new TestXMPP({
187
+ id: actor,
188
+ debug: sinon.fake(),
189
+ sendToClient: sinon.fake(),
190
+ });
210
191
  });
211
- });
212
192
 
213
- describe('Platform functionality', () => {
214
- beforeEach(done => {
215
- xp.connect(job.join, credentials, () => done());
193
+ afterEach(() => {
194
+ sinon.restore();
216
195
  });
217
196
 
218
- describe('#join', () => {
219
- it('calls xmpp.js correctly', (done) => {
220
- expect(xp.__client.send).to.be.instanceof(Function);
221
- xp.join(job.join, () => {
222
- sinon.assert.calledOnce(xp.__client.send);
223
- sinon.assert.calledWith(xmlFake, "presence", {
224
- "from": "testingham@jabber.net",
225
- "to": "partyroom@jabber.net/testing ham"
226
- });
227
- done();
197
+ describe("Successful initialization", () => {
198
+ it("works as intended", (done) => {
199
+ xp.connect(job.connect, credentials, () => {
200
+ sinon.assert.calledOnce(clientFake);
201
+ expect(xp.__client.on).toBeDefined();
202
+ expect(xp.__client.start).toBeDefined();
203
+ expect(xp.__client.send).toBeDefined();
204
+ expect(xp.__client.send.callCount).toEqual(0);
205
+ sinon.assert.calledOnce(clientObjectFake.start);
206
+ sinon.assert.notCalled(xp.sendToClient);
207
+ done();
208
+ });
228
209
  });
229
- });
230
210
  });
231
211
 
232
- describe('#leave', () => {
233
- it('calls xmpp.js correctly', (done) => {
234
- expect(xp.__client).to.not.be.undefined;
235
- expect(xp.__client.send).to.be.instanceof(Function);
236
- xp.leave(job.leave, () => {
237
- sinon.assert.calledOnce(xp.__client.send);
238
- sinon.assert.calledWith(xmlFake, "presence", {
239
- from: "testingham@jabber.net",
240
- to: "partyroom@jabber.net/testing ham",
241
- type: "unavailable"
242
- });
243
- done();
212
+ describe("Bad initialization", () => {
213
+ it("returns the existing __client object", (done) => {
214
+ const dummyClient = {
215
+ foo: "bar",
216
+ socket: {
217
+ writable: true
218
+ },
219
+ status: "online"
220
+ };
221
+ xp.__client = dummyClient
222
+ xp.connect(job.connect, credentials, (d) => {
223
+ console.log('result: ', d);
224
+ expect(xp.__client).toEqual(dummyClient);
225
+ sinon.assert.notCalled(clientFake);
226
+ sinon.assert.notCalled(xp.sendToClient);
227
+ // sinon.assert.calledOnce(clientFake);
228
+ // sinon.assert.calledOnce(xp.sendToClient);
229
+ done();
230
+ });
231
+ });
232
+
233
+ it("deletes the __client property on failed connect", (done) => {
234
+ clientObjectFake.start = sinon.fake.rejects("foo");
235
+ xp.connect(job.connect, credentials, () => {
236
+ expect(xp.__client).toBeUndefined();
237
+ sinon.assert.notCalled(xp.sendToClient);
238
+ done();
239
+ });
244
240
  });
245
- });
246
241
  });
247
242
 
248
- describe('#send', () => {
249
- it('calls xmpp.js correctly', (done) => {
250
- expect(xp.__client).to.not.be.undefined;
251
- expect(xp.__client.send).to.be.instanceof(Function);
252
- xp.send(job.send.chat, () => {
253
- sinon.assert.calledOnce(xp.__client.send);
254
- expect(xmlFake.getCall(0).args).to.eql(["body", {}, job.send.chat.object.content]);
255
- expect(xmlFake.getCall(1).args).to.eql(["message", {
256
- type: 'chat', to: job.send.chat.target.id, id: job.send.chat.object.id
257
- }, undefined, undefined]);
258
- done();
243
+ describe("Platform functionality", () => {
244
+ beforeEach((done) => {
245
+ xp.connect(job.join, credentials, () => done());
259
246
  });
260
- });
261
-
262
- it('calls xmpp.js correctly for a groupchat', (done) => {
263
- xp.send(job.send.groupchat, () => {
264
- sinon.assert.calledOnce(xp.__client.send);
265
- expect(xmlFake.getCall(0).args).to.eql(["body", {}, job.send.groupchat.object.content]);
266
- expect(xmlFake.getCall(1).args).to.eql(["message", {
267
- type: 'groupchat', to: job.send.groupchat.target.id, id: job.send.groupchat.object.id
268
- }, undefined, undefined]);
269
- done();
247
+
248
+ describe("#join", () => {
249
+ it("calls xmpp.js correctly", (done) => {
250
+ expect(xp.__client.send).toBeInstanceOf(Function);
251
+ xp.join(job.join, () => {
252
+ sinon.assert.calledOnce(xp.__client.send);
253
+
254
+ // Verify MUC <x> element was created with correct namespace
255
+ sinon.assert.calledWith(xmlFake, "x", { xmlns: "http://jabber.org/protocol/muc" });
256
+
257
+ // Verify presence stanza was created with correct attributes
258
+ sinon.assert.calledWith(xmlFake, "presence", {
259
+ from: "testingham@jabber.net",
260
+ to: "partyroom@jabber.net/testing ham",
261
+ });
262
+
263
+ done();
264
+ });
265
+ });
270
266
  });
271
- });
272
-
273
- it('calls xmpp.js correctly for a message correction', (done) => {
274
- xp.send(job.send.correction, () => {
275
- sinon.assert.calledOnce(xp.__client.send);
276
- expect(xmlFake.getCall(0).args).to.eql(["body", {}, job.send.correction.object.content]);
277
- expect(xmlFake.getCall(1).args).to.eql(["replace", {
278
- id: job.send.correction.object['xmpp:replace'].id, xmlns: 'urn:xmpp:message-correct:0'
279
- }]);
280
- expect(xmlFake.getCall(2).args).to.eql(["message", {
281
- type: 'groupchat', to: job.send.correction.target.id, id: job.send.correction.object.id
282
- }, undefined, undefined]);
283
- done();
267
+
268
+ describe("#leave", () => {
269
+ it("calls xmpp.js correctly", (done) => {
270
+ expect(xp.__client).toBeDefined();
271
+ expect(xp.__client.send).toBeInstanceOf(Function);
272
+ xp.leave(job.leave, () => {
273
+ sinon.assert.calledOnce(xp.__client.send);
274
+ sinon.assert.calledWith(xmlFake, "presence", {
275
+ from: "testingham@jabber.net",
276
+ to: "partyroom@jabber.net/testing ham",
277
+ type: "unavailable",
278
+ });
279
+ done();
280
+ });
281
+ });
284
282
  });
285
- });
286
- });
287
283
 
288
- describe('#update', () => {
289
- it('calls xml() correctly for available', (done) => {
290
- xp.update(job.update.presenceOnline, () => {
291
- sinon.assert.calledOnce(xp.__client.send);
292
- expect(xmlFake.getCall(0).args).to.eql(
293
- [ 'presence', {}, {}, { status: 'ready to chat' } ]);
294
- done();
284
+ describe("#send", () => {
285
+ it("calls xmpp.js correctly", (done) => {
286
+ expect(xp.__client).toBeDefined();
287
+ expect(xp.__client.send).toBeInstanceOf(Function);
288
+ xp.send(job.send.chat, () => {
289
+ sinon.assert.calledOnce(xp.__client.send);
290
+ expect(xmlFake.getCall(0).args).toEqual([
291
+ "body",
292
+ {},
293
+ job.send.chat.object.content,
294
+ ]);
295
+ expect(xmlFake.getCall(1).args).toEqual([
296
+ "message",
297
+ {
298
+ type: "chat",
299
+ to: job.send.chat.target.id,
300
+ id: job.send.chat.object.id,
301
+ },
302
+ undefined,
303
+ undefined,
304
+ ]);
305
+ done();
306
+ });
307
+ });
308
+
309
+ it("calls xmpp.js correctly for a groupchat", (done) => {
310
+ xp.send(job.send.groupchat, () => {
311
+ sinon.assert.calledOnce(xp.__client.send);
312
+ expect(xmlFake.getCall(0).args).toEqual([
313
+ "body",
314
+ {},
315
+ job.send.groupchat.object.content,
316
+ ]);
317
+ expect(xmlFake.getCall(1).args).toEqual([
318
+ "message",
319
+ {
320
+ type: "groupchat",
321
+ to: job.send.groupchat.target.id,
322
+ id: job.send.groupchat.object.id,
323
+ },
324
+ undefined,
325
+ undefined,
326
+ ]);
327
+ done();
328
+ });
329
+ });
330
+
331
+ it("calls xmpp.js correctly for a message correction", (done) => {
332
+ xp.send(job.send.correction, () => {
333
+ sinon.assert.calledOnce(xp.__client.send);
334
+ expect(xmlFake.getCall(0).args).toEqual([
335
+ "body",
336
+ {},
337
+ job.send.correction.object.content,
338
+ ]);
339
+ expect(xmlFake.getCall(1).args).toEqual([
340
+ "replace",
341
+ {
342
+ id: job.send.correction.object["xmpp:replace"].id,
343
+ xmlns: "urn:xmpp:message-correct:0",
344
+ },
345
+ ]);
346
+ expect(xmlFake.getCall(2).args).toEqual([
347
+ "message",
348
+ {
349
+ type: "groupchat",
350
+ to: job.send.correction.target.id,
351
+ id: job.send.correction.object.id,
352
+ },
353
+ undefined,
354
+ undefined,
355
+ ]);
356
+ done();
357
+ });
358
+ });
295
359
  });
296
- });
297
- it('calls xml() correctly for unavailable', (done) => {
298
- xp.update(job.update.presenceUnavailable, () => {
299
- sinon.assert.calledOnce(xp.__client.send);
300
- expect(xmlFake.getCall(0).args).to.eql(
301
- [ 'presence', {}, { show: 'away' }, { status: 'eating popcorn' } ]);
302
- done();
360
+
361
+ describe("#update", () => {
362
+ it("calls xml() correctly for available", (done) => {
363
+ xp.update(job.update.presenceOnline, () => {
364
+ sinon.assert.calledOnce(xp.__client.send);
365
+ expect(xmlFake.getCall(0).args).toEqual([
366
+ "presence",
367
+ {},
368
+ {},
369
+ { status: "ready to chat" },
370
+ ]);
371
+ done();
372
+ });
373
+ });
374
+ it("calls xml() correctly for unavailable", (done) => {
375
+ xp.update(job.update.presenceUnavailable, () => {
376
+ sinon.assert.calledOnce(xp.__client.send);
377
+ expect(xmlFake.getCall(0).args).toEqual([
378
+ "presence",
379
+ {},
380
+ { show: "away" },
381
+ { status: "eating popcorn" },
382
+ ]);
383
+ done();
384
+ });
385
+ });
386
+ it("calls xml() correctly for offline", (done) => {
387
+ xp.update(job.update.presenceOffline, () => {
388
+ sinon.assert.calledOnce(xp.__client.send);
389
+ expect(xmlFake.getCall(0).args).toEqual([
390
+ "presence",
391
+ { type: "unavailable" },
392
+ {},
393
+ {},
394
+ ]);
395
+ done();
396
+ });
397
+ });
303
398
  });
304
- });
305
- it('calls xml() correctly for offline', (done) => {
306
- xp.update(job.update.presenceOffline, () => {
307
- sinon.assert.calledOnce(xp.__client.send);
308
- expect(xmlFake.getCall(0).args).to.eql([ 'presence', { type: 'unavailable' }, {}, {} ]);
309
- done();
399
+
400
+ describe("#request-friend", () => {
401
+ it("calls xmpp.js correctly", (done) => {
402
+ xp["request-friend"](job["request-friend"], () => {
403
+ sinon.assert.calledOnce(xp.__client.send);
404
+ expect(xmlFake.getCall(0).args).toEqual([
405
+ "presence",
406
+ {
407
+ type: "subscribe",
408
+ to: job["request-friend"].target["id"],
409
+ },
410
+ ]);
411
+ done();
412
+ });
413
+ });
310
414
  });
311
- });
312
- });
313
415
 
314
- describe('#request-friend', () => {
315
- it('calls xmpp.js correctly', (done) => {
316
- xp['request-friend'](job['request-friend'], () => {
317
- sinon.assert.calledOnce(xp.__client.send);
318
- expect(xmlFake.getCall(0).args).to.eql(["presence", {
319
- type: "subscribe", to: job['request-friend'].target['id']
320
- }]);
321
- done();
416
+ describe("#remove-friend", () => {
417
+ it("calls xmpp.js correctly", (done) => {
418
+ xp["remove-friend"](job["remove-friend"], () => {
419
+ sinon.assert.calledOnce(xp.__client.send);
420
+ expect(xmlFake.getCall(0).args).toEqual([
421
+ "presence",
422
+ {
423
+ type: "unsubscribe",
424
+ to: job["remove-friend"].target["id"],
425
+ },
426
+ ]);
427
+ done();
428
+ });
429
+ });
322
430
  });
323
- });
324
- });
325
431
 
326
- describe('#remove-friend', () => {
327
- it('calls xmpp.js correctly', (done) => {
328
- xp['remove-friend'](job['remove-friend'], () => {
329
- sinon.assert.calledOnce(xp.__client.send);
330
- expect(xmlFake.getCall(0).args).to.eql(["presence", {
331
- type: "unsubscribe", to: job['remove-friend'].target['id']
332
- }]);
333
- done();
432
+ describe("#make-friend", () => {
433
+ it("calls xmpp.js correctly", (done) => {
434
+ xp["remove-friend"](job["remove-friend"], () => {
435
+ sinon.assert.calledOnce(xp.__client.send);
436
+ expect(xmlFake.getCall(0).args).toEqual([
437
+ "presence",
438
+ {
439
+ type: "unsubscribe",
440
+ to: job["make-friend"].target["id"],
441
+ },
442
+ ]);
443
+ done();
444
+ });
445
+ });
334
446
  });
335
- });
336
- });
337
447
 
338
- describe('#make-friend', () => {
339
- it('calls xmpp.js correctly', (done) => {
340
- xp['remove-friend'](job['remove-friend'], () => {
341
- sinon.assert.calledOnce(xp.__client.send);
342
- expect(xmlFake.getCall(0).args).to.eql(["presence", {
343
- type: "unsubscribe", to: job['make-friend'].target['id']
344
- }]);
345
- done();
448
+ describe("#query", () => {
449
+ it("calls xmpp.js correctly", (done) => {
450
+ xp.query(job.query, () => {
451
+ sinon.assert.calledOnce(xp.__client.send);
452
+ expect(xmlFake.getCall(0).args).toEqual([
453
+ "query",
454
+ { xmlns: "http://jabber.org/protocol/disco#items" },
455
+ ]);
456
+ expect(xmlFake.getCall(1).args).toEqual([
457
+ "iq",
458
+ {
459
+ id: "muc_id",
460
+ type: "get",
461
+ from: "testingham@jabber.net",
462
+ to: "partyroom@jabber.net",
463
+ },
464
+ undefined,
465
+ ]);
466
+ done();
467
+ });
468
+ });
346
469
  });
347
- });
348
- });
349
470
 
350
- describe('#query', () => {
351
- it('calls xmpp.js correctly', (done) => {
352
- xp.query(job.query, () => {
353
- sinon.assert.calledOnce(xp.__client.send);
354
- expect(xmlFake.getCall(0).args).to.eql(
355
- ["query", {xmlns: 'http://jabber.org/protocol/disco#items'}]);
356
- expect(xmlFake.getCall(1).args).to.eql(["iq", {
357
- id: 'muc_id',
358
- type: 'get',
359
- from: "testingham@jabber.net",
360
- to: "partyroom@jabber.net"
361
- }, undefined]);
362
- done();
471
+ describe("#disconnect", () => {
472
+ it("calls cleanup", (done) => {
473
+ let cleanupCalled = false;
474
+ xp.cleanup = (done) => {
475
+ cleanupCalled = true;
476
+ done();
477
+ }
478
+ xp.disconnect(job, () => {
479
+ expect(cleanupCalled).toEqual(true);
480
+ done()
481
+ });
482
+ })
483
+ });
484
+
485
+ describe("#cleanup", () => {
486
+ it("calls client.stop", (done) => {
487
+ expect(xp.config.initialized).toEqual(true);
488
+ xp.cleanup(() => {
489
+ expect(xp.config.initialized).toEqual(false);
490
+ sinon.assert.calledOnce(xp.__client.stop);
491
+ done()
492
+ });
493
+ })
494
+ });
495
+
496
+ describe("#join", () => {
497
+ it("creates correct MUC presence stanza with namespace", (done) => {
498
+ const joinJob = {
499
+ actor: {
500
+ id: "testingham@jabber.net",
501
+ name: "Testing Ham"
502
+ },
503
+ target: {
504
+ id: "testroom@conference.jabber.net"
505
+ }
506
+ };
507
+
508
+ xp.join(joinJob, () => {
509
+ sinon.assert.calledOnce(xp.__client.send);
510
+
511
+ // Verify MUC <x> element was created with correct namespace
512
+ sinon.assert.calledWith(xmlFake, "x", { xmlns: "http://jabber.org/protocol/muc" });
513
+
514
+ // Verify presence stanza was created with correct attributes
515
+ sinon.assert.calledWith(xmlFake, "presence", {
516
+ from: "testingham@jabber.net",
517
+ to: "testroom@conference.jabber.net/Testing Ham",
518
+ });
519
+
520
+ done();
521
+ });
522
+ });
363
523
  });
364
- });
365
524
  });
366
- });
367
525
  });