ChatRoomSpec.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. (function (root, factory) {
  2. define([
  3. "converse",
  4. "mock"
  5. ], function (converse, mock_connection) {
  6. return factory(converse, mock_connection);
  7. }
  8. );
  9. } (this, function (converse, mock_connection) {
  10. return describe("ChatRooms", $.proxy(function() {
  11. var chatroom_names = [
  12. 'Dyon van de Wege', 'Thomas Kalb', 'Dirk Theissen', 'Felix Hofmann', 'Ka Lek', 'Anne Ebersbacher'
  13. ];
  14. closeChatRoom = function (name) {
  15. converse.chatboxesview.views['lounge@muc.localhost'].closeChat();
  16. };
  17. describe("A Chat Room", $.proxy(function () {
  18. beforeEach($.proxy(function () {
  19. if (!$("div#controlbox").is(':visible')) {
  20. $('.toggle-online-users').click();
  21. }
  22. var roomspanel = this.chatboxesview.views.controlbox.roomspanel;
  23. var $input = roomspanel.$el.find('input.new-chatroom-name');
  24. var $server = roomspanel.$el.find('input.new-chatroom-server');
  25. $input.val('lounge');
  26. $server.val('muc.localhost');
  27. roomspanel.$el.find('form').submit();
  28. $('.toggle-online-users').click();
  29. }, converse));
  30. it("shows users currently present in the room", $.proxy(function () {
  31. var chatroomview = this.chatboxesview.views['lounge@muc.localhost'],
  32. $participant_list;
  33. var roster = {}, room = {}, i;
  34. for (i=0; i<chatroom_names.length-1; i++) {
  35. roster[chatroom_names[i]] = {};
  36. chatroomview.onChatRoomRoster(roster, room);
  37. $participant_list = chatroomview.$el.find('.participant-list');
  38. expect($participant_list.find('li').length).toBe(1+i);
  39. expect($($participant_list.find('li')[i]).text()).toBe(chatroom_names[i]);
  40. }
  41. roster[converse.bare_jid] = {};
  42. chatroomview.onChatRoomRoster(roster, room);
  43. }, converse));
  44. it("indicates moderators by means of a special css class and tooltip", $.proxy(function () {
  45. var chatroomview = this.chatboxesview.views['lounge@muc.localhost'];
  46. var roster = {}, idx = chatroom_names.length-1;
  47. roster[chatroom_names[idx]] = {};
  48. roster[chatroom_names[idx]].role = 'moderator';
  49. chatroomview.onChatRoomRoster(roster, {});
  50. var occupant = chatroomview.$el.find('.participant-list').find('li');
  51. expect(occupant.length).toBe(1);
  52. expect($(occupant).text()).toBe(chatroom_names[idx]);
  53. expect($(occupant).attr('class')).toBe('moderator');
  54. expect($(occupant).attr('title')).toBe('This user is a moderator');
  55. }, converse));
  56. it("shows received and sent groupchat messages", $.proxy(function () {
  57. var view = this.chatboxesview.views['lounge@muc.localhost'];
  58. if (!view.$el.find('.chat-area').length) { view.renderChatArea(); }
  59. var nick = chatroom_names[0];
  60. var text = 'This is a received message';
  61. var message = $msg({
  62. from: 'lounge@muc.localhost/'+nick,
  63. id: '1',
  64. to: 'dummy@localhost',
  65. type: 'groupchat'
  66. }).c('body').t(text);
  67. view.onChatRoomMessage(message.nodeTree);
  68. var $chat_content = view.$el.find('.chat-content');
  69. expect($chat_content.find('.chat-message').length).toBe(1);
  70. expect($chat_content.find('.chat-message-content').text()).toBe(text);
  71. }, converse));
  72. it("can be saved to, and retrieved from, localStorage", $.proxy(function () {
  73. // We instantiate a new ChatBoxes collection, which by default
  74. // will be empty.
  75. var newchatboxes = new this.ChatBoxes();
  76. expect(newchatboxes.length).toEqual(0);
  77. // The chatboxes will then be fetched from localStorage inside the
  78. // onConnected method
  79. newchatboxes.onConnected();
  80. expect(newchatboxes.length).toEqual(1);
  81. // Check that the chatrooms retrieved from localStorage
  82. // have the same attributes values as the original ones.
  83. attrs = ['id', 'box_id', 'visible'];
  84. for (i=0; i<attrs.length; i++) {
  85. new_attrs = _.pluck(_.pluck(newchatboxes.models, 'attributes'), attrs[i]);
  86. old_attrs = _.pluck(_.pluck(this.chatboxes.models, 'attributes'), attrs[i]);
  87. expect(_.isEqual(new_attrs, old_attrs)).toEqual(true);
  88. }
  89. this.rosterview.render();
  90. }, converse));
  91. it("can be closed again by clicking a DOM element with class 'close-chatbox-button'", $.proxy(function () {
  92. var view = this.chatboxesview.views['lounge@muc.localhost'], chatroom = view.model, $el;
  93. spyOn(view, 'closeChat').andCallThrough();
  94. spyOn(converse.connection.muc, 'leave');
  95. view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
  96. view.$el.find('.close-chatbox-button').click();
  97. expect(view.closeChat).toHaveBeenCalled();
  98. expect(converse.connection.muc.leave).toHaveBeenCalled();
  99. }, converse));
  100. }, converse));
  101. describe("When attempting to enter a chatroom", $.proxy(function () {
  102. beforeEach($.proxy(function () {
  103. var roomspanel = this.chatboxesview.views.controlbox.roomspanel;
  104. var $input = roomspanel.$el.find('input.new-chatroom-name');
  105. var $server = roomspanel.$el.find('input.new-chatroom-server');
  106. $input.val('problematic');
  107. $server.val('muc.localhost');
  108. roomspanel.$el.find('form').submit();
  109. }, converse));
  110. afterEach($.proxy(function () {
  111. var view = this.chatboxesview.views['problematic@muc.localhost'];
  112. view.closeChat();
  113. }, converse));
  114. it("will show an error message if the room requires a password", $.proxy(function () {
  115. var presence = $pres().attrs({
  116.   from:'coven@chat.shakespeare.lit/thirdwitch',
  117.     id:'n13mt3l',
  118.     to:'hag66@shakespeare.lit/pda',
  119.     type:'error'})
  120. .c('x').attrs({xmlns:'http://jabber.org/protocol/muc'}).up()
  121. .c('error').attrs({by:'coven@chat.shakespeare.lit', type:'auth'})
  122. .c('not-authorized').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
  123. var view = this.chatboxesview.views['problematic@muc.localhost'];
  124. spyOn(converse.connection.muc, 'removeRoom');
  125. spyOn(view, 'renderPasswordForm').andCallThrough();
  126. runs(function () {
  127. view.onChatRoomPresence(presence, {'nick': 'dummy'});
  128. });
  129. waits(250);
  130. runs(function () {
  131. var $chat_body = view.$el.find('.chat-body');
  132. expect(converse.connection.muc.removeRoom).toHaveBeenCalled();
  133. expect(view.renderPasswordForm).toHaveBeenCalled();
  134. expect($chat_body.find('form.chatroom-form').length).toBe(1);
  135. expect($chat_body.find('legend').text()).toBe('This chat room requires a password');
  136. });
  137. }, converse));
  138. it("will show an error message if the room is members-only and the user not included", $.proxy(function () {
  139. var presence = $pres().attrs({
  140.   from:'coven@chat.shakespeare.lit/thirdwitch',
  141.     id:'n13mt3l',
  142.     to:'hag66@shakespeare.lit/pda',
  143.     type:'error'})
  144. .c('x').attrs({xmlns:'http://jabber.org/protocol/muc'}).up()
  145. .c('error').attrs({by:'coven@chat.shakespeare.lit', type:'auth'})
  146. .c('registration-required').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
  147. var view = this.chatboxesview.views['problematic@muc.localhost'];
  148. spyOn(converse.connection.muc, 'removeRoom');
  149. spyOn(view, 'renderErrorMessage').andCallThrough();
  150. view.onChatRoomPresence(presence, {'nick': 'dummy'});
  151. expect(converse.connection.muc.removeRoom).toHaveBeenCalled();
  152. expect(view.$el.find('.chat-body p').text()).toBe('You are not on the member list of this room');
  153. }, converse));
  154. it("will show an error message if the user has been banned", $.proxy(function () {
  155. var presence = $pres().attrs({
  156.   from:'coven@chat.shakespeare.lit/thirdwitch',
  157.     id:'n13mt3l',
  158.     to:'hag66@shakespeare.lit/pda',
  159.     type:'error'})
  160. .c('x').attrs({xmlns:'http://jabber.org/protocol/muc'}).up()
  161. .c('error').attrs({by:'coven@chat.shakespeare.lit', type:'auth'})
  162. .c('forbidden').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
  163. var view = this.chatboxesview.views['problematic@muc.localhost'];
  164. spyOn(converse.connection.muc, 'removeRoom');
  165. spyOn(view, 'renderErrorMessage').andCallThrough();
  166. view.onChatRoomPresence(presence, {'nick': 'dummy'});
  167. expect(converse.connection.muc.removeRoom).toHaveBeenCalled();
  168. expect(view.$el.find('.chat-body p').text()).toBe('You have been banned from this room');
  169. }, converse));
  170. it("will show an error message if no nickname was specified for the user", $.proxy(function () {
  171. var presence = $pres().attrs({
  172.   from:'coven@chat.shakespeare.lit/thirdwitch',
  173.     id:'n13mt3l',
  174.     to:'hag66@shakespeare.lit/pda',
  175.     type:'error'})
  176. .c('x').attrs({xmlns:'http://jabber.org/protocol/muc'}).up()
  177. .c('error').attrs({by:'coven@chat.shakespeare.lit', type:'modify'})
  178. .c('jid-malformed').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
  179. var view = this.chatboxesview.views['problematic@muc.localhost'];
  180. spyOn(converse.connection.muc, 'removeRoom');
  181. spyOn(view, 'renderErrorMessage').andCallThrough();
  182. view.onChatRoomPresence(presence, {'nick': 'dummy'});
  183. expect(converse.connection.muc.removeRoom).toHaveBeenCalled();
  184. expect(view.$el.find('.chat-body p').text()).toBe('No nickname was specified');
  185. }, converse));
  186. it("will show an error message if the user is not allowed to have created the room", $.proxy(function () {
  187. var presence = $pres().attrs({
  188.   from:'coven@chat.shakespeare.lit/thirdwitch',
  189.     id:'n13mt3l',
  190.     to:'hag66@shakespeare.lit/pda',
  191.     type:'error'})
  192. .c('x').attrs({xmlns:'http://jabber.org/protocol/muc'}).up()
  193. .c('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
  194. .c('not-allowed').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
  195. var view = this.chatboxesview.views['problematic@muc.localhost'];
  196. spyOn(converse.connection.muc, 'removeRoom');
  197. spyOn(view, 'renderErrorMessage').andCallThrough();
  198. view.onChatRoomPresence(presence, {'nick': 'dummy'});
  199. expect(converse.connection.muc.removeRoom).toHaveBeenCalled();
  200. expect(view.$el.find('.chat-body p').text()).toBe('You are not allowed to create new rooms');
  201. }, converse));
  202. it("will show an error message if the user's nickname doesn't conform to room policy", $.proxy(function () {
  203. var presence = $pres().attrs({
  204.   from:'coven@chat.shakespeare.lit/thirdwitch',
  205.     id:'n13mt3l',
  206.     to:'hag66@shakespeare.lit/pda',
  207.     type:'error'})
  208. .c('x').attrs({xmlns:'http://jabber.org/protocol/muc'}).up()
  209. .c('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
  210. .c('not-acceptable').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
  211. var view = this.chatboxesview.views['problematic@muc.localhost'];
  212. spyOn(converse.connection.muc, 'removeRoom');
  213. spyOn(view, 'renderErrorMessage').andCallThrough();
  214. view.onChatRoomPresence(presence, {'nick': 'dummy'});
  215. expect(converse.connection.muc.removeRoom).toHaveBeenCalled();
  216. expect(view.$el.find('.chat-body p').text()).toBe("Your nickname doesn't conform to this room's policies");
  217. }, converse));
  218. it("will show an error message if the user's nickname is already taken", $.proxy(function () {
  219. var presence = $pres().attrs({
  220.   from:'coven@chat.shakespeare.lit/thirdwitch',
  221.     id:'n13mt3l',
  222.     to:'hag66@shakespeare.lit/pda',
  223.     type:'error'})
  224. .c('x').attrs({xmlns:'http://jabber.org/protocol/muc'}).up()
  225. .c('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
  226. .c('conflict').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
  227. var view = this.chatboxesview.views['problematic@muc.localhost'];
  228. spyOn(converse.connection.muc, 'removeRoom');
  229. spyOn(view, 'renderErrorMessage').andCallThrough();
  230. view.onChatRoomPresence(presence, {'nick': 'dummy'});
  231. expect(converse.connection.muc.removeRoom).toHaveBeenCalled();
  232. expect(view.$el.find('.chat-body p').text()).toBe("Your nickname is already taken");
  233. }, converse));
  234. it("will show an error message if the room doesn't yet exist", $.proxy(function () {
  235. var presence = $pres().attrs({
  236.   from:'coven@chat.shakespeare.lit/thirdwitch',
  237.     id:'n13mt3l',
  238.     to:'hag66@shakespeare.lit/pda',
  239.     type:'error'})
  240. .c('x').attrs({xmlns:'http://jabber.org/protocol/muc'}).up()
  241. .c('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
  242. .c('item-not-found').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
  243. var view = this.chatboxesview.views['problematic@muc.localhost'];
  244. spyOn(converse.connection.muc, 'removeRoom');
  245. spyOn(view, 'renderErrorMessage').andCallThrough();
  246. view.onChatRoomPresence(presence, {'nick': 'dummy'});
  247. expect(converse.connection.muc.removeRoom).toHaveBeenCalled();
  248. expect(view.$el.find('.chat-body p').text()).toBe("This room does not (yet) exist");
  249. }, converse));
  250. it("will show an error message if the room has reached it's maximum number of occupants", $.proxy(function () {
  251. var presence = $pres().attrs({
  252.   from:'coven@chat.shakespeare.lit/thirdwitch',
  253.     id:'n13mt3l',
  254.     to:'hag66@shakespeare.lit/pda',
  255.     type:'error'})
  256. .c('x').attrs({xmlns:'http://jabber.org/protocol/muc'}).up()
  257. .c('error').attrs({by:'coven@chat.shakespeare.lit', type:'cancel'})
  258. .c('service-unavailable').attrs({xmlns:'urn:ietf:params:xml:ns:xmpp-stanzas'}).nodeTree;
  259. var view = this.chatboxesview.views['problematic@muc.localhost'];
  260. spyOn(converse.connection.muc, 'removeRoom');
  261. spyOn(view, 'renderErrorMessage').andCallThrough();
  262. view.onChatRoomPresence(presence, {'nick': 'dummy'});
  263. expect(converse.connection.muc.removeRoom).toHaveBeenCalled();
  264. expect(view.$el.find('.chat-body p').text()).toBe("This room has reached it's maximum number of occupants");
  265. }, converse));
  266. }, converse));
  267. }, converse));
  268. }));