add-contact-modal.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*global mock, converse */
  2. const u = converse.env.utils;
  3. const Strophe = converse.env.Strophe;
  4. const sizzle = converse.env.sizzle;
  5. describe("The 'Add Contact' widget", function () {
  6. it("opens up an add modal when you click on it",
  7. mock.initConverse([], {}, async function (_converse) {
  8. await mock.waitForRoster(_converse, 'all');
  9. await mock.openControlBox(_converse);
  10. const cbview = _converse.chatboxviews.get('controlbox');
  11. const dropdown = await u.waitUntil(
  12. () => cbview.querySelector('.dropdown--contacts')
  13. );
  14. dropdown.querySelector('.add-contact').click()
  15. const modal = _converse.api.modal.get('converse-add-contact-modal');
  16. await u.waitUntil(() => u.isVisible(modal), 1000);
  17. expect(modal.querySelector('form.add-xmpp-contact')).not.toBe(null);
  18. const input_jid = modal.querySelector('input[name="jid"]');
  19. const input_name = modal.querySelector('input[name="name"]');
  20. input_jid.value = 'someone@';
  21. const evt = new Event('input');
  22. input_jid.dispatchEvent(evt);
  23. expect(modal.querySelector('.suggestion-box li').textContent).toBe('someone@montague.lit');
  24. input_jid.value = 'someone@montague.lit';
  25. input_name.value = 'Someone';
  26. modal.querySelector('button[type="submit"]').click();
  27. const sent_IQs = _converse.api.connection.get().IQ_stanzas;
  28. const sent_stanza = await u.waitUntil(() => sent_IQs.filter(iq => iq.querySelector(`iq[type="set"] query[xmlns="${Strophe.NS.ROSTER}"]`)).pop());
  29. expect(Strophe.serialize(sent_stanza)).toEqual(
  30. `<iq id="${sent_stanza.getAttribute('id')}" type="set" xmlns="jabber:client">`+
  31. `<query xmlns="jabber:iq:roster"><item jid="someone@montague.lit" name="Someone"><group></group></item></query>`+
  32. `</iq>`);
  33. }));
  34. it("can be configured to not provide search suggestions",
  35. mock.initConverse([], {'autocomplete_add_contact': false}, async function (_converse) {
  36. await mock.waitForRoster(_converse, 'all', 0);
  37. await mock.openControlBox(_converse);
  38. const cbview = _converse.chatboxviews.get('controlbox');
  39. cbview.querySelector('.add-contact').click()
  40. const modal = _converse.api.modal.get('converse-add-contact-modal');
  41. expect(modal.jid_auto_complete).toBe(undefined);
  42. expect(modal.name_auto_complete).toBe(undefined);
  43. await u.waitUntil(() => u.isVisible(modal), 1000);
  44. expect(modal.querySelector('form.add-xmpp-contact')).not.toBe(null);
  45. const input_jid = modal.querySelector('input[name="jid"]');
  46. input_jid.value = 'someone@montague.lit';
  47. modal.querySelector('button[type="submit"]').click();
  48. const IQ_stanzas = _converse.api.connection.get().IQ_stanzas;
  49. const sent_stanza = await u.waitUntil(
  50. () => IQ_stanzas.filter(s => sizzle(`iq[type="set"] query[xmlns="${Strophe.NS.ROSTER}"]`, s).length).pop()
  51. );
  52. expect(Strophe.serialize(sent_stanza)).toEqual(
  53. `<iq id="${sent_stanza.getAttribute('id')}" type="set" xmlns="jabber:client">`+
  54. `<query xmlns="jabber:iq:roster"><item jid="someone@montague.lit"><group></group></item></query>`+
  55. `</iq>`
  56. );
  57. }));
  58. it("integrates with xhr_user_search_url to search for contacts",
  59. mock.initConverse([], { 'xhr_user_search_url': 'http://example.org/?' },
  60. async function (_converse) {
  61. await mock.waitForRoster(_converse, 'all', 0);
  62. spyOn(window, 'fetch').and.callFake(() => {
  63. const json = [
  64. {"jid": "marty@mcfly.net", "fullname": "Marty McFly"},
  65. {"jid": "doc@brown.com", "fullname": "Doc Brown"}
  66. ];
  67. return { json };
  68. });
  69. await mock.openControlBox(_converse);
  70. const cbview = _converse.chatboxviews.get('controlbox');
  71. cbview.querySelector('.add-contact').click()
  72. const modal = _converse.api.modal.get('converse-add-contact-modal');
  73. await u.waitUntil(() => u.isVisible(modal), 1000);
  74. // TODO: We only have autocomplete for the name input
  75. const input_el = modal.querySelector('input[name="name"]');
  76. input_el.value = 'marty';
  77. input_el.dispatchEvent(new Event('input'));
  78. await u.waitUntil(() => modal.querySelector('.suggestion-box li'), 1000);
  79. expect(modal.querySelectorAll('.suggestion-box li').length).toBe(1);
  80. const suggestion = modal.querySelector('.suggestion-box li');
  81. expect(suggestion.textContent).toBe('Marty McFly');
  82. return;
  83. // Mock selection
  84. modal.name_auto_complete.select(suggestion);
  85. expect(input_el.value).toBe('Marty McFly');
  86. expect(modal.querySelector('input[name="jid"]').value).toBe('marty@mcfly.net');
  87. modal.querySelector('button[type="submit"]').click();
  88. const sent_IQs = _converse.api.connection.get().IQ_stanzas;
  89. const sent_stanza = await u.waitUntil(() => sent_IQs.filter(iq => iq.querySelector(`iq[type="set"] query[xmlns="${Strophe.NS.ROSTER}"]`)).pop());
  90. expect(Strophe.serialize(sent_stanza)).toEqual(
  91. `<iq id="${sent_stanza.getAttribute('id')}" type="set" xmlns="jabber:client">`+
  92. `<query xmlns="jabber:iq:roster"><item jid="marty@mcfly.net" name="Marty McFly"/></query>`+
  93. `</iq>`);
  94. window.XMLHttpRequest = XMLHttpRequestBackup;
  95. }));
  96. it("can be configured to not provide search suggestions for XHR search results",
  97. mock.initConverse([],
  98. { 'autocomplete_add_contact': false,
  99. 'xhr_user_search_url': 'http://example.org/?' },
  100. async function (_converse) {
  101. await mock.waitForRoster(_converse, 'all');
  102. await mock.openControlBox(_converse);
  103. spyOn(window, 'fetch').and.callFake(() => {
  104. let json;
  105. const value = modal.querySelector('input[name="name"]').value;
  106. if (value === 'existing') {
  107. const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
  108. json = [{"jid": contact_jid, "fullname": mock.cur_names[0]}];
  109. } else if (value === 'romeo') {
  110. json = [{"jid": "romeo@montague.lit", "fullname": "Romeo Montague"}];
  111. } else if (value === 'ambiguous') {
  112. json = [
  113. {"jid": "marty@mcfly.net", "fullname": "Marty McFly"},
  114. {"jid": "doc@brown.com", "fullname": "Doc Brown"}
  115. ];
  116. } else if (value === 'insufficient') {
  117. json = [];
  118. } else {
  119. json = [{"jid": "marty@mcfly.net", "fullname": "Marty McFly"}];
  120. }
  121. return { json };
  122. });
  123. const cbview = _converse.chatboxviews.get('controlbox');
  124. cbview.querySelector('.add-contact').click()
  125. const modal = _converse.api.modal.get('converse-add-contact-modal');
  126. await u.waitUntil(() => u.isVisible(modal), 1000);
  127. expect(modal.jid_auto_complete).toBe(undefined);
  128. expect(modal.name_auto_complete).toBe(undefined);
  129. const input_el = modal.querySelector('input[name="name"]');
  130. input_el.value = 'ambiguous';
  131. modal.querySelector('button[type="submit"]').click();
  132. const feedback_el = await u.waitUntil(() => modal.querySelector('.invalid-feedback'));
  133. expect(feedback_el.textContent).toBe('Sorry, could not find a contact with that name');
  134. input_el.value = 'existing';
  135. modal.querySelector('button[type="submit"]').click();
  136. await u.waitUntil(() => feedback_el.textContent === 'This contact has already been added');
  137. input_el.value = 'insufficient';
  138. modal.querySelector('button[type="submit"]').click();
  139. await u.waitUntil(() => feedback_el.textContent === 'Sorry, could not find a contact with that name');
  140. input_el.value = 'Marty McFly';
  141. modal.querySelector('button[type="submit"]').click();
  142. const sent_IQs = _converse.api.connection.get().IQ_stanzas;
  143. const sent_stanza = await u.waitUntil(() => sent_IQs.filter(iq => iq.querySelector(`iq[type="set"] query[xmlns="${Strophe.NS.ROSTER}"]`)).pop());
  144. expect(Strophe.serialize(sent_stanza)).toEqual(
  145. `<iq id="${sent_stanza.getAttribute('id')}" type="set" xmlns="jabber:client">`+
  146. `<query xmlns="jabber:iq:roster"><item jid="marty@mcfly.net" name="Marty McFly"><group></group></item></query>`+
  147. `</iq>`);
  148. }));
  149. });