Forráskód Böngészése

Check whether the user has a reserved nickname

when they enter a chat room. If they have, we'll use that, otherwise we render
a form where they can specify their nick.

Some chat room tests now fail and still need to be fixed.
JC Brand 9 éve
szülő
commit
f56b85cff7
2 módosított fájl, 133 hozzáadás és 22 törlés
  1. 75 2
      spec/chatroom.js
  2. 58 20
      src/converse-muc.js

+ 75 - 2
spec/chatroom.js

@@ -12,6 +12,7 @@
     );
 } (this, function ($, _, mock, test_utils, utils) {
     var $pres = converse_api.env.$pres;
+    var $iq = converse_api.env.$iq;
     var $msg = converse_api.env.$msg;
     var Strophe = converse_api.env.Strophe;
 
@@ -191,7 +192,7 @@
                     }).up()
                     .c('status').attrs({code:'110'}).nodeTree;
 
-                    this.connection._dataRecv(test_utils.createRequest(presence));
+                    converse.connection._dataRecv(test_utils.createRequest(presence));
                     expect(view.onChatRoomPresence).toHaveBeenCalled();
                     expect($occupants.find('li').length).toBe(1+i);
                     expect($($occupants.find('li')[i]).text()).toBe(mock.chatroom_names[i]);
@@ -214,7 +215,7 @@
                         jid: name.replace(/ /g,'.').toLowerCase() + '@localhost',
                         role: 'none'
                     }).nodeTree;
-                    this.connection._dataRecv(test_utils.createRequest(presence));
+                    converse.connection._dataRecv(test_utils.createRequest(presence));
                     expect(view.onChatRoomPresence).toHaveBeenCalled();
                     expect($occupants.find('li.online').length).toBe(i);
                 }
@@ -243,6 +244,78 @@
                 expect($(occupant).attr('title')).toBe('This user is a moderator');
             }.bind(converse));
 
+            it("will use the user's reserved nickname, if it exists", function () {
+                var sent_IQ, IQ_id;
+                var sendIQ = converse.connection.sendIQ;
+                spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
+                    sent_IQ = iq;
+                    IQ_id = sendIQ.bind(this)(iq, callback, errback);
+                });
+
+                test_utils.openChatRoom('lounge', 'localhost', 'dummy');
+                var view = converse.chatboxviews.get('lounge@localhost');
+                spyOn(view, 'join').andCallThrough();
+
+                /* <iq from='hag66@shakespeare.lit/pda'
+                 *     id='getnick1'
+                 *     to='coven@chat.shakespeare.lit'
+                 *     type='get'>
+                 * <query xmlns='http://jabber.org/protocol/disco#info'
+                 *         node='x-roomuser-item'/>
+                 * </iq>
+                 */
+                expect(sent_IQ.toLocaleString()).toBe(
+                    "<iq to='lounge@localhost' from='dummy@localhost/resource' "+
+                        "type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+
+                            "<query xmlns='http://jabber.org/protocol/disco#info' node='x-roomuser-item'/></iq>"
+                );
+
+                /* <iq from='coven@chat.shakespeare.lit'
+                 *     id='getnick1'
+                 *     to='hag66@shakespeare.lit/pda'
+                 *     type='result'>
+                 *     <query xmlns='http://jabber.org/protocol/disco#info'
+                 *             node='x-roomuser-item'>
+                 *         <identity
+                 *             category='conference'
+                 *             name='thirdwitch'
+                 *             type='text'/>
+                 *     </query>
+                 * </iq>
+                 */
+                var stanza = $iq({
+                    'type': 'result',
+                    'id': IQ_id,
+                    'from': view.model.get('jid'),
+                    'to': converse.connection.jid 
+                }).c('query', {'xmlns': 'http://jabber.org/protocol/disco#info', 'node': 'x-roomuser-item'})
+                  .c('identity', {'category': 'conference', 'name': 'thirdwitch', 'type': 'text'});
+                converse.connection._dataRecv(test_utils.createRequest(stanza));
+
+                expect(view.join).toHaveBeenCalled();
+
+                // The user has just entered the room (because join was called)
+                // and receives their own presence from the server.
+                // See example 24:
+                // http://xmpp.org/extensions/xep-0045.html#enter-pres
+                var presence = $pres({
+                        to:'dummy@localhost/resource',
+                        from:'lounge@localhost/thirdwitch',
+                        id:'DC352437-C019-40EC-B590-AF29E879AF97'
+                }).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
+                  .c('item').attrs({
+                      affiliation: 'member',
+                      jid: 'dummy@localhost/resource',
+                      role: 'occupant'
+                  }).up()
+                  .c('status').attrs({code:'110'}).up()
+                  .c('status').attrs({code:'210'}).nodeTree;
+
+                converse.connection._dataRecv(test_utils.createRequest(presence));
+                var info_text = view.$el.find('.chat-content .chat-info').text();
+                expect(info_text).toBe('Your nickname has been automatically set to: thirdwitch');
+            });
+
             it("allows the user to invite their roster contacts to enter the chat room", function () {
                 test_utils.openChatRoom('lounge', 'localhost', 'dummy');
                 spyOn(converse, 'emit');

+ 58 - 20
src/converse-muc.js

@@ -206,9 +206,9 @@
 
                     var nick = this.model.get('nick');
                     if (!nick) {
-                        this.renderNicknameForm();
+                        this.checkForReservedNick();
                     } else {
-                        this.join(null, {'maxstanzas': converse.muc_history_max_stanzas});
+                        this.join(nick);
                     }
 
                     this.fetchMessages().insertIntoDOM();
@@ -578,29 +578,26 @@
                 },
 
                 getRoomJIDAndNick: function (nick) {
-                    nick = nick || this.model.get('nick');
+                    if (nick) {
+                        this.model.set({'nick': nick});
+                    } else {
+                        nick = this.model.get('nick');
+                    }
                     var room = this.model.get('jid');
                     var node = Strophe.getNodeFromJid(room);
                     var domain = Strophe.getDomainFromJid(room);
                     return node + "@" + domain + (nick !== null ? "/" + nick : "");
                 },
 
-                join: function (password, history_attrs, extended_presence) {
+                join: function (nick, password) {
                     var stanza = $pres({
-                        from: converse.connection.jid,
-                        to: this.getRoomJIDAndNick()
-                    }).c("x", {
-                        xmlns: Strophe.NS.MUC
-                    });
-                    if (typeof history_attrs === "object" && Object.keys(history_attrs).length) {
-                        stanza = stanza.c("history", history_attrs).up();
-                    }
+                        'from': converse.connection.jid,
+                        'to': this.getRoomJIDAndNick(nick)
+                    }).c("x", {'xmlns': Strophe.NS.MUC})
+                      .c("history", {'maxstanzas': converse.muc_history_max_stanzas}).up();
                     if (password) {
                         stanza.cnode(Strophe.xmlElement("password", [], password));
                     }
-                    if (typeof extended_presence !== "undefined" && extended_presence !== null) {
-                        stanza.up.cnode(extended_presence);
-                    }
                     if (!this.handler) {
                         this.handler = converse.connection.addHandler(this.handleMUCStanza.bind(this));
                     }
@@ -742,9 +739,45 @@
                     else {
                         $nick.removeClass('error');
                     }
-                    this.model.save({'nick': nick});
                     this.$el.find('.chatroom-form-container').replaceWith('<span class="spinner centered"/>');
-                    this.join(null, {'maxstanzas': converse.muc_history_max_stanzas});
+                    this.join(nick);
+                },
+
+                checkForReservedNick: function () {
+                    /* User service-discovery to as the XMPP server whether
+                     * this user has a reserved nickname for this room.
+                     * If so, we'll use that, otherwise we render the nickname
+                     * form.
+                     */
+                    this.showSpinner();
+                    converse.connection.sendIQ(
+                        $iq({
+                            'to': this.model.get('jid'),
+                            'from': converse.connection.jid,
+                            'type': "get"
+                        }).c("query", {
+                            'xmlns': Strophe.NS.DISCO_INFO,
+                            'node': 'x-roomuser-item'
+                        }),
+                        this.onNickNameFound.bind(this),
+                        this.renderNicknameForm.bind(this)
+                    );
+                },
+
+                onNickNameFound: function (iq) {
+                    /* We've received an IQ response from the server which
+                     * might contain the user's reserved nickname.
+                     * If no nickname is found, we render a form for them to
+                     * specify one.
+                     */
+                    var nick = $(iq)
+                        .find('query[node="x-roomuser-item"] identity')
+                        .attr('name');
+                    if (!nick) {
+                        this.renderNicknameForm();
+                    } else {
+                        this.join(nick);
+                    }
                 },
 
                 renderNicknameForm: function () {
@@ -763,7 +796,7 @@
                     ev.preventDefault();
                     var password = this.$el.find('.chatroom-form').find('input[type=password]').val();
                     this.$el.find('.chatroom-form-container').replaceWith('<span class="spinner centered"/>');
-                    this.join(password, {'maxstanzas': converse.muc_history_max_stanzas});
+                    this.join(this.model.get('nick'), password);
                 },
 
                 renderPasswordForm: function () {
@@ -847,7 +880,7 @@
                 },
 
                 newNicknameMessages: {
-                    210: ___('Your nickname has been automatically changed to: <strong>%1$s</strong>'),
+                    210: ___('Your nickname has been automatically set to: <strong>%1$s</strong>'),
                     303: ___('Your nickname has been changed to: <strong>%1$s</strong>')
                 },
 
@@ -943,6 +976,11 @@
                     }
                 },
 
+                showSpinner: function () {
+                    this.$('.chatroom-body').children().addClass('hidden');
+                    this.$el.find('.chatroom-body').prepend('<span class="spinner centered"/>');
+                },
+
                 hideSpinner: function () {
                     /* Check if the spinner is being shown and if so, hide it.
                      * Also make sure then that the chat area and occupants
@@ -1542,7 +1580,7 @@
                                 [Strophe.Status.CONNECTING, Strophe.Status.CONNECTED],
                                 chatroom.get('connection_status'))
                             ) {
-                        converse.chatboxviews.get(room_jid).join(null, {'maxstanzas': converse.muc_history_max_stanzas});
+                        converse.chatboxviews.get(room_jid).join();
                     }
                 }
             };