ChatRoomSpec.js 15 KB

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