summaryrefslogtreecommitdiff
path: root/addons/im_livechat/static/tests
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/im_livechat/static/tests
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/im_livechat/static/tests')
-rw-r--r--addons/im_livechat/static/tests/helpers/mock_models.js42
-rw-r--r--addons/im_livechat/static/tests/helpers/mock_server.js263
2 files changed, 305 insertions, 0 deletions
diff --git a/addons/im_livechat/static/tests/helpers/mock_models.js b/addons/im_livechat/static/tests/helpers/mock_models.js
new file mode 100644
index 00000000..db18e8f7
--- /dev/null
+++ b/addons/im_livechat/static/tests/helpers/mock_models.js
@@ -0,0 +1,42 @@
+odoo.define('im_livechat/static/tests/helpers/mock_models.js', function (require) {
+'use strict';
+
+const MockModels = require('mail/static/tests/helpers/mock_models.js');
+
+MockModels.patch('im_livechat/static/tests/helpers/mock_models.js', T =>
+ class extends T {
+
+ //----------------------------------------------------------------------
+ // Public
+ //----------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ static generateData() {
+ const data = super.generateData(...arguments);
+ Object.assign(data, {
+ 'im_livechat.channel': {
+ fields: {
+ user_ids: { string: "Operators", type: 'many2many', relation: 'res.users' }
+ },
+ records: [],
+ }
+ });
+ Object.assign(data['mail.channel'].fields, {
+ anonymous_name: { string: "Anonymous Name", type: 'char' },
+ country_id: { string: "Country", type: 'many2one', relation: 'res.country' },
+ livechat_active: { string: "Is livechat ongoing?", type: 'boolean', default: false },
+ livechat_channel_id: { string: "Channel", type: 'many2one', relation: 'im_livechat.channel' },
+ livechat_operator_id: { string: "Operator", type: 'many2one', relation: 'res.partner' },
+ });
+ Object.assign(data['res.users'].fields, {
+ livechat_username: { string: 'Livechat Username', type: 'string' },
+ });
+ return data;
+ }
+
+ }
+);
+
+});
diff --git a/addons/im_livechat/static/tests/helpers/mock_server.js b/addons/im_livechat/static/tests/helpers/mock_server.js
new file mode 100644
index 00000000..e940cd5e
--- /dev/null
+++ b/addons/im_livechat/static/tests/helpers/mock_server.js
@@ -0,0 +1,263 @@
+odoo.define('im_livechat/static/tests/helpers/mock_server.js', function (require) {
+'use strict';
+
+require('mail.MockServer'); // ensure mail overrides are applied first
+
+const MockServer = require('web.MockServer');
+
+MockServer.include({
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ async _performRpc(route, args) {
+ if (route === '/im_livechat/get_session') {
+ const channel_id = args.channel_id;
+ const anonymous_name = args.anonymous_name;
+ const previous_operator_id = args.previous_operator_id;
+ const context = args.context;
+ return this._mockRouteImLivechatGetSession(channel_id, anonymous_name, previous_operator_id, context);
+ }
+ if (route === '/im_livechat/notify_typing') {
+ const uuid = args.uuid;
+ const is_typing = args.is_typing;
+ const context = args.context;
+ return this._mockRouteImLivechatNotifyTyping(uuid, is_typing, context);
+ }
+ return this._super(...arguments);
+ },
+
+ //--------------------------------------------------------------------------
+ // Private Mocked Routes
+ //--------------------------------------------------------------------------
+
+ /**
+ * Simulates the `/im_livechat/get_session` route.
+ *
+ * @private
+ * @param {integer} channel_id
+ * @param {string} anonymous_name
+ * @param {integer} [previous_operator_id]
+ * @param {Object} [context={}]
+ * @returns {Object}
+ */
+ _mockRouteImLivechatGetSession(channel_id, anonymous_name, previous_operator_id, context = {}) {
+ let user_id;
+ let country_id;
+ if ('mockedUserId' in context) {
+ // can be falsy to simulate not being logged in
+ user_id = context.mockedUserId;
+ } else {
+ user_id = this.currentUserId;
+ }
+ // don't use the anonymous name if the user is logged in
+ if (user_id) {
+ const user = this._getRecords('res.users', [['id', '=', user_id]])[0];
+ country_id = user.country_id;
+ } else {
+ // simulate geoip
+ const countryCode = context.mockedCountryCode;
+ const country = this._getRecords('res.country', [['code', '=', countryCode]])[0];
+ if (country) {
+ country_id = country.id;
+ anonymous_name = anonymous_name + ' (' + country.name + ')';
+ }
+ }
+ return this._mockImLivechatChannel_openLivechatMailChannel(channel_id, anonymous_name, previous_operator_id, user_id, country_id);
+ },
+ /**
+ * Simulates the `/im_livechat/notify_typing` route.
+ *
+ * @private
+ * @param {string} uuid
+ * @param {boolean} is_typing
+ * @param {Object} [context]
+ */
+ _mockRouteImLivechatNotifyTyping(uuid, is_typing, context) {
+ const mailChannel = this._getRecords('mail.channel', [['uuid', '=', uuid]])[0];
+ this._mockMailChannelNotifyTyping([mailChannel.id], is_typing, context);
+ },
+ /**
+ * @override
+ */
+ _mockRouteMailInitMessaging() {
+ const initMessaging = this._super(...arguments);
+
+ const livechats = this._getRecords('mail.channel', [
+ ['channel_type', '=', 'livechat'],
+ ['is_pinned', '=', true],
+ ['members', 'in', this.currentPartnerId],
+ ]);
+ initMessaging.channel_slots.channel_livechat = this._mockMailChannelChannelInfo(
+ livechats.map(channel => channel.id)
+ );
+
+ return initMessaging;
+ },
+
+ //--------------------------------------------------------------------------
+ // Private Mocked Methods
+ //--------------------------------------------------------------------------
+
+ /**
+ * Simulates `_channel_get_livechat_visitor_info` on `mail.channel`.
+ *
+ * @private
+ * @param {integer[]} ids
+ * @returns {Object}
+ */
+ _mockMailChannel_ChannelGetLivechatVisitorInfo(ids) {
+ const id = ids[0]; // ensure_one
+ const mailChannel = this._getRecords('mail.channel', [['id', '=', id]])[0];
+ // remove active test to ensure public partner is taken into account
+ let members = this._getRecords(
+ 'res.partner',
+ [['id', 'in', mailChannel.members]],
+ { active_test: false },
+ );
+ members = members.filter(member => member.id !== mailChannel.livechat_operator_id);
+ if (members.length === 0 && mailChannel.livechat_operator_id) {
+ // operator probably testing the livechat with his own user
+ members = [mailChannel.livechat_operator_id];
+ }
+ if (members.length > 0 && members[0].id !== this.publicPartnerId) {
+ // legit non-public partner
+ const country = this._getRecords('res.country', [['id', '=', members[0].country_id]])[0];
+ return {
+ 'country': country ? [country.id, country.name] : false,
+ 'id': members[0].id,
+ 'name': members[0].name,
+ };
+ }
+ return {
+ 'country': false,
+ 'id': false,
+ 'name': mailChannel.anonymous_name || "Visitor",
+ };
+ },
+ /**
+ * @override
+ */
+ _mockMailChannelChannelInfo(ids, extra_info) {
+ const channelInfos = this._super(...arguments);
+ for (const channelInfo of channelInfos) {
+ const channel = this._getRecords('mail.channel', [['id', '=', channelInfo.id]])[0];
+ // add the last message date
+ if (channel.channel_type === 'livechat') {
+ // add the operator id
+ if (channel.livechat_operator_id) {
+ const operator = this._getRecords('res.partner', [['id', '=', channel.livechat_operator_id]])[0];
+ // livechat_username ignored for simplicity
+ channelInfo.operator_pid = [operator.id, operator.display_name.replace(',', '')];
+ }
+ // add the anonymous or partner name
+ channelInfo.livechat_visitor = this._mockMailChannel_ChannelGetLivechatVisitorInfo([channel.id]);
+ }
+ }
+ return channelInfos;
+ },
+ /**
+ * Simulates `_get_available_users` on `im_livechat.channel`.
+ *
+ * @private
+ * @param {integer} id
+ * @returns {Object}
+ */
+ _mockImLivechatChannel_getAvailableUsers(id) {
+ const livechatChannel = this._getRecords('im_livechat.channel', [['id', '=', id]])[0];
+ const users = this._getRecords('res.users', [['id', 'in', livechatChannel.user_ids]]);
+ return users.filter(user => user.im_status === 'online');
+ },
+ /**
+ * Simulates `_get_livechat_mail_channel_vals` on `im_livechat.channel`.
+ *
+ * @private
+ * @param {integer} id
+ * @returns {Object}
+ */
+ _mockImLivechatChannel_getLivechatMailChannelVals(id, anonymous_name, operator, user_id, country_id) {
+ // partner to add to the mail.channel
+ const operator_partner_id = operator.partner_id;
+ const members = [[4, operator_partner_id]];
+ let visitor_user;
+ if (user_id) {
+ const visitor_user = this._getRecords('res.users', [['id', '=', user_id]])[0];
+ if (visitor_user && visitor_user.active) {
+ // valid session user (not public)
+ members.push([4, visitor_user.partner_id.id]);
+ }
+ } else {
+ // for simplicity of not having mocked channel.partner, add public partner here
+ members.push([4, this.publicPartnerId]);
+ }
+ const membersName = [
+ visitor_user ? visitor_user.display_name : anonymous_name,
+ operator.livechat_username ? operator.livechat_username : operator.name,
+ ];
+ return {
+ // Limitation of mocked models not having channel.partner: is_pinned
+ // is not supposed to be false for the visitor but must be false for
+ // the operator (writing on channel_partner_ids does not trigger the
+ // defaults that would set it to true) and here operator and visitor
+ // can't be differentiated in that regard.
+ 'is_pinned': false,
+ 'members': members, // channel_partner_ids
+ 'livechat_active': true,
+ 'livechat_operator_id': operator_partner_id,
+ 'livechat_channel_id': id,
+ 'anonymous_name': user_id ? false : anonymous_name,
+ 'country_id': country_id,
+ 'channel_type': 'livechat',
+ 'name': membersName.join(' '),
+ 'public': 'private',
+ 'mass_mailing': false, // email_send
+ };
+ },
+ /**
+ * Simulates `_get_random_operator` on `im_livechat.channel`.
+ * Simplified mock implementation: returns the first available operator.
+ *
+ * @private
+ * @param {integer} id
+ * @returns {Object}
+ */
+ _mockImLivechatChannel_getRandomOperator(id) {
+ const availableUsers = this._mockImLivechatChannel_getAvailableUsers(id);
+ return availableUsers[0];
+ },
+ /**
+ * Simulates `_open_livechat_mail_channel` on `im_livechat.channel`.
+ *
+ * @private
+ * @param {integer} id
+ * @param {string} anonymous_name
+ * @param {integer} [previous_operator_id]
+ * @param {integer} [user_id]
+ * @param {integer} [country_id]
+ * @returns {Object}
+ */
+ _mockImLivechatChannel_openLivechatMailChannel(id, anonymous_name, previous_operator_id, user_id, country_id) {
+ let operator;
+ if (previous_operator_id) {
+ const availableUsers = this._mockImLivechatChannel_getAvailableUsers(id);
+ operator = availableUsers.find(user => user.partner_id === previous_operator_id);
+ }
+ if (!operator) {
+ operator = this._mockImLivechatChannel_getRandomOperator(id);
+ }
+ if (!operator) {
+ // no one available
+ return false;
+ }
+ // create the session, and add the link with the given channel
+ const mailChannelVals = this._mockImLivechatChannel_getLivechatMailChannelVals(id, anonymous_name, operator, user_id, country_id);
+ const mailChannelId = this._mockCreate('mail.channel', mailChannelVals);
+ this._mockMailChannel_broadcast([mailChannelId], [operator.partner_id]);
+ return this._mockMailChannelChannelInfo([mailChannelId])[0];
+ },
+});
+
+});