mock.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. (function (root, factory) {
  2. define("mock", [], factory);
  3. }(this, function () {
  4. converse.load();
  5. const _ = converse.env._;
  6. const Promise = converse.env.Promise;
  7. const Strophe = converse.env.Strophe;
  8. const dayjs = converse.env.dayjs;
  9. const $iq = converse.env.$iq;
  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) { // eslint-disable-line no-unused-vars
  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.default_muc_features = [
  68. 'http://jabber.org/protocol/muc',
  69. 'jabber:iq:register',
  70. Strophe.NS.SID,
  71. Strophe.NS.MAM,
  72. 'muc_passwordprotected',
  73. 'muc_hidden',
  74. 'muc_temporary',
  75. 'muc_open',
  76. 'muc_unmoderated',
  77. 'muc_anonymous'
  78. ];
  79. mock.view_mode = 'overlayed';
  80. // Names from http://www.fakenamegenerator.com/
  81. mock.req_names = [
  82. 'Escalus, prince of Verona', 'The Nurse', 'Paris'
  83. ];
  84. mock.pend_names = [
  85. 'Lord Capulet', 'Guard', 'Servant'
  86. ];
  87. mock.current_contacts_map = {
  88. 'Mercutio': ['Colleagues', 'friends & acquaintences'],
  89. 'Juliet Capulet': ['friends & acquaintences'],
  90. 'Lady Montague': ['Colleagues', 'Family'],
  91. 'Lord Montague': ['Family'],
  92. 'Friar Laurence': ['friends & acquaintences'],
  93. 'Tybalt': ['friends & acquaintences'],
  94. 'Lady Capulet': ['ænemies'],
  95. 'Benviolo': ['friends & acquaintences'],
  96. 'Balthasar': ['Colleagues'],
  97. 'Peter': ['Colleagues'],
  98. 'Abram': ['Colleagues'],
  99. 'Sampson': ['Colleagues'],
  100. 'Gregory': ['friends & acquaintences'],
  101. 'Potpan': [],
  102. 'Friar John': []
  103. };
  104. const map = mock.current_contacts_map;
  105. const groups_map = {};
  106. Object.keys(map).forEach(k => {
  107. const groups = map[k].length ? map[k] : ["Ungrouped"];
  108. Object.values(groups).forEach(g => {
  109. groups_map[g] = groups_map[g] ? [...groups_map[g], k] : [k]
  110. });
  111. });
  112. mock.groups_map = groups_map;
  113. mock.cur_names = Object.keys(mock.current_contacts_map);
  114. mock.num_contacts = mock.req_names.length + mock.pend_names.length + mock.cur_names.length;
  115. mock.groups = {
  116. 'colleagues': 3,
  117. 'friends & acquaintences': 3,
  118. 'Family': 4,
  119. 'ænemies': 3,
  120. 'Ungrouped': 2
  121. };
  122. mock.chatroom_names = [
  123. 'Dyon van de Wege',
  124. 'Thomas Kalb',
  125. 'Dirk Theissen',
  126. 'Felix Hofmann',
  127. 'Ka Lek',
  128. 'Anne Ebersbacher'
  129. ];
  130. // TODO: need to also test other roles and affiliations
  131. mock.chatroom_roles = {
  132. 'Anne Ebersbacher': { affiliation: "owner", role: "moderator" },
  133. 'Dirk Theissen': { affiliation: "admin", role: "moderator" },
  134. 'Dyon van de Wege': { affiliation: "member", role: "occupant" },
  135. 'Felix Hofmann': { affiliation: "member", role: "occupant" },
  136. 'Ka Lek': { affiliation: "member", role: "occupant" },
  137. 'Thomas Kalb': { affiliation: "member", role: "occupant" }
  138. };
  139. mock.event = {
  140. 'preventDefault': function () {}
  141. };
  142. const OriginalConnection = Strophe.Connection;
  143. function MockConnection (service, options) {
  144. OriginalConnection.call(this, service, options);
  145. Strophe.Bosh.prototype._processRequest = function () {}; // Don't attempt to send out stanzas
  146. const sendIQ = this.sendIQ;
  147. this.IQ_stanzas = [];
  148. this.IQ_ids = [];
  149. this.sendIQ = function (iq, callback, errback) {
  150. if (!_.isElement(iq)) {
  151. iq = iq.nodeTree;
  152. }
  153. this.IQ_stanzas.push(iq);
  154. const id = sendIQ.bind(this)(iq, callback, errback);
  155. this.IQ_ids.push(id);
  156. return id;
  157. }
  158. const send = this.send;
  159. this.sent_stanzas = [];
  160. this.send = function (stanza) {
  161. if (_.isElement(stanza)) {
  162. this.sent_stanzas.push(stanza);
  163. } else {
  164. this.sent_stanzas.push(stanza.nodeTree);
  165. }
  166. return send.apply(this, arguments);
  167. }
  168. this.features = Strophe.xmlHtmlNode(
  169. '<stream:features xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">'+
  170. '<ver xmlns="urn:xmpp:features:rosterver"/>'+
  171. '<csi xmlns="urn:xmpp:csi:0"/>'+
  172. '<this xmlns="http://jabber.org/protocol/caps" ver="UwBpfJpEt3IoLYfWma/o/p3FFRo=" hash="sha-1" node="http://prosody.im"/>'+
  173. '<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">'+
  174. '<required/>'+
  175. '</bind>'+
  176. `<sm xmlns='urn:xmpp:sm:3'/>`+
  177. '<session xmlns="urn:ietf:params:xml:ns:xmpp-session">'+
  178. '<optional/>'+
  179. '</session>'+
  180. '</stream:features>').firstChild;
  181. this._proto._connect = () => {
  182. this.connected = true;
  183. this.mock = true;
  184. this.jid = 'romeo@montague.lit/orchard';
  185. this._changeConnectStatus(Strophe.Status.BINDREQUIRED);
  186. };
  187. this.bind = () => {
  188. this.authenticated = true;
  189. this.authenticated = true;
  190. this._changeConnectStatus(Strophe.Status.CONNECTED);
  191. };
  192. this._proto._disconnect = () => this._onDisconnectTimeout();
  193. this._proto._onDisconnectTimeout = _.noop;
  194. }
  195. MockConnection.prototype = Object.create(OriginalConnection.prototype);
  196. Strophe.Connection = MockConnection;
  197. async function initConverse (settings) {
  198. window.localStorage.clear();
  199. window.sessionStorage.clear();
  200. const _converse = await converse.initialize(Object.assign({
  201. 'animate': false,
  202. 'auto_subscribe': false,
  203. 'bosh_service_url': 'montague.lit/http-bind',
  204. 'debug': false,
  205. 'i18n': 'en',
  206. 'no_trimming': true,
  207. 'play_sounds': false,
  208. 'use_emojione': false,
  209. 'view_mode': mock.view_mode
  210. }, settings || {}));
  211. _converse.ChatBoxViews.prototype.trimChat = function () {};
  212. _converse.api.vcard.get = function (model, force) {
  213. let jid;
  214. if (_.isString(model)) {
  215. jid = model;
  216. } else if (!model.get('vcard_updated') || force) {
  217. jid = model.get('jid') || model.get('muc_jid');
  218. }
  219. let fullname;
  220. if (!jid || jid == 'romeo@montague.lit') {
  221. jid = 'romeo@montague.lit';
  222. fullname = 'Romeo Montague' ;
  223. } else {
  224. const name = jid.split('@')[0].replace(/\./g, ' ').split(' ');
  225. const last = name.length-1;
  226. name[0] = name[0].charAt(0).toUpperCase()+name[0].slice(1);
  227. name[last] = name[last].charAt(0).toUpperCase()+name[last].slice(1);
  228. fullname = name.join(' ');
  229. }
  230. const vcard = $iq().c('vCard').c('FN').t(fullname).nodeTree;
  231. return {
  232. 'vcard': vcard,
  233. 'fullname': _.get(vcard.querySelector('FN'), 'textContent'),
  234. 'image': _.get(vcard.querySelector('PHOTO BINVAL'), 'textContent'),
  235. 'image_type': _.get(vcard.querySelector('PHOTO TYPE'), 'textContent'),
  236. 'url': _.get(vcard.querySelector('URL'), 'textContent'),
  237. 'vcard_updated': dayjs().format(),
  238. 'vcard_error': undefined
  239. };
  240. };
  241. if (_.get(settings, 'auto_login') !== false) {
  242. _converse.api.user.login('romeo@montague.lit/orchard', 'secret');
  243. await _converse.api.waitUntil('afterResourceBinding');
  244. }
  245. window.converse_disable_effects = true;
  246. return _converse;
  247. }
  248. mock.initConverse = function (promise_names=[], settings=null, func) {
  249. if (_.isFunction(promise_names)) {
  250. func = promise_names;
  251. promise_names = []
  252. settings = null;
  253. }
  254. return async done => {
  255. const _converse = await initConverse(settings);
  256. async function _done () {
  257. if (_converse.api.connection.connected()) {
  258. await _converse.api.user.logout();
  259. }
  260. const el = document.querySelector('#conversejs');
  261. if (el) {
  262. el.parentElement.removeChild(el);
  263. }
  264. document.title = "Converse Tests";
  265. done();
  266. }
  267. await Promise.all((promise_names || []).map(_converse.api.waitUntil));
  268. try {
  269. await func(_done, _converse);
  270. } catch(e) {
  271. console.error(e);
  272. fail(e);
  273. _done();
  274. }
  275. }
  276. };
  277. return mock;
  278. }));