from odoo.tests.common import TransactionCase, tagged @tagged('-at_install', 'post_install', 'fp_perms') class TestMenuVisibility(TransactionCase): """Section 2.F of spec: per-role menu render matrix.""" def setUp(self): super().setUp() Users = self.env['res.users'].with_context(no_reset_password=True) def mk(name, xmlid): return Users.create({ 'login': f'menu_{name}', 'name': f'Menu Test {name}', 'email': f'menu_{name}@example.com', 'group_ids': [(6, 0, [self.env.ref(xmlid).id])] if xmlid else [(6, 0, [])], }) # "No" user has only base.group_user — no plating group no_user = Users.create({ 'login': 'menu_no', 'name': 'Menu Test no', 'email': 'menu_no@example.com', }) no_user.write({'group_ids': [(6, 0, [self.env.ref('base.group_user').id])]}) self.u_no = no_user self.u_tech = mk('tech', 'fusion_plating.group_fp_technician') self.u_sr = mk('sr', 'fusion_plating.group_fp_sales_rep') self.u_sm = mk('sm', 'fusion_plating.group_fp_shop_manager_v2') self.u_smg = mk('smg', 'fusion_plating.group_fp_sales_manager') self.u_mgr = mk('mgr', 'fusion_plating.group_fp_manager') self.u_qm = mk('qm', 'fusion_plating.group_fp_quality_manager') self.u_owner = mk('owner', 'fusion_plating.group_fp_owner') def _visible(self, user, menu_xmlid): menu = self.env.ref(menu_xmlid, raise_if_not_found=False) if not menu: return None # menu not installed # An "invisible" menu is one the user can't read return bool(self.env['ir.ui.menu'].with_user(user).search_count([('id', '=', menu.id)])) def test_no_sees_no_plating_root(self): result = self._visible(self.u_no, 'fusion_plating.menu_fp_root') if result is None: self.skipTest('Plating root menu not found') self.assertFalse(result, '"No" role must not see Plating root') def test_technician_sees_shop_floor(self): result = self._visible(self.u_tech, 'fusion_plating_shopfloor.menu_fp_shopfloor') if result is None: self.skipTest('Shop Floor menu not found') self.assertTrue(result) def test_technician_does_not_see_sales(self): result = self._visible(self.u_tech, 'fusion_plating_configurator.menu_fp_sales') if result is None: self.skipTest('Sales menu not found') self.assertFalse(result, 'Technician must not see Sales & Quoting') def test_sales_rep_sees_sales(self): result = self._visible(self.u_sr, 'fusion_plating_configurator.menu_fp_sales') if result is None: self.skipTest('Sales menu not found') self.assertTrue(result) def test_sales_rep_does_not_see_shop_floor(self): result = self._visible(self.u_sr, 'fusion_plating_shopfloor.menu_fp_shopfloor') if result is None: self.skipTest('Shop Floor menu not found') self.assertFalse(result, 'Sales Rep must not see Shop Floor') def test_manager_sees_quality(self): result = self._visible(self.u_mgr, 'fusion_plating_quality.menu_fp_quality') if result is None: self.skipTest('Quality menu not found') self.assertTrue(result) def test_manager_does_not_see_compliance(self): result = self._visible(self.u_mgr, 'fusion_plating.menu_fp_compliance_hub') if result is None: self.skipTest('Compliance hub not found') self.assertFalse(result, 'Manager must not see Compliance hub') def test_qm_sees_compliance(self): result = self._visible(self.u_qm, 'fusion_plating.menu_fp_compliance_hub') if result is None: self.skipTest('Compliance hub not found') self.assertTrue(result)