1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Business Applications
5 # Copyright (c) 2013-TODAY OpenERP S.A. <http://openerp.com>
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.
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.
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/>.
20 ##############################################################################
22 from openerp.addons.project.tests.test_project_base import TestProjectBase
23 from openerp.exceptions import AccessError
24 from openerp.osv.orm import except_orm
25 from openerp.tools import mute_logger
28 class TestPortalProjectBase(TestProjectBase):
31 super(TestPortalProjectBase, self).setUp()
32 cr, uid = self.cr, self.uid
35 group_portal_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_portal')
36 self.group_portal_id = group_portal_ref and group_portal_ref[1] or False
39 group_public_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_public')
40 self.group_public_id = group_public_ref and group_public_ref[1] or False
42 # # Test users to use through the various tests
43 self.user_portal_id = self.res_users.create(cr, uid, {
44 'name': 'Chell Portal',
46 'alias_name': 'chell',
47 'groups_id': [(6, 0, [self.group_portal_id])]
49 self.user_public_id = self.res_users.create(cr, uid, {
50 'name': 'Donovan Public',
52 'alias_name': 'donovan',
53 'groups_id': [(6, 0, [self.group_public_id])]
55 self.user_manager_id = self.res_users.create(cr, uid, {
56 'name': 'Eustache Manager',
58 'alias_name': 'eustache',
59 'groups_id': [(6, 0, [self.group_project_manager_id])]
63 self.project_pigs_id = self.project_project.create(cr, uid, {
64 'name': 'Pigs', 'privacy_visibility': 'public'}, {'mail_create_nolog': True})
66 self.task_1_id = self.project_task.create(cr, uid, {
67 'name': 'Test1', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
68 self.task_2_id = self.project_task.create(cr, uid, {
69 'name': 'Test2', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
70 self.task_3_id = self.project_task.create(cr, uid, {
71 'name': 'Test3', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
72 self.task_4_id = self.project_task.create(cr, uid, {
73 'name': 'Test4', 'user_id': self.user_projectuser_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
74 self.task_5_id = self.project_task.create(cr, uid, {
75 'name': 'Test5', 'user_id': self.user_portal_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
76 self.task_6_id = self.project_task.create(cr, uid, {
77 'name': 'Test6', 'user_id': self.user_public_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
80 class TestPortalProject(TestPortalProjectBase):
81 @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
82 def test_00_project_access_rights(self):
83 """ Test basic project access rights, for project and portal_project """
84 cr, uid, pigs_id = self.cr, self.uid, self.project_pigs_id
86 # ----------------------------------------
87 # CASE1: public project
88 # ----------------------------------------
90 # Do: Alfred reads project -> ok (employee ok public)
91 self.project_project.read(cr, self.user_projectuser_id, [pigs_id], ['state'])
92 # Test: all project tasks visible
93 task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
94 test_task_ids = set([self.task_1_id, self.task_2_id, self.task_3_id, self.task_4_id, self.task_5_id, self.task_6_id])
95 self.assertEqual(set(task_ids), test_task_ids,
96 'access rights: project user cannot see all tasks of a public project')
97 # Test: all project tasks readable
98 self.project_task.read(cr, self.user_projectuser_id, task_ids, ['name'])
99 # Test: all project tasks writable
100 self.project_task.write(cr, self.user_projectuser_id, task_ids, {'description': 'TestDescription'})
102 # Do: Bert reads project -> crash, no group
103 self.assertRaises(AccessError, self.project_project.read, cr, self.user_none_id, [pigs_id], ['state'])
104 # Test: no project task visible
105 self.assertRaises(AccessError, self.project_task.search, cr, self.user_none_id, [('project_id', '=', pigs_id)])
106 # Test: no project task readable
107 self.assertRaises(AccessError, self.project_task.read, cr, self.user_none_id, task_ids, ['name'])
108 # Test: no project task writable
109 self.assertRaises(AccessError, self.project_task.write, cr, self.user_none_id, task_ids, {'description': 'TestDescription'})
111 # Do: Chell reads project -> ok (portal ok public)
112 self.project_project.read(cr, self.user_portal_id, [pigs_id], ['state'])
113 # Test: all project tasks visible
114 task_ids = self.project_task.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
115 self.assertEqual(set(task_ids), test_task_ids,
116 'access rights: project user cannot see all tasks of a public project')
117 # Test: all project tasks readable
118 self.project_task.read(cr, self.user_portal_id, task_ids, ['name'])
119 # Test: no project task writable
120 self.assertRaises(AccessError, self.project_task.write, cr, self.user_portal_id, task_ids, {'description': 'TestDescription'})
122 # Do: Donovan reads project -> ok (public)
123 self.project_project.read(cr, self.user_public_id, [pigs_id], ['state'])
124 # Test: all project tasks visible
125 task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
126 self.assertEqual(set(task_ids), test_task_ids,
127 'access rights: public user cannot see all tasks of a public project')
128 # Test: all project tasks readable
129 self.project_task.read(cr, self.user_public_id, task_ids, ['name'])
130 # Test: no project task writable
131 self.assertRaises(AccessError, self.project_task.write, cr, self.user_public_id, task_ids, {'description': 'TestDescription'})
133 # ----------------------------------------
134 # CASE2: portal project
135 # ----------------------------------------
136 self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'portal'})
137 self.project_project.invalidate_cache(cr, uid)
139 # Do: Alfred reads project -> ok (employee ok public)
140 self.project_project.read(cr, self.user_projectuser_id, [pigs_id], ['state'])
141 # Test: all project tasks visible
142 task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
143 self.assertEqual(set(task_ids), test_task_ids,
144 'access rights: project user cannot see all tasks of a portal project')
146 # Do: Bert reads project -> crash, no group
147 self.assertRaises(AccessError, self.project_project.read, cr, self.user_none_id, [pigs_id], ['state'])
148 # Test: no project task searchable
149 self.assertRaises(AccessError, self.project_task.search, cr, self.user_none_id, [('project_id', '=', pigs_id)])
151 # Data: task follower
152 self.project_project.message_subscribe_users(cr, self.user_manager_id, [pigs_id], [self.user_portal_id])
153 self.project_task.message_subscribe_users(cr, self.user_projectuser_id, [self.task_1_id, self.task_3_id], [self.user_portal_id])
155 # Do: Chell reads project -> ok (portal ok portal)
156 self.project_project.read(cr, self.user_portal_id, [pigs_id], ['state'])
158 # Do: Donovan reads project -> ko (public ko portal)
159 self.assertRaises(except_orm, self.project_project.read, cr, self.user_public_id, [pigs_id], ['state'])
160 # Test: no project task visible
161 task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
162 self.assertFalse(task_ids, 'access rights: public user should not see tasks of a portal project')
164 # Data: task follower cleaning
165 self.project_task.message_unsubscribe_users(cr, self.user_projectuser_id, [self.task_1_id, self.task_3_id], [self.user_portal_id])
167 # ----------------------------------------
168 # CASE3: employee project
169 # ----------------------------------------
170 self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'employees'})
171 self.project_project.invalidate_cache(cr, uid)
173 # Do: Alfred reads project -> ok (employee ok employee)
174 self.project_project.read(cr, self.user_projectuser_id, [pigs_id], ['state'])
175 # Test: all project tasks visible
176 task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
177 test_task_ids = set([self.task_1_id, self.task_2_id, self.task_3_id, self.task_4_id, self.task_5_id, self.task_6_id])
178 self.assertEqual(set(task_ids), test_task_ids,
179 'access rights: project user cannot see all tasks of an employees project')
181 # Do: Bert reads project -> crash, no group
182 self.assertRaises(AccessError, self.project_project.read, cr, self.user_none_id, [pigs_id], ['state'])
184 # Do: Chell reads project -> ko (portal ko employee)
185 self.assertRaises(except_orm, self.project_project.read, cr, self.user_portal_id, [pigs_id], ['state'])
186 # Test: no project task visible + assigned
187 task_ids = self.project_task.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
188 self.assertFalse(task_ids, 'access rights: portal user should not see tasks of an employees project, even if assigned')
190 # Do: Donovan reads project -> ko (public ko employee)
191 self.assertRaises(except_orm, self.project_project.read, cr, self.user_public_id, [pigs_id], ['state'])
192 # Test: no project task visible
193 task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
194 self.assertFalse(task_ids, 'access rights: public user should not see tasks of an employees project')
196 # Do: project user is employee and can create a task
197 tmp_task_id = self.project_task.create(cr, self.user_projectuser_id, {
198 'name': 'Pigs task', 'project_id': pigs_id
199 }, {'mail_create_nolog': True})
200 self.project_task.unlink(cr, self.user_projectuser_id, [tmp_task_id])
202 # ----------------------------------------
203 # CASE4: followers project
204 # ----------------------------------------
205 self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'followers'})
206 self.project_project.invalidate_cache(cr, uid)
208 # Do: Alfred reads project -> ko (employee ko followers)
209 self.assertRaises(except_orm, self.project_project.read, cr, self.user_projectuser_id, [pigs_id], ['state'])
210 # Test: no project task visible
211 task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
212 test_task_ids = set([self.task_4_id])
213 self.assertEqual(set(task_ids), test_task_ids,
214 'access rights: employee user should not see tasks of a not-followed followers project, only assigned')
216 # Do: Bert reads project -> crash, no group
217 self.assertRaises(AccessError, self.project_project.read, cr, self.user_none_id, [pigs_id], ['state'])
219 # Do: Chell reads project -> ko (portal ko followers)
220 self.project_project.message_unsubscribe_users(cr, self.user_portal_id, [pigs_id], [self.user_portal_id])
221 self.assertRaises(except_orm, self.project_project.read, cr, self.user_portal_id, [pigs_id], ['state'])
222 # Test: no project task visible
223 task_ids = self.project_task.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
224 test_task_ids = set([self.task_5_id])
225 self.assertEqual(set(task_ids), test_task_ids,
226 'access rights: portal user should not see tasks of a not-followed followers project, only assigned')
228 # Do: Donovan reads project -> ko (public ko employee)
229 self.assertRaises(except_orm, self.project_project.read, cr, self.user_public_id, [pigs_id], ['state'])
230 # Test: no project task visible
231 task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
232 self.assertFalse(task_ids, 'access rights: public user should not see tasks of a followers project')
234 # Data: subscribe Alfred, Chell and Donovan as follower
235 self.project_project.message_subscribe_users(cr, uid, [pigs_id], [self.user_projectuser_id, self.user_portal_id, self.user_public_id])
236 self.project_task.message_subscribe_users(cr, self.user_manager_id, [self.task_1_id, self.task_3_id], [self.user_portal_id, self.user_projectuser_id])
238 # Do: Alfred reads project -> ok (follower ok followers)
239 self.project_project.read(cr, self.user_projectuser_id, [pigs_id], ['state'])
241 # Do: Chell reads project -> ok (follower ok follower)
242 self.project_project.read(cr, self.user_portal_id, [pigs_id], ['state'])
244 # Do: Donovan reads project -> ko (public ko follower even if follower)
245 self.assertRaises(except_orm, self.project_project.read, cr, self.user_public_id, [pigs_id], ['state'])
247 # Do: project user is follower of the project and can create a task
248 self.project_task.create(cr, self.user_projectuser_id, {
249 'name': 'Pigs task', 'project_id': pigs_id
250 }, {'mail_create_nolog': True})
252 # not follower user should not be able to create a task
253 self.project_project.message_unsubscribe_users(cr, self.user_projectuser_id, [pigs_id], [self.user_projectuser_id])
254 self.assertRaises(except_orm,
255 self.project_task.create, cr, self.user_projectuser_id, {'name': 'Pigs task', 'project_id': pigs_id}, {'mail_create_nolog': True}
258 # Do: project user can create a task without project
259 self.project_task.create(cr, self.user_projectuser_id, {
260 'name': 'Pigs task', 'project_id': False
261 }, {'mail_create_nolog': True})