diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/im_livechat/static/tests | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/im_livechat/static/tests')
| -rw-r--r-- | addons/im_livechat/static/tests/helpers/mock_models.js | 42 | ||||
| -rw-r--r-- | addons/im_livechat/static/tests/helpers/mock_server.js | 263 |
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]; + }, +}); + +}); |
