From aaaf49989ce7c827beaf91047e0c5446246a484d Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Sun, 19 Apr 2026 13:45:39 -0400 Subject: [PATCH] test(fusion_accounting_bank_rec): coexistence behavior Verifies that the coexistence group recompute method works as expected in both Enterprise-present and Enterprise-absent scenarios, and that the bank-rec menu is gated by the group while the engine itself is always available. Made-with: Cursor --- fusion_accounting_bank_rec/__manifest__.py | 2 +- fusion_accounting_bank_rec/tests/__init__.py | 1 + .../tests/test_coexistence.py | 86 +++++++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 fusion_accounting_bank_rec/tests/test_coexistence.py diff --git a/fusion_accounting_bank_rec/__manifest__.py b/fusion_accounting_bank_rec/__manifest__.py index 351435d3..1fd91b0c 100644 --- a/fusion_accounting_bank_rec/__manifest__.py +++ b/fusion_accounting_bank_rec/__manifest__.py @@ -1,6 +1,6 @@ { 'name': 'Fusion Accounting — Bank Reconciliation', - 'version': '19.0.1.0.24', + 'version': '19.0.1.0.25', 'category': 'Accounting/Accounting', 'sequence': 28, 'summary': 'Native V19 bank reconciliation widget with AI confidence scoring + behavioural learning.', diff --git a/fusion_accounting_bank_rec/tests/__init__.py b/fusion_accounting_bank_rec/tests/__init__.py index b7b1532e..1d31ba0e 100644 --- a/fusion_accounting_bank_rec/tests/__init__.py +++ b/fusion_accounting_bank_rec/tests/__init__.py @@ -19,3 +19,4 @@ from . import test_controller from . import test_auto_reconcile_wizard from . import test_bulk_reconcile_wizard from . import test_migration_round_trip +from . import test_coexistence diff --git a/fusion_accounting_bank_rec/tests/test_coexistence.py b/fusion_accounting_bank_rec/tests/test_coexistence.py new file mode 100644 index 00000000..77ad0e7e --- /dev/null +++ b/fusion_accounting_bank_rec/tests/test_coexistence.py @@ -0,0 +1,86 @@ +"""Coexistence tests: fusion_accounting_bank_rec menus only visible +when Enterprise's account_accountant is absent. + +Strategy: mock the install state by toggling the group's user list directly, +then verify the recompute method aligns it with module presence.""" + +from unittest.mock import patch +from odoo.tests.common import TransactionCase, tagged + + +@tagged('post_install', '-at_install') +class TestCoexistence(TransactionCase): + + def setUp(self): + super().setUp() + self.group = self.env.ref( + 'fusion_accounting_core.group_fusion_show_when_enterprise_absent') + + def _account_accountant_installed(self): + return bool(self.env['ir.module.module'].sudo().search([ + ('name', '=', 'account_accountant'), + ('state', '=', 'installed'), + ])) + + def test_group_exists(self): + self.assertTrue(self.group, "Coexistence group must exist") + + def test_recompute_when_enterprise_present(self): + """When account_accountant is installed, group should be empty.""" + if not self._account_accountant_installed(): + self.skipTest( + "Local DB doesn't have account_accountant installed; " + "this test only meaningful in Enterprise-present scenario" + ) + self.env['res.users']._fusion_recompute_coexistence_group() + self.assertEqual( + len(self.group.user_ids), 0, + "Coexistence group should be empty when Enterprise is installed", + ) + + def test_recompute_when_enterprise_absent(self): + """When account_accountant is uninstalled, all internal users get the group.""" + if self._account_accountant_installed(): + # Simulate by mocking the enterprise-installed check. + with patch.object( + type(self.env['ir.module.module']), + '_fusion_is_enterprise_accounting_installed', + return_value=False, + ): + self.env['res.users']._fusion_recompute_coexistence_group() + internal_users = self.env['res.users'].search([ + ('share', '=', False), + ]) + self.assertGreater( + len(self.group.user_ids & internal_users), 0, + "Coexistence group should contain internal users when " + "Enterprise is absent", + ) + else: + self.env['res.users']._fusion_recompute_coexistence_group() + internal = self.env['res.users'].search([('share', '=', False)]) + self.assertGreater(len(self.group.user_ids & internal), 0) + + def test_menu_has_coexistence_group(self): + """The fusion bank-rec root menu must have the coexistence group attached.""" + menu = self.env.ref( + 'fusion_accounting_bank_rec.menu_fusion_bank_rec_root', + raise_if_not_found=False, + ) + if not menu: + self.skipTest("Menu not yet loaded — Task 42 must run first") + # Odoo 19 renamed ir.ui.menu.groups_id -> group_ids; tolerate either. + groups_field = getattr(menu, 'group_ids', None) or menu.groups_id + self.assertIn( + self.group, groups_field, + "Menu must require the coexistence group", + ) + + def test_engine_works_regardless_of_coexistence(self): + """The reconcile engine must work even when Enterprise is installed + (it's the AI tools/menu that gate; the engine is always available).""" + self.assertIn( + 'fusion.reconcile.engine', self.env.registry, + "Engine must always be available when fusion_accounting_bank_rec " + "is installed", + )