odoo18/addons_extensions/documents/tests/test_documents_multicompany.py

184 lines
9.2 KiB
Python

from odoo.addons.documents.tests.test_documents_common import TransactionCaseDocuments
from odoo import Command
from odoo.exceptions import ValidationError
from odoo.tools import mute_logger
MEMBER_VIEW, INTERNAL_VIEW, MEMBER_INTERNAL_VIEW, OWNER, MEMBER_VIEW_LINK_EDIT, INTERNAL_VIEW_LINK_EDIT = range(6)
class TestDocumentsMulticompany(TransactionCaseDocuments):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.company_allowed, cls.company_other, cls.company_disabled = cls.env['res.company'].create([
{'name': f'Company {name}'} for name in ['Allowed', 'Other', 'Disabled']
])
cls.admin_user = cls.env['res.users'].create({
'email': "an_admin@yourcompany.com",
'groups_id': [Command.link(cls.env.ref('documents.group_documents_system').id)],
'login': "an_admin",
'name': "An Admin",
})
(cls.internal_user + cls.document_manager + cls.portal_user + cls.admin_user).write({
'company_ids': [Command.link(cls.company_allowed.id), Command.link(cls.company_disabled.id)],
})
def _make_test_documents(self, company_id, user):
technical_root = self.env['documents.document'].sudo().create({
'name': 'tech root', 'type': 'folder', 'access_internal': 'none', 'access_via_link': 'none',
'company_id': self.company_other.id, 'owner_id': self.env.ref('base.user_root').id,
})
common = {
'type': 'folder',
'folder_id': technical_root.id,
'access_internal': 'none',
'access_via_link': 'none',
'company_id': company_id
}
documents = (
member_view, _internal_view, member_internal_view, _owner, member_view_link_edit,
_internal_view_link_edit
) = (
self.env['documents.document'].sudo().create([
common | {'name': 'member view'},
common | {'name': 'internal view', 'access_internal': 'view'},
common | {'name': 'member + internal view', 'access_internal': 'view'},
common | {'name': 'owner', 'owner_id': user.id},
common | {'name': 'member view + link edit', 'access_via_link': 'edit'},
common | {'name': 'internal view + link edit', 'access_internal': 'view', 'access_via_link': 'edit'}
])
)
self.env['documents.access'].sudo().create([
{
'document_id': document.id,
'partner_id': user.partner_id.id,
'role': 'view'
} for document in (member_view, member_internal_view, member_view_link_edit)
])
return documents.with_context({'allowed_company_ids': self.company_allowed.ids})
@staticmethod
def _assert_documents_equal(found, expected):
message_items = []
if extra := found - expected:
message_items.append(f'Extra records found: {extra.mapped("name")}')
if missing := expected - found:
message_items.append(f'Missing records: {missing.mapped("name")}')
if message_items:
raise AssertionError(" - ".join(message_items))
@mute_logger('odoo.addons.base.models.ir_rule')
def test_company_access_simple(self):
self.assertEqual(self.folder_b.access_internal, 'view')
self.folder_b.company_id = self.company_allowed
self.folder_b.with_user(self.internal_user).with_company(self.company_allowed).check_access('read')
self._assert_raises_check_access_rule(
self.folder_b.with_user(self.internal_user).with_company(self.company_other), 'read')
def _test_company_with_user(self, cases, user):
"""Test access rights depending on access rights and company.
:param list[tuple] cases: shaped as (company, expected_edit_indices, expected_view_indices) with:
company: company used as documents company_id,
expected_edit_indices: indices for documents with expected 'edit' permission,
expected_view_indices: indices for documents with expected 'view' permission
:param: user used as member or owner when creating documents and to test access for
"""
for company, expected_edit_indices, expected_view_indices in cases:
with self.subTest(company_name=company.name):
Documents_with_ctx = self.env['documents.document'].with_user(user).with_context(
allowed_company_ids=self.company_allowed.ids
)
docs = self._make_test_documents(company.id, user)
expected_view = Documents_with_ctx.browse(docs[idx].id for idx in expected_view_indices)
expected_edit = Documents_with_ctx.browse(docs[idx].id for idx in expected_edit_indices)
search_view = Documents_with_ctx.search([('id', 'in', docs.ids), ('user_permission', '=', 'view')])
with self.subTest(permission='view'):
self._assert_documents_equal(search_view, expected_view)
search_edit = Documents_with_ctx.search([('id', 'in', docs.ids), ('user_permission', '=', 'edit')])
with self.subTest(permission='edit'):
self._assert_documents_equal(search_edit, expected_edit)
expected_user_permissions = [
'view' if document in expected_view else 'edit' if document in expected_edit else 'none'
for document in docs
]
user_permissions = docs.with_user(user).mapped('user_permission')
self.assertListEqual(user_permissions, expected_user_permissions)
@mute_logger('odoo.addons.base.models.ir_rule')
def test_company_access_admin(self):
ALL_DOCUMENTS = list(range(6))
cases = [
(self.env['res.company'], ALL_DOCUMENTS, []),
(self.company_allowed, ALL_DOCUMENTS, []),
(self.company_other, ALL_DOCUMENTS, []),
(self.company_disabled, [], []),
]
self._test_company_with_user(cases, self.admin_user)
@mute_logger('odoo.addons.base.models.ir_rule')
def test_company_access_manager(self):
cases = [
(self.env['res.company'],
[INTERNAL_VIEW, MEMBER_INTERNAL_VIEW, OWNER, MEMBER_VIEW_LINK_EDIT, INTERNAL_VIEW_LINK_EDIT], [MEMBER_VIEW]),
(self.company_allowed,
[INTERNAL_VIEW, OWNER, MEMBER_INTERNAL_VIEW, MEMBER_VIEW_LINK_EDIT, INTERNAL_VIEW_LINK_EDIT], [MEMBER_VIEW]),
(self.company_other, [OWNER, MEMBER_VIEW_LINK_EDIT], [MEMBER_VIEW, MEMBER_INTERNAL_VIEW]),
(self.company_disabled, [], []),
]
self._test_company_with_user(cases, self.document_manager)
@mute_logger('odoo.addons.base.models.ir_rule')
def test_company_access_internal(self):
cases = [
(self.env['res.company'],
[OWNER, MEMBER_VIEW_LINK_EDIT, INTERNAL_VIEW_LINK_EDIT], [MEMBER_VIEW, INTERNAL_VIEW, MEMBER_INTERNAL_VIEW]),
(self.company_allowed,
[OWNER, MEMBER_VIEW_LINK_EDIT, INTERNAL_VIEW_LINK_EDIT], [MEMBER_VIEW, INTERNAL_VIEW, MEMBER_INTERNAL_VIEW]),
(self.company_other, [OWNER, MEMBER_VIEW_LINK_EDIT], [MEMBER_VIEW, MEMBER_INTERNAL_VIEW]),
(self.company_disabled, [], []),
]
self._test_company_with_user(cases, self.internal_user)
@mute_logger('odoo.addons.base.models.ir_rule')
def test_company_access_portal(self):
cases = [
(self.env['res.company'], [OWNER, MEMBER_VIEW_LINK_EDIT], [MEMBER_VIEW, MEMBER_INTERNAL_VIEW]),
(self.company_allowed, [OWNER, MEMBER_VIEW_LINK_EDIT], [MEMBER_VIEW, MEMBER_INTERNAL_VIEW]),
(self.company_other, [OWNER, MEMBER_VIEW_LINK_EDIT], [MEMBER_VIEW, MEMBER_INTERNAL_VIEW]),
(self.company_disabled, [], []),
]
self._test_company_with_user(cases, self.portal_user)
@mute_logger('odoo.addons.base.models.ir_rule')
def test_company_shortcut_mismatch(self):
docs = self._make_test_documents(self.company_allowed.id, self.internal_user)
member_view_link_edit = docs[4]
Documents_with_ctx = self.env['documents.document'].with_user(self.internal_user).with_context(
allowed_company_ids=self.company_allowed.ids
)
self.assertEqual(member_view_link_edit.user_permission, 'edit')
shortcut = member_view_link_edit.action_create_shortcut(False)
self.assertEqual(shortcut.company_id, self.company_allowed)
member_view_link_edit.company_id = self.company_disabled
self.assertFalse(Documents_with_ctx.search([('id', '=', shortcut.id)]))
self.assertEqual(shortcut.user_permission, 'none')
member_view_link_edit.company_id = self.company_allowed
self.assertEqual(shortcut.company_id, self.company_allowed)
with self.assertRaises(ValidationError):
shortcut.sudo().company_id = self.company_disabled
member_view_link_edit.company_id = False
self.assertEqual(shortcut.company_id, self.company_allowed)
self.assertEqual(Documents_with_ctx.search([('id', '=', shortcut.id)]), shortcut)
self.assertEqual(shortcut.user_permission, 'edit')
# todo: access via parent