autocomplete.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. (function (root, factory) {
  2. define([
  3. "jasmine",
  4. "mock",
  5. "test-utils"
  6. ], factory);
  7. } (this, function (jasmine, mock, test_utils) {
  8. "use strict";
  9. const _ = converse.env._;
  10. const $iq = converse.env.$iq;
  11. const $msg = converse.env.$msg;
  12. const $pres = converse.env.$pres;
  13. const Strophe = converse.env.Strophe;
  14. const u = converse.env.utils;
  15. describe("The nickname autocomplete feature", function () {
  16. it("shows all autocompletion options when the user presses @",
  17. mock.initConverse(
  18. null, ['rosterGroupsFetched'], {},
  19. async function (done, _converse) {
  20. await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'montague.lit', 'tom');
  21. const view = _converse.chatboxviews.get('lounge@montague.lit');
  22. ['dick', 'harry'].forEach((nick) => {
  23. _converse.connection._dataRecv(test_utils.createRequest(
  24. $pres({
  25. 'to': 'tom@montague.lit/resource',
  26. 'from': `lounge@montague.lit/${nick}`
  27. })
  28. .c('x', {xmlns: Strophe.NS.MUC_USER})
  29. .c('item', {
  30. 'affiliation': 'none',
  31. 'jid': `${nick}@montague.lit/resource`,
  32. 'role': 'participant'
  33. })));
  34. });
  35. // Test that pressing @ brings up all options
  36. const textarea = view.el.querySelector('textarea.chat-textarea');
  37. const at_event = {
  38. 'target': textarea,
  39. 'preventDefault': _.noop,
  40. 'stopPropagation': _.noop,
  41. 'keyCode': 50,
  42. 'key': '@'
  43. };
  44. view.onKeyDown(at_event);
  45. textarea.value = '@';
  46. view.onKeyUp(at_event);
  47. expect(view.el.querySelectorAll('.suggestion-box__results li').length).toBe(3);
  48. expect(view.el.querySelector('.suggestion-box__results li:first-child').textContent).toBe('dick');
  49. expect(view.el.querySelector('.suggestion-box__results li:nth-child(2)').textContent).toBe('harry');
  50. expect(view.el.querySelector('.suggestion-box__results li:nth-child(3)').textContent).toBe('tom');
  51. done();
  52. }));
  53. it("autocompletes when the user presses tab",
  54. mock.initConverse(
  55. null, ['rosterGroupsFetched'], {},
  56. async function (done, _converse) {
  57. await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'montague.lit', 'romeo');
  58. const view = _converse.chatboxviews.get('lounge@montague.lit');
  59. expect(view.model.occupants.length).toBe(1);
  60. let presence = $pres({
  61. 'to': 'romeo@montague.lit/orchard',
  62. 'from': 'lounge@montague.lit/some1'
  63. })
  64. .c('x', {xmlns: Strophe.NS.MUC_USER})
  65. .c('item', {
  66. 'affiliation': 'none',
  67. 'jid': 'some1@montague.lit/resource',
  68. 'role': 'participant'
  69. });
  70. _converse.connection._dataRecv(test_utils.createRequest(presence));
  71. expect(view.model.occupants.length).toBe(2);
  72. const textarea = view.el.querySelector('textarea.chat-textarea');
  73. textarea.value = "hello som";
  74. // Press tab
  75. const tab_event = {
  76. 'target': textarea,
  77. 'preventDefault': _.noop,
  78. 'stopPropagation': _.noop,
  79. 'keyCode': 9,
  80. 'key': 'Tab'
  81. }
  82. view.onKeyDown(tab_event);
  83. view.onKeyUp(tab_event);
  84. expect(view.el.querySelector('.suggestion-box__results').hidden).toBeFalsy();
  85. expect(view.el.querySelectorAll('.suggestion-box__results li').length).toBe(1);
  86. expect(view.el.querySelector('.suggestion-box__results li').textContent).toBe('some1');
  87. const backspace_event = {
  88. 'target': textarea,
  89. 'preventDefault': _.noop,
  90. 'keyCode': 8
  91. }
  92. for (var i=0; i<3; i++) {
  93. // Press backspace 3 times to remove "som"
  94. view.onKeyDown(backspace_event);
  95. textarea.value = textarea.value.slice(0, textarea.value.length-1)
  96. view.onKeyUp(backspace_event);
  97. }
  98. expect(view.el.querySelector('.suggestion-box__results').hidden).toBeTruthy();
  99. presence = $pres({
  100. 'to': 'romeo@montague.lit/orchard',
  101. 'from': 'lounge@montague.lit/some2'
  102. })
  103. .c('x', {xmlns: Strophe.NS.MUC_USER})
  104. .c('item', {
  105. 'affiliation': 'none',
  106. 'jid': 'some2@montague.lit/resource',
  107. 'role': 'participant'
  108. });
  109. _converse.connection._dataRecv(test_utils.createRequest(presence));
  110. textarea.value = "hello s s";
  111. view.onKeyDown(tab_event);
  112. view.onKeyUp(tab_event);
  113. expect(view.el.querySelector('.suggestion-box__results').hidden).toBeFalsy();
  114. expect(view.el.querySelectorAll('.suggestion-box__results li').length).toBe(2);
  115. const up_arrow_event = {
  116. 'target': textarea,
  117. 'preventDefault': () => (up_arrow_event.defaultPrevented = true),
  118. 'stopPropagation': _.noop,
  119. 'keyCode': 38
  120. }
  121. view.onKeyDown(up_arrow_event);
  122. view.onKeyUp(up_arrow_event);
  123. expect(view.el.querySelectorAll('.suggestion-box__results li').length).toBe(2);
  124. expect(view.el.querySelector('.suggestion-box__results li[aria-selected="false"]').textContent).toBe('some1');
  125. expect(view.el.querySelector('.suggestion-box__results li[aria-selected="true"]').textContent).toBe('some2');
  126. view.onKeyDown({
  127. 'target': textarea,
  128. 'preventDefault': _.noop,
  129. 'stopPropagation': _.noop,
  130. 'keyCode': 13 // Enter
  131. });
  132. expect(textarea.value).toBe('hello s @some2 ');
  133. // Test that pressing tab twice selects
  134. presence = $pres({
  135. 'to': 'romeo@montague.lit/orchard',
  136. 'from': 'lounge@montague.lit/z3r0'
  137. })
  138. .c('x', {xmlns: Strophe.NS.MUC_USER})
  139. .c('item', {
  140. 'affiliation': 'none',
  141. 'jid': 'z3r0@montague.lit/resource',
  142. 'role': 'participant'
  143. });
  144. _converse.connection._dataRecv(test_utils.createRequest(presence));
  145. textarea.value = "hello z";
  146. view.onKeyDown(tab_event);
  147. view.onKeyUp(tab_event);
  148. view.onKeyDown(tab_event);
  149. view.onKeyUp(tab_event);
  150. expect(textarea.value).toBe('hello @z3r0 ');
  151. done();
  152. }));
  153. it("autocompletes when the user presses backspace",
  154. mock.initConverse(
  155. null, ['rosterGroupsFetched'], {},
  156. async function (done, _converse) {
  157. await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'montague.lit', 'romeo');
  158. const view = _converse.chatboxviews.get('lounge@montague.lit');
  159. expect(view.model.occupants.length).toBe(1);
  160. const presence = $pres({
  161. 'to': 'romeo@montague.lit/orchard',
  162. 'from': 'lounge@montague.lit/some1'
  163. })
  164. .c('x', {xmlns: Strophe.NS.MUC_USER})
  165. .c('item', {
  166. 'affiliation': 'none',
  167. 'jid': 'some1@montague.lit/resource',
  168. 'role': 'participant'
  169. });
  170. _converse.connection._dataRecv(test_utils.createRequest(presence));
  171. expect(view.model.occupants.length).toBe(2);
  172. const textarea = view.el.querySelector('textarea.chat-textarea');
  173. textarea.value = "hello @some1 ";
  174. // Press backspace
  175. const backspace_event = {
  176. 'target': textarea,
  177. 'preventDefault': _.noop,
  178. 'stopPropagation': _.noop,
  179. 'keyCode': 8,
  180. 'key': 'Backspace'
  181. }
  182. view.onKeyDown(backspace_event);
  183. textarea.value = "hello @some1"; // Mimic backspace
  184. view.onKeyUp(backspace_event);
  185. expect(view.el.querySelector('.suggestion-box__results').hidden).toBeFalsy();
  186. expect(view.el.querySelectorAll('.suggestion-box__results li').length).toBe(1);
  187. expect(view.el.querySelector('.suggestion-box__results li').textContent).toBe('some1');
  188. done();
  189. }));
  190. });
  191. }));