Files

302 lines
16 KiB
Python

# -*- coding: utf-8 -*-
from odoo import http
from odoo.exceptions import AccessError, UserError, ValidationError
from odoo.tests.common import HttpCase, RecordCapturer, tagged
from .test_documents_hr_common import TransactionCaseDocumentsHr
@tagged('post_install', '-at_install', 'test_document_bridge')
class TestCaseDocumentsBridgeHR(HttpCase, TransactionCaseDocumentsHr):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.employee = cls.env['hr.employee'].create({
'name': 'Employee (related to doc_user)',
'user_id': cls.doc_user.id,
'work_contact_id': cls.doc_user.partner_id.id,
'wage': 1,
})
cls.contract = cls.employee.version_id
def test_documents_hr_employees_folders_no_owner(self):
# Document owner is the user that creates the document. But hr 'system' folders cannot be owned by anyone.
public_user = self.env['res.users'].create({
'name': 'Johnny Applicant',
'login': 'applicant',
'email': '[email protected]',
})
employee = self.env['hr.employee'].with_user(public_user).sudo().create({
'name': 'Johnny Employee'
})
self.assertTrue(employee.hr_employee_folder_id)
self.assertFalse(employee.hr_employee_folder_id.owner_id)
def test_employee_subfolder_generation_renaming_and_access(self):
# hr_employee_folder_id should have been created at employee creation
self.assertEqual(self.employee.hr_employee_folder_id.name, self.employee.name,
"HR Employee Subfolder should have the same name as the employee.")
self.employee.name = "Zator"
self.assertEqual(self.employee.hr_employee_folder_id.name, "Zator",
"HR Employee Subfolder should be renamed when renaming the employee.")
admin_user = self.env.ref('base.user_admin')
# Test on new Company - HR Employee folder should be created on company create.
# and a new employee should generate a subfolder for that employee inside the company's HR Employee folder.
new_company = self.env['res.company'].with_user(admin_user).create({
'name': 'New Company'
})
self.assertTrue(new_company.documents_employee_folder_id)
# Newly created folder, created on company creation, should be in the company root.
self.assertFalse(new_company.documents_employee_folder_id.owner_id)
self.assertEqual(new_company.documents_employee_folder_id.user_folder_id, 'COMPANY')
new_company_employee = self.env['hr.employee'].create({
'name': 'New Company Employee',
'user_id': self.doc_user_2.id,
'company_id': new_company.id
})
self.assertTrue(new_company_employee.hr_employee_folder_id)
self.assertEqual(new_company_employee.hr_employee_folder_id.access_via_link, 'edit')
self.assertEqual(new_company_employee.hr_employee_folder_id.access_internal, 'none')
self.assertEqual(new_company_employee.hr_employee_folder_id.folder_id, new_company.documents_employee_folder_id)
# Test unconfigured companies: employees should not have a subfolder
doc_employee_folder_id = new_company.documents_employee_folder_id.id
new_company.documents_employee_folder_id = False
new_company_employee_bis = self.env['hr.employee'].create({
'name': 'New Company Employee Bis',
'company_id': new_company.id
})
self.assertFalse(new_company_employee_bis.hr_employee_folder_id)
# Reconfiguring the company should create employee subfolders for employee that has none
new_company.documents_employee_folder_id = doc_employee_folder_id
self.assertTrue(new_company_employee_bis.hr_employee_folder_id)
self.assertEqual(new_company_employee_bis.hr_employee_folder_id.folder_id, new_company.documents_employee_folder_id)
# Test changing settings for Documents HR Employee folder. All employee subfolders should follow.
new_folder = self.env['documents.document'].create({
'name': 'New folder',
'type': 'folder'
})
self.env.company.documents_employee_folder_id = new_folder.id
self.assertEqual(self.env.company.documents_employee_folder_id.access_via_link, 'none')
self.assertEqual(self.env.company.documents_employee_folder_id.access_internal, 'none')
self.assertEqual(new_company_employee.hr_employee_folder_id.access_via_link, 'edit')
self.assertEqual(new_company_employee.hr_employee_folder_id.access_internal, 'none')
self.assertEqual(self.employee.hr_employee_folder_id.folder_id.id, new_folder.id,
"Changing HR Employee folder target should be propagated to each employee subfolders.")
self.assertEqual(self.employee.hr_employee_folder_id.access_via_link, 'edit')
self.assertEqual(self.employee.hr_employee_folder_id.access_internal, 'none')
# Check access - only used for HR users - even employee should not have access to their "own" subfolder
with self.assertRaises(AccessError):
self.employee.hr_employee_folder_id.with_user(self.doc_user_2).read(['name'])
with self.assertRaises(AccessError):
self.employee.hr_employee_folder_id.with_user(self.employee.user_id).read(['name'])
with self.assertRaises(AccessError):
self.employee.hr_employee_folder_id.with_user(self.employee.user_id).write({'name': "Test"})
# Hr manager have access because added as edit member
self.employee.hr_employee_folder_id.with_user(self.hr_manager).read(['name'])
self.employee.hr_employee_folder_id.with_user(self.hr_manager).write({'name': "Test2"})
self.employee.hr_employee_folder_id.access_ids = False
# Hr user and HR manager should be able to view and edit but only using the access token
# see @test_open_document_from_hr test method - If access to smart button and action, access to the records.
with self.assertRaises(AccessError):
self.employee.hr_employee_folder_id.with_user(self.hr_manager).read(['name'])
with self.assertRaises(AccessError):
self.employee.hr_employee_folder_id.with_user(self.hr_user).read(['name'])
with self.assertRaises(AccessError):
self.employee.hr_employee_folder_id.with_user(self.hr_manager).write({'name': "Test2"})
with self.assertRaises(AccessError):
self.employee.hr_employee_folder_id.with_user(self.hr_user).write({'name': "Test"})
def test_bridge_hr_settings_on_write(self):
"""
Makes sure the settings apply their values when an ir_attachment is set as message_main_attachment_id
on invoices.
"""
attachment_txt_test = self.env['ir.attachment'].create({
'datas': self.TEXT,
'name': 'fileText_test.txt',
'mimetype': 'text/plain',
'res_model': 'hr.employee',
'res_id': self.employee.id,
})
document = self.env['documents.document'].search([('attachment_id', '=', attachment_txt_test.id)])
self.assertTrue(document.exists(), "There should be a new document created from the attachment")
self.assertFalse(document.owner_id)
self.assertEqual(document.partner_id, self.employee.work_contact_id, "The partner_id should be the employee's address")
self.assertEqual(document.access_via_link, "none")
self.assertEqual(document.access_internal, "none")
self.assertTrue(document.is_access_via_link_hidden)
def test_upload_employee_attachment(self):
"""
Make sure an employee's attachment is linked to the existing document
and a new one is not created.
"""
document = self.env['documents.document'].create({
'name': 'Doc',
'folder_id': self.employee.hr_employee_folder_id.id,
'res_model': self.employee._name,
'res_id': self.employee.id,
})
document.write({
'datas': self.TEXT,
'mimetype': 'text/plain',
})
self.assertTrue(document.attachment_id, "An attachment should have been created")
def test_hr_employee_document_auto_created_not_shared_with_employee(self):
""" Test that automatically created employee documents from attachment are not shared with the employee. """
attachment = self.env['ir.attachment'].create({
'name': 'test.txt',
'mimetype': 'text/plain',
'datas': self.TEXT,
'res_model': 'hr.employee',
'res_id': self.employee.id,
})
document = self.env['documents.document'].search([('attachment_id', '=', attachment.id)])
self.assertTrue(document)
self.assertEqual(document.with_user(self.employee.user_id).user_permission, 'none')
def test_hr_employee_document_upload_not_shared_with_employee(self):
"""Test that uploaded hr.employee documents are not shared with the employee."""
self.authenticate(self.hr_manager.login, self.hr_manager.login)
with RecordCapturer(self.env['documents.document'], []) as capture:
res = self.url_open(f'/documents/upload/{self.employee.hr_employee_folder_id.access_token}',
data={
'csrf_token': http.Request.csrf_token(self),
'res_id': self.employee.id,
'res_model': 'hr.employee',
},
files={'ufile': ('hello.txt', b"Hello", 'text/plain')},
)
res.raise_for_status()
document = capture.records.ensure_one()
self.assertEqual(document.res_model, "hr.employee",
"The uploaded document is linked to the employee model")
self.assertEqual(document.res_id, self.employee.id,
"The uploaded document is linked to the employee record")
self.assertEqual(document.with_user(self.doc_user).user_permission, "none",
"The employee has no access to the uploaded document")
self.assertEqual(document.with_user(self.hr_manager).user_permission, "edit",
"The HR manager has access to the uploaded document")
def test_open_document_from_hr(self):
""" Test that opening the document app from an employee (hr app) is opening only for hr users. """
with self.assertRaises(AccessError):
self.employee.with_user(self.doc_user_2).action_open_documents()
action = self.employee.with_user(self.hr_user).action_open_documents()
self.assertEqual(action['type'], 'ir.actions.act_url')
self.assertEqual(action['url'].split('/')[-1], self.employee.hr_employee_folder_id.access_token)
def test_raise_if_used_folder(self):
"""It shouldn't be possible to archive/delete a folder used by a company (see _unlink_except_company_folders)"""
company_b = self.env['res.company'].create({'name': 'Company B'})
root = self.env['documents.document'].create({'name': 'root', 'type': 'folder', 'access_internal': 'edit'})
folder_parent = self.env['documents.document'].create(
{'name': 'parent', 'type': 'folder', 'folder_id': root.id})
folder_hr_employees2 = self.env['documents.document'].create({
'name': 'Employees - company 2', 'type': 'folder', 'folder_id': folder_parent.id, 'access_internal': 'none'})
company_b.documents_employee_folder_id = folder_hr_employees2
company_b.documents_hr_settings = False
self.assertEqual(folder_parent.with_user(self.doc_user).user_permission, 'edit')
self.assertEqual(folder_hr_employees2.with_user(self.doc_user).user_permission, 'none')
# It should be possible to archive an unused 'HR' folder"
with self.assertRaises(UserError,
msg="It should not be possible for non admin to archive the 'HR Employee' folder"):
folder_hr_employees2.with_user(self.doc_user).action_archive()
folder_hr_employees2.action_archive()
folder_hr_employees2.action_unarchive()
company_b.documents_hr_settings = True
with self.assertRaises(UserError,
msg="It should not be possible to archive an used 'HR Employee' folder"):
folder_hr_employees2.action_archive()
with self.assertRaises(UserError,
msg="It should not be possible to archive an ancestor of the used 'HR' folder"):
folder_parent.action_archive()
with self.assertRaises(UserError,
msg="It should not be possible to unlink a 'HR Employee' folder"):
folder_hr_employees2.unlink()
with self.assertRaises(UserError,
msg="It should not be possible to delete an ancestor of the 'HR' folder"):
folder_parent.unlink()
self.assertTrue(folder_parent.exists())
self.assertTrue(folder_hr_employees2.exists())
with self.assertRaises(UserError,
msg="It should not be possible to delete an employee subfolder of the 'HR' Employee folder"):
self.employee.hr_employee_folder_id.unlink()
def test_portal_user_own_root_documents(self):
""" Portal user (linked to employee!!) should be able to own root
documents as they are now allowed to be set as employee related user
and employee documents are store in their "my drive", and are,
by definition, root documents"""
employee_portal_user, normal_portal_user = self.env['res.users'].create([{
'name': "Employee Portal User",
'login': "employee_portal",
'email': "[email protected]",
'group_ids': [(6, 0, [self.env.ref('base.group_portal').id])]
}, {
'name': "Normal Portal User",
'login': "normal_portal",
'email': "[email protected]",
'group_ids': [(6, 0, [self.env.ref('base.group_portal').id])]
}])
self.employee.user_id = employee_portal_user
self.env['documents.document'].create({
'name': 'test',
'folder_id': False,
'owner_id': employee_portal_user.id
})
with self.assertRaises(ValidationError, msg="Portal users that are not linked to an employee cannot own root documents."):
self.env['documents.document'].create({
'name': 'test',
'folder_id': False,
'owner_id': normal_portal_user.id
})
def test_contract_document_creation(self):
attachment = self.env['ir.attachment'].create({
'datas': self.TEXT,
'name': 'fileText_test.txt',
'mimetype': 'text/plain',
'res_model': self.contract._name,
'res_id': self.contract.id,
})
document = self.env['documents.document'].search([('attachment_id', '=', attachment.id)])
self.assertTrue(document.exists(), "There should be a new document created from the attachment")
self.assertFalse(document.owner_id)
self.assertEqual(document.partner_id, self.employee.work_contact_id, "The partner_id should be the employee's work contact")
self.assertEqual(document.access_via_link, "none")
self.assertEqual(document.access_internal, "none")
self.assertTrue(document.is_access_via_link_hidden)
def test_hr_contract_document_creation_permission_employee_only(self):
""" Test that created hr.contract documents are only viewable by the employee and editable by hr managers. """
self.check_document_creation_permission(self.contract)
def test_document_count_multi_company(self):
"""Ensure computing document counts does not raise a singleton error in multi-company."""
company_2 = self.env['res.company'].create({'name': 'Test company'})
employee_1, employee_2 = self.env['hr.employee'].create([
{
'name': 'Employee company_1',
'company_id': self.env.user.company_id.id,
},
{
'name': 'Employee company_2',
'company_id': company_2.id,
},
])
self.env.user.company_ids |= company_2
self.assertEqual((employee_1 | employee_2).mapped('document_count'), [0, 0], "Document count should be zero.")