375 lines
18 KiB
Python
375 lines
18 KiB
Python
from odoo import Command
|
|
from odoo.exceptions import UserError
|
|
from odoo.fields import Domain
|
|
from odoo.tests import users
|
|
|
|
from odoo.addons.documents.controllers.documents import ShareRoute
|
|
from odoo.addons.documents.tests.test_documents_common import TransactionCaseDocuments
|
|
|
|
|
|
class TestDocumentsUserFolder(TransactionCaseDocuments):
|
|
|
|
def assertDocumentsEqual(self, actual, expected):
|
|
missing = (expected - actual).mapped("name")
|
|
extra = (actual - expected).mapped("name")
|
|
msg = f"{f'Missing: {missing}, ' if missing else ''}{f'Unexpected: {extra}' if extra else ''}"
|
|
self.assertEqual(actual, expected, msg=msg)
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.document_sys_admin = cls.env['res.users'].create([
|
|
{
|
|
'group_ids': [Command.link(cls.env.ref('documents.group_documents_system').id)],
|
|
'login': "doc_system",
|
|
'name': "Documents System Administrator",
|
|
},
|
|
])
|
|
(
|
|
cls.company_doc,
|
|
cls.company_restr_doc,
|
|
cls.internal_drive,
|
|
cls.company_folder,
|
|
cls.company_restr_folder,
|
|
) = cls.env['documents.document'].sudo().create([
|
|
{'name': 'Company Document', 'owner_id': False, 'access_internal': 'view'},
|
|
{'name': 'Company Document Restricted', 'owner_id': False},
|
|
{
|
|
'name': "Internal User's Drive Document",
|
|
'owner_id': cls.internal_user.id,
|
|
'type': 'folder',
|
|
},
|
|
{
|
|
'name': 'Company Folder',
|
|
'type': 'folder',
|
|
'access_internal': 'edit',
|
|
'owner_id': False,
|
|
},
|
|
{
|
|
'name': 'Company Restricted Folder',
|
|
'type': 'folder',
|
|
'access_internal': 'none',
|
|
'owner_id': False,
|
|
'access_ids': False,
|
|
},
|
|
])
|
|
|
|
cls.sub_company_admin, cls.sub_drive_admin = cls.env['documents.document'].sudo().create([{
|
|
'name': f'{label} Admin Subfolder',
|
|
'type': 'folder',
|
|
'folder_id': folder.id,
|
|
'owner_id': False,
|
|
'access_internal': 'none',
|
|
'access_ids': False,
|
|
} for label, folder in (('Company', cls.company_folder), ('Drive', cls.internal_drive))])
|
|
(
|
|
cls.shared_doc_company_sub,
|
|
cls.shared_doc_drive,
|
|
cls.shared_doc_company
|
|
) = cls.env["documents.document"].create([{
|
|
'name': f'{label} Shared doc',
|
|
'folder_id': folder.id,
|
|
'access_internal': 'view',
|
|
} for (label, folder) in (
|
|
('Company', cls.sub_company_admin),
|
|
('Drive', cls.sub_drive_admin),
|
|
('Company Restricted', cls.company_restr_folder))
|
|
])
|
|
cls.test_documents = (
|
|
cls.company_doc # no owner, access_internal='view'
|
|
| cls.company_restr_doc # no owner, but no access to internal users
|
|
| cls.internal_drive # internal_user's drive
|
|
| cls.folder_a # doc_user's drive
|
|
| cls.folder_a_a
|
|
| cls.folder_b # doc_user's drive
|
|
| cls.company_folder
|
|
| cls.sub_company_admin # Company subfolder, restricted
|
|
| cls.shared_doc_company_sub
|
|
| cls.sub_drive_admin # internal_user's drive subfolder, restricted
|
|
| cls.shared_doc_drive
|
|
| cls.company_restr_folder
|
|
| cls.shared_doc_company # Company folder, restricted
|
|
)
|
|
cls.folder_a.action_update_access_rights(
|
|
access_internal='edit',
|
|
partners={cls.portal_user.partner_id: ('view', False)}
|
|
)
|
|
# Log access to folder_a
|
|
for user in cls.doc_user, cls.document_sys_admin, cls.portal_user, cls.internal_user:
|
|
ShareRoute._upsert_last_access_date(cls.env(user=user), cls.folder_a)
|
|
|
|
cls.company_restr_doc.action_update_access_rights(partners={cls.doc_user.partner_id: ('view', False)})
|
|
cls.env['documents.document'].search([('id', 'not in', cls.test_documents.ids)]).action_archive()
|
|
|
|
@users('dtdm')
|
|
def test_create_with_default_user_folder_id(self):
|
|
context = {'default_user_folder_id': 'COMPANY'}
|
|
no_folder = self.env['documents.document']
|
|
no_user = self.env['res.users']
|
|
cases = [
|
|
(
|
|
{'name': 'Company root, no vals'},
|
|
{'folder_id': no_folder, 'owner_id': no_user}
|
|
), (
|
|
{'name': 'In folder A > A from folder_id in vals', 'folder_id': self.folder_a_a.id},
|
|
{'folder_id': self.folder_a_a, 'owner_id': self.document_manager, 'user_folder_id': str(self.folder_a_a.id)}
|
|
), (
|
|
{'name': 'In folder A from user_folder_id in vals', 'user_folder_id': str(self.folder_a.id)},
|
|
{'folder_id': self.folder_a, 'owner_id': self.document_manager, 'user_folder_id': str(self.folder_a.id)}
|
|
), (
|
|
{'name': 'In My Drive from user_folder_id in vals', 'user_folder_id': 'MY'},
|
|
{'folder_id': no_folder, 'owner_id': self.document_manager, 'user_folder_id': 'MY'}
|
|
), (
|
|
{'name': 'In My Drive from owner_id in vals', 'owner_id': self.document_manager.id},
|
|
{'folder_id': no_folder, 'owner_id': self.document_manager, 'user_folder_id': 'MY'}
|
|
)
|
|
]
|
|
for vals, expected in cases:
|
|
with self.subTest(vals=vals):
|
|
doc = self.env['documents.document'].with_context(context).create(vals)
|
|
for key, value in expected.items():
|
|
self.assertEqual(doc[key], value)
|
|
|
|
@users('internal_user')
|
|
def test_create_write_user_folder_id(self):
|
|
defaults, company, my, folder_a_b, folder_a_b_2 = self.env['documents.document'].with_context(
|
|
default_folder_id=self.folder_a_a.id,
|
|
default_owner_id=self.doc_user.id,
|
|
).create([
|
|
{
|
|
'name': 'defaults',
|
|
},
|
|
{
|
|
'name': 'Company document',
|
|
'user_folder_id': 'COMPANY',
|
|
}, {
|
|
'name': 'My Drive Document',
|
|
'user_folder_id': 'MY',
|
|
}, {
|
|
'name': 'Folder A/B',
|
|
'type': 'folder',
|
|
'user_folder_id': str(self.folder_a.id),
|
|
}, {
|
|
'name': 'Document A/B2',
|
|
'folder_id': self.folder_a.id,
|
|
'user_folder_id': str(self.folder_a.id),
|
|
}
|
|
])
|
|
self.assertEqual(defaults.folder_id.id, self.folder_a_a.id)
|
|
self.assertEqual(defaults.owner_id.id, self.doc_user.id)
|
|
self.assertFalse(company.folder_id)
|
|
self.assertFalse(company.owner_id)
|
|
self.assertFalse(my.folder_id)
|
|
self.assertEqual(my.owner_id, self.internal_user) # user_folder_id=MY primes over context defaults
|
|
self.assertEqual(folder_a_b.folder_id, self.folder_a)
|
|
self.assertEqual(folder_a_b.owner_id, self.doc_user) # context default used
|
|
self.assertEqual(folder_a_b_2.folder_id, self.folder_a)
|
|
|
|
for user_folder_id in ('ALL', 'RECENT', 'SHARED', 'TRASH'):
|
|
with self.subTest(user_folder_id=user_folder_id):
|
|
with self.assertRaises(UserError):
|
|
self.env['documents.document'].create({
|
|
'name': 'Should fail',
|
|
'user_folder_id': user_folder_id,
|
|
})
|
|
for idx, values in enumerate((
|
|
{'user_folder_id': str(self.folder_a_a.id), 'folder_id': self.folder_a.id}, # different folder_id
|
|
{'user_folder_id': 'COMPANY', 'folder_id': self.folder_a.id}, # Company has folder_id=False
|
|
{'user_folder_id': 'COMPANY', 'owner_id': self.internal_user.id}, # Company has owner_id=False
|
|
)):
|
|
with self.subTest(idx=idx):
|
|
with self.subTest(kind='create'), self.assertRaises(UserError):
|
|
self.env['documents.document'].create(values)
|
|
with self.subTest(kind='write'), self.assertRaises(UserError):
|
|
my.write(values)
|
|
|
|
@users('internal_user')
|
|
def test_search_child_of(self):
|
|
my_subfolder, company_subfolder, sub_sub_company_admin = self.env["documents.document"].sudo().create([
|
|
{'name': 'My Subfolder', 'folder_id': self.internal_drive.id},
|
|
{'name': 'Company Subfolder', 'type': 'folder', 'folder_id': self.company_folder.id},
|
|
{
|
|
'name': 'Sub Company Admin Folder',
|
|
'type': 'folder',
|
|
'access_internal': 'view',
|
|
'folder_id': self.sub_company_admin.id,
|
|
},
|
|
])
|
|
sub_company_admin_folder_doc = self.env['documents.document'].create({
|
|
'name': 'Sub Company Admin Folder Doc',
|
|
'access_internal': 'view',
|
|
'folder_id': sub_sub_company_admin.id,
|
|
})
|
|
cases = [
|
|
('SHARED',
|
|
self.folder_a | self.folder_a_a | self.folder_b | self.shared_doc_company_sub | self.shared_doc_drive
|
|
| self.shared_doc_company | sub_sub_company_admin | sub_company_admin_folder_doc),
|
|
('MY', self.internal_drive | my_subfolder),
|
|
('COMPANY', self.company_folder | company_subfolder | self.company_doc),
|
|
(str(self.internal_drive.id), my_subfolder),
|
|
]
|
|
accessible_documents = self.env["documents.document"].search([])
|
|
for user_folder_id, expected in cases:
|
|
with self.subTest(user_folder_id=user_folder_id):
|
|
domain = [('user_folder_id', 'child_of', user_folder_id)]
|
|
actual = self.env['documents.document'].search(domain)
|
|
self.assertDocumentsEqual(actual, expected)
|
|
filtered = accessible_documents.filtered_domain(domain)
|
|
self.assertDocumentsEqual(filtered, expected)
|
|
|
|
@users('internal_user')
|
|
def test_search_folder_id_child_of(self):
|
|
my_subfolder, company_subfolder = self.env['documents.document'].create([
|
|
{'name': 'My Subfolder', 'folder_id': self.internal_drive.id},
|
|
{'name': 'Company Subfolder', 'type': 'folder', 'folder_id': self.company_folder.id},
|
|
])
|
|
cases = [
|
|
(self.internal_drive, self.internal_drive | my_subfolder), # not shared_doc_drive
|
|
(self.company_folder, self.company_folder | company_subfolder) # not shared_doc_company_sub
|
|
]
|
|
accessible_documents = self.env["documents.document"].search([])
|
|
for folder, expected in cases:
|
|
with self.subTest(folder=folder.name):
|
|
domain = [('folder_id', 'child_of', folder.id)]
|
|
actual = self.env['documents.document'].search(domain)
|
|
self.assertDocumentsEqual(actual, expected)
|
|
filtered = accessible_documents.filtered_domain(domain)
|
|
self.assertDocumentsEqual(filtered, expected)
|
|
|
|
def test_compute_and_search_user_folder_id_equal(self):
|
|
"""Test user_folder_id's compute and search with "equal" operator.
|
|
|
|
Cases are shaped as [(user, expected), ...], where:
|
|
user: test user,
|
|
expected: records per user_folder_id value, such that
|
|
* searching for this value (if truthy) should retrieve these records
|
|
* computing user_folder_id for the records is correct ('False' for inaccessible docs)
|
|
"""
|
|
Document = self.env['documents.document']
|
|
cases = [
|
|
(self.internal_user, {
|
|
'COMPANY': self.company_doc | self.company_folder,
|
|
'MY': self.internal_drive,
|
|
'SHARED': self.folder_a | self.folder_b | self.shared_doc_company_sub | self.shared_doc_drive | self.shared_doc_company,
|
|
'RECENT': self.internal_drive | self.folder_a,
|
|
str(self.folder_a.id): self.folder_a_a,
|
|
False: self.company_restr_doc | self.company_restr_folder | self.sub_company_admin | self.sub_drive_admin
|
|
}),
|
|
(self.doc_user, {
|
|
'COMPANY': self.company_doc | self.company_folder | self.company_restr_doc,
|
|
'MY': self.folder_a | self.folder_b,
|
|
'SHARED': self.shared_doc_company_sub | self.shared_doc_drive | self.shared_doc_company,
|
|
'RECENT': self.folder_a | self.folder_a_a | self.folder_b,
|
|
str(self.folder_a.id): self.folder_a_a,
|
|
False: self.internal_drive | self.sub_company_admin | self.sub_drive_admin,
|
|
}),
|
|
(self.portal_user, {
|
|
'COMPANY': Document,
|
|
'MY': Document,
|
|
'SHARED': self.folder_a,
|
|
'RECENT': self.folder_a,
|
|
str(self.folder_a.id): self.folder_a_a,
|
|
False: self.test_documents - self.folder_a_a,
|
|
}),
|
|
(self.document_sys_admin, {
|
|
'COMPANY': self.company_doc | self.company_restr_doc | self.company_folder | self.company_restr_folder,
|
|
'MY': Document,
|
|
'SHARED': self.internal_drive | self.folder_a | self.folder_b,
|
|
'RECENT': self.folder_a,
|
|
str(self.folder_a.id): self.folder_a_a,
|
|
str(self.company_folder.id): self.sub_company_admin,
|
|
str(self.internal_drive.id): self.sub_drive_admin,
|
|
str(self.company_restr_folder.id): self.shared_doc_company,
|
|
str(self.sub_drive_admin.id): self.shared_doc_drive,
|
|
}),
|
|
]
|
|
for user, expected in cases:
|
|
for user_folder_id, documents in expected.items():
|
|
with self.subTest(user=user.name, user_folder_id=user_folder_id):
|
|
if user_folder_id:
|
|
actual = self.env['documents.document'].with_user(user).search(
|
|
Domain('user_folder_id', '=', user_folder_id))
|
|
self.assertDocumentsEqual(actual, documents)
|
|
# Test compute except for no records or search-only results
|
|
if (
|
|
documents
|
|
and user_folder_id != 'RECENT'
|
|
and (user_folder_id != 'SHARED' or user != self.portal_user)
|
|
):
|
|
self.assertEqual(set(documents.with_user(user).mapped('user_folder_id')), {user_folder_id})
|
|
|
|
@users('internal_user')
|
|
def test_search_user_folder_id_in_and_not_in(self):
|
|
to_find_all = ['COMPANY', 'MY', 'SHARED', str(self.folder_a.id)]
|
|
expected_all = self.company_doc | self.company_folder | self.internal_drive | self.folder_a | self.folder_a_a \
|
|
| self.folder_b | self.shared_doc_company_sub | self.shared_doc_drive | self.shared_doc_company
|
|
actual = self.env['documents.document'].search([('user_folder_id', 'in', to_find_all)])
|
|
self.assertDocumentsEqual(actual, expected_all)
|
|
|
|
expected_company = self.company_doc | self.company_folder
|
|
actual_company = self.env['documents.document'].search([('user_folder_id', 'in', 'COMPANY')])
|
|
self.assertDocumentsEqual(actual_company, expected_company)
|
|
|
|
expected_not_company = expected_all - expected_company
|
|
actual_not_company = self.env['documents.document'].search([('user_folder_id', 'not in', 'COMPANY')])
|
|
self.assertDocumentsEqual(actual_not_company, expected_not_company)
|
|
|
|
expected_my = self.internal_drive
|
|
actual_my = self.env['documents.document'].search([('user_folder_id', 'in', 'MY')])
|
|
self.assertDocumentsEqual(actual_my, expected_my)
|
|
|
|
expected_not_my = expected_all - expected_my
|
|
actual_not_my = self.env['documents.document'].search([('user_folder_id', 'not in', 'MY')])
|
|
self.assertDocumentsEqual(actual_not_my, expected_not_my)
|
|
|
|
expected_shared = self.folder_a | self.folder_b | self.shared_doc_company_sub | self.shared_doc_drive | self.shared_doc_company
|
|
actual_shared = self.env['documents.document'].search([('user_folder_id', 'in', 'SHARED')])
|
|
self.assertDocumentsEqual(actual_shared, expected_shared)
|
|
|
|
expected_not_shared = expected_all - expected_shared
|
|
actual_not_shared = self.env['documents.document'].search([('user_folder_id', 'not in', 'SHARED')])
|
|
self.assertDocumentsEqual(actual_not_shared, expected_not_shared)
|
|
|
|
expected_folder_a = self.folder_a_a
|
|
actual_folder_a = self.env['documents.document'].search([('user_folder_id', 'in', str(self.folder_a.id))])
|
|
self.assertDocumentsEqual(actual_folder_a, expected_folder_a)
|
|
|
|
expected_not_folder_a = expected_all - expected_folder_a
|
|
actual_not_folder_a = self.env['documents.document'].search([('user_folder_id', 'not in', str(self.folder_a.id))])
|
|
self.assertDocumentsEqual(actual_not_folder_a, expected_not_folder_a)
|
|
|
|
def test_documents_search_panel(self):
|
|
cases = [
|
|
(
|
|
{},
|
|
{
|
|
"Company": None,
|
|
"Company Admin Subfolder": self.company_folder.id,
|
|
"Company Folder": "COMPANY",
|
|
"Company Restricted Folder": "COMPANY",
|
|
"Drive Admin Subfolder": self.internal_drive.id,
|
|
"Internal User's Drive Document": "SHARED",
|
|
"My Drive": None,
|
|
"Recent": None,
|
|
"Shared with me": None,
|
|
"Trash": None,
|
|
"folder A": "SHARED",
|
|
"folder A - A": self.folder_a.id,
|
|
"folder B": "SHARED",
|
|
},
|
|
),
|
|
(
|
|
{"documents_unique_folder_id": self.folder_a.id},
|
|
{
|
|
"folder A": False,
|
|
"folder A - A": self.folder_a.id,
|
|
},
|
|
),
|
|
]
|
|
for context, expected in cases:
|
|
with self.subTest(context=context):
|
|
Documents = self.env['documents.document'].with_context(context)
|
|
actual = Documents.search_panel_select_range("user_folder_id")['values']
|
|
user_folder_ids = {vals["display_name"]: vals.get("user_folder_id") for vals in actual}
|
|
self.assertEqual(user_folder_ids, expected)
|