from __future__ import annotations import unittest from govoplan_core.core.modules import ( DocumentationConfigurationDecision, DocumentationConfigurationProviderRegistration, DocumentationCondition, DocumentationSourceDefinition, 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 test_documentation_configuration_and_source_extensions_are_validated(self) -> None: resolver = lambda _context, keys: { # noqa: E731 key: DocumentationConfigurationDecision(key=key, state="enabled") for key in keys } registry = PlatformRegistry() registry.register(ModuleManifest( id="example", name="Example", version="1.0.0", documentation_configuration_providers=( DocumentationConfigurationProviderRegistration( keys=("example.feature",), resolve=resolver, ), ), documentation_sources=( DocumentationSourceDefinition( id="example.handbook", kind="repository", label="Example handbook", ), ), )) registry.validate() duplicate = PlatformRegistry() duplicate.register(ModuleManifest( id="example", name="Example", version="1.0.0", documentation_configuration_providers=( DocumentationConfigurationProviderRegistration( keys=("example.feature",), resolve=resolver, ), DocumentationConfigurationProviderRegistration( keys=("example.feature",), resolve=resolver, ), ), )) with self.assertRaisesRegex(RegistryError, "duplicate documentation configuration key"): duplicate.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()