spoilers.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. (function (root, factory) {
  2. define(["jasmine", "mock", "test-utils"], factory);
  3. } (this, function (jasmine, mock, test_utils) {
  4. var _ = converse.env._;
  5. var Strophe = converse.env.Strophe;
  6. var $msg = converse.env.$msg;
  7. var $pres = converse.env.$pres;
  8. var u = converse.env.utils;
  9. return describe("A spoiler message", function () {
  10. it("can be received with a hint",
  11. mock.initConverseWithPromises(
  12. null, ['rosterGroupsFetched'], {},
  13. function (done, _converse) {
  14. test_utils.createContacts(_converse, 'current');
  15. var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
  16. /* <message to='romeo@montague.net/orchard' from='juliet@capulet.net/balcony' id='spoiler2'>
  17. * <body>And at the end of the story, both of them die! It is so tragic!</body>
  18. * <spoiler xmlns='urn:xmpp:spoiler:0'>Love story end</spoiler>
  19. * </message>
  20. */
  21. var spoiler_hint = "Love story end"
  22. var spoiler = "And at the end of the story, both of them die! It is so tragic!";
  23. var msg = $msg({
  24. 'xmlns': 'jabber:client',
  25. 'to': _converse.bare_jid,
  26. 'from': sender_jid,
  27. 'type': 'chat'
  28. }).c('body').t(spoiler).up()
  29. .c('spoiler', {
  30. 'xmlns': 'urn:xmpp:spoiler:0',
  31. }).t(spoiler_hint)
  32. .tree();
  33. _converse.chatboxes.onMessage(msg);
  34. var view = _converse.chatboxviews.get(sender_jid);
  35. return test_utils.waitUntil(() => view.model.vcard.get('fullname') === 'Max Frankfurter')
  36. .then(function () {
  37. expect(view.el.querySelector('.chat-msg__author').textContent.trim()).toBe('Max Frankfurter');
  38. var message_content = view.el.querySelector('.chat-msg__text');
  39. expect(message_content.textContent).toBe(spoiler);
  40. var spoiler_hint_el = view.el.querySelector('.spoiler-hint');
  41. expect(spoiler_hint_el.textContent).toBe(spoiler_hint);
  42. done();
  43. });
  44. }));
  45. it("can be received without a hint",
  46. mock.initConverseWithPromises(
  47. null, ['rosterGroupsFetched'], {},
  48. function (done, _converse) {
  49. test_utils.createContacts(_converse, 'current');
  50. var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
  51. /* <message to='romeo@montague.net/orchard' from='juliet@capulet.net/balcony' id='spoiler2'>
  52. * <body>And at the end of the story, both of them die! It is so tragic!</body>
  53. * <spoiler xmlns='urn:xmpp:spoiler:0'>Love story end</spoiler>
  54. * </message>
  55. */
  56. var spoiler = "And at the end of the story, both of them die! It is so tragic!";
  57. var msg = $msg({
  58. 'xmlns': 'jabber:client',
  59. 'to': _converse.bare_jid,
  60. 'from': sender_jid,
  61. 'type': 'chat'
  62. }).c('body').t(spoiler).up()
  63. .c('spoiler', {
  64. 'xmlns': 'urn:xmpp:spoiler:0',
  65. }).tree();
  66. _converse.chatboxes.onMessage(msg);
  67. var view = _converse.chatboxviews.get(sender_jid);
  68. return test_utils.waitUntil(() => view.model.vcard.get('fullname') === 'Max Frankfurter')
  69. .then(function () {
  70. expect(_.includes(view.el.querySelector('.chat-msg__author').textContent, 'Max Frankfurter')).toBeTruthy();
  71. var message_content = view.el.querySelector('.chat-msg__text');
  72. expect(message_content.textContent).toBe(spoiler);
  73. var spoiler_hint_el = view.el.querySelector('.spoiler-hint');
  74. expect(spoiler_hint_el.textContent).toBe('');
  75. done();
  76. }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
  77. }));
  78. it("can be sent without a hint",
  79. mock.initConverseWithPromises(
  80. null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
  81. function (done, _converse) {
  82. test_utils.createContacts(_converse, 'current', 1);
  83. _converse.emit('rosterContactsFetched');
  84. test_utils.openControlBox();
  85. const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
  86. // XXX: We need to send a presence from the contact, so that we
  87. // have a resource, that resource is then queried to see
  88. // whether Strophe.NS.SPOILER is supported, in which case
  89. // the spoiler button will appear.
  90. var presence = $pres({
  91. 'from': contact_jid+'/phone',
  92. 'to': 'dummy@localhost'
  93. });
  94. _converse.connection._dataRecv(test_utils.createRequest(presence));
  95. test_utils.openChatBoxFor(_converse, contact_jid)
  96. .then(() => test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]))
  97. .then(() => {
  98. var view = _converse.chatboxviews.get(contact_jid);
  99. spyOn(view, 'onMessageSubmitted').and.callThrough();
  100. spyOn(_converse.connection, 'send');
  101. var spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
  102. spoiler_toggle.click();
  103. var textarea = view.el.querySelector('.chat-textarea');
  104. textarea.value = 'This is the spoiler';
  105. view.keyPressed({
  106. target: textarea,
  107. preventDefault: _.noop,
  108. keyCode: 13
  109. });
  110. expect(view.onMessageSubmitted).toHaveBeenCalled();
  111. /* Test the XML stanza
  112. *
  113. * <message from="dummy@localhost/resource"
  114. * to="max.frankfurter@localhost"
  115. * type="chat"
  116. * id="4547c38b-d98b-45a5-8f44-b4004dbc335e"
  117. * xmlns="jabber:client">
  118. * <body>This is the spoiler</body>
  119. * <active xmlns="http://jabber.org/protocol/chatstates"/>
  120. * <spoiler xmlns="urn:xmpp:spoiler:0"/>
  121. * </message>"
  122. */
  123. var stanza = _converse.connection.send.calls.argsFor(0)[0].tree();
  124. var spoiler_el = stanza.querySelector('spoiler[xmlns="urn:xmpp:spoiler:0"]');
  125. expect(_.isNull(spoiler_el)).toBeFalsy();
  126. expect(spoiler_el.textContent).toBe('');
  127. var body_el = stanza.querySelector('body');
  128. expect(body_el.textContent).toBe('This is the spoiler');
  129. /* Test the HTML spoiler message */
  130. expect(view.el.querySelector('.chat-msg__author').textContent.trim()).toBe('Max Mustermann');
  131. var spoiler_msg_el = view.el.querySelector('.chat-msg__text.spoiler');
  132. expect(spoiler_msg_el.textContent).toBe('This is the spoiler');
  133. expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeTruthy();
  134. spoiler_toggle = view.el.querySelector('.spoiler-toggle');
  135. expect(spoiler_toggle.textContent).toBe('Show more');
  136. spoiler_toggle.click();
  137. expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeFalsy();
  138. expect(spoiler_toggle.textContent).toBe('Show less');
  139. spoiler_toggle.click();
  140. expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeTruthy();
  141. done();
  142. }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
  143. }));
  144. it("can be sent with a hint",
  145. mock.initConverseWithPromises(
  146. null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
  147. function (done, _converse) {
  148. test_utils.createContacts(_converse, 'current', 1);
  149. _converse.emit('rosterContactsFetched');
  150. test_utils.openControlBox();
  151. var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
  152. // XXX: We need to send a presence from the contact, so that we
  153. // have a resource, that resource is then queried to see
  154. // whether Strophe.NS.SPOILER is supported, in which case
  155. // the spoiler button will appear.
  156. var presence = $pres({
  157. 'from': contact_jid+'/phone',
  158. 'to': 'dummy@localhost'
  159. });
  160. _converse.connection._dataRecv(test_utils.createRequest(presence));
  161. test_utils.openChatBoxFor(_converse, contact_jid)
  162. .then(() => test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]))
  163. .then(() => {
  164. var view = _converse.chatboxviews.get(contact_jid);
  165. var spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
  166. spoiler_toggle.click();
  167. spyOn(view, 'onMessageSubmitted').and.callThrough();
  168. spyOn(_converse.connection, 'send');
  169. var textarea = view.el.querySelector('.chat-textarea');
  170. textarea.value = 'This is the spoiler';
  171. var hint_input = view.el.querySelector('.spoiler-hint');
  172. hint_input.value = 'This is the hint';
  173. view.keyPressed({
  174. target: textarea,
  175. preventDefault: _.noop,
  176. keyCode: 13
  177. });
  178. expect(view.onMessageSubmitted).toHaveBeenCalled();
  179. /* Test the XML stanza
  180. *
  181. * <message from="dummy@localhost/resource"
  182. * to="max.frankfurter@localhost"
  183. * type="chat"
  184. * id="4547c38b-d98b-45a5-8f44-b4004dbc335e"
  185. * xmlns="jabber:client">
  186. * <body>This is the spoiler</body>
  187. * <active xmlns="http://jabber.org/protocol/chatstates"/>
  188. * <spoiler xmlns="urn:xmpp:spoiler:0">This is the hint</spoiler>
  189. * </message>"
  190. */
  191. var stanza = _converse.connection.send.calls.argsFor(0)[0].tree();
  192. var spoiler_el = stanza.querySelector('spoiler[xmlns="urn:xmpp:spoiler:0"]');
  193. expect(_.isNull(spoiler_el)).toBeFalsy();
  194. expect(spoiler_el.textContent).toBe('This is the hint');
  195. var body_el = stanza.querySelector('body');
  196. expect(body_el.textContent).toBe('This is the spoiler');
  197. /* Test the HTML spoiler message */
  198. expect(view.el.querySelector('.chat-msg__author').textContent.trim()).toBe('Max Mustermann');
  199. var spoiler_msg_el = view.el.querySelector('.chat-msg__text.spoiler');
  200. expect(spoiler_msg_el.textContent).toBe('This is the spoiler');
  201. expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeTruthy();
  202. spoiler_toggle = view.el.querySelector('.spoiler-toggle');
  203. expect(spoiler_toggle.textContent).toBe('Show more');
  204. spoiler_toggle.click();
  205. expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeFalsy();
  206. expect(spoiler_toggle.textContent).toBe('Show less');
  207. spoiler_toggle.click();
  208. expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeTruthy();
  209. done();
  210. });
  211. }));
  212. });
  213. }));