Files

105 lines
4.5 KiB
Python
Raw Permalink Normal View History

"""M5 — Plugin-MiniApps tests.
Each business plugin contributes its MiniApps via the manifest
contribution (same pattern as contacts_stats from M4): dms, mail, wiki,
graph_rag and automation ship one dashboard app each, wired to the
plugin's own permission and frontend component.
"""
from __future__ import annotations
import pytest
@pytest.fixture(autouse=True)
def _fresh_registry():
from app.plugins.miniapp_registry import reset_miniapp_registry
reset_miniapp_registry()
yield
reset_miniapp_registry()
# (plugin_name, app_id, permission, component, order)
EXPECTED_APPS: list[tuple[str, str, str, str, int]] = [
("dms", "dms_folders", "dms:read", "@/components/dashboard/DmsFoldersWidget", 60),
("mail", "mail_unread", "mail:read", "@/components/dashboard/MailUnreadWidget", 70),
("wiki", "wiki_recent", "wiki:read", "@/components/dashboard/WikiRecentWidget", 80),
("graph_rag", "graph_overview", "graph:read", "@/components/dashboard/GraphOverviewWidget", 90),
("automation", "automation_status", "automation:read", "@/components/dashboard/AutomationStatusWidget", 100),
]
class TestPluginMiniAppContributions:
@pytest.mark.parametrize("plugin_name,app_id,permission,component,order", EXPECTED_APPS)
def test_manifest_contains_miniapp(
self, plugin_name: str, app_id: str, permission: str, component: str, order: int
):
"""The plugin manifest declares the MiniApp with the right fields."""
import importlib
module = importlib.import_module(f"app.plugins.builtins.{plugin_name}.plugin")
plugin_cls = getattr(module, f"{plugin_name.replace('_', '').title().replace('Graphrag', 'GraphRAG')}Plugin")
contributions = plugin_cls().manifest.miniapps
found = [m for m in contributions if m.app_id == app_id]
assert len(found) == 1, f"{plugin_name}: miniapp {app_id} missing"
app = found[0]
assert app.permission == permission
assert app.component == component
assert app.order == order
assert "dashboard" in app.hosts
def test_lifecycle_registers_all_plugin_miniapps(self):
"""BasePlugin._register_manifest_miniapps carries component (M4 fix)
for every contributing plugin — all five apps land in the registry."""
from app.plugins.miniapp_registry import get_miniapp_registry
registry = get_miniapp_registry()
for plugin_name, app_id, _permission, component, _order in EXPECTED_APPS:
import importlib
module = importlib.import_module(f"app.plugins.builtins.{plugin_name}.plugin")
plugin_cls = getattr(
module, f"{plugin_name.replace('_', '').title().replace('Graphrag', 'GraphRAG')}Plugin"
)
plugin_cls()._register_manifest_miniapps()
app = registry.get_app(app_id)
assert app is not None, f"{app_id} not registered"
assert app.component == component, f"{app_id}: component lost"
def test_settings_schemas_present(self):
"""List-style widgets expose max_items in their settings_schema so the
generic settings form (M3) can render it."""
import importlib
for plugin_name, app_id, *_rest in EXPECTED_APPS:
module = importlib.import_module(f"app.plugins.builtins.{plugin_name}.plugin")
plugin_cls = getattr(
module, f"{plugin_name.replace('_', '').title().replace('Graphrag', 'GraphRAG')}Plugin"
)
contributions = plugin_cls().manifest.miniapps
app = next(m for m in contributions if m.app_id == app_id)
fields = app.settings_schema.get("fields", [])
assert any(f["name"] == "max_items" for f in fields), (
f"{app_id}: max_items missing in settings_schema"
)
def test_automation_legacy_reregistration_removed():
"""M5 fix: automation's on_activate used to re-register manifest
miniapps with only a subset of fields AFTER super().on_activate(),
overwriting the correct M1 registration (component/permission lost —
measured live on production 2026-08-30: automation_status comp=no).
The legacy block must stay removed; super() owns the registration.
"""
import inspect
from app.plugins.builtins.automation.plugin import AutomationPlugin
src = inspect.getsource(AutomationPlugin.on_activate)
assert "for miniapp in self.manifest.miniapps" not in src, (
"legacy miniapp re-registration re-introduced"
)
assert "kommunikation.contracts import get_miniapp_registry" not in src