ChatRoomSpec.js 15 KB

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