ChatRoomSpec.js 15 KB

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