Commit b2240cfe authored by JC Brand's avatar JC Brand

Use $.when to keep track of all outgoing promises

Now that we are sending multiple IQ stanzas when setting affiliations.
We now again have a sendAffiliation method, so we use that.
parent f5fbf712
......@@ -1163,11 +1163,59 @@
}));
it("to make a user an owner", mock.initConverse(function (converse) {
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(converse, 'lounge', 'localhost', 'dummy');
var view = converse.chatboxviews.get('lounge@localhost');
spyOn(view, 'onMessageSubmitted').andCallThrough();
spyOn(view, 'setAffiliation').andCallThrough();
spyOn(view, 'showStatusNotification').andCallThrough();
spyOn(view, 'validateRoleChangeCommand').andCallThrough();
view.$el.find('.chat-textarea').text('/owner');
view.$el.find('textarea.chat-textarea').trigger($.Event('keypress', {keyCode: 13}));
expect(view.onMessageSubmitted).toHaveBeenCalled();
expect(view.validateRoleChangeCommand).toHaveBeenCalled();
expect(view.showStatusNotification).toHaveBeenCalledWith(
"Error: the \"owner\" command takes two arguments, the user's nickname and optionally a reason.",
true
);
expect(view.setAffiliation).not.toHaveBeenCalled();
// Call now with the correct amount of arguments.
// XXX: Calling onMessageSubmitted directly, trying
// again via triggering Event doesn't work for some weird
// reason.
view.onMessageSubmitted('/owner annoyingGuy@localhost You\'re annoying');
expect(view.validateRoleChangeCommand.callCount).toBe(2);
expect(view.showStatusNotification.callCount).toBe(1);
expect(view.setAffiliation).toHaveBeenCalled();
// Check that the member list now gets updated
expect(sent_IQ.toLocaleString()).toBe(
"<iq to='lounge@localhost' type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
"<query xmlns='http://jabber.org/protocol/muc#admin'>"+
"<item affiliation='owner' jid='annoyingGuy@localhost'>"+
"<reason>You&apos;re annoying</reason>"+
"</item>"+
"</query>"+
"</iq>");
}));
it("to ban a user", mock.initConverse(function (converse) {
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(converse, 'lounge', 'localhost', 'dummy');
var view = converse.chatboxviews.get('lounge@localhost');
spyOn(view, 'onMessageSubmitted').andCallThrough();
spyOn(view, 'setAffiliations').andCallThrough();
spyOn(view, 'setAffiliation').andCallThrough();
spyOn(view, 'showStatusNotification').andCallThrough();
spyOn(view, 'validateRoleChangeCommand').andCallThrough();
view.$el.find('.chat-textarea').text('/ban');
......@@ -1178,16 +1226,24 @@
"Error: the \"ban\" command takes two arguments, the user's nickname and optionally a reason.",
true
);
expect(view.setAffiliations).not.toHaveBeenCalled();
expect(view.setAffiliation).not.toHaveBeenCalled();
// Call now with the correct amount of arguments.
// XXX: Calling onMessageSubmitted directly, trying
// again via triggering Event doesn't work for some weird
// reason.
view.onMessageSubmitted('/ban jid This is the reason');
view.onMessageSubmitted('/ban annoyingGuy@localhost You\'re annoying');
expect(view.validateRoleChangeCommand.callCount).toBe(2);
expect(view.showStatusNotification.callCount).toBe(1);
expect(view.setAffiliations).toHaveBeenCalled();
expect(view.setAffiliation).toHaveBeenCalled();
// Check that the member list now gets updated
expect(sent_IQ.toLocaleString()).toBe(
"<iq to='lounge@localhost' type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
"<query xmlns='http://jabber.org/protocol/muc#admin'>"+
"<item affiliation='outcast' jid='annoyingGuy@localhost'>"+
"<reason>You&apos;re annoying</reason>"+
"</item>"+
"</query>"+
"</iq>");
}));
});
......
......@@ -586,14 +586,52 @@
return delta;
},
setAffiliation: function (affiliation, members) {
/* Send an IQ stanzas to the server to modify one particular
* affiliation for certain members
*
* See: http://xmpp.org/extensions/xep-0045.html#modifymember
*
* Parameters:
* (Object) members: A map of jids, affiliations and
* optionally reasons. Only those entries with the
* same affiliation as being currently set will be
* considered.
*
* Returns:
* A promise which resolves and fails depending on the
* XMPP server response.
*/
var deferred = new $.Deferred();
var iq = $iq({to: this.model.get('jid'), type: "set"})
.c("query", {xmlns: Strophe.NS.MUC_ADMIN});
_.each(members, function (member) {
if (!_.isUndefined(member.affiliation) &&
member.affiliation !== affiliation) {
return;
}
iq.c("item", {
'affiliation': member.affiliation || affiliation,
'jid': member.jid
});
if (!_.isUndefined(member.reason)) {
iq.c("reason", member.reason).up();
}
iq.up();
});
converse.connection.sendIQ(iq, deferred.resolve, deferred.reject);
return deferred;
},
setAffiliations: function (members, onSuccess, onError) {
/* Send an IQ stanza to the server to modify the
/* Send IQ stanzas to the server to modify the
* affiliations in this room.
*
* See: http://xmpp.org/extensions/xep-0045.html#modifymember
*
* Parameters:
* (Object) members: A map of jids and affiliations
* (Object) members: A map of jids, affiliations and optionally reasons
* (Function) onSuccess: callback for a succesful response
* (Function) onError: callback for an error response
*/
......@@ -602,26 +640,9 @@
onSuccess(null);
return;
}
var room_jid = this.model.get('jid');
var affiliations = _.uniq(_.pluck(members, 'affiliation'));
_.each(affiliations, function (affiliation) {
var iq = $iq({to: room_jid, type: "set"})
.c("query", {xmlns: Strophe.NS.MUC_ADMIN});
_.each(members, function (member) {
if (member.affiliation !== affiliation) {
return;
}
iq.c("item", {
'affiliation': member.affiliation,
'jid': member.jid
});
if (!_.isUndefined(member.reason)) {
iq.c("reason", member.reason).up();
}
iq.up();
});
converse.connection.sendIQ(iq, onSuccess, onError);
});
var promises = _.map(affiliations, _.partial(this.setAffiliation, _, members), this);
$.when.apply($, promises).done(onSuccess).fail(onError);
},
marshallAffiliationIQs: function () {
......@@ -836,21 +857,17 @@
switch (match[1]) {
case 'admin':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
this.setAffiliations(
[{'jid': args[0],
'affiliation': 'admin',
'reason': args[1]
}], undefined, this.onCommandError.bind(this)
);
this.setAffiliation('admin',
[{ 'jid': args[0],
'reason': args[1]
}]).fail(this.onCommandError.bind(this));
break;
case 'ban':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
this.setAffiliations(
[{'jid': args[0],
'affiliation': 'outcast',
'reason': args[1]
}], undefined, this.onCommandError.bind(this)
);
this.setAffiliation('outcast',
[{ 'jid': args[0],
'reason': args[1]
}]).fail(this.onCommandError.bind(this));
break;
case 'clear':
this.clearChatRoomMessages();
......@@ -894,12 +911,10 @@
break;
case 'member':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
this.setAffiliations(
[{'jid': args[0],
'affiliation': 'member',
'reason': args[1]
}], undefined, this.onCommandError.bind(this)
);
this.setAffiliation('member',
[{ 'jid': args[0],
'reason': args[1]
}]).fail(this.onCommandError.bind(this));
break;
case 'nick':
converse.connection.send($pres({
......@@ -910,12 +925,10 @@
break;
case 'owner':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
this.setAffiliations(
[{'jid': args[0],
'affiliation': 'owner',
'reason': args[1]
}], undefined, this.onCommandError.bind(this)
);
this.setAffiliation('owner',
[{ 'jid': args[0],
'reason': args[1]
}]).fail(this.onCommandError.bind(this));
break;
case 'op':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
......@@ -925,12 +938,10 @@
break;
case 'revoke':
if (!this.validateRoleChangeCommand(match[1], args)) { break; }
this.setAffiliations(
[{'jid': args[0],
'affiliation': 'none',
'reason': args[1]
}], undefined, this.onCommandError.bind(this)
);
this.setAffiliation('none',
[{ 'jid': args[0],
'reason': args[1]
}]).fail(this.onCommandError.bind(this));
break;
case 'topic':
converse.connection.send(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment