Files
odoo_source/addons/mail/tests/test_message_read.py
T
Valerie Pirenne c24332e6da [IMP][ADD] mail, various: timeline view.
This commit introduces a new view type, the timeline view. This view is
intended to display messages like the previous chatter. This is now a view
like the form or list view. Like other views it will be possible to have
custom templates for some specific needs, allowing customization.

[IMP] mail: the value tracking is modified. Previously messages were created
containing the modified values. Those values are now stored, using a new
model mail.tracking.value. The message body is dynamically build based on
the values. Tests have been updated.

This version is temporary. Indeed two main modifications will come in a short
future :

 - the new design will improve the display
 - the slack mode will change the way the Inbox and notifications are managed

All glory to the Hypnotoad.

Special thanks to Valerie Pirenne (vpi), Jerome Maes (jem) and Richat Mathot
(rim) that did not code but said a lot of things. Martin Trigaux (mat) did
nothing, a bit like for the slides modules, but he is busy sending emails.
2015-05-21 12:10:25 +02:00

171 lines
15 KiB
Python

# -*- coding: utf-8 -*-
from openerp.addons.mail.tests.common import TestMail
from openerp.tools import mute_logger
class TestMessageRead(TestMail):
@mute_logger('openerp.addons.mail.models.mail_mail')
def setUp(self):
super(TestMessageRead, self).setUp()
self.group_pigs.message_subscribe_users([self.user_employee.id])
self.msg_0 = self.group_pigs.message_post(body='0', subtype='mt_comment')
self.msg_1 = self.group_pigs.message_post(body='1', subtype='mt_comment')
self.msg_2 = self.group_pigs.message_post(body='2', subtype='mt_comment')
self.msg_3 = self.group_pigs.message_post(body='1-1', subtype='mt_comment', parent_id=self.msg_1.id)
self.msg_4 = self.group_pigs.message_post(body='2-1', subtype='mt_comment', parent_id=self.msg_2.id)
self.msg_5 = self.group_pigs.message_post(body='1-2', subtype='mt_comment', parent_id=self.msg_1.id)
self.msg_6 = self.group_pigs.message_post(body='2-2', subtype='mt_comment', parent_id=self.msg_2.id)
self.msg_7 = self.group_pigs.message_post(body='1-1-1', subtype='mt_comment', parent_id=self.msg_1.id)
self.msg_8 = self.group_pigs.message_post(body='2-1-1', subtype='mt_comment', parent_id=self.msg_2.id)
self.msg_9 = self.group_pigs.message_post(body='1-1-1', subtype='mt_comment', parent_id=self.msg_1.id)
self.msg_10 = self.group_pigs.message_post(body='2-1-1', subtype='mt_comment', parent_id=self.msg_2.id)
self.msg_ids = [self.msg_10.id, self.msg_9.id, self.msg_8.id, self.msg_7.id, self.msg_6.id, self.msg_5.id, self.msg_4.id, self.msg_3.id, self.msg_2.id, self.msg_1.id, self.msg_0.id]
self.ordered_msg_ids = [self.msg_10.id, self.msg_8.id, self.msg_6.id, self.msg_4.id, self.msg_2.id, self.msg_9.id, self.msg_7.id, self.msg_5.id, self.msg_3.id, self.msg_1.id, self.msg_0.id]
# TODO: with_context({'mail_read_set_read': True})
def test_message_read_ids(self):
""" message_read: test reading specific ids """
messages = self.env['mail.message'].sudo(self.user_employee).browse(self.msg_ids[2:4]).message_read(domain=[('body', 'like', 'dummy')])
read_msg_list = messages['threads'][0]
msg_ids = [msg.get('id') for msg in read_msg_list]
self.assertEqual(msg_ids, self.msg_ids[2:4], 'message_read with direct ids should read only the requested ids')
def test_message_read_domain(self):
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs.id)], limit=200, child_limit=200)
read_msg_list = [msg for thread in messages['threads'] for msg in thread]
read_msg_ids = [msg.get('id') for msg in read_msg_list]
self.assertEqual(read_msg_ids, self.msg_ids, 'message_read flat with domain on Pigs should equal all messages of Pigs')
def test_message_read_domain_thread(self):
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs.id)], thread_level=1, limit=200, child_limit=200)
read_msg_list = [msg for thread in messages['threads'] for msg in thread]
read_msg_ids = [msg.get('id') for msg in read_msg_list]
self.assertEqual(read_msg_ids, self.ordered_msg_ids, 'message_read threaded with domain on Pigs should equal all messages of Pigs, and sort them with newer thread first, last message last in thread')
def test_message_read_expandable(self):
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs.id)], thread_level=1, limit=1, child_limit=1)
read_msg_list = [msg for thread in messages['threads'] for msg in thread]
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('message_type') != 'expandable']
read_ancestor_ids = [msg.get('parent_id') if msg.get('parent_id') != 0 else msg.get('id') for msg in read_msg_list if msg.get('message_type') != 'expandable']
type_list = [msg.get('message_type') for msg in read_msg_list]
# Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
self.assertEqual(len(type_list), 4, 'message_read on last Pigs message should return 2 messages and 2 expandables')
self.assertEqual(set([self.msg_2.id, self.msg_10.id]), set(read_msg_ids), 'message_read on the last Pigs message should also get its parent')
self.assertEqual(read_ancestor_ids[0], read_ancestor_ids[1], 'message_read should set the ancestor to the thread header')
# Data: get expandables
new_threads_exp, new_msg_exp = None, None
new_threads_exp = read_msg_list[-1]
for msg in read_msg_list:
if msg.get('parent_id') and msg.get('message_type') == 'expandable':
new_msg_exp = msg
# Do: fetch new messages in first thread, domain from expandable
self.assertIsNotNone(new_msg_exp, 'message_read on last Pigs message should have returned a new messages expandable')
domain = new_msg_exp.get('domain', [])
# Test: expandable, conditions in domain
self.assertIn(('parent_id', '=', self.msg_2.id), domain, 'new messages expandable domain should contain a child_of condition')
self.assertIn(('id', '>', self.msg_2.id), domain, 'new messages expandable domain should contain an id greater than condition')
self.assertIn(('id', '<', self.msg_10.id), domain, 'new messages expandable domain should contain an id less than condition')
self.assertEqual(new_msg_exp.get('parent_id'), self.msg_2.id, 'new messages expandable should have parent_id set to the thread header')
# Do: message_read with domain, thread_level=0, parent_id=msg_id2 (should be imposed by JS), 2 messages
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=domain, thread_level=0, limit=2)
read_msg_list = [msg for thread in messages['threads'] for msg in thread]
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('message_type') != 'expandable']
new_msg_exp = [msg for msg in read_msg_list if msg.get('message_type') == 'expandable'][0]
# Test: structure content, 2 messages and 1 thread expandable
self.assertEqual(len(read_msg_list), 3, 'message_read in Pigs thread should return 2 messages and 1 expandables')
self.assertEqual(set([self.msg_6.id, self.msg_8.id]), set(read_msg_ids), 'message_read in Pigs thread should return 2 more previous messages in thread')
# Do: read the last message
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=new_msg_exp.get('domain'), thread_level=0, limit=2)
read_msg_list = [msg for thread in messages['threads'] for msg in thread]
read_msg_ids = [msg.get('id') for msg in read_msg_list]
# Test: structure content, 1 message
self.assertEqual(len(read_msg_list), 1, 'message_read in Pigs thread should return 1 message')
self.assertEqual(set([self.msg_4.id]), set(read_msg_ids), 'message_read in Pigs thread should return the last message in thread')
# Do: fetch a new thread, domain from expandable
self.assertIsNotNone(new_threads_exp, 'message_read on last Pigs message should have returned a new threads expandable')
domain = new_threads_exp.get('domain', [])
# Test: expandable, conditions in domain
for condition in [('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs.id)]:
self.assertIn(condition, domain, 'new threads expandable domain should contain the message_read domain parameter')
self.assertFalse(new_threads_exp.get('parent_id'), 'new threads expandable should not have an parent_id')
# Do: message_read with domain, thread_level=1 (should be imposed by JS)
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=domain, thread_level=1, limit=1, child_limit=1)
read_msg_list = [msg for thread in messages['threads'] for msg in thread]
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('message_type') != 'expandable']
read_ancestor_ids = [msg.get('parent_id') if msg.get('parent_id') != 0 else msg.get('id') for msg in read_msg_list if msg.get('message_type') != 'expandable']
type_list = [msg.get('message_type') for msg in read_msg_list]
# Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
self.assertEqual(len(type_list), 4, 'message_read on Pigs should return 2 messages and 2 expandables')
self.assertEqual(set([self.msg_1.id, self.msg_9.id]), set(read_msg_ids), 'message_read on a Pigs message should also get its parent')
self.assertEqual(read_ancestor_ids[0], read_ancestor_ids[1], 'message_read should set the ancestor to the thread header')
# Data: get expandables
new_threads_exp, new_msg_exp = None, None
new_threads_exp = read_msg_list[-1]
for msg in read_msg_list:
if msg.get('parent_id') and msg.get('message_type') == 'expandable':
new_msg_exp = msg
# Do: fetch new messages in second thread, domain from expandable
self.assertIsNotNone(new_msg_exp, 'message_read on Pigs message should have returned a new messages expandable')
domain = new_msg_exp.get('domain', [])
# Test: expandable, conditions in domain
self.assertIn(('parent_id', '=', self.msg_1.id), domain, 'new messages expandable domain should contain a child_of condition')
self.assertIn(('id', '>', self.msg_1.id), domain, 'new messages expandable domain should contain an id greater than condition')
self.assertIn(('id', '<', self.msg_9.id), domain, 'new messages expandable domain should contain an id less than condition')
self.assertEqual(new_msg_exp.get('parent_id'), self.msg_1.id, 'new messages expandable should have ancestor_id set to the thread header')
# Do: message_read with domain, thread_level=0, parent_id=msg_id1 (should be imposed by JS)
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=domain, thread_level=0, limit=200)
read_msg_list = [msg for thread in messages['threads'] for msg in thread]
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('message_type') != 'expandable']
# Test: other message in thread have been fetch
self.assertEqual(set([self.msg_3.id, self.msg_5.id, self.msg_7.id]), set(read_msg_ids), 'message_read on the last Pigs message should also get its parent')
# Test: fetch a new thread, domain from expandable
self.assertIsNotNone(new_threads_exp, 'message_read should have returned a new threads expandable')
domain = new_threads_exp.get('domain', [])
# Test: expandable, conditions in domain
for condition in [('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs.id)]:
self.assertIn(condition, domain, 'general expandable domain should contain the message_read domain parameter')
# Do: message_read with domain, thread_level=1 (should be imposed by JS)
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=domain, thread_level=1, limit=1, child_limit=1)
read_msg_list = [msg for thread in messages['threads'] for msg in thread]
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('message_type') != 'expandable']
type_list = [msg.get('message_type') for msg in read_msg_list]
# Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
self.assertEqual(len(type_list), 1, 'message_read on Pigs should return 1 message because everything else has been fetched')
self.assertEqual([self.msg_0.id], read_msg_ids, 'message_read after 2 More should return only 1 last message')
# ----------------------------------------
# CASE2: message_read with domain, flat
# ----------------------------------------
# Do: read 2 lasts message, flat
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=[('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs.id)], thread_level=0, limit=2)
read_msg_list = [msg for thread in messages['threads'] for msg in thread]
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('message_type') != 'expandable']
# Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is not set, 1 expandable
self.assertEqual(len(read_msg_list), 3, 'message_read on last Pigs message should return 2 messages and 1 expandable')
self.assertEqual(set([self.msg_9.id, self.msg_10.id]), set(read_msg_ids), 'message_read flat on Pigs last messages should only return those messages')
self.assertFalse(read_msg_list[0].get('parent_id'), 'message_read flat should set the ancestor as False')
self.assertFalse(read_msg_list[1].get('parent_id'), 'message_read flat should set the ancestor as False')
# Data: get expandables
new_msg_exp = None
for msg in read_msg_list:
if msg.get('message_type') == 'expandable':
new_msg_exp = msg
# Do: fetch new messages, domain from expandable
self.assertIsNotNone(new_msg_exp, 'message_read flat on the 2 last Pigs messages should have returns a new threads expandable')
domain = new_msg_exp.get('domain', [])
# Test: expandable, conditions in domain
for condition in [('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs.id)]:
self.assertIn(condition, domain, 'new threads expandable domain should contain the message_read domain parameter')
# Do: message_read with domain, thread_level=0 (should be imposed by JS)
messages = self.env['mail.message'].sudo(self.user_employee).message_read(domain=domain, thread_level=0, limit=20)
read_msg_list = [msg for thread in messages['threads'] for msg in thread]
read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('message_type') != 'expandable']
# Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
self.assertEqual(len(read_msg_list), 9, 'message_read on Pigs should return 9 messages and 0 expandable')
self.assertEqual([self.msg_8.id, self.msg_7.id, self.msg_6.id, self.msg_5.id, self.msg_4.id, self.msg_3.id, self.msg_2.id, self.msg_1.id, self.msg_0.id], read_msg_ids,
'message_read, More on flat, should return all remaning messages')