refactor(plating-sec): sweep all ACL CSVs to new role group xmlids

Phase B of permissions overhaul. Mechanical text replacement across
11 ir.model.access.csv files:
  - group_fusion_plating_operator    -> fusion_plating.group_fp_technician
  - group_fusion_plating_supervisor  -> fusion_plating.group_fp_shop_manager_v2
  - group_fusion_plating_manager     -> fusion_plating.group_fp_manager
  - group_fusion_plating_admin       -> fusion_plating.group_fp_owner
  - group_fp_estimator (configurator)-> fusion_plating.group_fp_sales_rep
  - group_fp_accounting              -> fusion_plating.group_fp_manager
  - group_fp_receiving               -> fusion_plating.group_fp_shop_manager_v2
  - group_fp_shop_manager (legacy)   -> fusion_plating.group_fp_manager
  - group_fusion_plating_cgp_officer -> fusion_plating.group_fp_quality_manager
  - group_fusion_plating_cgp_designated_official -> fusion_plating.group_fp_owner

Backward-compat: old group xmlids still resolve (Phase A's implied_ids
chains keep old ACLs working for users still holding old groups).
This sweep ensures future-state correctness: when old groups are deleted
after the 30-day rollback window, ACLs continue resolving via the new
group xmlids.

Also adds fusion_plating/tests/test_acl_migration.py with sample-based
per-role access checks. The 2 CAPA tests are expected to fail until
Phase C implements the Manager/QM quality split.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-24 01:14:02 -04:00
parent bdf676e05a
commit 8eb2c2de95
26 changed files with 421 additions and 364 deletions

View File

@@ -4,3 +4,4 @@ from . import test_fp_job_state_machine
from . import test_fp_job_step_state_machine
from . import test_simple_recipe_flatten
from . import test_role_groups
from . import test_acl_migration

View File

@@ -0,0 +1,56 @@
from odoo.tests.common import TransactionCase, tagged
from odoo.exceptions import AccessError
@tagged('-at_install', 'post_install', 'fp_perms')
class TestAclMigration(TransactionCase):
"""Sample-based ACL coverage: pick 1 model per role and verify access."""
def setUp(self):
super().setUp()
Users = self.env['res.users'].with_context(no_reset_password=True)
def make(login, group_xmlid):
return Users.create({
'login': f'fp_test_{login}',
'name': f'FP Test {login.title()}',
'email': f'fp_test_{login}@example.com',
'groups_id': [(6, 0, [self.env.ref(group_xmlid).id])],
})
self.u_tech = make('tech', 'fusion_plating.group_fp_technician')
self.u_sm = make('sm', 'fusion_plating.group_fp_shop_manager_v2')
self.u_mgr = make('mgr', 'fusion_plating.group_fp_manager')
self.u_qm = make('qm', 'fusion_plating.group_fp_quality_manager')
self.u_sr = make('sr', 'fusion_plating.group_fp_sales_rep')
self.u_smg = make('smg', 'fusion_plating.group_fp_sales_manager')
def test_technician_can_read_jobs(self):
Jobs = self.env['fp.job'].with_user(self.u_tech)
Jobs.check_access_rights('read')
def test_technician_cannot_read_part_catalog(self):
Parts = self.env['fp.part.catalog'].with_user(self.u_tech)
with self.assertRaises(AccessError):
Parts.check_access_rights('read')
def test_sales_rep_can_read_part_catalog(self):
Parts = self.env['fp.part.catalog'].with_user(self.u_sr)
Parts.check_access_rights('read')
def test_shop_manager_can_read_receiving(self):
Rec = self.env['fp.receiving'].with_user(self.u_sm)
Rec.check_access_rights('read')
def test_manager_can_create_ncr(self):
Ncr = self.env['fusion.plating.ncr'].with_user(self.u_mgr)
Ncr.check_access_rights('create')
def test_manager_can_only_read_capa(self):
Capa = self.env['fusion.plating.capa'].with_user(self.u_mgr)
Capa.check_access_rights('read')
with self.assertRaises(AccessError):
Capa.check_access_rights('write')
def test_qm_can_write_capa(self):
Capa = self.env['fusion.plating.capa'].with_user(self.u_qm)
Capa.check_access_rights('write')