modtools.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. (function (root, factory) {
  2. define(["jasmine", "mock", "test-utils" ], factory);
  3. } (this, function (jasmine, mock, test_utils) {
  4. const _ = converse.env._;
  5. const $iq = converse.env.$iq;
  6. const sizzle = converse.env.sizzle;
  7. const Strophe = converse.env.Strophe;
  8. const u = converse.env.utils;
  9. describe("The groupchat moderator tool", function () {
  10. it("allows you to set affiliations and roles",
  11. mock.initConverse(
  12. ['rosterGroupsFetched'], {},
  13. async function (done, _converse) {
  14. spyOn(_converse.ChatRoomView.prototype, 'showModeratorToolsModal').and.callThrough();
  15. const muc_jid = 'lounge@montague.lit';
  16. let members = [
  17. {'jid': 'hag66@shakespeare.lit', 'nick': 'witch', 'affiliation': 'member'},
  18. {'jid': 'gower@shakespeare.lit', 'nick': 'gower', 'affiliation': 'member'},
  19. {'jid': 'wiccarocks@shakespeare.lit', 'nick': 'wiccan', 'affiliation': 'admin'},
  20. {'jid': 'crone1@shakespeare.lit', 'nick': 'thirdwitch', 'affiliation': 'owner'},
  21. {'jid': 'romeo@montague.lit', 'nick': 'romeo', 'affiliation': 'owner'},
  22. ];
  23. await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo', [], members);
  24. const view = _converse.chatboxviews.get(muc_jid);
  25. await u.waitUntil(() => (view.model.occupants.length === 5), 1000);
  26. const textarea = view.el.querySelector('.chat-textarea');
  27. textarea.value = '/modtools';
  28. const enter = { 'target': textarea, 'preventDefault': function preventDefault () {}, 'keyCode': 13 };
  29. view.onKeyDown(enter);
  30. await u.waitUntil(() => view.showModeratorToolsModal.calls.count());
  31. const modal = view.modtools_modal;
  32. await u.waitUntil(() => u.isVisible(modal.el), 1000);
  33. let tab = modal.el.querySelector('#affiliations-tab');
  34. // Clear so that we don't match older stanzas
  35. _converse.connection.IQ_stanzas = [];
  36. tab.click();
  37. let select = modal.el.querySelector('.select-affiliation');
  38. expect(select.value).toBe('owner');
  39. select.value = 'admin';
  40. let button = modal.el.querySelector('.btn-primary[name="users_with_affiliation"]');
  41. button.click();
  42. await u.waitUntil(() => !modal.loading_users_with_affiliation);
  43. let user_els = modal.el.querySelectorAll('.list-group--users > li');
  44. expect(user_els.length).toBe(1);
  45. expect(user_els[0].querySelector('.list-group-item.active').textContent.trim()).toBe('JID: wiccarocks@shakespeare.lit');
  46. expect(user_els[0].querySelector('.list-group-item:nth-child(2n)').textContent.trim()).toBe('Nickname: wiccan');
  47. expect(user_els[0].querySelector('.list-group-item:nth-child(3n) div').textContent.trim()).toBe('Affiliation: admin');
  48. _converse.connection.IQ_stanzas = [];
  49. select.value = 'owner';
  50. button.click();
  51. await u.waitUntil(() => !modal.loading_users_with_affiliation);
  52. user_els = modal.el.querySelectorAll('.list-group--users > li');
  53. expect(user_els.length).toBe(2);
  54. expect(user_els[0].querySelector('.list-group-item.active').textContent.trim()).toBe('JID: romeo@montague.lit');
  55. expect(user_els[0].querySelector('.list-group-item:nth-child(2n)').textContent.trim()).toBe('Nickname: romeo');
  56. expect(user_els[0].querySelector('.list-group-item:nth-child(3n) div').textContent.trim()).toBe('Affiliation: owner');
  57. expect(user_els[1].querySelector('.list-group-item.active').textContent.trim()).toBe('JID: crone1@shakespeare.lit');
  58. expect(user_els[1].querySelector('.list-group-item:nth-child(2n)').textContent.trim()).toBe('Nickname: thirdwitch');
  59. expect(user_els[1].querySelector('.list-group-item:nth-child(3n) div').textContent.trim()).toBe('Affiliation: owner');
  60. const toggle = user_els[1].querySelector('.list-group-item:nth-child(3n) .toggle-form');
  61. const form = user_els[1].querySelector('.list-group-item:nth-child(3n) .affiliation-form');
  62. expect(u.hasClass('hidden', form)).toBeTruthy();
  63. toggle.click();
  64. expect(u.hasClass('hidden', form)).toBeFalsy();
  65. select = form.querySelector('.select-affiliation');
  66. expect(select.value).toBe('owner');
  67. select.value = 'admin';
  68. const input = form.querySelector('input[name="reason"]');
  69. input.value = "You're an admin now";
  70. const submit = form.querySelector('.btn-primary');
  71. submit.click();
  72. spyOn(_converse.ChatRoomOccupants.prototype, 'fetchMembers').and.callThrough();
  73. const sent_IQ = _converse.connection.IQ_stanzas.pop();
  74. expect(Strophe.serialize(sent_IQ)).toBe(
  75. `<iq id="${sent_IQ.getAttribute('id')}" to="lounge@montague.lit" type="set" xmlns="jabber:client">`+
  76. `<query xmlns="http://jabber.org/protocol/muc#admin">`+
  77. `<item affiliation="admin" jid="crone1@shakespeare.lit">`+
  78. `<reason>You&apos;re an admin now</reason>`+
  79. `</item>`+
  80. `</query>`+
  81. `</iq>`);
  82. _converse.connection.IQ_stanzas = [];
  83. const stanza = $iq({
  84. 'type': 'result',
  85. 'id': sent_IQ.getAttribute('id'),
  86. 'from': view.model.get('jid'),
  87. 'to': _converse.connection.jid
  88. });
  89. _converse.connection._dataRecv(test_utils.createRequest(stanza));
  90. await u.waitUntil(() => view.model.occupants.fetchMembers.calls.count());
  91. members = [
  92. {'jid': 'hag66@shakespeare.lit', 'nick': 'witch', 'affiliation': 'member'},
  93. {'jid': 'gower@shakespeare.lit', 'nick': 'gower', 'affiliation': 'member'},
  94. {'jid': 'wiccarocks@shakespeare.lit', 'nick': 'wiccan', 'affiliation': 'admin'},
  95. {'jid': 'crone1@shakespeare.lit', 'nick': 'thirdwitch', 'affiliation': 'admin'},
  96. {'jid': 'romeo@montague.lit', 'nick': 'romeo', 'affiliation': 'owner'},
  97. ];
  98. await test_utils.returnMemberLists(_converse, muc_jid, members);
  99. await u.waitUntil(() => view.model.occupants.pluck('affiliation').filter(o => o === 'owner').length === 1);
  100. const alert = modal.el.querySelector('.alert-primary');
  101. expect(alert.textContent.trim()).toBe('Affiliation changed');
  102. user_els = modal.el.querySelectorAll('.list-group--users > li');
  103. expect(user_els.length).toBe(1);
  104. expect(user_els[0].querySelector('.list-group-item.active').textContent.trim()).toBe('JID: romeo@montague.lit');
  105. expect(user_els[0].querySelector('.list-group-item:nth-child(2n)').textContent.trim()).toBe('Nickname: romeo');
  106. expect(user_els[0].querySelector('.list-group-item:nth-child(3n) div').textContent.trim()).toBe('Affiliation: owner');
  107. tab = modal.el.querySelector('#roles-tab');
  108. tab.click();
  109. select = modal.el.querySelector('.select-role');
  110. expect(u.isVisible(select)).toBe(true);
  111. expect(select.value).toBe('moderator');
  112. button = modal.el.querySelector('.btn-primary[name="users_with_role"]');
  113. button.click();
  114. const roles_panel = modal.el.querySelector('#roles-tabpanel');
  115. await u.waitUntil(() => roles_panel.querySelectorAll('.list-group--users > li').length === 1);
  116. select.value = 'participant';
  117. button.click();
  118. await u.waitUntil(() => !modal.loading_users_with_affiliation);
  119. user_els = roles_panel.querySelectorAll('.list-group--users > li')
  120. expect(user_els.length).toBe(1);
  121. expect(user_els[0].textContent.trim()).toBe('No users with that role found.');
  122. done();
  123. }));
  124. it("shows an error message if a particular affiliation list may not be retrieved",
  125. mock.initConverse(
  126. ['rosterGroupsFetched'], {},
  127. async function (done, _converse) {
  128. spyOn(_converse.ChatRoomView.prototype, 'showModeratorToolsModal').and.callThrough();
  129. const muc_jid = 'lounge@montague.lit';
  130. const members = [
  131. {'jid': 'hag66@shakespeare.lit', 'nick': 'witch', 'affiliation': 'member'},
  132. {'jid': 'gower@shakespeare.lit', 'nick': 'gower', 'affiliation': 'member'},
  133. {'jid': 'wiccarocks@shakespeare.lit', 'nick': 'wiccan', 'affiliation': 'admin'},
  134. {'jid': 'crone1@shakespeare.lit', 'nick': 'thirdwitch', 'affiliation': 'owner'},
  135. {'jid': 'romeo@montague.lit', 'nick': 'romeo', 'affiliation': 'owner'},
  136. ];
  137. await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo', [], members);
  138. const view = _converse.chatboxviews.get(muc_jid);
  139. await u.waitUntil(() => (view.model.occupants.length === 5));
  140. const textarea = view.el.querySelector('.chat-textarea');
  141. textarea.value = '/modtools';
  142. const enter = { 'target': textarea, 'preventDefault': function preventDefault () {}, 'keyCode': 13 };
  143. view.onKeyDown(enter);
  144. await u.waitUntil(() => view.showModeratorToolsModal.calls.count());
  145. const modal = view.modtools_modal;
  146. await u.waitUntil(() => u.isVisible(modal.el), 1000);
  147. const tab = modal.el.querySelector('#affiliations-tab');
  148. // Clear so that we don't match older stanzas
  149. _converse.connection.IQ_stanzas = [];
  150. const IQ_stanzas = _converse.connection.IQ_stanzas;
  151. tab.click();
  152. const select = modal.el.querySelector('.select-affiliation');
  153. select.value = 'outcast';
  154. const button = modal.el.querySelector('.btn-primary[name="users_with_affiliation"]');
  155. button.click();
  156. const iq_query = await u.waitUntil(() => _.filter(
  157. IQ_stanzas,
  158. s => sizzle(`iq[to="${muc_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="outcast"]`, s).length
  159. ).pop());
  160. const error = u.toStanza(
  161. `<iq from="${muc_jid}"
  162. id="${iq_query.getAttribute('id')}"
  163. type="error"
  164. to="${_converse.jid}">
  165. <error type="auth">
  166. <forbidden xmlns="${Strophe.NS.STANZAS}"/>
  167. </error>
  168. </iq>`);
  169. _converse.connection._dataRecv(test_utils.createRequest(error));
  170. await u.waitUntil(() => !modal.loading_users_with_affiliation);
  171. const user_els = modal.el.querySelectorAll('.list-group--users > li');
  172. expect(user_els.length).toBe(1);
  173. expect(user_els[0].textContent.trim()).toBe('Error: not allowed to fetch outcast list for MUC lounge@montague.lit');
  174. done();
  175. }));
  176. });
  177. }));