Added achtung images
[odoo/odoo.git] / addons / mail / tests / test_message_read.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Business Applications
5 #    Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22 from openerp.addons.mail.tests.test_mail_base import TestMailBase
23
24
25 class test_mail_access_rights(TestMailBase):
26
27     def test_00_message_read(self):
28         """ Tests for message_read and expandables. """
29         cr, uid, user_admin, user_raoul, group_pigs = self.cr, self.uid, self.user_admin, self.user_raoul, self.group_pigs
30         self.mail_group.message_subscribe_users(cr, uid, [group_pigs.id], [user_raoul.id])
31         pigs_domain = [('model', '=', 'mail.group'), ('res_id', '=', self.group_pigs_id)]
32
33         # Data: create a discussion in Pigs (3 threads, with respectively 0, 4 and 4 answers)
34         msg_id0 = self.group_pigs.message_post(body='0', subtype='mt_comment')
35         msg_id1 = self.group_pigs.message_post(body='1', subtype='mt_comment')
36         msg_id2 = self.group_pigs.message_post(body='2', subtype='mt_comment')
37         msg_id3 = self.group_pigs.message_post(body='1-1', subtype='mt_comment', parent_id=msg_id1)
38         msg_id4 = self.group_pigs.message_post(body='2-1', subtype='mt_comment', parent_id=msg_id2)
39         msg_id5 = self.group_pigs.message_post(body='1-2', subtype='mt_comment', parent_id=msg_id1)
40         msg_id6 = self.group_pigs.message_post(body='2-2', subtype='mt_comment', parent_id=msg_id2)
41         msg_id7 = self.group_pigs.message_post(body='1-1-1', subtype='mt_comment', parent_id=msg_id3)
42         msg_id8 = self.group_pigs.message_post(body='2-1-1', subtype='mt_comment', parent_id=msg_id4)
43         msg_id9 = self.group_pigs.message_post(body='1-1-1', subtype='mt_comment', parent_id=msg_id3)
44         msg_id10 = self.group_pigs.message_post(body='2-1-1', subtype='mt_comment', parent_id=msg_id4)
45         msg_ids = [msg_id10, msg_id9, msg_id8, msg_id7, msg_id6, msg_id5, msg_id4, msg_id3, msg_id2, msg_id1, msg_id0]
46         ordered_msg_ids = [msg_id2, msg_id4, msg_id6, msg_id8, msg_id10, msg_id1, msg_id3, msg_id5, msg_id7, msg_id9, msg_id0]
47
48         # Test: raoul received notifications
49         raoul_notification_ids = self.mail_notification.search(cr, user_raoul.id, [('read', '=', False), ('message_id', 'in', msg_ids), ('partner_id', '=', user_raoul.partner_id.id)])
50         self.assertEqual(len(raoul_notification_ids), 11, 'message_post: wrong number of produced notifications')
51
52         # Test: read some specific ids
53         read_msg_list = self.mail_message.message_read(cr, user_raoul.id, ids=msg_ids[2:4], domain=[('body', 'like', 'dummy')], context={'mail_read_set_read': True})
54         read_msg_ids = [msg.get('id') for msg in read_msg_list]
55         self.assertEqual(msg_ids[2:4], read_msg_ids, 'message_read with direct ids should read only the requested ids')
56
57         # Test: read messages of Pigs through a domain, being thread or not threaded
58         read_msg_list = self.mail_message.message_read(cr, user_raoul.id, domain=pigs_domain, limit=200)
59         read_msg_ids = [msg.get('id') for msg in read_msg_list]
60         self.assertEqual(msg_ids, read_msg_ids, 'message_read flat with domain on Pigs should equal all messages of Pigs')
61         read_msg_list = self.mail_message.message_read(cr, user_raoul.id, domain=pigs_domain, limit=200, thread_level=1)
62         read_msg_ids = [msg.get('id') for msg in read_msg_list]
63         self.assertEqual(ordered_msg_ids, read_msg_ids,
64             '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')
65
66         # ----------------------------------------
67         # CASE1: message_read with domain, threaded
68         # We simulate an entire flow, using the expandables to test them
69         # ----------------------------------------
70
71         # Do: read last message, threaded
72         read_msg_list = self.mail_message.message_read(cr, uid, domain=pigs_domain, limit=1, thread_level=1)
73         read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
74         # TDE TODO: test expandables order
75         type_list = map(lambda item: item.get('type'), read_msg_list)
76         # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
77         self.assertEqual(len(read_msg_list), 4, 'message_read on last Pigs message should return 2 messages and 2 expandables')
78         self.assertEqual(set([msg_id2, msg_id10]), set(read_msg_ids), 'message_read on the last Pigs message should also get its parent')
79         self.assertEqual(read_msg_list[1].get('parent_id'), read_msg_list[0].get('id'), 'message_read should set the ancestor to the thread header')
80         # Data: get expandables
81         new_threads_exp, new_msg_exp = None, None
82         for msg in read_msg_list:
83             if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('max_limit'):
84                 new_threads_exp = msg
85             elif msg.get('type') == 'expandable':
86                 new_msg_exp = msg
87
88         # Do: fetch new messages in first thread, domain from expandable
89         self.assertIsNotNone(new_msg_exp, 'message_read on last Pigs message should have returned a new messages expandable')
90         domain = new_msg_exp.get('domain', [])
91         # Test: expandable, conditions in domain
92         self.assertIn(('id', 'child_of', msg_id2), domain, 'new messages expandable domain should contain a child_of condition')
93         self.assertIn(('id', '>=', msg_id4), domain, 'new messages expandable domain should contain an id greater than condition')
94         self.assertIn(('id', '<=', msg_id8), domain, 'new messages expandable domain should contain an id less than condition')
95         self.assertEqual(new_msg_exp.get('parent_id'), msg_id2, 'new messages expandable should have parent_id set to the thread header')
96         # Do: message_read with domain, thread_level=0, parent_id=msg_id2 (should be imposed by JS), 2 messages
97         read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=2, thread_level=0, parent_id=msg_id2)
98         read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
99         new_msg_exp = [msg for msg in read_msg_list if msg.get('type') == 'expandable'][0]
100         # Test: structure content, 2 messages and 1 thread expandable
101         self.assertEqual(len(read_msg_list), 3, 'message_read in Pigs thread should return 2 messages and 1 expandables')
102         self.assertEqual(set([msg_id6, msg_id8]), set(read_msg_ids), 'message_read in Pigs thread should return 2 more previous messages in thread')
103         # Do: read the last message
104         read_msg_list = self.mail_message.message_read(cr, uid, domain=new_msg_exp.get('domain'), limit=2, thread_level=0, parent_id=msg_id2)
105         read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
106         # Test: structure content, 1 message
107         self.assertEqual(len(read_msg_list), 1, 'message_read in Pigs thread should return 1 message')
108         self.assertEqual(set([msg_id4]), set(read_msg_ids), 'message_read in Pigs thread should return the last message in thread')
109
110         # Do: fetch a new thread, domain from expandable
111         self.assertIsNotNone(new_threads_exp, 'message_read on last Pigs message should have returned a new threads expandable')
112         domain = new_threads_exp.get('domain', [])
113         # Test: expandable, conditions in domain
114         for condition in pigs_domain:
115             self.assertIn(condition, domain, 'new threads expandable domain should contain the message_read domain parameter')
116         self.assertFalse(new_threads_exp.get('parent_id'), 'new threads expandable should not have an parent_id')
117         # Do: message_read with domain, thread_level=1 (should be imposed by JS)
118         read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=1, thread_level=1)
119         read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
120         # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
121         self.assertEqual(len(read_msg_list), 4, 'message_read on Pigs should return 2 messages and 2 expandables')
122         self.assertEqual(set([msg_id1, msg_id9]), set(read_msg_ids), 'message_read on a Pigs message should also get its parent')
123         self.assertEqual(read_msg_list[1].get('parent_id'), read_msg_list[0].get('id'), 'message_read should set the ancestor to the thread header')
124         # Data: get expandables
125         new_threads_exp, new_msg_exp = None, None
126         for msg in read_msg_list:
127             if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('max_limit'):
128                 new_threads_exp = msg
129             elif msg.get('type') == 'expandable':
130                 new_msg_exp = msg
131
132         # Do: fetch new messages in second thread, domain from expandable
133         self.assertIsNotNone(new_msg_exp, 'message_read on Pigs message should have returned a new messages expandable')
134         domain = new_msg_exp.get('domain', [])
135         # Test: expandable, conditions in domain
136         self.assertIn(('id', 'child_of', msg_id1), domain, 'new messages expandable domain should contain a child_of condition')
137         self.assertIn(('id', '>=', msg_id3), domain, 'new messages expandable domain should contain an id greater than condition')
138         self.assertIn(('id', '<=', msg_id7), domain, 'new messages expandable domain should contain an id less than condition')
139         self.assertEqual(new_msg_exp.get('parent_id'), msg_id1, 'new messages expandable should have ancestor_id set to the thread header')
140         # Do: message_read with domain, thread_level=0, parent_id=msg_id1 (should be imposed by JS)
141         read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=200, thread_level=0, parent_id=msg_id1)
142         read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
143         # Test: other message in thread have been fetch
144         self.assertEqual(set([msg_id3, msg_id5, msg_id7]), set(read_msg_ids), 'message_read on the last Pigs message should also get its parent')
145
146         # Test: fetch a new thread, domain from expandable
147         self.assertIsNotNone(new_threads_exp, 'message_read should have returned a new threads expandable')
148         domain = new_threads_exp.get('domain', [])
149         # Test: expandable, conditions in domain
150         for condition in pigs_domain:
151             self.assertIn(condition, domain, 'general expandable domain should contain the message_read domain parameter')
152         # Do: message_read with domain, thread_level=1 (should be imposed by JS)
153         read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=1, thread_level=1)
154         read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
155         # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
156         self.assertEqual(len(read_msg_list), 1, 'message_read on Pigs should return 1 message because everything else has been fetched')
157         self.assertEqual([msg_id0], read_msg_ids, 'message_read after 2 More should return only 1 last message')
158
159         # ----------------------------------------
160         # CASE2: message_read with domain, flat
161         # ----------------------------------------
162
163         # Do: read 2 lasts message, flat
164         read_msg_list = self.mail_message.message_read(cr, uid, domain=pigs_domain, limit=2, thread_level=0)
165         read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
166         # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is not set, 1 expandable
167         self.assertEqual(len(read_msg_list), 3, 'message_read on last Pigs message should return 2 messages and 1 expandable')
168         self.assertEqual(set([msg_id9, msg_id10]), set(read_msg_ids), 'message_read flat on Pigs last messages should only return those messages')
169         self.assertFalse(read_msg_list[0].get('parent_id'), 'message_read flat should set the ancestor as False')
170         self.assertFalse(read_msg_list[1].get('parent_id'), 'message_read flat should set the ancestor as False')
171         # Data: get expandables
172         new_threads_exp, new_msg_exp = None, None
173         for msg in read_msg_list:
174             if msg.get('type') == 'expandable' and msg.get('nb_messages') == -1 and msg.get('max_limit'):
175                 new_threads_exp = msg
176
177         # Do: fetch new messages, domain from expandable
178         self.assertIsNotNone(new_threads_exp, 'message_read flat on the 2 last Pigs messages should have returns a new threads expandable')
179         domain = new_threads_exp.get('domain', [])
180         # Test: expandable, conditions in domain
181         for condition in pigs_domain:
182             self.assertIn(condition, domain, 'new threads expandable domain should contain the message_read domain parameter')
183         # Do: message_read with domain, thread_level=0 (should be imposed by JS)
184         read_msg_list = self.mail_message.message_read(cr, uid, domain=domain, limit=20, thread_level=0)
185         read_msg_ids = [msg.get('id') for msg in read_msg_list if msg.get('type') != 'expandable']
186         # Test: structure content, ancestor is added to the read messages, ordered by id, ancestor is set, 2 expandables
187         self.assertEqual(len(read_msg_list), 9, 'message_read on Pigs should return 9 messages and 0 expandable')
188         self.assertEqual([msg_id8, msg_id7, msg_id6, msg_id5, msg_id4, msg_id3, msg_id2, msg_id1, msg_id0], read_msg_ids,
189             'message_read, More on flat, should return all remaning messages')