ChatRoomSpec.js 15 KB

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