from __future__ import annotations import unittest from govoplan_access.backend.manifest import manifest class InterfaceDocumentationContractTests(unittest.TestCase): def test_password_f1_contexts_resolve_once_to_concise_bilingual_topics(self) -> None: expected = { "access.password.change": "access.help.password-change", "access.password.recover": "access.help.password-recovery", "access.password.issue-recovery": "access.help.password-issue-recovery", } for context, topic_id in expected.items(): with self.subTest(context=context): matches = [topic for topic in manifest.documentation if context in (topic.metadata or {}).get("help_contexts", ())] self.assertEqual([topic_id], [topic.id for topic in matches]) topic = matches[0] self.assertEqual({"admin", "user"}, set(topic.documentation_types)) for body in (topic.body, topic.translations["de"]["body"]): self.assertLessEqual(len(body.split()), 180) self.assertIn("API", body) self.assertIn("URLs", body) if context != "access.password.change": self.assertIn("15 minutes", topic.body) self.assertIn("15 Minuten", topic.translations["de"]["body"]) def test_password_change_flag_documents_opt_in_and_complete_recovery(self) -> None: topic = next(item for item in manifest.documentation if item.id == "access.reference.authentication-fields") self.assertIn("defaults to false", topic.body) self.assertIn("remains advisory metadata", topic.body) self.assertIn("standardmäßig false", topic.translations["de"]["body"]) recovery = next(item for item in manifest.documentation if item.id == "access.workflow.local-password-recovery") for required in ("15 minutes", "single-use", "system:*", "human API keys", "e9a2c5f8b1d4", "does not send email"): self.assertIn(required, recovery.body) self.assertIn("issued by that account for other people", recovery.body) self.assertIn("von diesem Konto für andere Personen ausgestellte", recovery.translations["de"]["body"]) def test_all_static_topics_have_complete_german_content(self) -> None: for topic in manifest.documentation: german = (topic.translations or {}).get("de", {}) self.assertEqual( {"title", "summary", "body"}, set(german), topic.id, ) self.assertTrue( all(str(value).strip() for value in german.values()), topic.id ) def test_access_admin_topics_publish_stable_help_contexts(self) -> None: topics = {topic.id: topic for topic in manifest.documentation} expected_contexts = { "access.workflow.grant-user-access": { "access.admin.users", "access.admin.groups", "access.admin.roles", "access.admin.blocked", }, "access.reference.admin-access-fields": { "access.admin.system-users", "access.admin.system-roles", "access.admin.tenant-users", "access.admin.tenant-groups", "access.admin.tenant-roles", }, "access.workflow.manage-api-keys": { "access.admin.api-keys", "access.api-keys.action.create", "access.api-keys.action.revoke", "access.api-keys.field.owner", "access.api-keys.field.expiry", "access.api-keys.field.scopes", "access.api-keys.secret", "access.api-keys.confirm-revoke", }, "access.workflow.manage-reusable-credentials": { "access.admin.system-credentials", "access.admin.tenant-credentials", "access.admin.group-credentials", "access.admin.user-credentials", "access.settings.credentials", "access.credentials", "access.credentials.field.secret", "access.credentials.field.clear-secret", "access.credentials.field.inherit-to-lower-scopes", "access.credentials.action.delete", "access.credentials.confirm-delete", }, "access.reference.external-function-role-mappings": { "access.admin.function-mappings", "access.explanation", }, "access.workflow.manage-service-account-credentials": { "access.admin.service-accounts", "access.service-accounts.action.create", "access.service-accounts.action.activation", "access.service-accounts.action.retire", "access.service-accounts.field.scope-ceiling", "access.service-accounts.action.rotate-credential", "access.service-accounts.action.revoke-credential", "access.service-accounts.field.credential-expiry", "access.service-accounts.field.credential-scopes", "access.service-accounts.secret", "access.service-accounts.confirm-retire", }, "access.workflow.manage-sessions": { "access.settings.sessions", "access.sessions.action.revoke", "access.sessions.action.revoke-others", "access.admin.user-sessions", }, } for topic_id, expected in expected_contexts.items(): self.assertIn(topic_id, topics) metadata = topics[topic_id].metadata or {} self.assertTrue( expected.issubset(set(metadata.get("help_contexts", ()))), topic_id, ) credential_topic = topics["access.workflow.manage-reusable-credentials"] self.assertEqual( {"title", "summary", "body"}, set(credential_topic.translations["de"]), ) self.assertIn( "nicht rückgängig gemacht", credential_topic.translations["de"]["body"], ) api_key_topic = topics["access.workflow.manage-api-keys"] self.assertEqual( {"title", "summary", "body"}, set(api_key_topic.translations["de"]), ) self.assertIn( "sofort und kann für diesen Schlüssel nicht rückgängig gemacht werden", api_key_topic.translations["de"]["body"], ) service_account_topic = topics[ "access.workflow.manage-service-account-credentials" ] self.assertEqual( {"title", "summary", "body"}, set(service_account_topic.translations["de"]), ) self.assertIn( "widerruft sämtliche aktiven Zugangsdaten", service_account_topic.translations["de"]["body"], ) def test_access_admin_surfaces_remain_declared(self) -> None: surface_ids = {surface.id for surface in manifest.frontend.view_surfaces} self.assertTrue( { "access.admin.system-roles", "access.admin.system-users", "access.admin.system-credentials", "access.admin.tenant-roles", "access.admin.tenant-function-mappings", "access.admin.tenant-groups", "access.admin.tenant-users", "access.admin.tenant-credentials", "access.admin.tenant-api-keys", "access.admin.tenant-service-accounts", "access.admin.group-credentials", "access.admin.user-credentials", "access.settings.credentials", "access.settings.sessions", }.issubset(surface_ids) ) if __name__ == "__main__": unittest.main()