Browse Source

Fetch VCard when starting a chat with someone not in the user's roster

JC Brand 7 years ago
parent
commit
1adc4938a8
4 changed files with 65 additions and 5 deletions
  1. 1 0
      CHANGES.md
  2. 59 0
      spec/chatbox.js
  3. 0 1
      src/converse-chatview.js
  4. 5 4
      src/converse-vcard.js

+ 1 - 0
CHANGES.md

@@ -25,6 +25,7 @@
   This removes the need for separate `inverse.js` and `converse-mobile.js`
   builds. Instead the `converse.js` build is now used with `view_mode` set to
   `fullscreen` and `mobile` respectively.
+- Fetch VCard when starting a chat with someone not in the user's roster.
 
 ### API changes
 - New API method `_converse.disco.supports` to check whether a certain

+ 59 - 0
spec/chatbox.js

@@ -13,6 +13,7 @@
     var $iq = converse.env.$iq;
     var $msg = converse.env.$msg;
     var Strophe = converse.env.Strophe;
+    var Promise = converse.env.Promise;
     var moment = converse.env.moment;
 
     return describe("Chatboxes", function() {
@@ -588,7 +589,65 @@
                         });
                     }));
 
+                    describe("when a chatbox is opened for someone who is not in the roster", function () {
+
+                        it("the VCard for that user is fetched and the chatbox updated with the results",
+                            mock.initConverseWithPromises(
+                                null, ['rosterGroupsFetched'], {},
+                                function (done, _converse) {
+
+                            _converse.allow_non_roster_messaging = true;
+                            spyOn(_converse, 'emit').and.callThrough();
+
+                            var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
+                            var vcard_fetched = false;
+                            spyOn(_converse.api.vcard, "get").and.callFake(function () {
+                                vcard_fetched = true;
+                                return Promise.resolve({
+                                    'fullname': mock.cur_names[0],
+                                    'vcard_updated': moment().format(),
+                                    'jid': sender_jid
+                                });
+                            });
+                            var message = 'This is a received message from someone not on the roster';
+                            var msg = $msg({
+                                    from: sender_jid,
+                                    to: _converse.connection.jid,
+                                    type: 'chat',
+                                    id: (new Date()).getTime()
+                                }).c('body').t(message).up()
+                                .c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
+
+                            // We don't already have an open chatbox for this user
+                            expect(_converse.chatboxes.get(sender_jid)).not.toBeDefined();
+
+                            _converse.chatboxes.onMessage(msg);
+                            expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
+
+                            // Check that the chatbox and its view now exist
+                            var chatbox = _converse.chatboxes.get(sender_jid);
+                            var chatboxview = _converse.chatboxviews.get(sender_jid);
+                            expect(chatbox).toBeDefined();
+                            expect(chatboxview).toBeDefined();
+                            // XXX: I don't really like the convention of
+                            // setting "fullname" to the JID if there's
+                            // no fullname. Should ideally be null if
+                            // there's no fullname.
+                            expect(chatbox.get('fullname') === sender_jid);
+                            test_utils.waitUntil(function () { return vcard_fetched; }, 100)
+                            .then(function () {
+                                expect(_converse.api.vcard.get).toHaveBeenCalled();
+                                return test_utils.waitUntil(function () {
+                                    return chatbox.get('fullname') === mock.cur_names[0]; 
+                                }, 100);
+                            }).then(function () {
+                                done();
+                            });
+                        }));
+                    });
+
                     describe("who is not on the roster", function () {
+
                         it("will open a chatbox and be displayed inside it if allow_non_roster_messaging is true",
                             mock.initConverseWithPromises(
                                 null, ['rosterGroupsFetched'], {},

+ 0 - 1
src/converse-chatview.js

@@ -274,7 +274,6 @@
                     this.model.on('showHelpMessages', this.showHelpMessages, this);
                     this.model.on('sendMessage', this.sendMessage, this);
 
-
                     this.render().renderToolbar().insertHeading().fetchMessages();
                     utils.refreshWebkit();
                     _converse.emit('chatBoxOpened', this);

+ 5 - 4
src/converse-vcard.js

@@ -154,19 +154,20 @@
                 }
             });
 
-            const updateVCardForChatBox = function (chatbox) {
+            _converse.on('chatBoxInitialized', function (chatbox) {
                 if (!_converse.use_vcards || chatbox.model.get('type') === 'headline') {
                     return;
                 }
                 _converse.api.waitUntil('rosterInitialized').then(() => {
                     const jid = chatbox.model.get('jid'),
                         contact = _converse.roster.get(jid);
-                    if ((contact) && (!contact.get('vcard_updated'))) {
+                    if (contact && !contact.get('vcard_updated') ||
+                        _.isUndefined(contact) && _converse.allow_non_roster_messaging) {
+
                         updateChatBoxFromVCard(_converse, jid);
                     }
                 }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
-            };
-            _converse.on('chatBoxInitialized', updateVCardForChatBox);
+            });
 
             _converse.on('initialized', () => {
                 _converse.roster.on("add", (contact) => {