From 93925e7edb7d1eafb7f0bf74d6f255d0473c2a88 Mon Sep 17 00:00:00 2001 From: git_admin Date: Mon, 27 Apr 2026 08:18:29 +0000 Subject: [PATCH] Tower: upload cetmix_tower_server 16.0.3.0.1 (via marketplace) --- .../tests/test_plan_line_action.py | 255 ++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 addons/cetmix_tower_server/tests/test_plan_line_action.py diff --git a/addons/cetmix_tower_server/tests/test_plan_line_action.py b/addons/cetmix_tower_server/tests/test_plan_line_action.py new file mode 100644 index 0000000..ddd694d --- /dev/null +++ b/addons/cetmix_tower_server/tests/test_plan_line_action.py @@ -0,0 +1,255 @@ +# Copyright (C) 2025 Cetmix OÜ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.exceptions import AccessError + +from .common import TestTowerCommon + + +class TestTowerPlanLineAction(TestTowerCommon): + """Test the cx.tower.plan.line.action model access rights.""" + + @classmethod + def setUpClass(cls): + super().setUpClass() + + # Create a test server + cls.server = cls.Server.create( + { + "name": "Test Server", + "ip_v4_address": "localhost", + "ssh_username": "test", + "ssh_password": "test", + "ssh_port": 22, + "user_ids": [(6, 0, [cls.user.id])], + "manager_ids": [(6, 0, [cls.manager.id])], + } + ) + + # Create a test plan with access level 1 for user tests + cls.test_plan = cls.Plan.create( + { + "name": "Test Access Plan", + "access_level": "1", + "user_ids": [(6, 0, [cls.user.id])], + "manager_ids": [(6, 0, [cls.manager.id])], + } + ) + + # Create a test plan line + cls.test_plan_line = cls.plan_line.create( + { + "plan_id": cls.test_plan.id, + "command_id": cls.command_create_dir.id, + "sequence": 10, + } + ) + + # Create a test action + cls.test_action = cls.plan_line_action.create( + { + "line_id": cls.test_plan_line.id, + "condition": "==", + "value_char": "0", + "action": "n", + } + ) + + def test_user_read_access(self): + """Test user read access to plan line actions""" + # Case 1: User should be able to read action when: + # - access_level == "1" + # - user is in plan's user_ids OR server's user_ids + recs = self.plan_line_action.with_user(self.user).search( + [("id", "=", self.test_action.id)] + ) + self.assertIn( + self.test_action, + recs, + "User should be able to read action when conditions are met", + ) + + # Case 2: User should not be able to read when access_level > "1" + self.test_plan.access_level = "2" + recs = self.plan_line_action.with_user(self.user).search( + [("id", "=", self.test_action.id)] + ) + self.assertNotIn( + self.test_action, + recs, + "User should not be able to read action when access_level > '1'", + ) + + # Case 3: User should not be able to read when not in user_ids + self.test_plan.access_level = "1" + self.test_plan.user_ids = [(5, 0, 0)] # Remove all users + recs = self.plan_line_action.with_user(self.user).search( + [("id", "=", self.test_action.id)] + ) + self.assertNotIn( + self.test_action, + recs, + "User should not be able to read action when not in user_ids", + ) + + # Case 4: User should be able to read when in server's user_ids + self.test_plan.server_ids = [(6, 0, [self.server.id])] + recs = self.plan_line_action.with_user(self.user).search( + [("id", "=", self.test_action.id)] + ) + self.assertIn( + self.test_action, + recs, + "User should be able to read action when in server's user_ids", + ) + + def test_user_write_create_unlink_access(self): + """Test user write/create/unlink access restrictions""" + # Users should not be able to create actions + with self.assertRaises(AccessError): + self.plan_line_action.with_user(self.user).create( + { + "line_id": self.test_plan_line.id, + "condition": "==", + "value_char": "0", + "action": "n", + } + ) + + # Users should not be able to write actions + with self.assertRaises(AccessError): + self.test_action.with_user(self.user).write({"value_char": "1"}) + + # Users should not be able to unlink actions + with self.assertRaises(AccessError): + self.test_action.with_user(self.user).unlink() + + def test_manager_read_access(self): + """Test manager read access to plan line actions""" + # Case 1: Manager should be able to read when: + # - access_level <= "2" + # - manager is in plan's manager_ids + recs = self.plan_line_action.with_user(self.manager).search( + [("id", "=", self.test_action.id)] + ) + self.assertIn( + self.test_action, + recs, + "Manager should be able to read action when conditions are met", + ) + + # Case 2: Manager should not be able to read when access_level > "2" + self.test_plan.access_level = "3" + recs = self.plan_line_action.with_user(self.manager).search( + [("id", "=", self.test_action.id)] + ) + self.assertNotIn( + self.test_action, + recs, + "Manager should not be able to read action when access_level > '2'", + ) + + # Case 3: Manager should be able to read when in server's manager_ids + self.test_plan.access_level = "2" + self.test_plan.manager_ids = [(5, 0, 0)] # Remove all managers + self.test_plan.server_ids = [(6, 0, [self.server.id])] + recs = self.plan_line_action.with_user(self.manager).search( + [("id", "=", self.test_action.id)] + ) + self.assertIn( + self.test_action, + recs, + "Manager should be able to read when in server's manager_ids", + ) + + def test_manager_write_create_access(self): + """Test manager write/create access to plan line actions""" + # Case 1: Manager should be able to create/write when: + # - access_level <= "2" + # - manager is in plan's manager_ids + try: + # Test create + self.plan_line_action.with_user(self.manager).create( + { + "line_id": self.test_plan_line.id, + "condition": "==", + "value_char": "1", + "action": "n", + } + ) + # Test write + self.test_action.with_user(self.manager).write({"value_char": "2"}) + except AccessError: + self.fail("Manager should be able to create/write when conditions are met") + + # Case 2: Manager should not be able to create/write when access_level > "2" + self.test_plan.access_level = "3" + with self.assertRaises(AccessError): + self.plan_line_action.with_user(self.manager).create( + { + "line_id": self.test_plan_line.id, + "condition": "==", + "value_char": "1", + "action": "n", + } + ) + with self.assertRaises(AccessError): + self.test_action.with_user(self.manager).write({"value_char": "3"}) + + def test_manager_unlink_access(self): + """Test manager unlink access to plan line actions""" + # Create action as manager to test unlink rights + action = self.plan_line_action.with_user(self.manager).create( + { + "line_id": self.test_plan_line.id, + "condition": "==", + "value_char": "0", + "action": "n", + } + ) + + # Case 1: Manager should be able to unlink when: + # - access_level <= "2" + # - manager is the creator + # - manager is in plan's manager_ids + try: + action.unlink() + except AccessError: + self.fail("Manager should be able to unlink when conditions are met") + + # Case 2: Manager should not be able to unlink actions created by others + action = self.test_action # Created by admin in setUp + with self.assertRaises(AccessError): + action.with_user(self.manager).unlink() + + def test_root_unrestricted_access(self): + """Test root user unrestricted access""" + # Root should have full access regardless of conditions + try: + # Test read + recs = self.plan_line_action.with_user(self.root).search( + [("id", "=", self.test_action.id)] + ) + self.assertIn( + self.test_action, + recs, + "Root should be able to read action without restrictions", + ) + + # Test create + new_action = self.plan_line_action.with_user(self.root).create( + { + "line_id": self.test_plan_line.id, + "condition": "==", + "value_char": "1", + "action": "n", + } + ) + + # Test write + self.test_action.with_user(self.root).write({"value_char": "2"}) + + # Test unlink + new_action.unlink() + except AccessError: + self.fail("Root user should have unrestricted access")