mock.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. (function (root, factory) {
  2. define("mock", [], factory);
  3. }(this, function () {
  4. const _ = converse.env._;
  5. const Promise = converse.env.Promise;
  6. const Strophe = converse.env.Strophe;
  7. const dayjs = converse.env.dayjs;
  8. const $iq = converse.env.$iq;
  9. const u = converse.env.utils;
  10. window.libsignal = {
  11. 'SignalProtocolAddress': function (name, device_id) {
  12. this.name = name;
  13. this.deviceId = device_id;
  14. },
  15. 'SessionCipher': function (storage, remote_address) {
  16. this.remoteAddress = remote_address;
  17. this.storage = storage;
  18. this.encrypt = () => Promise.resolve({
  19. 'type': 1,
  20. 'body': 'c1ph3R73X7',
  21. 'registrationId': '1337'
  22. });
  23. this.decryptPreKeyWhisperMessage = (key_and_tag) => {
  24. return Promise.resolve(key_and_tag);
  25. };
  26. this.decryptWhisperMessage = (key_and_tag) => {
  27. return Promise.resolve(key_and_tag);
  28. }
  29. },
  30. 'SessionBuilder': function (storage, remote_address) {
  31. this.processPreKey = function () {
  32. return Promise.resolve();
  33. }
  34. },
  35. 'KeyHelper': {
  36. 'generateIdentityKeyPair': function () {
  37. return Promise.resolve({
  38. 'pubKey': new TextEncoder('utf-8').encode('1234'),
  39. 'privKey': new TextEncoder('utf-8').encode('4321')
  40. });
  41. },
  42. 'generateRegistrationId': function () {
  43. return '123456789';
  44. },
  45. 'generatePreKey': function (keyid) {
  46. return Promise.resolve({
  47. 'keyId': keyid,
  48. 'keyPair': {
  49. 'pubKey': new TextEncoder('utf-8').encode('1234'),
  50. 'privKey': new TextEncoder('utf-8').encode('4321')
  51. }
  52. });
  53. },
  54. 'generateSignedPreKey': function (identity_keypair, keyid) {
  55. return Promise.resolve({
  56. 'signature': new TextEncoder('utf-8').encode('11112222333344445555'),
  57. 'keyId': keyid,
  58. 'keyPair': {
  59. 'pubKey': new TextEncoder('utf-8').encode('1234'),
  60. 'privKey': new TextEncoder('utf-8').encode('4321')
  61. }
  62. });
  63. }
  64. }
  65. };
  66. const mock = {};
  67. mock.view_mode = 'overlayed';
  68. // Names from http://www.fakenamegenerator.com/
  69. mock.req_names = [
  70. 'Escalus, Prince of Verona', 'The Nurse', 'Paris'
  71. ];
  72. mock.pend_names = [
  73. 'Lord Capulet', 'Lady Capulet', 'Servant'
  74. ];
  75. mock.cur_names = [
  76. 'Mercutio', 'Juliet Capulet', 'Lady Montague', 'Lord Montague', 'Friar Laurence',
  77. 'Tybalt', 'Lady Capulet', 'Benviolo', 'Balthasar',
  78. 'Peter', 'Abram', 'Sampson', 'Gregory', 'Potpan', 'Friar John'
  79. ];
  80. mock.num_contacts = mock.req_names.length + mock.pend_names.length + mock.cur_names.length;
  81. mock.groups = {
  82. 'colleagues': 3,
  83. 'friends & acquaintences': 3,
  84. 'Family': 4,
  85. 'ænemies': 3,
  86. 'Ungrouped': 2
  87. };
  88. mock.chatroom_names = [
  89. 'Dyon van de Wege', 'Thomas Kalb', 'Dirk Theissen', 'Felix Hofmann', 'Ka Lek', 'Anne Ebersbacher'
  90. ];
  91. // TODO: need to also test other roles and affiliations
  92. mock.chatroom_roles = {
  93. 'Anne Ebersbacher': { affiliation: "owner", role: "moderator" },
  94. 'Dirk Theissen': { affiliation: "admin", role: "moderator" },
  95. 'Dyon van de Wege': { affiliation: "member", role: "occupant" },
  96. 'Felix Hofmann': { affiliation: "member", role: "occupant" },
  97. 'Ka Lek': { affiliation: "member", role: "occupant" },
  98. 'Thomas Kalb': { affiliation: "member", role: "occupant" }
  99. };
  100. mock.event = {
  101. 'preventDefault': function () {}
  102. };
  103. mock.mock_connection = function () { // eslint-disable-line wrap-iife
  104. return function () {
  105. Strophe.Bosh.prototype._processRequest = function () {}; // Don't attempt to send out stanzas
  106. const c = new Strophe.Connection('jasmine tests');
  107. const sendIQ = c.sendIQ;
  108. c.IQ_stanzas = [];
  109. c.IQ_ids = [];
  110. c.sendIQ = function (iq, callback, errback) {
  111. if (!_.isElement(iq)) {
  112. iq = iq.nodeTree;
  113. }
  114. this.IQ_stanzas.push(iq);
  115. const id = sendIQ.bind(this)(iq, callback, errback);
  116. this.IQ_ids.push(id);
  117. return id;
  118. }
  119. const send = c.send;
  120. c.sent_stanzas = [];
  121. c.send = function (stanza) {
  122. if (_.isElement(stanza)) {
  123. this.sent_stanzas.push(stanza);
  124. } else {
  125. this.sent_stanzas.push(stanza.nodeTree);
  126. }
  127. return send.apply(this, arguments);
  128. }
  129. c.features = Strophe.xmlHtmlNode(
  130. '<stream:features xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">'+
  131. '<ver xmlns="urn:xmpp:features:rosterver"/>'+
  132. '<csi xmlns="urn:xmpp:csi:0"/>'+
  133. '<c xmlns="http://jabber.org/protocol/caps" ver="UwBpfJpEt3IoLYfWma/o/p3FFRo=" hash="sha-1" node="http://prosody.im"/>'+
  134. '<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">'+
  135. '<required/>'+
  136. '</bind>'+
  137. `<sm xmlns='urn:xmpp:sm:3'/>`+
  138. '<session xmlns="urn:ietf:params:xml:ns:xmpp-session">'+
  139. '<optional/>'+
  140. '</session>'+
  141. '</stream:features>').firstChild;
  142. c._proto._connect = function () {
  143. c.connected = true;
  144. c.mock = true;
  145. c.jid = 'romeo@montague.lit/orchard';
  146. c._changeConnectStatus(Strophe.Status.BINDREQUIRED);
  147. };
  148. c.bind = function () {
  149. c.authenticated = true;
  150. this.authenticated = true;
  151. c._changeConnectStatus(Strophe.Status.CONNECTED);
  152. };
  153. c._proto._disconnect = function () {
  154. c._onDisconnectTimeout();
  155. }
  156. c._proto._onDisconnectTimeout = _.noop;
  157. return c;
  158. };
  159. }();
  160. async function initConverse (settings, spies, promises) {
  161. window.localStorage.clear();
  162. window.sessionStorage.clear();
  163. const el = document.querySelector('#conversejs');
  164. if (el) {
  165. el.parentElement.removeChild(el);
  166. }
  167. const connection = mock.mock_connection();
  168. if (!_.isNil(spies)) {
  169. _.forEach(spies.connection, method => spyOn(connection, method));
  170. }
  171. const _converse = await converse.initialize(Object.assign({
  172. 'i18n': 'en',
  173. 'auto_subscribe': false,
  174. 'play_sounds': false,
  175. 'bosh_service_url': 'montague.lit/http-bind',
  176. 'connection': connection,
  177. 'animate': false,
  178. 'use_emojione': false,
  179. 'no_trimming': true,
  180. 'view_mode': mock.view_mode,
  181. 'debug': false
  182. }, settings || {}));
  183. if (!_.isNil(spies)) {
  184. _.forEach(spies._converse, method => spyOn(_converse, method).and.callThrough());
  185. }
  186. _converse.ChatBoxViews.prototype.trimChat = function () {};
  187. _converse.api.vcard.get = function (model, force) {
  188. return new Promise((resolve, reject) => {
  189. let jid;
  190. if (_.isString(model)) {
  191. jid = model;
  192. } else if (!model.get('vcard_updated') || force) {
  193. jid = model.get('jid') || model.get('muc_jid');
  194. }
  195. let fullname;
  196. if (!jid || jid == 'romeo@montague.lit') {
  197. jid = 'romeo@montague.lit';
  198. fullname = 'Romeo Montague' ;
  199. } else {
  200. const name = jid.split('@')[0].replace(/\./g, ' ').split(' ');
  201. const last = name.length-1;
  202. name[0] = name[0].charAt(0).toUpperCase()+name[0].slice(1);
  203. name[last] = name[last].charAt(0).toUpperCase()+name[last].slice(1);
  204. fullname = name.join(' ');
  205. }
  206. const vcard = $iq().c('vCard').c('FN').t(fullname).nodeTree;
  207. const result = {
  208. 'vcard': vcard,
  209. 'fullname': _.get(vcard.querySelector('FN'), 'textContent'),
  210. 'image': _.get(vcard.querySelector('PHOTO BINVAL'), 'textContent'),
  211. 'image_type': _.get(vcard.querySelector('PHOTO TYPE'), 'textContent'),
  212. 'url': _.get(vcard.querySelector('URL'), 'textContent'),
  213. 'vcard_updated': dayjs().format(),
  214. 'vcard_error': undefined
  215. };
  216. resolve(result);
  217. }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
  218. };
  219. if (_.get(settings, 'auto_login') !== false) {
  220. _converse.api.user.login('romeo@montague.lit/orchard', 'secret');
  221. await _converse.api.waitUntil('afterResourceBinding');
  222. }
  223. window.converse_disable_effects = true;
  224. return _converse;
  225. }
  226. mock.initConverse = function (spies, promise_names=null, settings=null, func) {
  227. if (_.isFunction(spies)) {
  228. func = spies;
  229. spies = null;
  230. promise_names = null
  231. settings = null;
  232. }
  233. return async done => {
  234. const _converse = await initConverse(settings, spies);
  235. function _done () {
  236. // _converse.api.user.logout();
  237. done();
  238. }
  239. const promises = _.map(promise_names, _converse.api.waitUntil);
  240. await Promise.all(promises);
  241. func(_done, _converse);
  242. }
  243. };
  244. return mock;
  245. }));