roomslist.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. (function (root, factory) {
  2. define(["jasmine", "mock", "test-utils"], factory);
  3. } (this, function (jasmine, mock, test_utils) {
  4. var _ = converse.env._;
  5. var $msg = converse.env.$msg;
  6. var $iq = converse.env.$iq;
  7. var $pres = converse.env.$pres;
  8. var Promise = converse.env.Promise;
  9. var Strophe = converse.env.Strophe;
  10. var u = converse.env.utils;
  11. describe("A list of open rooms", function () {
  12. it("is shown in the \"Rooms\" panel", mock.initConverseWithPromises(
  13. null, ['rosterGroupsFetched'],
  14. { allow_bookmarks: false // Makes testing easier, otherwise we
  15. // have to mock stanza traffic.
  16. },
  17. function (done, _converse) {
  18. test_utils.openControlBox();
  19. var controlbox = _converse.chatboxviews.get('controlbox');
  20. var list = controlbox.el.querySelector('div.rooms-list-container');
  21. expect(_.includes(list.classList, 'hidden')).toBeTruthy();
  22. test_utils.openChatRoom(_converse, 'room', 'conference.shakespeare.lit', 'JC');
  23. expect(_.isUndefined(_converse.rooms_list_view)).toBeFalsy();
  24. var room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
  25. expect(room_els.length).toBe(1);
  26. expect(room_els[0].innerText).toBe('room@conference.shakespeare.lit');
  27. test_utils.openChatRoom(_converse, 'lounge', 'localhost', 'dummy');
  28. room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
  29. expect(room_els.length).toBe(2);
  30. var view = _converse.chatboxviews.get('room@conference.shakespeare.lit');
  31. view.close();
  32. room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
  33. expect(room_els.length).toBe(1);
  34. expect(room_els[0].innerText).toBe('lounge@localhost');
  35. list = controlbox.el.querySelector('div.rooms-list-container');
  36. expect(_.includes(list.classList, 'hidden')).toBeFalsy();
  37. view = _converse.chatboxviews.get('lounge@localhost');
  38. view.close();
  39. room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
  40. expect(room_els.length).toBe(0);
  41. list = controlbox.el.querySelector('div.rooms-list-container');
  42. expect(_.includes(list.classList, 'hidden')).toBeTruthy();
  43. done();
  44. }
  45. ));
  46. });
  47. describe("A room shown in the rooms list", function () {
  48. it("has an info icon which opens a details modal when clicked", mock.initConverseWithPromises(
  49. null, ['rosterGroupsFetched'],
  50. { whitelisted_plugins: ['converse-roomslist'],
  51. allow_bookmarks: false // Makes testing easier, otherwise we
  52. // have to mock stanza traffic.
  53. }, function (done, _converse) {
  54. test_utils.openControlBox();
  55. _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'});
  56. const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
  57. const last_stanza = _.last(_converse.connection.IQ_stanzas).nodeTree;
  58. const IQ_id = last_stanza.getAttribute('id');
  59. const features_stanza = $iq({
  60. 'from': 'coven@chat.shakespeare.lit',
  61. 'id': IQ_id,
  62. 'to': 'dummy@localhost/desktop',
  63. 'type': 'result'
  64. })
  65. .c('query', { 'xmlns': 'http://jabber.org/protocol/disco#info'})
  66. .c('identity', {
  67. 'category': 'conference',
  68. 'name': 'A Dark Cave',
  69. 'type': 'text'
  70. }).up()
  71. .c('feature', {'var': 'http://jabber.org/protocol/muc'}).up()
  72. .c('feature', {'var': 'muc_passwordprotected'}).up()
  73. .c('feature', {'var': 'muc_hidden'}).up()
  74. .c('feature', {'var': 'muc_temporary'}).up()
  75. .c('feature', {'var': 'muc_open'}).up()
  76. .c('feature', {'var': 'muc_unmoderated'}).up()
  77. .c('feature', {'var': 'muc_nonanonymous'}).up()
  78. .c('feature', {'var': 'urn:xmpp:mam:0'}).up()
  79. .c('x', { 'xmlns':'jabber:x:data', 'type':'result'})
  80. .c('field', {'var':'FORM_TYPE', 'type':'hidden'})
  81. .c('value').t('http://jabber.org/protocol/muc#roominfo').up().up()
  82. .c('field', {'type':'text-single', 'var':'muc#roominfo_description', 'label':'Description'})
  83. .c('value').t('This is the description').up().up()
  84. .c('field', {'type':'text-single', 'var':'muc#roominfo_occupants', 'label':'Number of occupants'})
  85. .c('value').t(0);
  86. _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
  87. test_utils.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING)
  88. .then(function () {
  89. var presence = $pres({
  90. to: _converse.connection.jid,
  91. from: 'coven@chat.shakespeare.lit/some1',
  92. id: 'DC352437-C019-40EC-B590-AF29E879AF97'
  93. }).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
  94. .c('item').attrs({
  95. affiliation: 'member',
  96. jid: _converse.bare_jid,
  97. role: 'participant'
  98. }).up()
  99. .c('status').attrs({code:'110'});
  100. _converse.connection._dataRecv(test_utils.createRequest(presence));
  101. const room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
  102. expect(room_els.length).toBe(1);
  103. var info_el = _converse.rooms_list_view.el.querySelector(".room-info");
  104. info_el.click();
  105. const modal = view.model.room_details_modal;
  106. return test_utils.waitUntil(() => u.isVisible(modal.el), 2000);
  107. }).then(() => {
  108. const modal = view.model.room_details_modal;
  109. let els = modal.el.querySelectorAll('p.room-info');
  110. expect(els[0].textContent).toBe("Room address (JID): coven@chat.shakespeare.lit")
  111. expect(els[1].textContent).toBe("Name: A Dark Cave")
  112. expect(els[2].textContent).toBe("Description: This is the description")
  113. expect(els[3].textContent).toBe("Online users: 1")
  114. const features_list = modal.el.querySelector('.features-list');
  115. expect(features_list.textContent.replace(/(\n|\s{2,})/g, '')).toBe(
  116. 'Password protected - This room requires a password before entry'+
  117. 'Hidden - This room is not publicly searchable'+
  118. 'Open - Anyone can join this room'+
  119. 'Temporary - This room will disappear once the last person leaves'+
  120. 'Not anonymous - All other room occupants can see your XMPP username'+
  121. 'Not moderated - This room is not being moderated'
  122. );
  123. const presence = $pres({
  124. to: 'dummy@localhost/_converse.js-29092160',
  125. from: 'coven@chat.shakespeare.lit/newguy'
  126. })
  127. .c('x', {xmlns: Strophe.NS.MUC_USER})
  128. .c('item', {
  129. 'affiliation': 'none',
  130. 'jid': 'newguy@localhost/_converse.js-290929789',
  131. 'role': 'participant'
  132. });
  133. _converse.connection._dataRecv(test_utils.createRequest(presence));
  134. els = modal.el.querySelectorAll('p.room-info');
  135. expect(els[3].textContent).toBe("Online users: 2")
  136. done();
  137. });
  138. }));
  139. it("can be closed", mock.initConverseWithPromises(
  140. null, ['rosterGroupsFetched'],
  141. { whitelisted_plugins: ['converse-roomslist'],
  142. allow_bookmarks: false // Makes testing easier, otherwise we
  143. // have to mock stanza traffic.
  144. },
  145. function (done, _converse) {
  146. spyOn(window, 'confirm').and.callFake(function () {
  147. return true;
  148. });
  149. expect(_converse.chatboxes.length).toBe(1);
  150. test_utils.openChatRoom(
  151. _converse, 'lounge', 'conference.shakespeare.lit', 'JC');
  152. expect(_converse.chatboxes.length).toBe(2);
  153. var room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
  154. expect(room_els.length).toBe(1);
  155. var close_el = _converse.rooms_list_view.el.querySelector(".close-room");
  156. close_el.click();
  157. expect(window.confirm).toHaveBeenCalledWith(
  158. 'Are you sure you want to leave the room lounge@conference.shakespeare.lit?');
  159. room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
  160. expect(room_els.length).toBe(0);
  161. expect(_converse.chatboxes.length).toBe(1);
  162. done();
  163. }));
  164. it("shows unread messages directed at the user", mock.initConverseWithAsync(
  165. { whitelisted_plugins: ['converse-roomslist'],
  166. allow_bookmarks: false // Makes testing easier, otherwise we
  167. // have to mock stanza traffic.
  168. }, function (done, _converse) {
  169. test_utils.waitUntil(function () {
  170. return !_.isUndefined(_converse.rooms_list_view)
  171. }, 500)
  172. .then(function () {
  173. var room_jid = 'kitchen@conference.shakespeare.lit';
  174. test_utils.openAndEnterChatRoom(
  175. _converse, 'kitchen', 'conference.shakespeare.lit', 'romeo').then(function () {
  176. var view = _converse.chatboxviews.get(room_jid);
  177. view.model.set({'minimized': true});
  178. var contact_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost';
  179. var nick = mock.chatroom_names[0];
  180. view.model.onMessage(
  181. $msg({
  182. from: room_jid+'/'+nick,
  183. id: (new Date()).getTime(),
  184. to: 'dummy@localhost',
  185. type: 'groupchat'
  186. }).c('body').t('foo').tree());
  187. // If the user isn't mentioned, the counter doesn't get incremented, but the text of the room is bold
  188. var room_el = _converse.rooms_list_view.el.querySelector(
  189. ".available-chatroom"
  190. );
  191. expect(_.includes(room_el.classList, 'unread-msgs'));
  192. // If the user is mentioned, the counter also gets updated
  193. view.model.onMessage(
  194. $msg({
  195. from: room_jid+'/'+nick,
  196. id: (new Date()).getTime(),
  197. to: 'dummy@localhost',
  198. type: 'groupchat'
  199. }).c('body').t('romeo: Your attention is required').tree()
  200. );
  201. var indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator");
  202. expect(indicator_el.textContent).toBe('1');
  203. view.model.onMessage(
  204. $msg({
  205. from: room_jid+'/'+nick,
  206. id: (new Date()).getTime(),
  207. to: 'dummy@localhost',
  208. type: 'groupchat'
  209. }).c('body').t('romeo: and another thing...').tree()
  210. );
  211. indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator");
  212. expect(indicator_el.textContent).toBe('2');
  213. // When the chat gets maximized again, the unread indicators are removed
  214. view.model.set({'minimized': false});
  215. indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator");
  216. expect(_.isNull(indicator_el));
  217. room_el = _converse.rooms_list_view.el.querySelector(".available-chatroom");
  218. expect(_.includes(room_el.classList, 'unread-msgs')).toBeFalsy();
  219. done();
  220. });
  221. });
  222. }));
  223. });
  224. }));