Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace)

This commit is contained in:
2026-04-27 08:18:20 +00:00
parent 4f1b44f859
commit 50f45a25f6

View File

@@ -0,0 +1,647 @@
# Copyright (C) 2025 Cetmix OÜ
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.exceptions import AccessError
from .common_jets import TestTowerJetsCommon
class TestTowerJetActionAccess(TestTowerJetsCommon):
"""
Test access rules for Jet Action model (cx.tower.jet.action)
"""
# ======================
# User Read Access
# ======================
def test_user_read_access_level_user_and_template_user(self):
"""
User: can read when action access_level is User
(1) AND template access_level is User (1)
"""
template = self.JetTemplate.create(
{
"name": "User Level Template",
"reference": "user_level_template",
"access_level": "1", # User level
"user_ids": False,
"manager_ids": False,
}
)
action = self.JetAction.create(
{
"name": "Action U",
"reference": "action_u",
"access_level": "1", # User level
"jet_template_id": template.id,
"state_from_id": self.state_running.id,
"state_to_id": self.state_stopped.id,
"state_transit_id": self.state_stopping.id,
}
)
records = self.JetAction.with_user(self.user).search([("id", "=", action.id)])
self.assertEqual(
len(records),
1,
"User should read when action and template access_level are User",
)
def test_user_read_when_in_template_users(self):
"""
User: can read when action access_level is User (1)
AND user is added to template Users
"""
template = self.JetTemplate.create(
{
"name": "Manager Level Template (user granted)",
"reference": "manager_level_template_user",
"access_level": "2", # Manager level
"user_ids": [(4, self.user.id)],
"manager_ids": False,
}
)
action = self.JetAction.create(
{
"name": "Action TU",
"reference": "action_tu",
"access_level": "1", # User level
"jet_template_id": template.id,
"state_from_id": self.state_running.id,
"state_to_id": self.state_stopped.id,
"state_transit_id": self.state_stopping.id,
}
)
records = self.JetAction.with_user(self.user).search([("id", "=", action.id)])
self.assertEqual(
len(records),
1,
"User should read when action access_level is"
" User and user in template Users",
)
def test_user_read_when_in_jet_users(self):
"""
User: can read when action access_level is
User (1) AND user is added to Jet Users
"""
template = self.JetTemplate.create(
{
"name": "Manager Level Template",
"reference": "manager_level_template_jet",
"access_level": "2", # Manager level
"user_ids": False,
"manager_ids": False,
}
)
# Add server to template's server_ids for jet creation
template.write({"server_ids": [(4, self.server_test_1.id)]})
self._create_jet(
name="Test Jet from Template",
reference="test_jet_from_template",
template=template,
server=self.server_test_1,
user_ids=[(4, self.user.id)], # Add user to Jet's user_ids
server_user_ids=[(4, self.user.id)], # Also add to server for jet access
)
action = self.JetAction.create(
{
"name": "Action JU",
"reference": "action_ju",
"access_level": "1", # User level
"jet_template_id": template.id,
"state_from_id": self.state_running.id,
"state_to_id": self.state_stopped.id,
"state_transit_id": self.state_stopping.id,
}
)
records = self.JetAction.with_user(self.user).search([("id", "=", action.id)])
self.assertEqual(
len(records),
1,
"User should read when action access_level is User and user in Jet Users",
)
def test_user_read_no_access_action_not_user_level(self):
"""User: cannot read when action access_level is NOT User (1)"""
template = self.JetTemplate.create(
{
"name": "User Level Template",
"reference": "user_level_template_no_access",
"access_level": "1", # User level
"user_ids": False,
"manager_ids": False,
}
)
action = self.JetAction.create(
{
"name": "Action M",
"reference": "action_m",
"access_level": "2", # Manager level
"jet_template_id": template.id,
"state_from_id": self.state_running.id,
"state_to_id": self.state_stopped.id,
"state_transit_id": self.state_stopping.id,
}
)
records = self.JetAction.with_user(self.user).search([("id", "=", action.id)])
self.assertEqual(
len(records),
0,
"User should not read when action access_level is not User",
)
def test_user_read_no_access_template_conditions_not_met(self):
"""
User: cannot read when action access_level is User (1)
and template conditions not met
"""
template = self.JetTemplate.create(
{
"name": "Manager Level Template",
"reference": "manager_level_template_no_access",
"access_level": "2", # Manager level
"user_ids": False, # User not in template Users
"manager_ids": False,
}
)
# Don't create any jets with user in user_ids
action = self.JetAction.create(
{
"name": "Action NA",
"reference": "action_na",
"access_level": "1", # User level
"jet_template_id": template.id,
"state_from_id": self.state_running.id,
"state_to_id": self.state_stopped.id,
"state_transit_id": self.state_stopping.id,
}
)
records = self.JetAction.with_user(self.user).search([("id", "=", action.id)])
self.assertEqual(
len(records),
0,
"User should not read when action is User level"
" and template conditions not met",
)
def test_user_write_forbidden(self):
"""User: cannot write/create/delete records"""
template = self.JetTemplate.create(
{
"name": "User Level Template",
"reference": "user_level_template_write",
"access_level": "1",
"user_ids": [(4, self.user.id)],
}
)
action = self.JetAction.create(
{
"name": "Action W",
"reference": "action_w_user",
"access_level": "1",
"jet_template_id": template.id,
"state_from_id": self.state_running.id,
"state_to_id": self.state_stopped.id,
"state_transit_id": self.state_stopping.id,
}
)
# Write forbidden
with self.assertRaises(AccessError):
self.JetAction.with_user(self.user).browse(action.id).write({"priority": 5})
# Create forbidden
with self.assertRaises(AccessError):
self.JetAction.with_user(self.user).create(
{
"name": "Action Created",
"reference": "action_created_user",
"access_level": "1",
"jet_template_id": template.id,
"state_from_id": self.state_stopped.id,
"state_to_id": self.state_running.id,
"state_transit_id": self.state_starting.id,
}
)
# Delete forbidden
with self.assertRaises(AccessError):
self.JetAction.with_user(self.user).browse(action.id).unlink()
# ======================
# Manager Read Access
# ======================
def test_manager_read_access_level_manager_or_less(self):
"""
Manager: can read when action access_level <= Manager (2)
AND template access_level <= Manager (2)
"""
template = self.JetTemplate.create(
{
"name": "Manager Level Template",
"reference": "manager_level_template",
"access_level": "2",
}
)
action = self.JetAction.create(
{
"name": "Action R",
"reference": "action_r",
"access_level": "2", # Manager level
"jet_template_id": template.id,
"state_from_id": self.state_running.id,
"state_to_id": self.state_stopped.id,
"state_transit_id": self.state_stopping.id,
}
)
records = self.JetAction.with_user(self.manager).search(
[("id", "=", action.id)]
)
self.assertEqual(
len(records),
1,
"Manager should read when action and template level <= Manager",
)
def test_manager_read_when_in_template_users(self):
"""
Manager: can read when action access_level <= Manager (2)
AND user is added to template Users
even if template access_level is Root (3)
"""
template = self.JetTemplate.create(
{
"name": "Root Level Template (user granted)",
"reference": "root_level_template_user",
"access_level": "3",
"user_ids": [(4, self.manager.id)],
}
)
action = self.JetAction.create(
{
"name": "Action RU",
"reference": "action_ru",
"access_level": "2", # Manager level
"jet_template_id": template.id,
"state_from_id": self.state_running.id,
"state_to_id": self.state_stopped.id,
"state_transit_id": self.state_stopping.id,
}
)
records = self.JetAction.with_user(self.manager).search(
[("id", "=", action.id)]
)
self.assertEqual(
len(records),
1,
"Manager should read when action level <= Manager and in template Users",
)
def test_manager_read_when_in_template_managers(self):
"""
Manager: can read when action access_level <= Manager (2)
AND user is added to template Managers
even if template access_level is Root (3)
"""
template = self.JetTemplate.create(
{
"name": "Root Level Template (manager)",
"reference": "root_level_template_manager",
"access_level": "3",
"manager_ids": [(4, self.manager.id)],
}
)
action = self.JetAction.create(
{
"name": "Action RM",
"reference": "action_rm",
"access_level": "2", # Manager level
"jet_template_id": template.id,
"state_from_id": self.state_running.id,
"state_to_id": self.state_stopped.id,
"state_transit_id": self.state_stopping.id,
}
)
records = self.JetAction.with_user(self.manager).search(
[("id", "=", action.id)]
)
self.assertEqual(
len(records),
1,
"Manager should read when action level <= Manager and in template Managers",
)
def test_manager_read_no_access_action_root_level(self):
"""
Manager: cannot read when action access_level is Root (3)
even if template conditions are met
"""
template = self.JetTemplate.create(
{
"name": "Manager Level Template",
"reference": "manager_level_template_no_access",
"access_level": "2",
"manager_ids": [(4, self.manager.id)],
}
)
action = self.JetAction.create(
{
"name": "Action Root",
"reference": "action_root",
"access_level": "3", # Root level
"jet_template_id": template.id,
"state_from_id": self.state_running.id,
"state_to_id": self.state_stopped.id,
"state_transit_id": self.state_stopping.id,
}
)
records = self.JetAction.with_user(self.manager).search(
[("id", "=", action.id)]
)
self.assertEqual(
len(records),
0,
"Manager should not read when action access_level is Root",
)
# ======================
# Manager Write/Create/Delete
# ======================
def test_manager_write_when_in_template_managers(self):
"""
Manager: can write when action access_level <= Manager (2)
AND user is in template Managers
"""
template = self.JetTemplate.create(
{
"name": "Template For Write",
"reference": "template_for_write",
"manager_ids": [(4, self.manager.id)],
}
)
action = self.JetAction.create(
{
"name": "Action W",
"reference": "action_w",
"access_level": "2", # Manager level
"jet_template_id": template.id,
"state_from_id": self.state_running.id,
"state_to_id": self.state_stopped.id,
"state_transit_id": self.state_stopping.id,
}
)
# Write
self.JetAction.with_user(self.manager).browse(action.id).write({"priority": 99})
action.invalidate_recordset()
self.assertEqual(
action.priority,
99,
"Manager should be able to write when action level"
" <= Manager and in Managers",
)
# Create
created = self.JetAction.with_user(self.manager).create(
{
"name": "Action W Created",
"reference": "action_w_created",
"access_level": "2", # Manager level
"jet_template_id": template.id,
"state_from_id": self.state_stopped.id,
"state_to_id": self.state_running.id,
"state_transit_id": self.state_starting.id,
}
)
self.assertTrue(
created,
"Manager should be able to create when action level "
"<= Manager and in Managers",
)
# Delete
self.JetAction.with_user(self.manager).browse(created.id).unlink()
after = self.JetAction.search([("id", "=", created.id)])
self.assertEqual(
len(after),
0,
"Manager should be able to delete when action level "
"<= Manager and in Managers",
)
def test_manager_write_forbidden_when_not_in_template_managers(self):
"""
Manager: cannot write/create/delete if NOT in template Managers
even if action access_level <= Manager (2)
"""
template = self.JetTemplate.create(
{
"name": "Template No Write",
"reference": "template_no_write",
}
)
action = self.JetAction.create(
{
"name": "Action NW",
"reference": "action_nw",
"access_level": "2", # Manager level
"jet_template_id": template.id,
"state_from_id": self.state_running.id,
"state_to_id": self.state_stopped.id,
"state_transit_id": self.state_stopping.id,
}
)
# Write forbidden
with self.assertRaises(AccessError):
self.JetAction.with_user(self.manager).browse(action.id).write(
{"priority": 5}
)
# Create forbidden
with self.assertRaises(AccessError):
self.JetAction.with_user(self.manager).create(
{
"name": "Action NW Created",
"reference": "action_nw_created",
"access_level": "2", # Manager level
"jet_template_id": template.id,
"state_from_id": self.state_stopped.id,
"state_to_id": self.state_running.id,
"state_transit_id": self.state_starting.id,
}
)
# Delete forbidden
with self.assertRaises(AccessError):
self.JetAction.with_user(self.manager).browse(action.id).unlink()
def test_manager_write_forbidden_when_action_root_level(self):
"""
Manager: cannot write/create/delete when action access_level is Root (3)
even if user is in template Managers
"""
template = self.JetTemplate.create(
{
"name": "Template For Write",
"reference": "template_for_write_root",
"manager_ids": [(4, self.manager.id)],
}
)
action = self.JetAction.create(
{
"name": "Action Root W",
"reference": "action_root_w",
"access_level": "3", # Root level
"jet_template_id": template.id,
"state_from_id": self.state_running.id,
"state_to_id": self.state_stopped.id,
"state_transit_id": self.state_stopping.id,
}
)
# Write forbidden
with self.assertRaises(AccessError):
self.JetAction.with_user(self.manager).browse(action.id).write(
{"priority": 5}
)
# Create forbidden
with self.assertRaises(AccessError):
self.JetAction.with_user(self.manager).create(
{
"name": "Action Root Created",
"reference": "action_root_created",
"access_level": "3", # Root level
"jet_template_id": template.id,
"state_from_id": self.state_stopped.id,
"state_to_id": self.state_running.id,
"state_transit_id": self.state_starting.id,
}
)
# Delete forbidden
with self.assertRaises(AccessError):
self.JetAction.with_user(self.manager).browse(action.id).unlink()
def test_manager_write_on_root_level_template_when_in_managers(self):
"""
Manager: can write/create/delete on Root-level template
when action access_level <= Manager (2) AND user is in Managers
"""
template = self.JetTemplate.create(
{
"name": "Root Level Template For Write",
"reference": "root_level_template_for_write",
"access_level": "3",
"manager_ids": [(4, self.manager.id)],
}
)
action = self.JetAction.create(
{
"name": "Action RW",
"reference": "action_rw",
"access_level": "2", # Manager level
"jet_template_id": template.id,
"state_from_id": self.state_running.id,
"state_to_id": self.state_stopped.id,
"state_transit_id": self.state_stopping.id,
}
)
# Write
self.JetAction.with_user(self.manager).browse(action.id).write({"priority": 42})
action.invalidate_recordset()
self.assertEqual(
action.priority,
42,
"Manager should write on Root-level template when action level "
"<= Manager and in Managers",
)
# Create
created = self.JetAction.with_user(self.manager).create(
{
"name": "Action RW Created",
"reference": "action_rw_created",
"access_level": "2", # Manager level
"jet_template_id": template.id,
"state_from_id": self.state_stopped.id,
"state_to_id": self.state_running.id,
"state_transit_id": self.state_starting.id,
}
)
self.assertTrue(
created,
"Manager should create on Root-level template when action level "
"<= Manager and in Managers",
)
# Delete
self.JetAction.with_user(self.manager).browse(created.id).unlink()
after = self.JetAction.search([("id", "=", created.id)])
self.assertEqual(
len(after),
0,
"Manager should delete on Root-level template when action level "
"<= Manager and in Managers",
)
# ======================
# Root Access
# ======================
def test_root_full_access(self):
"""Root: full CRUD access for any record"""
template = self.JetTemplate.with_user(self.root).create(
{
"name": "Root Template",
"reference": "root_template",
"access_level": "3",
}
)
# Create
action = self.JetAction.with_user(self.root).create(
{
"name": "Root Action",
"reference": "root_action",
"jet_template_id": template.id,
"state_from_id": self.state_initial.id,
"state_to_id": self.state_running.id,
"state_transit_id": self.state_starting.id,
}
)
# Read
records = self.JetAction.with_user(self.root).search([("id", "=", action.id)])
self.assertEqual(len(records), 1, "Root should read any record")
# Write
action.with_user(self.root).write({"priority": 7})
action.invalidate_recordset()
self.assertEqual(action.priority, 7, "Root should update any record")
# Delete
action.with_user(self.root).unlink()
self.assertEqual(
len(
self.JetAction.with_user(self.root).search(
[("reference", "=", "root_action")]
)
),
0,
"Root should delete any record",
)