from __future__ import annotations import unittest from sqlalchemy import create_engine from sqlalchemy.orm import Session from govoplan_core.core.modules import ( FrontendModule, ModuleManifest, QuickAccessTool, ) from govoplan_core.core.registry import PlatformRegistry from govoplan_quick_access.backend.db.models import QuickAccessProfile from govoplan_quick_access.backend.service import build_catalogue, resolve_effective def registry_with_tools() -> PlatformRegistry: registry = PlatformRegistry() registry.register( ModuleManifest( id="example", name="Example", version="test", frontend=FrontendModule( module_id="example", quick_access_tools=( QuickAccessTool( id="example.work", module_id="example", category_id="work", label="Example work", surface_id="example.module", icon="list-checks", required_any=("example:item:read",), ), ), ), ) ) return registry class QuickAccessTests(unittest.TestCase): def setUp(self) -> None: self.engine = create_engine("sqlite+pysqlite:///:memory:") QuickAccessProfile.__table__.create(self.engine) def tearDown(self) -> None: self.engine.dispose() def test_catalogue_is_derived_from_manifest_tools(self) -> None: catalogue = build_catalogue(registry_with_tools()) self.assertEqual(["work", "calendar", "messages", "files"], [item.id for item in catalogue.categories]) self.assertEqual("example.work", catalogue.tools[0].id) def test_personal_catalogue_excludes_tools_without_permission(self) -> None: catalogue = build_catalogue( registry_with_tools(), permission_checker=lambda _scope: False ) self.assertEqual([], catalogue.tools) def test_catalogue_excludes_modules_outside_the_tenant_graph(self) -> None: catalogue = build_catalogue( registry_with_tools(), allowed_module_ids=(), ) self.assertEqual([], catalogue.tools) def test_upper_scope_block_cannot_be_overridden_by_user(self) -> None: with Session(self.engine) as session: session.add_all( ( QuickAccessProfile( scope_type="system", tenant_id=None, scope_id=None, scope_key="system:*", category_preferences={}, tool_preferences={"example.work": {"enabled": False}}, revision=2, ), QuickAccessProfile( scope_type="user", tenant_id="tenant-1", scope_id="account-1", scope_key="user:tenant-1:account-1", category_preferences={}, tool_preferences={"example.work": {"enabled": True}}, revision=2, ), ) ) session.commit() effective = resolve_effective( session, registry=registry_with_tools(), tenant_id="tenant-1", account_id="account-1", permission_checker=lambda _scope: True, ) work = next(item for item in effective.categories if item.id == "work") self.assertFalse(work.enabled) self.assertFalse(work.tools[0].enabled) self.assertEqual("system", work.tools[0].locked_by) def test_forced_tenant_category_remains_visible(self) -> None: with Session(self.engine) as session: session.add( QuickAccessProfile( scope_type="tenant", tenant_id="tenant-1", scope_id="tenant-1", scope_key="tenant:tenant-1", category_preferences={"work": {"enabled": True, "forced": True}}, tool_preferences={}, revision=2, ) ) session.commit() effective = resolve_effective( session, registry=registry_with_tools(), tenant_id="tenant-1", account_id="account-1", permission_checker=lambda _scope: True, ) work = next(item for item in effective.categories if item.id == "work") self.assertTrue(work.enabled) self.assertTrue(work.forced) self.assertEqual("tenant", work.locked_by) if __name__ == "__main__": unittest.main()