from __future__ import annotations import unittest from govoplan_core.core.modules import ( DocumentationCondition, DocumentationTopic, ModuleManifest, user_workflow_scope_condition_issues, ) from govoplan_core.core.registry import PlatformRegistry, RegistryError def workflow_topic( *, conditions: tuple[DocumentationCondition, ...], documentation_types: tuple[str, ...] = ("user",), kind: str = "workflow", ) -> DocumentationTopic: return DocumentationTopic( id="example.workflow.task", title="Complete a task", summary="Complete the example task.", documentation_types=documentation_types, # type: ignore[arg-type] conditions=conditions, metadata={"kind": kind}, ) class DocumentationTopicContractTests(unittest.TestCase): def test_user_workflow_requires_scope_conditions(self) -> None: topic = workflow_topic(conditions=()) self.assertEqual( user_workflow_scope_condition_issues(topic), ("user workflow topics must declare at least one scope-conditioned alternative",), ) with self.assertRaisesRegex(RegistryError, "scope-conditioned alternative"): registry_for(topic).validate() def test_every_condition_alternative_must_be_scope_conditioned(self) -> None: topic = workflow_topic( conditions=( DocumentationCondition(required_scopes=("example:item:read",)), DocumentationCondition(required_modules=("example",)), ) ) with self.assertRaisesRegex(RegistryError, r"unscoped alternative\(s\): 2"): registry_for(topic).validate() def test_scoped_user_workflow_and_non_user_topics_are_accepted(self) -> None: scoped = workflow_topic( conditions=( DocumentationCondition(required_scopes=("example:item:read",)), DocumentationCondition(any_scopes=("example:item:write", "example:item:admin")), ) ) admin_workflow = workflow_topic( conditions=(), documentation_types=("admin",), ) user_reference = workflow_topic(conditions=(), kind="reference") self.assertEqual(user_workflow_scope_condition_issues(scoped), ()) self.assertEqual(user_workflow_scope_condition_issues(admin_workflow), ()) self.assertEqual(user_workflow_scope_condition_issues(user_reference), ()) registry_for(scoped, admin_workflow, user_reference).validate() def registry_for(*topics: DocumentationTopic) -> PlatformRegistry: registry = PlatformRegistry() registry.register( ModuleManifest( id="example", name="Example", version="1.0.0", documentation=topics, ) ) return registry if __name__ == "__main__": unittest.main()