浏览代码

parse and emit identity information in MUC_MEMBER_JOINED event (#724)

* remove unused 'show' field

* extract and emit identity information from presence

also replaces some uses of jquery

* combine eslint-disable lines
master
bbaldino 7 年前
父节点
当前提交
3fdbf68d93
共有 2 个文件被更改,包括 148 次插入17 次删除
  1. 45
    16
      modules/xmpp/ChatRoom.js
  2. 103
    1
      modules/xmpp/ChatRoom.spec.js

+ 45
- 16
modules/xmpp/ChatRoom.js 查看文件

@@ -390,28 +390,25 @@ export default class ChatRoom extends Listenable {
390 390
      */
391 391
     onPresence(pres) {
392 392
         const from = pres.getAttribute('from');
393
-
394
-        // Parse roles.
395 393
         const member = {};
394
+        const statusEl = pres.getElementsByTagName('status')[0];
396 395
 
397
-        member.show = $(pres).find('>show').text();
398
-        const $statusNode = $(pres).find('>status');
399
-        const hasStatus = $statusNode.length;
400
-
401
-        if (hasStatus) {
402
-            member.status = $statusNode.text();
396
+        if (statusEl) {
397
+            member.status = statusEl.textContent || '';
403 398
         }
404 399
         let hasStatusUpdate = false;
405
-
400
+        const xElement
401
+            = pres.getElementsByTagNameNS(
402
+                'http://jabber.org/protocol/muc#user', 'x')[0];
406 403
         const mucUserItem
407
-            = $(pres).find(
408
-                '>x[xmlns="http://jabber.org/protocol/muc#user"]>item');
404
+            = xElement && xElement.getElementsByTagName('item')[0];
409 405
 
410
-        member.affiliation = mucUserItem.attr('affiliation');
411
-        member.role = mucUserItem.attr('role');
406
+        member.affiliation
407
+            = mucUserItem && mucUserItem.getAttribute('affiliation');
408
+        member.role = mucUserItem && mucUserItem.getAttribute('role');
412 409
 
413 410
         // Focus recognition
414
-        const jid = mucUserItem.attr('jid');
411
+        const jid = mucUserItem && mucUserItem.getAttribute('jid');
415 412
 
416 413
         member.jid = jid;
417 414
         member.isFocus
@@ -421,7 +418,12 @@ export default class ChatRoom extends Listenable {
421 418
                 && this.options.hiddenDomain
422 419
                     === jid.substring(jid.indexOf('@') + 1, jid.indexOf('/'));
423 420
 
424
-        $(pres).find('>x').remove();
421
+        const xEl = pres.querySelectorAll('x')[0];
422
+
423
+        if (xEl) {
424
+            xEl.remove();
425
+        }
426
+
425 427
         const nodes = [];
426 428
 
427 429
         parser.packet2JSON(pres, nodes);
@@ -430,6 +432,29 @@ export default class ChatRoom extends Listenable {
430 432
 
431 433
         // process nodes to extract data needed for MUC_JOINED and
432 434
         // MUC_MEMBER_JOINED events
435
+        const extractIdentityInformation = node => {
436
+            const identity = {};
437
+            const userInfo = node.children.find(c => c.tagName === 'user');
438
+
439
+            if (userInfo) {
440
+                identity.user = {};
441
+                for (const tag of [ 'id', 'name', 'avatar' ]) {
442
+                    const child
443
+                        = userInfo.children.find(c => c.tagName === tag);
444
+
445
+                    if (child) {
446
+                        identity.user[tag] = child.value;
447
+                    }
448
+                }
449
+            }
450
+            const groupInfo = node.children.find(c => c.tagName === 'group');
451
+
452
+            if (groupInfo) {
453
+                identity.group = groupInfo.value;
454
+            }
455
+
456
+            return identity;
457
+        };
433 458
 
434 459
         for (let i = 0; i < nodes.length; i++) {
435 460
             const node = nodes[i];
@@ -444,6 +469,9 @@ export default class ChatRoom extends Listenable {
444 469
             case 'stats-id':
445 470
                 member.statsID = node.value;
446 471
                 break;
472
+            case 'identity':
473
+                member.identity = extractIdentityInformation(node);
474
+                break;
447 475
             }
448 476
         }
449 477
 
@@ -486,7 +514,8 @@ export default class ChatRoom extends Listenable {
486 514
                     member.role,
487 515
                     member.isHiddenDomain,
488 516
                     member.statsID,
489
-                    member.status);
517
+                    member.status,
518
+                    member.identity);
490 519
 
491 520
                 // we are reporting the status with the join
492 521
                 // so we do not want a second event about status update

+ 103
- 1
modules/xmpp/ChatRoom.spec.js 查看文件

@@ -1,9 +1,12 @@
1
-import { parser } from './ChatRoom';
1
+import ChatRoom, { parser } from './ChatRoom';
2 2
 import { $pres } from 'strophe.js';
3
+import XMPPEvents from '../../service/xmpp/XMPPEvents';
3 4
 
4 5
 // This rule makes creating the xml elements take up way more
5 6
 // space than necessary.
6 7
 /* eslint-disable newline-per-chained-call */
8
+// These rules makes the xml strings harder to read
9
+/* eslint-disable operator-linebreak, max-len */
7 10
 
8 11
 describe('ChatRoom', () => {
9 12
     describe('packet2JSON', () => {
@@ -126,4 +129,103 @@ describe('ChatRoom', () => {
126 129
             expect(identity.value).toBeFalsy();
127 130
         });
128 131
     });
132
+
133
+    describe('onPresence', () => {
134
+        let room;
135
+        let emitterSpy;
136
+
137
+        beforeEach(() => {
138
+            const xmpp = {
139
+                options: {}
140
+            };
141
+
142
+            room = new ChatRoom(
143
+                {} /* connection */,
144
+                'jid',
145
+                'password',
146
+                xmpp,
147
+                {} /* options */);
148
+            emitterSpy = spyOn(room.eventEmitter, 'emit');
149
+        });
150
+        it('parses status correctly', () => {
151
+            const presStr = '' +
152
+                '<presence to="tojid" from="fromjid">' +
153
+                    '<status>status-text</status>' +
154
+                '</presence>';
155
+            const pres = new DOMParser().parseFromString(presStr, 'text/xml').documentElement;
156
+
157
+            room.onPresence(pres);
158
+            expect(emitterSpy.calls.count()).toEqual(1);
159
+            expect(emitterSpy).toHaveBeenCalledWith(
160
+                XMPPEvents.MUC_MEMBER_JOINED,
161
+                'fromjid',
162
+                undefined, // nick
163
+                undefined, // role
164
+                undefined, // isHiddenDomain
165
+                undefined, // statsID
166
+                'status-text',
167
+                undefined);
168
+        });
169
+
170
+        it('parses muc user item correctly', () => {
171
+            const presStr = '' +
172
+                '<presence to="tojid" from="fromjid">' +
173
+                    '<x xmlns="http://jabber.org/protocol/muc#user">' +
174
+                        '<item jid="jid=attr" affiliation="affiliation-attr" role="role-attr"/>' +
175
+                    '</x>' +
176
+                '</presence>';
177
+            const pres = new DOMParser().parseFromString(presStr, 'text/xml').documentElement;
178
+
179
+            room.onPresence(pres);
180
+            expect(emitterSpy.calls.count()).toEqual(1);
181
+            expect(emitterSpy).toHaveBeenCalledWith(
182
+                XMPPEvents.MUC_MEMBER_JOINED,
183
+                'fromjid',
184
+                undefined, // nick
185
+                'role-attr', // role
186
+                jasmine.any(Boolean), // isHiddenDomain
187
+                undefined, // statsID
188
+                undefined,
189
+                undefined);
190
+        });
191
+
192
+        it('parses identity correctly', () => {
193
+            const presStr = '' +
194
+                '<presence to="tojid" from="fromjid">' +
195
+                    '<status>status-text</status>' +
196
+                    '<identity>' +
197
+                        '<user>' +
198
+                            '<id>id-text</id>' +
199
+                            '<name>name-text</name>' +
200
+                            '<avatar>avatar-text</avatar>' +
201
+                        '</user>' +
202
+                        '<group>group-text</group>' +
203
+                    '</identity>' +
204
+                '</presence>';
205
+            const pres = new DOMParser().parseFromString(presStr, 'text/xml').documentElement;
206
+
207
+            const expectedIdentity = {
208
+                user: {
209
+                    id: 'id-text',
210
+                    name: 'name-text',
211
+                    avatar: 'avatar-text'
212
+                },
213
+                group: 'group-text'
214
+            };
215
+
216
+            room.onPresence(pres);
217
+            expect(emitterSpy.calls.count()).toEqual(1);
218
+            expect(emitterSpy).toHaveBeenCalledWith(
219
+                XMPPEvents.MUC_MEMBER_JOINED,
220
+                'fromjid',
221
+                undefined, // nick
222
+                undefined, // role
223
+                undefined, // isHiddenDomain
224
+                undefined, // statsID
225
+                'status-text',
226
+                expectedIdentity);
227
+        });
228
+
229
+    });
129 230
 });
231
+

正在加载...
取消
保存