Commit 0d48929b authored by JC Brand's avatar JC Brand

Show join/leave messages in chat rooms. Updates #365

parent e140eb84
......@@ -50,6 +50,9 @@
- Bugfix. `TypeError: this.sendConfiguration(...).then is not a function` when
an instant room is created. [jcbrand]
- Ensure consistent behavior from `show_controlbox_by_default` [jcbrand]
- #365 Show join/leave messages for chat rooms.
New configuration setting:
[muc_show_join_leave](https://conversejs.org/docs/html/configuration.html#muc-show-join-leave)
- #366 Show the chat room occupant's JID in the tooltip (if you're allowed to see it). [jcbrand]
- #610, #785 Add presence priority handling [w3host, jcbrand]
- #694 The `notification_option` wasn't being used consistently. [jcbrand]
......
......@@ -791,6 +791,14 @@ automatically be "john". If now john@differentdomain.com tries to join the
room, his nickname will be "john-2", and if john@somethingelse.com joins, then
his nickname will be "john-3", and so forth.
muc_show_join_leave
-------------------
* Default; ``true``
Determines whether Converse.js will show info messages inside a chat room
whenever a user joins or leaves it.
notify_all_room_messages
------------------------
......
......@@ -345,6 +345,76 @@
describe("A Chat Room", function () {
it("shows join/leave messages when users enter or exit a room", mock.initConverse(function (_converse) {
test_utils.openChatRoom(_converse, "coven", 'chat.shakespeare.lit', 'some1');
var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
var $chat_content = view.$el.find('.chat-content');
/* We don't show join/leave messages for existing occupants. We
* know about them because we receive their presences before we
* receive our own.
*/
presence = $pres({
to: 'dummy@localhost/_converse.js-29092160',
from: 'coven@chat.shakespeare.lit/oldguy'
}).c('x', {xmlns: Strophe.NS.MUC_USER})
.c('item', {
'affiliation': 'none',
'jid': 'oldguy@localhost/_converse.js-290929789',
'role': 'participant'
});
_converse.connection._dataRecv(test_utils.createRequest(presence));
expect($chat_content.find('div.chat-info').length).toBe(0);
/* <presence to="dummy@localhost/_converse.js-29092160"
* from="coven@chat.shakespeare.lit/some1">
* <x xmlns="http://jabber.org/protocol/muc#user">
* <item affiliation="owner" jid="dummy@localhost/_converse.js-29092160" role="moderator"/>
* <status code="110"/>
* </x>
* </presence></body>
*/
var presence = $pres({
to: 'dummy@localhost/_converse.js-29092160',
from: 'coven@chat.shakespeare.lit/some1'
}).c('x', {xmlns: Strophe.NS.MUC_USER})
.c('item', {
'affiliation': 'owner',
'jid': 'dummy@localhost/_converse.js-29092160',
'role': 'moderator'
}).up()
.c('status', {code: '110'});
_converse.connection._dataRecv(test_utils.createRequest(presence));
expect($chat_content.find('div.chat-info:first').html()).toBe("some1 has joined the room");
presence = $pres({
to: 'dummy@localhost/_converse.js-29092160',
from: 'coven@chat.shakespeare.lit/newguy'
}).c('x', {xmlns: Strophe.NS.MUC_USER})
.c('item', {
'affiliation': 'none',
'jid': 'newguy@localhost/_converse.js-290929789',
'role': 'participant'
});
_converse.connection._dataRecv(test_utils.createRequest(presence));
expect($chat_content.find('div.chat-info').length).toBe(2);
expect($chat_content.find('div.chat-info:last').html()).toBe("newguy has joined the room");
presence = $pres({
to: 'dummy@localhost/_converse.js-29092160',
type: 'unavailable',
from: 'coven@chat.shakespeare.lit/newguy'
}).c('x', {xmlns: Strophe.NS.MUC_USER})
.c('item', {
'affiliation': 'none',
'jid': 'newguy@localhost/_converse.js-290929789',
'role': 'participant'
});
_converse.connection._dataRecv(test_utils.createRequest(presence));
expect($chat_content.find('div.chat-info').length).toBe(3);
expect($chat_content.find('div.chat-info:last').html()).toBe("newguy has left the room");
}));
it("shows its description in the chat heading", mock.initConverse(function (_converse) {
var sent_IQ, IQ_id;
var sendIQ = _converse.connection.sendIQ;
......@@ -1036,8 +1106,7 @@
_converse.connection._dataRecv(test_utils.createRequest(stanza));
var view = _converse.chatboxviews.get('jdev@conference.jabber.org');
var $chat_content = view.$el.find('.chat-content');
expect($chat_content.find('.chat-info').length).toBe(1);
expect($chat_content.find('.chat-info').text()).toBe('Topic set by ralphm to: '+text);
expect($chat_content.find('.chat-info:last').text()).toBe('Topic set by ralphm to: '+text);
}));
it("escapes the subject before rendering it, to avoid JS-injection attacks", mock.initConverse(function (_converse) {
......@@ -1047,8 +1116,7 @@
var view = _converse.chatboxviews.get('jdev@conference.jabber.org');
view.setChatRoomSubject('ralphm', subject);
var $chat_content = view.$el.find('.chat-content');
expect($chat_content.find('.chat-info').length).toBe(1);
expect($chat_content.find('.chat-info').text()).toBe('Topic set by ralphm to: '+subject);
expect($chat_content.find('.chat-info:last').text()).toBe('Topic set by ralphm to: '+subject);
}));
it("informs users if their nicknames has been changed.", mock.initConverse(function (_converse) {
......@@ -1114,8 +1182,9 @@
expect($occupants.children().length).toBe(1);
expect($occupants.children().first(0).text()).toBe("oldnick");
expect($chat_content.find('div.chat-info').length).toBe(1);
expect($chat_content.find('div.chat-info').html()).toBe(__(_converse.muc.new_nickname_messages["210"], "oldnick"));
expect($chat_content.find('div.chat-info').length).toBe(2);
expect($chat_content.find('div.chat-info:first').html()).toBe("oldnick has joined the room");
expect($chat_content.find('div.chat-info:last').html()).toBe(__(_converse.muc.new_nickname_messages["210"], "oldnick"));
presence = $pres().attrs({
from:'lounge@localhost/oldnick',
......@@ -1134,7 +1203,7 @@
.c('status').attrs({code:'110'}).nodeTree;
_converse.connection._dataRecv(test_utils.createRequest(presence));
expect($chat_content.find('div.chat-info').length).toBe(2);
expect($chat_content.find('div.chat-info').length).toBe(3);
expect($chat_content.find('div.chat-info').last().html()).toBe(__(_converse.muc.new_nickname_messages["303"], "newnick"));
$occupants = view.$('.occupant-list');
......@@ -1154,8 +1223,9 @@
.c('status').attrs({code:'110'}).nodeTree;
_converse.connection._dataRecv(test_utils.createRequest(presence));
expect($chat_content.find('div.chat-info').length).toBe(2);
expect($chat_content.find('div.chat-info').last().html()).toBe(__(_converse.muc.new_nickname_messages["303"], "newnick"));
expect($chat_content.find('div.chat-info').length).toBe(4);
expect($chat_content.find('div.chat-info').get(2).textContent).toBe(__(_converse.muc.new_nickname_messages["303"], "newnick"));
expect($chat_content.find('div.chat-info').last().html()).toBe("newnick has joined the room");
$occupants = view.$('.occupant-list');
expect($occupants.children().length).toBe(1);
expect($occupants.children().first(0).text()).toBe("newnick");
......@@ -1400,7 +1470,7 @@
describe("Each chat room can take special commands", function () {
it("to set the room subject", mock.initConverse(function (_converse) {
it("to set the room topic", mock.initConverse(function (_converse) {
var sent_stanza;
test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy');
var view = _converse.chatboxviews.get('lounge@localhost');
......
......@@ -50,10 +50,10 @@
it("can be used to replay conversations", mock.initConverse(function (_converse) {
/*
test_utils.openChatRoom("discuss", 'conference.conversejs.org', 'jc');
test_utils.openChatRoom("dummy", 'rooms.localhost', 'jc');
test_utils.openChatRoom("prosody", 'conference.prosody.im', 'jc');
test_utils.openChatRoom(_converse, "dummy", 'rooms.localhost', 'jc');
test_utils.openChatRoom(_converse, "prosody", 'conference.prosody.im', 'jc');
*/
test_utils.openChatRoom(_converse, "discuss", 'conference.conversejs.org', 'ee');
spyOn(_converse, 'areDesktopNotificationsEnabled').andReturn(true);
_.each(transcripts, function (transcript) {
var text = transcript();
......
This diff is collapsed.
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