[IMP] mail, *: display rating in systray
* = im_livechat, test_mail_full Display the rating changes that generate a notification under the systray. Using the rating faces to represent the result. task-2794182 closes odoo/odoo#89537 Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
@@ -6,3 +6,4 @@ from . import test_chatbot_form_ui
|
||||
from . import test_chatbot_internals
|
||||
from . import test_get_mail_channel
|
||||
from . import test_im_livechat_support_page
|
||||
from . import test_message
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import Command
|
||||
from odoo.tests.common import users, tagged, TransactionCase
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestImLivechatMessage(TransactionCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.users = self.env['res.users'].create([
|
||||
{
|
||||
'email': 'e.e@example.com',
|
||||
'groups_id': [Command.link(self.env.ref('base.group_user').id)],
|
||||
'login': 'emp',
|
||||
'name': 'Ernest Employee',
|
||||
'notification_type': 'inbox',
|
||||
'odoobot_state': 'disabled',
|
||||
'signature': '--\nErnest',
|
||||
},
|
||||
{'name': 'test1', 'login': 'test1', 'email': 'test1@example.com'},
|
||||
])
|
||||
|
||||
@users('emp')
|
||||
def test_message_format(self):
|
||||
im_livechat_channel = self.env['im_livechat.channel'].sudo().create({'name': 'support', 'user_ids': [Command.link(self.users[0].id)]})
|
||||
self.users[0].im_status = 'online' # make available for livechat (ignore leave)
|
||||
channel_livechat_1 = self.env['mail.channel'].browse(im_livechat_channel._open_livechat_mail_channel(anonymous_name='anon 1', previous_operator_id=self.users[0].partner_id.id, user_id=self.users[1].id, country_id=self.env.ref('base.in').id)['id'])
|
||||
record_rating = self.env['rating.rating'].create({
|
||||
'res_model_id': self.env['ir.model']._get('mail.channel').id,
|
||||
'res_id': channel_livechat_1.id,
|
||||
'parent_res_model_id': self.env['ir.model']._get('im_livechat.channel').id,
|
||||
'parent_res_id': im_livechat_channel.id,
|
||||
'rated_partner_id': self.users[0].partner_id.id,
|
||||
'partner_id': self.users[1].partner_id.id,
|
||||
'rating': 5,
|
||||
'consumed': True,
|
||||
})
|
||||
message = channel_livechat_1.message_post(
|
||||
author_id=record_rating.partner_id.id,
|
||||
body="<img src='%s' alt=':%s/5' style='width:18px;height:18px;float:left;margin-right: 5px;'/>%s"
|
||||
% (record_rating.rating_image_url, record_rating.rating, record_rating.feedback),
|
||||
rating_id=record_rating.id,
|
||||
)
|
||||
self.assertEqual(message.message_format(), [{
|
||||
'attachment_ids': [],
|
||||
'author_id': (self.users[1].partner_id.id, "test1"),
|
||||
'body': message.body,
|
||||
'date': message.date,
|
||||
'history_partner_ids': [],
|
||||
'id': message.id,
|
||||
'is_discussion': False,
|
||||
'is_note': True,
|
||||
'is_notification': False,
|
||||
'message_type': 'notification',
|
||||
'messageReactionGroups': [('insert-and-replace', [])],
|
||||
'model': 'mail.channel',
|
||||
'module_icon': '/mail/static/description/icon.png',
|
||||
'needaction_partner_ids': [],
|
||||
'notifications': [],
|
||||
'rating': [('insert-and-replace', {
|
||||
'id': record_rating.id,
|
||||
'ratingImageUrl': record_rating.rating_image_url,
|
||||
'ratingText': record_rating.rating_text,
|
||||
})],
|
||||
'recipients': [],
|
||||
'record_name': "test1 Ernest Employee",
|
||||
'res_id': channel_livechat_1.id,
|
||||
'sms_ids': [],
|
||||
'starred_partner_ids': [],
|
||||
'subject': False,
|
||||
'subtype_description': False,
|
||||
'subtype_id': (self.env.ref('mail.mt_note').id, 'Note'),
|
||||
'trackingValues': [('insert-and-replace', [])],
|
||||
}])
|
||||
-14
@@ -1,7 +1,5 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import * as mailUtils from '@mail/js/utils';
|
||||
|
||||
import { useRefToModel } from '@mail/component_hooks/use_ref_to_model';
|
||||
import { registerMessagingComponent } from '@mail/utils/messaging_component';
|
||||
|
||||
@@ -39,18 +37,6 @@ export class ThreadNeedactionPreview extends Component {
|
||||
return '/mail/static/src/img/smiley/avatar.jpg';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get inline content of the last message of this conversation.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
get inlineLastNeedactionMessageAsOriginThreadBody() {
|
||||
if (!this.threadNeedactionPreviewView.thread.lastNeedactionMessageAsOriginThread) {
|
||||
return '';
|
||||
}
|
||||
return mailUtils.htmlToTextContentInline(this.threadNeedactionPreviewView.thread.lastNeedactionMessageAsOriginThread.prettyBody);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {ThreadNeedactionPreviewView}
|
||||
*/
|
||||
|
||||
+2
-2
@@ -41,11 +41,11 @@
|
||||
</t>
|
||||
</div>
|
||||
<div class="o_ThreadNeedactionPreview_core d-flex align-items-baseline">
|
||||
<span class="o_NotificationListItem_coreItem o_NotificationListItem_inlineText o_ThreadNeedactionPreview_coreItem o_ThreadNeedactionPreview_inlineText me-2 text-truncate" t-att-class="{ 'o-empty': inlineLastNeedactionMessageAsOriginThreadBody.length === 0 }">
|
||||
<span class="o_NotificationListItem_coreItem o_NotificationListItem_inlineText o_ThreadNeedactionPreview_coreItem o_ThreadNeedactionPreview_inlineText me-2 text-truncate" t-att-class="{ 'o-empty': threadNeedactionPreviewView.isEmpty }">
|
||||
<t t-if="threadNeedactionPreviewView.messageAuthorPrefixView">
|
||||
<MessageAuthorPrefix record="threadNeedactionPreviewView.messageAuthorPrefixView"/>
|
||||
</t>
|
||||
<t t-esc="inlineLastNeedactionMessageAsOriginThreadBody"/>
|
||||
<span class="o_ThreadNeedactionPreview_messageBody" t-esc="threadNeedactionPreviewView.inlineLastNeedactionMessageAsOriginThreadBody"/>
|
||||
</span>
|
||||
<span class="flex-grow-1"/>
|
||||
<span class="o_NotificationListItem_coreItem o_NotificationListItem_markAsRead o_ThreadNeedactionPreview_coreItem o_ThreadNeedactionPreview_markAsRead fa fa-check d-flex flex-shrink-0 ms-2 text-600 opacity-50 opacity-100-hover" title="Mark as Read" t-on-click="threadNeedactionPreviewView.onClickMarkAsRead" t-ref="markAsRead"/>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import * as mailUtils from '@mail/js/utils';
|
||||
|
||||
import { useRefToModel } from '@mail/component_hooks/use_ref_to_model';
|
||||
import { registerMessagingComponent } from '@mail/utils/messaging_component';
|
||||
|
||||
@@ -33,18 +31,6 @@ export class ThreadPreview extends Component {
|
||||
return `/web/image/mail.channel/${this.threadPreviewView.thread.id}/avatar_128?unique=${this.threadPreviewView.thread.avatarCacheKey}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get inline content of the last message of this conversation.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
get inlineLastMessageBody() {
|
||||
if (!this.threadPreviewView.thread.lastMessage) {
|
||||
return '';
|
||||
}
|
||||
return mailUtils.htmlToTextContentInline(this.threadPreviewView.thread.lastMessage.prettyBody);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {ThreadPreviewView}
|
||||
*/
|
||||
|
||||
@@ -45,11 +45,11 @@
|
||||
</t>
|
||||
</div>
|
||||
<div class="o_ThreadPreview_core d-flex align-items-baseline">
|
||||
<span class="o_NotificationListItem_coreItem o_NotificationListItem_inlineText o_ThreadPreview_coreItem o_ThreadPreview_inlineText me-2 text-truncate" t-att-class="{ 'o-empty': inlineLastMessageBody.length === 0 }">
|
||||
<span class="o_NotificationListItem_coreItem o_NotificationListItem_inlineText o_ThreadPreview_coreItem o_ThreadPreview_inlineText me-2 text-truncate" t-att-class="{ 'o-empty': threadPreviewView.isEmpty }">
|
||||
<t t-if="threadPreviewView.messageAuthorPrefixView">
|
||||
<MessageAuthorPrefix record="threadPreviewView.messageAuthorPrefixView"/>
|
||||
</t>
|
||||
<t t-esc="inlineLastMessageBody"/>
|
||||
<span class="o_ThreadPreview_messageBody" t-esc="threadPreviewView.inlineLastMessageBody"/>
|
||||
</span>
|
||||
<span class="flex-grow-1"/>
|
||||
<t t-if="threadPreviewView.thread.localMessageUnreadCounter > 0">
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { registerModel } from '@mail/model/model_core';
|
||||
import { attr, one } from '@mail/model/model_field';
|
||||
import { clear, insertAndReplace } from '@mail/model/model_field_command';
|
||||
import { htmlToTextContentInline } from '@mail/js/utils';
|
||||
|
||||
registerModel({
|
||||
name: 'ThreadNeedactionPreviewView',
|
||||
@@ -34,6 +35,23 @@ registerModel({
|
||||
['res_id', '=', this.thread.id],
|
||||
]);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {string|FieldCommand}
|
||||
*/
|
||||
_computeInlineLastNeedactionMessageAsOriginThreadBody() {
|
||||
if (!this.thread.lastNeedactionMessageAsOriginThread) {
|
||||
return clear();
|
||||
}
|
||||
return htmlToTextContentInline(this.thread.lastNeedactionMessageAsOriginThread.prettyBody);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_computeIsEmpty() {
|
||||
return !this.inlineLastNeedactionMessageAsOriginThreadBody;
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {FieldCommand}
|
||||
@@ -49,6 +67,15 @@ registerModel({
|
||||
},
|
||||
},
|
||||
fields: {
|
||||
inlineLastNeedactionMessageAsOriginThreadBody: attr({
|
||||
compute: '_computeInlineLastNeedactionMessageAsOriginThreadBody',
|
||||
default: "",
|
||||
readonly: true,
|
||||
}),
|
||||
isEmpty: attr({
|
||||
compute: '_computeIsEmpty',
|
||||
readonly: true,
|
||||
}),
|
||||
/**
|
||||
* Reference of the "mark as read" button. Useful to disable the
|
||||
* top-level click handler when clicking on this specific button.
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { registerModel } from '@mail/model/model_core';
|
||||
import { attr, one } from '@mail/model/model_field';
|
||||
import { clear, insertAndReplace } from '@mail/model/model_field_command';
|
||||
import { htmlToTextContentInline } from '@mail/js/utils';
|
||||
|
||||
registerModel({
|
||||
name: 'ThreadPreviewView',
|
||||
@@ -33,6 +34,23 @@ registerModel({
|
||||
this.thread.markAsSeen(this.thread.lastNonTransientMessage);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {string|FieldCommand}
|
||||
*/
|
||||
_computeInlineLastMessageBody() {
|
||||
if (!this.thread.lastMessage) {
|
||||
return clear();
|
||||
}
|
||||
return htmlToTextContentInline(this.thread.lastMessage.prettyBody);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_computeIsEmpty() {
|
||||
return !this.inlineLastMessageBody;
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {FieldCommand}
|
||||
@@ -48,6 +66,15 @@ registerModel({
|
||||
},
|
||||
},
|
||||
fields: {
|
||||
inlineLastMessageBody: attr({
|
||||
compute: '_computeInlineLastMessageBody',
|
||||
default: "",
|
||||
readonly: true,
|
||||
}),
|
||||
isEmpty: attr({
|
||||
compute: '_computeIsEmpty',
|
||||
readonly: true,
|
||||
}),
|
||||
/**
|
||||
* Reference of the "mark as read" button. Useful to disable the
|
||||
* top-level click handler when clicking on this specific button.
|
||||
|
||||
@@ -21,10 +21,18 @@ This module allows a customer to give rating.
|
||||
'assets': {
|
||||
'web.assets_backend': [
|
||||
'rating/static/src/scss/rating_rating_views.scss',
|
||||
'rating/static/src/components/*/*.scss',
|
||||
'rating/static/src/models/*.js',
|
||||
],
|
||||
'web.assets_frontend': [
|
||||
'rating/static/src/scss/rating_templates.scss',
|
||||
],
|
||||
'web.assets_qweb': [
|
||||
'rating/static/src/components/*/*.xml',
|
||||
],
|
||||
'web.tests_assets': [
|
||||
'rating/static/tests/helpers/*.js',
|
||||
],
|
||||
},
|
||||
'license': 'LGPL-3',
|
||||
}
|
||||
|
||||
@@ -25,3 +25,19 @@ class MailMessage(models.Model):
|
||||
('message_id', '!=', False)
|
||||
])
|
||||
return [('id', 'in', ratings.mapped('message_id').ids)]
|
||||
|
||||
def message_format(self, format_reply=True):
|
||||
message_values = super().message_format(format_reply=format_reply)
|
||||
rating_mixin_messages = self.filtered(lambda message: issubclass(self.pool[message.model], self.pool['rating.mixin']))
|
||||
if rating_mixin_messages:
|
||||
ratings = self.env['rating.rating'].sudo().search([('message_id', 'in', rating_mixin_messages.ids), ('consumed', '=', True)])
|
||||
rating_by_message_id = dict((r.message_id.id, r) for r in ratings)
|
||||
for vals in message_values:
|
||||
if vals['id'] in rating_by_message_id:
|
||||
rating = rating_by_message_id[vals['id']]
|
||||
vals['rating'] = [('insert-and-replace', {
|
||||
'id': rating.id,
|
||||
'ratingImageUrl': rating.rating_image_url,
|
||||
'ratingText': rating.rating_text,
|
||||
})]
|
||||
return message_values
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
.o_ThreadNeedactionPreview_ratingImage {
|
||||
height: $font-size-base;
|
||||
width: $font-size-base;
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-inherit="mail.ThreadNeedactionPreview" t-inherit-mode="extension">
|
||||
<xpath expr="//*[hasclass('o_ThreadNeedactionPreview_messageBody')]" position="replace">
|
||||
<t t-if="threadNeedactionPreviewView.isRating">
|
||||
<span class="o_ThreadNeedactionPreview_ratingText">Rating:</span>
|
||||
<img class="o_ThreadNeedactionPreview_ratingImage ml-2" t-att-src="threadNeedactionPreviewView.thread.lastNeedactionMessageAsOriginThread.rating.ratingImageUrl" t-att-alt="threadNeedactionPreviewView.thread.lastNeedactionMessageAsOriginThread.rating.ratingText"/>
|
||||
</t>
|
||||
<t t-else="">$0</t>
|
||||
</xpath>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -0,0 +1,4 @@
|
||||
.o_ThreadPreview_ratingImage {
|
||||
height: $font-size-base;
|
||||
width: $font-size-base;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-inherit="mail.ThreadPreview" t-inherit-mode="extension">
|
||||
<xpath expr="//*[hasclass('o_ThreadPreview_messageBody')]" position="replace">
|
||||
<t t-if="threadPreviewView.isRating">
|
||||
<span class="o_ThreadPreview_ratingText">Rating:</span>
|
||||
<img class="o_ThreadPreview_ratingImage ml-2" t-att-src="threadPreviewView.thread.lastMessage.rating.ratingImageUrl" t-att-alt="threadPreviewView.thread.lastMessage.rating.ratingText"/>
|
||||
</t>
|
||||
<t t-else="">$0</t>
|
||||
</xpath>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -0,0 +1,26 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { addFields, patchModelMethods } from '@mail/model/model_core';
|
||||
import { one } from '@mail/model/model_field';
|
||||
// ensure the model definition is loaded before the patch
|
||||
import '@mail/models/message';
|
||||
|
||||
patchModelMethods('Message', {
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
convertData(data) {
|
||||
const data2 = this._super(data);
|
||||
if ('rating' in data) {
|
||||
data2.rating = data.rating;
|
||||
}
|
||||
return data2;
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
addFields('Message', {
|
||||
rating: one('Rating', {
|
||||
isCausal: true,
|
||||
}),
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { registerModel } from '@mail/model/model_core';
|
||||
import { attr } from '@mail/model/model_field';
|
||||
|
||||
registerModel({
|
||||
name: 'Rating',
|
||||
identifyingFields: ['id'],
|
||||
fields: {
|
||||
id: attr({
|
||||
readonly: true,
|
||||
required: true,
|
||||
}),
|
||||
ratingImageUrl: attr({
|
||||
readonly: true,
|
||||
}),
|
||||
ratingText: attr({
|
||||
readonly: true,
|
||||
}),
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { addFields, addRecordMethods, patchRecordMethods } from '@mail/model/model_core';
|
||||
import { attr } from '@mail/model/model_field';
|
||||
// ensure the model definition is loaded before the patch
|
||||
import '@mail/models/thread_needaction_preview_view';
|
||||
|
||||
patchRecordMethods('ThreadNeedactionPreviewView', {
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_computeIsEmpty() {
|
||||
return this.isRating || this._super();
|
||||
},
|
||||
});
|
||||
|
||||
addRecordMethods('ThreadNeedactionPreviewView', {
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_computeIsRating() {
|
||||
return Boolean(this.thread.lastNeedactionMessageAsOriginThread && this.thread.lastNeedactionMessageAsOriginThread.rating);
|
||||
},
|
||||
});
|
||||
|
||||
addFields('ThreadNeedactionPreviewView', {
|
||||
isRating: attr({
|
||||
compute: '_computeIsRating',
|
||||
readonly: true,
|
||||
}),
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { addFields, addRecordMethods, patchRecordMethods } from '@mail/model/model_core';
|
||||
import { attr } from '@mail/model/model_field';
|
||||
// ensure the model definition is loaded before the patch
|
||||
import '@mail/models/thread_preview_view';
|
||||
|
||||
patchRecordMethods('ThreadPreviewView', {
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_computeIsEmpty() {
|
||||
return this.isRating || this._super();
|
||||
},
|
||||
});
|
||||
|
||||
addRecordMethods('ThreadPreviewView', {
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_computeIsRating() {
|
||||
return Boolean(this.thread.lastMessage && this.thread.lastMessage.rating);
|
||||
},
|
||||
});
|
||||
|
||||
addFields('ThreadPreviewView', {
|
||||
isRating: attr({
|
||||
compute: '_computeIsRating',
|
||||
readonly: true,
|
||||
}),
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import '@mail/../tests/helpers/mock_server'; // ensure mail overrides are applied first
|
||||
|
||||
import { patch } from "@web/core/utils/patch";
|
||||
import { MockServer } from "@web/../tests/helpers/mock_server";
|
||||
|
||||
patch(MockServer.prototype, 'rating', {
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_mockMailMessageMessageFormat(ids) {
|
||||
const formattedMessages = this._super(...arguments);
|
||||
for (const formattedMessage of formattedMessages) {
|
||||
const [rating] = this.getRecords('rating.rating', [
|
||||
['message_id', '=', formattedMessage.id],
|
||||
]);
|
||||
if (rating) {
|
||||
formattedMessage['rating'] = [['insert-and-replace', {
|
||||
'id': rating.id,
|
||||
'ratingImageUrl': rating.rating_image_url,
|
||||
'ratingText': rating.rating_text,
|
||||
}]];
|
||||
}
|
||||
}
|
||||
return formattedMessages;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,5 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { addModelNamesToFetch } from '@mail/../tests/helpers/model_definitions_helpers';
|
||||
|
||||
addModelNamesToFetch(['rating.rating']);
|
||||
@@ -28,6 +28,14 @@ real applications. """,
|
||||
'security/ir.model.access.csv',
|
||||
'security/ir_rule_data.xml',
|
||||
],
|
||||
'assets': {
|
||||
'web.qunit_suite_tests': [
|
||||
'test_mail_full/static/tests/qunit_suite_tests/*.js',
|
||||
],
|
||||
'web.tests_assets': [
|
||||
'test_mail_full/static/tests/helpers/*.js',
|
||||
],
|
||||
},
|
||||
'installable': True,
|
||||
'license': 'LGPL-3',
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { addModelNamesToFetch } from '@mail/../tests/helpers/model_definitions_helpers';
|
||||
|
||||
addModelNamesToFetch(['mail.test.rating']);
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { afterNextRender, start, startServer } from '@mail/../tests/helpers/test_utils';
|
||||
|
||||
QUnit.module('test_mail_full', {}, function () {
|
||||
QUnit.module('thread_needaction_preview_tests.js');
|
||||
|
||||
QUnit.test('rating value displayed on the thread needaction preview', async function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
const pyEnv = await startServer();
|
||||
const resPartnerId1 = pyEnv['res.partner'].create();
|
||||
const mailTestRating1 = pyEnv['mail.test.rating'].create();
|
||||
const mailMessageId1 = pyEnv['mail.message'].create({
|
||||
model: 'mail.test.rating',
|
||||
needaction: true,
|
||||
needaction_partner_ids: [pyEnv.currentPartnerId],
|
||||
res_id: mailTestRating1,
|
||||
});
|
||||
pyEnv['mail.notification'].create({
|
||||
mail_message_id: mailMessageId1,
|
||||
notification_status: 'sent',
|
||||
notification_type: 'inbox',
|
||||
res_partner_id: pyEnv.currentPartnerId,
|
||||
});
|
||||
pyEnv['rating.rating'].create([{
|
||||
consumed: true,
|
||||
message_id: mailMessageId1,
|
||||
partner_id: resPartnerId1,
|
||||
rating_image_url: "/rating/static/src/img/rating_5.png",
|
||||
rating_text: "top",
|
||||
}]);
|
||||
const { afterEvent, createMessagingMenuComponent } = await start();
|
||||
await createMessagingMenuComponent();
|
||||
await afterNextRender(() => afterEvent({
|
||||
eventName: 'o-thread-cache-loaded-messages',
|
||||
func: () => document.querySelector('.o_MessagingMenu_toggler').click(),
|
||||
message: "should wait until inbox loaded initial needaction messages",
|
||||
predicate: ({ threadCache }) => {
|
||||
return threadCache.thread.model === 'mail.box' && threadCache.thread.id === 'inbox';
|
||||
},
|
||||
}));
|
||||
assert.strictEqual(
|
||||
document.querySelector('.o_ThreadNeedactionPreview_ratingText').textContent,
|
||||
"Rating:",
|
||||
"should display the correct content (Rating:)"
|
||||
);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_ThreadNeedactionPreview_ratingImage',
|
||||
"should have a rating image in the body"
|
||||
);
|
||||
assert.strictEqual(
|
||||
$('.o_ThreadNeedactionPreview_ratingImage').attr('data-src'),
|
||||
"/rating/static/src/img/rating_5.png",
|
||||
"should contain the correct rating image"
|
||||
);
|
||||
assert.strictEqual(
|
||||
$('.o_ThreadNeedactionPreview_ratingImage').attr('alt'),
|
||||
"top",
|
||||
"should contain the correct rating text"
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { afterNextRender, start, startServer } from '@mail/../tests/helpers/test_utils';
|
||||
|
||||
QUnit.module('test_mail_full', {}, function () {
|
||||
QUnit.module('thread_preview_tests.js');
|
||||
|
||||
QUnit.test('rating value displayed on the thread preview', async function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
const pyEnv = await startServer();
|
||||
const resPartnerId1 = pyEnv['res.partner'].create();
|
||||
const mailChannelId1 = pyEnv['mail.channel'].create();
|
||||
const mailMessageId1 = pyEnv['mail.message'].create([
|
||||
{ author_id: resPartnerId1, model: 'mail.channel', res_id: mailChannelId1 },
|
||||
]);
|
||||
pyEnv['rating.rating'].create({
|
||||
consumed: true,
|
||||
message_id: mailMessageId1,
|
||||
partner_id: resPartnerId1,
|
||||
rating_image_url: "/rating/static/src/img/rating_5.png",
|
||||
rating_text: "top",
|
||||
});
|
||||
const { afterEvent, createMessagingMenuComponent } = await start();
|
||||
await createMessagingMenuComponent();
|
||||
await afterNextRender(() => afterEvent({
|
||||
eventName: 'o-thread-cache-loaded-messages',
|
||||
func: () => document.querySelector('.o_MessagingMenu_toggler').click(),
|
||||
message: "should wait until inbox loaded initial needaction messages",
|
||||
predicate: ({ threadCache }) => {
|
||||
return threadCache.thread.model === 'mail.box' && threadCache.thread.id === 'inbox';
|
||||
},
|
||||
}));
|
||||
assert.strictEqual(
|
||||
document.querySelector('.o_ThreadPreview_ratingText').textContent,
|
||||
"Rating:",
|
||||
"should display the correct content (Rating:)"
|
||||
);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_ThreadPreview_ratingImage',
|
||||
"should have a rating image in the body"
|
||||
);
|
||||
assert.strictEqual(
|
||||
$('.o_ThreadPreview_ratingImage').attr('data-src'),
|
||||
"/rating/static/src/img/rating_5.png",
|
||||
"should contain the correct rating image"
|
||||
);
|
||||
assert.strictEqual(
|
||||
$('.o_ThreadPreview_ratingImage').attr('alt'),
|
||||
"top",
|
||||
"should contain the correct rating text"
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user